description: “Telecom 通话管理框架架构设计——Android 通话的调度中心,涵盖 CallsManager 通话调度、ConnectionService 底层连接、InCallService 上层 UI、PhoneAccount 路由选择、CallAudioRoute 音频路由、CallRedirectionService 呼叫重定向。”Telecom 是 Android 通话能力的中央调度中心。它位于 Telephony 框架(底层)和 Dialer 应用(上层)之间,负责管理所有来电/去电的完整生命周期。无论通话是 CS (2G/3G)、VoLTE、VoWiFi 还是 VoIP (如微信/WhatsApp),Telecom 都以统一的方式处理。Telecom 解决了 Android 生态中一个根本问题:如何让不同的"电话服务提供方"(Telephony 的 CS、IMS 的 VoLTE、第三方的 VoIP)和不同的"电话 UI 体验方"(Dialer 应用、车载系统、手表)无缝协作。这就是 Google 的 “Telecom 通话分离” 设计。设计理念: Telecom 的设计核心是"关注点分离" (Separation of Concerns)。Connector Service 负责"如何建立媒体通道",InCall Service 负责"如何展示 UI"。两者通过 Telecom 的Connection和Call抽象进行桥接,彼此完全解耦。1. 核心职责通话调度 (CallsManager):管理所有活跃通话,处理来电排队/去电冲突路由选择 (PhoneAccount):根据PhoneAccount选择合适的ConnectionService发起通话ConnectionService 管理:绑定并管理 CS/IMS/VoIP 等不同的 ConnectionService 实现InCallService 管理:绑定并管理 Dialer/车载/手表等不同的 InCall UI 实现音频路由 (CallAudioRoute):管理音频从哪个设备输出(听筒/扬声器/蓝牙/有线耳机)通话筛选 (CallScreening):在来电被 UI 展示前进行筛选(静音/拒绝/重定向)2. 核心类与源码锚点[CallsManager.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java):通话调度核心。管理所有Call对象,处理 addCall/removeCall 回调。[Call.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/Call.java):单次通话的框架表示。包含通话状态、呼叫者信息、通话分析数据。[ConnectionServiceWrapper.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceWrapper.java):ConnectionService的包装器。管理与 Telephony/VoIP 等底层连接服务的 Binder 通信。[InCallController.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/InCallController.java):InCallService的控制器。管理 Dialer UI 的绑定和通信。[CallAudioRouteStateMachine.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/CallAudioRouteStateMachine.java):音频路由状态机。自动选择听筒/扬声器/蓝牙/有线耳机。[TelecomSystem.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/TelecomSystem.java):Telecom 服务的系统入口。负责初始化所有组件。[ConnectionServiceRepository.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceRepository.java):ConnectionService的仓库。管理所有已注册的 ConnectionService 实现。[ConnectionServiceFocusManager.java](file:///d:/Resource%20Android%2016/android-16/packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceFocusManager.java):管理不同 ConnectionService 之间的焦点切换。3. Google 设计技巧深入分析3.1 Connection/Call 双层抽象 — 通话分离的核心这是 Telecom 最重要的设计决策:Telephony Side (ConnectionService) Telecom (Call) UI Side (InCallService) ┌────────────────────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ TelephonyConnectionService │ │ │ │ DialerInCallService │ │ └→ Connection (CS/VoLTE) │ ←───→ │ Call │ ←───→ │ └→ InCallService UI │ │ │ │ │ │ │ │ VoIPConnectionService │ │ (状态管理) │ │ CarInCallService │ │ └→ Connection (SIP) │ ←───→ │ │ ←───→ │ └→ 车载 UI │ └────────────────────────────┘ └──────────────┘ └──────────────────────┘Connection(左侧):由ConnectionService创建,代表"媒体通道已经建立"Call(中间):Telecom 的抽象,独立于任何具体的 ConnectionServiceInCallService(右侧):将Call的状态渲染为 UIGoogle设计技巧 #1 — ConnectionService ↔ InCallService 的"桥接模式"解耦:Call类中通过CachedCallback统一管理状态回调和队列回调:staticfinalintTYPE_QUEUE=1;// 批量处理的回调(如视频状态切换)staticfinalintTYPE_STATE=2;// 状态变更回调(如 ACTIVE→HOLDING)这种分类允许 Telecom 在TYPE_QUEUE场景下做批量优化,减少不必要的 IPC 调用。而TYPE_STATE的回调需要立刻处理。3.2 CallsManager — 通话调度状态机publicclassCallsManagerextendsCall.ListenerBaseimplementsCreateConnectionResponse,EventManager.Loggable{// CallsManager 监听每个 Call 的状态变化@OverridepublicvoidonCallAdded(Callcall){...}@OverridepublicvoidonCallRemoved(Callcall){...}}Google设计技巧 #2 — CallsManager 的 Listener 模式 + 分层处理:CallsManagerListenerBase提供了所有回调的默认空实现,InCallController继承它并只重写自己关心的回调。这是一个"模板方法 + 观察者"的组合模式——基类定义所有可能的回调,子类选择性重写。publicabstractclassCallsManagerListenerBaseimplementsCallsManager.CallsManagerListener{publicvoidonCallAdded(Callcall){}publicvoidonCallRemoved(Callcall){}publicvoidonCallStateChanged(Callcall,intoldState,intnewState){}// ... 更多回调}3.3 PhoneAccount — 通话路由选择PhoneAccount是 Telecom 的路由机制核心——它将每个"电话能力"抽象为一个账户:SIM 卡通话:PhoneAccount对应一个 SubIdVoIP 通话:PhoneAccount对应一个 VoIP 应用(如 WhatsApp)紧急呼叫:PhoneAccount带有CAPABILITY_PLACE_EMERGENCY_CALLS标记publicclassPhoneAccount{publicstaticfinalintCAPABILITY_PLACE_EMERGENCY_CALLS=0x10;publicstaticfinalintCAPABILITY_SIM_SUBSCRIPTION=0x01;// ...}Google设计技巧 #3 — PhoneAccount 架构解决的问题:在没有 PhoneAccount 之前,Android 通话只有一个"默认电话应用"。引入 PhoneAccount 后:用户可以在 Dual-SIM 设备上选择"用 SIM1 打"还是"用 SIM2 打"VoIP 应用可以与系统电话应用平级——用户可以在通讯录中选择"用 WhatsApp 呼叫"还是"用电话呼叫"每个PhoneAccount关联一个ConnectionService,Telecom 通过它找到正确的底层服务3.4 CallAudioRoute — 音频路由状态机CallAudioRouteStateMachine管理音频输出设备的自动选择:publicclassCallAudioRouteStateMachineextendsStateMachineimplementsCallAudioRouteAdapter{// 音频路由由 Peripheral Adapter 监听物理设备变化// 通过 StateMachine 自动切换}CallAudioRoutePeripheralAdapter监听外部设备:publicclassCallAudioRoutePeripheralAdapterimplementsWiredHeadsetManager.Listener{// 监听有线耳机插拔// 监听蓝牙 SCO 连接}Google设计技巧 #4 — StateMachine + Adapter 的音频路由架构:音频路由是一个典型的"环境感知"场景——设备插入/拔出耳机、蓝牙连接/断开、用户手动切换听筒/扬声器。CallAudioRouteStateMachine使用StateMachine(Android 的经典状态机框架)管理这些转换,CallAudioRoutePeripheralAdapter负责感知物理设备变化。两者通过CallAudioRouteAdapter接口解耦。3.5 InCallController — 多 UI 端支持publicclassInCallControllerextendsCallsManagerListenerBase{publicclassInCallServiceConnection{...}publicstaticclassInCallServiceInfo{...}// 一个 InCallServiceBindingConnection 绑定一个 InCallServiceprivateclassInCallServiceBindingConnectionextendsInCallServiceConnection{...}}Google设计技巧 #5 — 一个 Telecom 实例支持多个 InCallService 同时连接:Telecom 不是只绑定一个 Dialer 应用。它通过InCallController管理多个InCallServiceConnection,每个InCallServiceConnection绑定一个不同的 UI 提供方(如 Dialer + 车载系统 + 穿戴设备)。这一设计使多屏生态成为可能——用户在车载屏幕上接电话的同时,手机上的 Dialer UI 也同步显示通话状态。3.6 ConnectionServiceFocusManager — 多服务焦点管理publicclassConnectionServiceFocusManager{// 当多个 ConnectionService 需要同时使用音频时// 焦点管理器决定哪个服务持有音频焦点}Google设计技巧 #6 — 服务间音频焦点的仲裁机制:在 Multi-SIM 或 CS+VoIP 混合场景,可能有多个ConnectionService同时活跃。ConnectionServiceFocusManager决定哪个服务获得音频焦点——例如,当 CS 通话被 hold,VoIP 通话变为 active 时,焦点管理器将音频路由从 CS 转移到 VoIP。这与 Android 的AudioManager音频焦点系统协同工作,但专门针对通话场景进行了优化。4. 核心架构4.1 分层关系