Telephony 整体架构

3 阅读6分钟

一、架构分层概览

┌─────────────────────────────────────────────────────────────┐
│                    应用层 (Applications)                      │
│      (Phone App / Message App / ConnectivityService)        │
└────────────────────┬────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────┐
│         Java Framework 层 (frameworks_opt_telephony)         │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Public API 层                                        │   │
│  │ - TelephonyManager                                   │   │
│  │ - SubscriptionManager                               │   │
│  │ - SmsManager / MmsManager                            │   │
│  │ - CarrierConfigManager                              │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ 内部框架层 (Internal Framework)                      │   │
│  │                                                      │   │
│  │ ┌──────────────┐  ┌─────────────────────────────┐   │   │
│  │ │PhoneFactory  │  │  Phone Objects              │   │   │
│  │ │ -创建Phone   │  │  - GsmCdmaPhone             │   │   │
│  │ │   实例       │  │  - ImsPhone                 │   │   │
│  │ │              │  │  - Phone (接口)             │   │   │
│  │ └──────────────┘  └─────────────────────────────┘   │   │
│  │                                                      │   │
│  │ ┌────────────────────────────────────────────────┐  │   │
│  │ │         RIL (Radio Interface Layer)             │  │   │
│  │ │ - 与 Modem 通信的核心枢纽                       │  │   │
│  │ │ - 异步命令/响应处理                             │  │   │
│  │ │ - RadioIndication 无线指示处理                  │  │   │
│  │ └────────────────────────────────────────────────┘  │   │
│  │                                                      │   │
│  │ ┌──────────────────────────────────────────────┐    │   │
│  │ │    核心管理器                                │    │   │
│  │ │ - ServiceStateTracker (网络状态)              │    │   │
│  │ │ - CallTracker (通话状态)                      │    │   │
│  │ │ - SmsDispatcher (短信分发)                    │    │   │
│  │ │ - DataNetworkController (数据连接)            │    │   │
│  │ │ - UiccController (卡管理)                     │    │   │
│  │ │ - SubscriptionManagerService (订阅管理)       │    │   │
│  │ │ - PhoneSwitcher (多卡协调)                    │    │   │
│  │ │ - PhoneNotifier (状态通知)                    │    │   │
│  │ │ - TelephonyRegistry (广播注册)                │    │   │
│  │ └──────────────────────────────────────────────┘    │   │
│  └──────────────────────────────────────────────────────┘   │
└────────────────────┬────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────┐
│              HAL 层 (Hardware Abstraction)                   │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ HIDL 1.0-1.6 / AIDL (Android 13+)                   │   │
│  │ - IRadio (请求/响应)                               │   │
│  │ - IRadioIndication (无线指示)                       │   │
│  │ - IRadioResponse (请求响应)                        │   │
│  │ - IRadioConfig (配置管理)                          │   │
│  │                                                      │   │
│  │ 分类服务 (AIDL 分组):                               │   │
│  │ - IRadioData (数据相关)                            │   │
│  │ - IRadioMessaging (短彩信)                         │   │
│  │ - IRadioModem (Modem 管理)                         │   │
│  │ - IRadioNetwork (网络注册)                         │   │
│  │ - IRadioSim (SIM 卡)                              │   │
│  │ - IRadioVoice (语音呼叫)                           │   │
│  │ - IRadioIms (IMS)                                 │   │
│  └──────────────────────────────────────────────────────┘   │
└────────────────────┬────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────┐
│            Modem RIL (Baseband Processor)                    │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ libril.so (RIL daemon)                              │   │
│  │ - 请求队列管理 (RequestInfo 链表)                   │   │
│  │ - 与 Vendor RIL 通信 (dlopen vendor lib)            │   │
│  │ - 无线指示分发                                       │   │
│  │ - Wake Lock 管理                                    │   │
│  │ - 超时重试机制                                       │   │
│  └──────────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Vendor RIL (如 QCRIL/高通)                          │   │
│  │ - 厂商特定实现                                       │   │
│  │ - Modem 驱动交互                                    │   │
│  └──────────────────────────────────────────────────────┘   │
└────────────────────┬────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────┐
│         Modem (Baseband/处理器)                              │
│  - 真实硬件处理通话、短信、数据、信号                          │
│  - 与运营商网络通信                                          │
│  - PDP Context 管理                                        │
│  - 信号强度/网络制式检测                                     │
└─────────────────────────────────────────────────────────────┘

二、关键组件详解

2.1 PhoneFactory - 初始化工厂

// 创建多张卡的 Phone 对象和 RIL 实例
int numPhones = TelephonyManager.getDefault().getActiveModemCount();
sPhones = new Phone[numPhones];
sCommandsInterfaces = new RIL[numPhones];

for (int i = 0; i < numPhones; i++) {
    sCommandsInterfaces[i] = new RIL(context,
            RadioAccessFamily.getRafFromNetworkType(networkModes[i]),
            cdmaSubscription, i, featureFlags);
}

// 创建其他全局组件
sUiccController = UiccController.make(context);
sSubscriptionManagerService = new SubscriptionManagerService(context, ...);
sPhoneSwitcher = new PhoneSwitcher(context, looper);

职责

  • 单例工厂,创建和管理系统中所有 Phone 实例
  • 创建 RIL 实例(每个 Modem 一个)
  • 初始化全局服务(UICC、Subscription、PhoneSwitcher 等)

2.2 Phone 接口与实现

Phone 是逻辑手机对象,代表一个 Modem/SIM 卡:

/**
 * A base implementation for the com.android.internal.telephony.Phone interface.
 */
public class Phone {
    // RIL 引用(与 Modem 通信)
    protected CommandsInterface mCi;
    
    // 回调通知
    protected PhoneNotifier mNotifier;
    
    // 核心功能管理
    protected ServiceStateTracker mSST;           // 网络状态
    protected CallTracker mCallTracker;            // 通话状态
    protected SmsDispatcher mSmsDispatcher;        // 短信
    protected DataNetworkController mDataNetworkController;  // 数据连接
    
    // 卡管理
    protected UiccController mUiccController;
    protected IccFileHandler mIccFileHandler;
    protected IccRecords mIccRecords;
    
    // IMS 支持
    protected ImsPhone mImsPhone;
    
    // 订阅
    protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    protected int mPhoneId;  // 物理卡槽编号
}

Phone 的主要实现

  • GsmCdmaPhone - 支持 GSM/CDMA 的逻辑手机
  • ImsPhone - IMS(VoIP)实现

2.3 RIL - 无线接口层

/**
 * RIL implementation of the CommandsInterface.
 * 
 * HIDL/AIDL IRadio 与 Java RIL 之间的适配
 */
public class RIL extends BaseCommands implements CommandsInterface {
    // 待发送的请求队列
    SparseArray<RILRequest> mRequestList = new SparseArray<>();
    
    // Modem 对象引用
    volatile android.hardware.radio.V1_4.IRadio mRadioProxy = null;
    
    // Wake Lock(防止系统睡眠)
    WakeLock mRILWakeLock;
    
    // 指示处理
    RadioIndication mRadioIndication;
    RadioResponse mRadioResponse;
    
    // 订阅 ID
    final Integer mPhoneId;
}

RIL 的核心职责

  1. 命令分发 - 将 Phone 的请求转换为 HAL 调用
  2. 异步处理 - 维护请求队列,管理 token 匹配
  3. 指示处理 - 接收来自 Modem 的无线指示
  4. Wake Lock - 长操作期间防止睡眠

2.4 ServiceStateTracker - 网络状态管理

public class ServiceStateTracker extends Handler {
    // 网络注册状态
    private ServiceState mServiceState;
    
    // 信号强度
    private SignalStrength mSignalStrength;
    
    // 运营商信息
    private OperatorInfo mOperatorInfo;
    
    // 监听 RIL 指示
    mCi.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
    mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGED, null);
    
    // 卡状态变化
    mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
}

功能

  • 监听 RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 等指示
  • 更新网络状态(2G/3G/4G/5G、漫游、信号强度等)
  • 通知 PhoneNotifier 进行系统广播

2.5 DataNetworkController - 数据连接管理

负责 3G/4G/5G 数据连接的全生命周期:

主要子组件:
├─ DataProfileManager        - APN 配置管理
├─ DataNetworkList           - 活跃连接列表
├─ DataEvaluation            - 连接评估逻辑
├─ DataSettingsManager       - 数据设置(用户关闭/运营商配置)
└─ DataStallRecoveryManager  - 卡顿恢复

关键流程

  1. ConnectivityService 请求数据连接
  2. TelephonyNetworkFactory 转发到 DataNetworkController
  3. DataProfileManager 选择合适的 APN
  4. 通过 RIL 向 Modem 发送 setupDataCall()
  5. Modem 激活 PDP Context,返回 IP 等信息
  6. DataNetwork 更新 LinkProperties,通知系统

2.6 PhoneSwitcher - 多卡协调

/**
 * PhoneSwitcher 负责多卡协调:
 * 1. 多个 Phone 对象与单个数据连接的映射
 * 2. 数据卡/语音卡的切换
 * 3. 网络请求的优先级评估
 */
private final PhoneSwitcher mPhoneSwitcher;

多卡场景处理

场景处理方式
副卡发送彩信PhoneSwitcher 临时为副卡建立 MMS 数据连接
副卡通话保持默认数据卡的连接,在主卡通话的同时
用户切换默认数据卡释放旧卡连接,为新卡建立连接
IMS 数据请求可能需要特殊 APN 或卡槽

2.7 SubscriptionManagerService - 订阅管理

/**
 * 管理 SIM 卡订阅信息
 */
public class SubscriptionManagerService {
    // 默认语音卡
    private final WatchedInt mDefaultVoiceSubId;
    
    // 默认数据卡
    private final WatchedInt mDefaultDataSubId;
    
    // 默认短信/彩信卡
    private final WatchedInt mDefaultSmsSubId;
    
    // 每个卡槽的状态
    private final int[] mSimState;
    
    // subId 到 SubscriptionInfo 的映射
    private final SubscriptionMap<Integer, SubscriptionInfo> mSubscriptionInfoMap;
}

职责

  • 维护 SubId ↔ PhoneId 映射
  • 管理默认卡设置
  • 卡状态变化处理
  • 订阅信息持久化

2.8 PhoneNotifier 与 TelephonyRegistry

┌─────────────────────────────────────────┐
│  Phone 状态变化事件                      │
│  (如网络状态、来电、信号强度等)          │
└──────────────┬──────────────────────────┘
               │
       ┌───────▼────────┐
       │ PhoneNotifier  │
       │ (接口定义)     │
       └───────┬────────┘
               │
   ┌───────────▼─────────────┐
   │ DefaultPhoneNotifier    │
   │ (具体实现)              │
   └───────────┬─────────────┘
               │
       ┌───────▼──────────────┐
       │ TelephonyRegistry    │
       │ (系统服务)           │
       └───────┬──────────────┘
               │
   ┌───────────▼──────────────────────┐
   │  广播给监听者                    │
   │  - TelephonyManager              │
   │  - TelephonyCallback             │
   │  - PhoneStateListener            │
   │  - Phone App (UI 更新)           │
   └────────────────────────────────────┘

三、关键数据流

场景:来电显示流程

Modem 检测来电
    ↓
RIL daemon 接收 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
    ↓
RadioIndication.callStateChanged(indicationType)
    ↓
RIL.processIndication() → RIL.unsljLogRec()
    ↓
Phone.notifyCallStateChanged()
    ↓
CallTracker 更新呼叫状态
    ↓
PhoneNotifier.notifyCallStateChanged()
    ↓
TelephonyRegistry.notifyCallStateForSubscriber(subId, ...)
    ↓
广播 TelephonyManager.ACTION_PHONE_STATE_CHANGED
    ↓
Phone App / Telecom 服务接收
    ↓
UI 更新 & 振铃音

关键点

  • subId 在整个流程中追踪,确保正确卡槽
  • 多卡时 TelephonyRegistry 能区分不同卡的状态

场景:副卡数据连接建立

App 请求网络 (任意 App)
    ↓
ConnectivityService.requestNetwork(NetworkRequest with MMS capability)
    ↓
TelephonyNetworkFactory[subId=2].requestNetwork()
    ↓
PhoneSwitcher.onRequestNetwork() 
    → 检查多卡设备上是否需要切换
    → 如果当前 subId != 2,临时切换
    ↓
DataNetworkController[subId=2].setupDataNetwork()
    ↓
DataProfileManager.selectDataProfile(subId=2, apnType=MMS)
    → 选择副卡的 MMS APN 配置
    ↓
RIL[phoneId=1].setupDataCall(apn="mms.carrier.com", ...)
    ↓
Modem 建立 PDP Context
    ↓
RadioResponse.setupDataCallResponse()
    ↓
DataNetwork 更新 LinkProperties
    ↓
ConnectivityService 更新路由
    ↓
App 获得数据连接
    ↓
MMS 操作完成后释放连接

多卡特殊处理

  • PhoneSwitcher 记录数据切换事件(metrics)
  • DataSettingsManager 检查 MMS_ALWAYS_ALLOWED 政策
  • 连接释放时恢复原默认数据卡

四、系统启动顺序

1. SystemServer.startOtherServices()
    ↓
2. TelephonyRegistry 启动
    ↓
3. PhoneFactory.makeDefaults()
    → 创建 RIL 数组
    → 创建 Phone 数组
    → 创建 UiccController
    → 创建 SubscriptionManagerService
    → 创建 PhoneSwitcher
    → 创建 TelephonyNetworkFactory 数组
    ↓
4. 每个 Phone 初始化
    → 创建 ServiceStateTracker
    → 创建 CallTracker
    → 创建 DataNetworkController
    → 创建 ImsPhone
    ↓
5. RIL 与 HAL 连接
    → getService("android.hardware.radio.IRadio")
    → 初始化 RadioIndication / RadioResponse
    ↓
6. 卡状态检测
    → UiccController 扫描卡
    → SubscriptionManagerService 加载订阅信息
    ↓
7. 网络注册
    → ServiceStateTracker 向 RIL 注册各种指示
    → Phone 进入等待网络状态的循环
    ↓
8. 服务就绪

五、层次通信方式

Java → HAL (同步或异步)

Phone/RIL (Java) 
    ↓ (Binder/JNI)
IRadio HAL (C++)
    ↓ (hwbinder)
Vendor RIL (C)
    ↓ (Socket/其他)
Modem 驱动

HAL → Java (异步回调)

Modem 事件
    ↓ (socket/serial)
Vendor RIL 接收
    ↓ (RIL_onUnsolicitedResponse)
RIL daemon (libril.so)
    ↓ (binder callback)
RadioIndication (HAL)
    ↓ (binder)
RIL.processIndication() (Java)
    ↓
Phone 处理器
    ↓
状态更新 + 广播

六、重要的交互模式

1. 观察者模式(Registrant)

// Phone 注册状态变化回调
mCi.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);

// RIL 指示到达时触发
→ ServiceStateTracker.handleMessage(EVENT_NETWORK_STATE_CHANGED)
  → 查询网络状态
  → 更新 mServiceState
  → 通知 PhoneNotifier

2. 消息队列处理

// 所有 Phone/RIL 操作都通过 Handler 消息队列
Handler mCiHandler = new Handler(looper);

// 异步执行
mCiHandler.post(() -> {
    // RIL 操作
    mRil.setupDataCall(...);
});

3. 回调链(Callback Chain)

PendingIntent (应用层)
    ↓
SMSDispatcher
    ↓
RIL.sendSMS()
    ↓
HAL.sendSms()
    ↓
RadioResponse.sendSmsResponse()
    ↓
RIL 回调 SMSDispatcher
    ↓
SMSDispatcher 触发 PendingIntent
    ↓
应用接收结果

这就是 Android Telephony 的完整架构!重点是理解三层分离(应用 → Framework → HAL → Modem)和异步事件驱动的设计模式。

有任何具体流程想深入了解吗?