资讯动态

Matter tv-app Android Common-API 模块详解:内容应用与 Matter Agent 服务的 AIDL 跨进程通信机制

发布时间:2026/9/18 12:39:58 来源:尧图企业网站定制
Matter tv-app Android Common-API 模块详解内容应用与 Matter Agent 服务的 AIDL 跨进程通信机制【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip本文围绕 Matter 项目connectedhomeip中 tv-app 的 Androidcommon-api模块展开系统讲解内容应用Content App如何借助 AIDL 接口、集群/属性 ID 常量与 Intent 常量与 Matter Agent 服务进行跨进程交互。读完本文你将理解setSupportedClusters与reportAttributeChange两个核心接口的语义边界、权限绑定校验机制并能结合仓库内的示例客户端与服务端实现走通完整的动态端点注册与属性变更上报流程。一、模块定位common-api 是什么Matter 的 tv-app 示例采用平台应用platform-app 内容应用content-app的双进程架构Matter 协议栈运行在平台应用中而具体的流媒体内容由第三方内容应用承载。common-api模块就是为二者定义契约的公共接口层。根据 模块说明文档The tv-app common-api module defines the interface to interact with the Matter agent service for the content apps. This module defines the AIDL interfaces, clusters and command abstractions accessible. It also defines various constants and intent field definitions that would be used by the content app while interacting with the Matter SDK.概括来说common-api提供四类内容AIDL 接口跨进程调用 Matter Agent 服务的抽象接口集群与命令抽象媒体投屏相关的 Cluster/Command/Attribute ID 常量Intent 常量命令下发、属性读取等交互所需的 Action 与 extra 字段名动态端点能力帮助内容应用动态注册端点集群并向 SDK 上报属性变更。模块目录结构如下examples/tv-app/android/App/common-api/common-api/ ├── README.md └── src/main/ ├── aidl/com/matter/tv/app/api/ │ ├── IMatterAppAgent.aidl # 核心 AIDL 接口 │ ├── SetSupportedClustersRequest.aidl │ └── SupportedCluster.aidl └── java/com/matter/tv/app/api/ ├── Clusters.java # Cluster/Command/Attribute ID 常量 └── MatterIntentConstants.java # Action / 权限 / extra 字段常量二、权限要求绑定 Matter Agent 服务的前置条件按照 README 的 Permissions needed 一节内容应用要使用 Matter Agent 接口必须同时满足三个条件内容应用需查询并绑定query and bind一个处理com.matter.tv.app.api.action.MatterAppAgentAction 的服务宿主进程即平台应用必须持有com.matter.tv.app.api.permission.SEND_DATA权限内容应用客户端自身必须持有com.matter.tv.app.api.permission.BIND_SERVICE_PERMISSION权限才能完成绑定。这三个字符串并非文档中的口头约定它们由 MatterIntentConstants.java 精确定义public static final String ACTION_MATTER_COMMAND com.matter.tv.app.api.action.MATTER_COMMAND; public static final String ACTION_MATTER_AGENT com.matter.tv.app.api.action.MatterAppAgent; public static final String PERMISSION_MATTER_AGENT_BIND com.matter.tv.app.api.permission.BIND_SERVICE_PERMISSION; public static final String PERMISSION_MATTER_AGENT com.matter.tv.app.api.permission.SEND_DATA;权限校验在 AIDL 文件头部注释中同样有说明见 IMatterAppAgent.aidl/* * To use this interface, partners should query for and bind to a service that handles the com.matter.tv.app.api.action.MatterAppAgent Action. * They should verify the host process holds the com.matter.tv.app.api.permission.SEND_DATA permission * To bind to this service the client app itself must hold com.matter.tv.app.api.permission.BIND_SERVICE_PERMISSION. */ interface IMatterAppAgent { ... }三、Matter App Agent 核心 AIDL 接口Matter Agent 服务对外暴露的接口是IMatterAppAgent包含两个方法。完整定义见 IMatterAppAgent.aidlinterface IMatterAppAgent { boolean setSupportedClusters(in SetSupportedClustersRequest request); boolean reportAttributeChange(in int clusterId, in int attributeId); }3.1 setSupportedClusters动态集群上报该 API 允许合作方内容应用向 Matter Agent动态上报其支持的集群集合。README 与 AIDL 注释中对其语义有三点重要约束值得逐条展开非增量式not incremental每次调用都必须上报应用支持的全量集群列表而不是只上报新增部分缺省即删除上一次调用中上报、但本次调用中遗漏的集群会被移除不影响静态集群在应用资源中静态声明的集群不受此机制影响、不会被移除但动态集群可以基于集群名cluster name覆盖并隐藏override and hide同名静态集群。这一语义在服务端实现 ContentAppAgentService.java 中得到印证服务通过Binder.getCallingUid()反查调用方包名再从已发现的内容应用集合中定位ContentApp对象并整体替换其集群列表final int callingUID Binder.getCallingUid(); final String pkg getApplicationContext().getPackageManager().getNameForUid(callingUID); ContentApp contentApp ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApp(pkg); if (contentApp ! null) { contentApp.setSupportedClusters(request.supportedClusters); return true; }注意服务端还有一层身份核验它不信任调用方自报的包名而是以 UID 为据反查确保动态集群只能归属到真实发起调用的内容应用。3.2 reportAttributeChange属性变更上报该 API 让内容应用在自身属性值发生变化后通知 SDK参数为集群 ID 与属性 IDpublic boolean reportAttributeChange(int clusterId, int attributeId) { ... }从服务端实现可以看到其处理链路reportAttributeChange找到调用方对应的ContentApp端点后通过线程池异步转发给AppPlatformService.reportAttributeChange(endpointId, clusterId, attributeId)——注释中说明这样做的目的是避免内容应用在命令处理过程中同步调用时阻塞 CHIP 协议栈锁// Make this call async so that even if the content apps make this call during command // processing and synchronously, the command processing thread will not block for the // chip stack lock. executorService.execute(() - { AppPlatformService.get() .reportAttributeChange(contentApp.getEndpointId(), clusterId, attributeId); });即reportAttributeChange只是告诉平台应用这个端点上的这个属性变了最终由平台应用侧的 CHIP 栈完成向控制端的属性通知Notify分发。此外若该内容应用尚无有效端点endpointId INVALID_ENDPOINTID调用会直接失败并返回 false。3.3 请求数据结构SupportedCluster 与 SetSupportedClustersRequest集群上报通过两个 parcelable 数据结构承载。SupportedCluster.aidl 定义了单个集群的完整描述parcelable SupportedCluster { int clusterIdentifier; // 集群 ID int features; // 功能位图 int[] optionalCommandIdentifiers; // 可选命令 ID 列表 int[] optionalAttributesIdentifiers; // 可选属性 ID 列表 }SetSupportedClustersRequest.aidl 则是一次请求的载体parcelable SetSupportedClustersRequest { ListSupportedCluster supportedClusters; }从字段设计可以推断该结构能够表达支持哪些集群、启用哪些 feature、支持哪些可选命令与可选属性这与 Matter 数据模型中集群的 feature/optional command/optional attribute 概念一一对应。四、Clusters 常量类集群、命令与属性 ID 速查Clusters.java 以嵌套静态类的方式组织常用集群 ID 及其对应的命令、属性、类型常量为媒体投屏场景下各端与 Matter 规范中定义的相关集群之间提供免查表的引用方式。文件头注释注明其定位是media related clusters并留有通过 ZAP 工具生成的 TODO。当前已覆盖的集群及其 ID 如下集群常量类集群 ID典型命令命令 ID典型属性属性 IDClusters.AccountLogin0x050EGetSetupPIN(0x00)、Login(0x02)、Logout(0x03)—Clusters.MediaPlayback0x0506Play(0x00)、Pause(0x01)、Seek(0x0B) 等CurrentState(0x00)、SampledPosition(0x03)、PlaybackSpeed(0x04)Clusters.ContentLauncher0x050ALaunchContent(0x00)、LaunchURL(0x01)AcceptHeader(0x00)、SupportedStreamingProtocols(0x01)Clusters.TargetNavigator0x0505NavigateTarget(0x00)TargetList(0x00)、CurrentTarget(0x01)几个有代表性的常量定义示例// MediaPlayback 集群播放状态枚举与状态码 public static class Types { public static class PlaybackStateEnum { public static final int Playing 0x00; public static final int Paused 0x01; public static final int NotPlaying 0x02; public static final int Buffering 0x03; } public static class StatusEnum { public static final int Success 0x00; public static final int InvalidStateForCommand 0x01; public static final int NotAllowed 0x02; ... } } // ContentLauncher 集群搜索参数类型枚举Actor/Channel/Genre/Provider... public static class ParameterEnum { public static final int Actor 0x00; public static final int Channel 0x01; ... public static final int Video 0x0D; }配合reportAttributeChange使用时内容应用可直接引用这些常量避免裸写魔法数字例如// 上报 MediaPlayback 集群的 CurrentState 属性变更 client.reportAttributeChange(Clusters.MediaPlayback.Id, Clusters.MediaPlayback.Attributes.CurrentState);五、Intent 常量命令下发与属性读取的交互契约MatterIntentConstants.java 除了前文介绍的 Action 与权限字符串外还定义了命令/属性交互所需的全部 extra 字段名常量值用途ACTION_MATTER_COMMANDcom.matter.tv.app.api.action.MATTER_COMMAND平台应用向内容应用下发 Matter 命令ACTION_MATTER_AGENTcom.matter.tv.app.api.action.MatterAppAgent绑定 Matter Agent 服务的 ActionPERMISSION_MATTER_AGENT_BIND...permission.BIND_SERVICE_PERMISSION客户端绑定所需权限PERMISSION_MATTER_AGENT...permission.SEND_DATA宿主进程需持有的权限EXTRA_COMMAND_PAYLOADEXTRA_COMMAND_PAYLOAD命令参数负载字节数组EXTRA_RESPONSE_PAYLOADEXTRA_RESPONSE_PAYLOAD响应负载EXTRA_ATTRIBUTE_ACTIONEXTRA_ATTRIBUTE_ACTION属性操作类型ATTRIBUTE_ACTION_READATTRIBUTE_ACTION_READ属性读取操作标记EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT—携带用于回复的 PendingIntentEXTRA_COMMAND_ID/EXTRA_CLUSTER_ID/EXTRA_ATTRIBUTE_ID—命令/集群/属性 ID在命令下发方向服务端 ContentAppAgentService.java 的sendCommand静态方法演示了这些常量的实际拼装方式以ACTION_MATTER_COMMAND构建 Intent写入EXTRA_COMMAND_PAYLOAD、EXTRA_COMMAND_ID、EXTRA_CLUSTER_ID并指定目标包名后投递给内容应用同时定义了ACTION_MATTER_RESPONSEcom.matter.tv.app.api.action.MATTER_COMMAND_RESPONSE用于内容应用回传结果以及FAILED_UNSUPPORTED_CLUSTER0xc3、FAILED_UNSUPPORTED_COMMAND0x81、FAILED_UNSUPPORTED_ATTRIBUTE0x86、FAILED_TIMEOUT0x94等错误状态码常量供命令链路两端统一错误语义。六、实战内容应用侧的完整调用链仓库自带的内容应用示例 MatterAgentClient.java 展示了第三方内容应用接入common-api的标准姿势可作为集成参考实现。其流程为初始化在 Activity 或 BroadcastReceiver 中调用MatterAgentClient.initialize(context)缓存 Context用于连接丢失后重连解析与绑定以new Intent(MatterIntentConstants.ACTION_MATTER_AGENT)查询可绑定的服务并通过resolveBindIntent校验客户端自身持有PERMISSION_MATTER_AGENT_BIND、宿主持有PERMISSION_MATTER_AGENTSEND_DATA再执行bindService同步屏障首次远端调用前用CountDownLatch等待服务连接建立超时 8 秒避免在 binder 尚未就绪时调用业务调用两个对外方法与 AIDL 接口一一对应并处理RemoteExceptionpublic boolean reportClusters(SetSupportedClustersRequest request) { IMatterAppAgent matterAgent getOrReinitializeMatterAgent(); if (matterAgent null) return false; try { return matterAgent.setSupportedClusters(request); } catch (RemoteException e) { Log.e(TAG, Error invoking remote method to set supported clusters to Matter agent); } return false; } public boolean reportAttributeChange(int clusterId, int attributeId) { IMatterAppAgent matterAgent getOrReinitializeMatterAgent(); if (matterAgent null) return false; try { return matterAgent.reportAttributeChange(clusterId, attributeId); } catch (RemoteException e) { Log.e(TAG, Error invoking remote method to report attribute change to Matter agent); } return false; }值得注意的健壮性设计getOrReinitializeMatterAgent()在发现 binder 为空时会触发一次重连重试保证内容应用进程重启、服务重启等场景下调用依然可用。七、关键文件索引内容路径模块说明文档examples/tv-app/android/App/common-api/README.md核心 AIDL 接口IMatterAppAgent.aidl请求数据结构SupportedCluster.aidl、SetSupportedClustersRequest.aidl集群/属性 ID 常量Clusters.javaIntent/权限常量MatterIntentConstants.java内容应用参考客户端MatterAgentClient.java平台应用 Agent 服务实现ContentAppAgentService.java八、小结common-api是 Matter tv-app 双进程架构中的契约层它以 AIDL 定义了setSupportedClusters全量覆盖式动态集群注册与reportAttributeChange属性变更通知两条上行通道以 Intent 常量定义了下行命令与属性读取通道并以Clusters常量类消除了内容应用与 Matter 集群 ID 之间的认知成本。对合作方而言集成路径清晰——依赖该模块、声明相应权限、参考MatterAgentClient完成服务绑定即可获得动态端点注册与属性上报能力对平台侧而言服务端以 UID 反查包名的做法在开放 API 的同时保证了端点归属的安全性。【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价