Android Telephony 系统 - 完整功能与核心类深度解析(基于 AOSP 源码)

3 阅读17分钟

一、系统整体架构

Android Telephony 系统是一个分层的通信管理框架,负责管理语音通话、短信/彩信、数据连接、SIM 卡管理和各种电信功能。从源码角度看,它横跨多个代码仓库:

┌───────────────────────────────────────────────────────────────────┐
│                   应用层 API (frameworks/base)                     │
│  TelephonyManager, SmsManager, TelecomManager,                    │
│  TelephonyCallback, SubscriptionManager, SignalStrength           │
└────────────────────────┬──────────────────────────────────────────┘
                         │ AIDL / Binder
┌────────────────────────▼──────────────────────────────────────────┐
│         Framework 服务层 (packages/services/Telephony)            │
│  PhoneGlobals, PhoneInterfaceManager(ITelephony),                 │
│  TelephonyConnectionService, ImsService                           │
└────────────────────────┬──────────────────────────────────────────┘
                         │ 直接调用
┌────────────────────────▼──────────────────────────────────────────┐
│      核心业务逻辑层 (frameworks/opt/telephony)                     │
│  PhoneFactory → Phone → GsmCdmaPhone / ImsPhone                  │
│  GsmCdmaCallTracker, ServiceStateTracker,                         │
│  DataNetworkController, InboundSmsHandler,                        │
│  UiccController, SubscriptionController                           │
└────────────────────────┬──────────────────────────────────────────┘
                         │ CommandsInterface
┌────────────────────────▼──────────────────────────────────────────┐
│          RIL 通信层 (frameworks/opt/telephony)                    │
│  RIL.java → HIDL/AIDL HAL → RadioDataProxy                       │
│  与底层 modem/RIL 通信                                            │
└────────────────────────┬──────────────────────────────────────────┘
                         │ IRadio HAL
┌────────────────────────▼──────────────────────────────────────────┐
│              硬件层 (Modem/RIL)                                    │
│   2G/3G/4G/5G 无线电收发                                          │
└───────────────────────────────────────────────────────────────────┘

1.1 关键源码路径

模块源码路径
公开 APIframeworks/base/telephony/java/android/telephony/
Telephony 服务packages/services/Telephony/
核心业务逻辑frameworks/opt/telephony/src/java/com/android/internal/telephony/
IMS 电话frameworks/opt/telephony/.../imsphone/
UICC/SIMframeworks/opt/telephony/.../uicc/
数据连接frameworks/opt/telephony/.../data/
RILframeworks/opt/telephony/.../RIL.java

二、Phone 接口体系 - 核心抽象层

2.1 Phone 类层次结构

// 源码: Phone.java
public abstract class Phone extends Handler implements PhoneInternalInterface {
    // Phone 是所有电话实现的基础抽象类
    // 关键成员:
    protected CommandsInterface mCi;              // RIL 接口
    public ServiceStateTracker mSST;              // 服务状态追踪
    public GsmCdmaCallTracker mCT;                // 呼叫追踪器
    private ImsPhone mImsPhone;                   // IMS 电话实例
    
    // 数据管理 (新数据栈)
    private DataNetworkController mDataNetworkController;
    // 数据管理 (旧数据栈)
    private DcTracker mDcTracker;
}
                    Phone (抽象基类)
                    implements PhoneInternalInterface
                         │
          ┌──────────────┼──────────────┐
          │              │              │
   GsmCdmaPhone    ImsPhoneBase    SipPhone(已废弃)
          │              │
          │         ImsPhone
          │
    ┌─────┴──────┐
    │ GSM 模式    │ CDMA 模式
    │ isPhoneTypeGsm() 切换
    └────────────┘

2.2 GsmCdmaPhone - 核心实现

GsmCdmaPhone.java 是 Phone 的主要实现,统一了 GSM 和 CDMA 两种电话技术:

// 源码: GsmCdmaPhone.java
public class GsmCdmaPhone extends Phone {
    public GsmCdmaCallTracker mCT;        // 呼叫追踪器
    public ServiceStateTracker mSST;      // 服务状态追踪
    
    // 关键: IMS 电话优先处理
    @Override
    public void acceptCall(int videoState) throws CallStateException {
        Phone imsPhone = mImsPhone;
        if (imsPhone != null && imsPhone.getRingingCall().isRinging()) {
            imsPhone.acceptCall(videoState);  // IMS 来电优先
        } else {
            mCT.acceptCall();                 // CS 域来电
        }
    }
    
    @Override
    public void rejectCall() throws CallStateException {
        mCT.rejectCall();
    }
    
    @Override
    public void conference() {
        if (mImsPhone != null && mImsPhone.canConference()) {
            mImsPhone.conference();  // IMS 会议优先
            return;
        }
        if (isPhoneTypeGsm()) {
            mCT.conference();        // GSM 会议
        }
        // CDMA 不支持标准会议
    }
}

GsmCdmaPhone 的关键设计

  • IMS 优先策略:当 mImsPhone 不为 null 且 IMS 呼叫活跃时,优先委托给 ImsPhone 处理
  • GSM/CDMA 双模式:通过 isPhoneTypeGsm() 在运行时切换行为
  • 组件组合:通过 mCT(呼叫追踪)、mSST(服务状态)、mCi(RIL 接口)组合实现功能

2.3 ImsPhone - IMS 电话实现

ImsPhone.java 处理所有 IMS 相关的电话功能:

// 源码: ImsPhone.java
public class ImsPhone extends ImsPhoneBase {
    // IMS 专有扩展参数
    public static class ImsDialArgs extends DialArgs {
        private RttTextStream mRttTextStream;        // RTT 实时文本
        private int mRetryCallFailCause;              // 重试失败原因
        private int mRetryCallFailNetworkType;        // 重试失败网络类型
        private boolean mIsWpsCall;                   // WPS 紧急呼叫
    }
    
    // IMS 注册管理
    // VoLTE/VoWiFi 呼叫处理
    // SRVCC (CS → IMS 切换) 支持
}

2.4 PhoneFactory - Phone 实例管理

// PhoneFactory 负责创建和管理 Phone 实例
// 支持多 SIM (DSDS/DSDA):
Phone[] sPhones;  // 每个 SIM 卡槽对应一个 Phone 实例

// Phone 创建流程:
PhoneFactory.makePhone() → 
    new GsmCdmaPhone() → 
        初始化 mCT, mSST, mCi →
            注册 RIL 事件监听

三、呼叫管理系统

3.1 Call 状态机详解

GsmCdmaCallTracker.java 管理三个核心 Call 对象:

// 源码: GsmCdmaCallTracker.java
public class GsmCdmaCallTracker extends CallTracker {
    // 三个主要的 Call 容器
    public GsmCdmaCall mRingingCall = new GsmCdmaCall(this);     // 来电/来电等待
    public GsmCdmaCall mForegroundCall = new GsmCdmaCall(this);  // 前景呼叫(活跃)
    public GsmCdmaCall mBackgroundCall = new GsmCdmaCall(this);  // 背景呼叫(保持)
    
    // 连接数组 - 单个通话的底层连接
    public GsmCdmaConnection[] mConnections;
    
    // GSM: 最多 19 个连接 (7 GSM + 12 IMS SRVCC)
    public static final int MAX_CONNECTIONS_GSM = 19;
    // CDMA: 最多 8 个连接
    private static final int MAX_CONNECTIONS_CDMA = 8;
    
    // 整体电话状态
    public PhoneConstants.State mState = PhoneConstants.State.IDLE;
}

Call 状态转移图

┌──────────────────────────────────────────────────────────────┐
│                    GsmCdmaCall.State                          │
│                                                              │
│  IDLE ──dial()──→ DIALING ──alerting──→ ALERTING            │
│                      │                        │              │
│                      └────────────────────────┘              │
│                                   │                          │
│                               connected                      │
│                                   │                          │
│                               ACTIVE                         │
│                              ╱       ╲                       │
│                    hold() ╱           ╲ switchWaiting...     │
│                          ╱               ╲                   │
│                     HOLDING          WAITING (来电等待)      │
│                          ╲               ╱                   │
│                    unhold() ╲           ╱ acceptCall()       │
│                              ╲       ╱                       │
│                               ACTIVE                         │
│                                   │                          │
│                              hangup()                        │
│                                   │                          │
│                               DISCONNECTED → IDLE           │
└──────────────────────────────────────────────────────────────┘

3.2 呼叫操作源码解析

acceptCall - 接听来电

// 源码: GsmCdmaCallTracker.java:594
public void acceptCall() throws CallStateException {
    if (mRingingCall.getState() == GsmCdmaCall.State.INCOMING) {
        // 新来电: 直接发送 ATA 命令
        setMute(false);
        mCi.acceptCall(obtainCompleteMessage());
    } else if (mRingingCall.getState() == GsmCdmaCall.State.WAITING) {
        // 来电等待: 需要先保持当前通话
        if (isPhoneTypeGsm()) {
            setMute(false);
        } else {
            // CDMA: 直接将等待连接移到前景
            GsmCdmaConnection cwConn = (GsmCdmaConnection)(mRingingCall.getLatestConnection());
            cwConn.updateParent(mRingingCall, mForegroundCall);
            cwConn.onConnectedInOrOut();
            updatePhoneState();
        }
        switchWaitingOrHoldingAndActive();
    } else {
        throw new CallStateException("phone not ringing");
    }
}

rejectCall - 拒接来电

// 源码: GsmCdmaCallTracker.java:625
public void rejectCall() throws CallStateException {
    if (mRingingCall.getState().isRinging()) {
        // AT+CHLD=0: "release held or UDUB"
        mCi.rejectCall(obtainCompleteMessage());
    } else {
        throw new CallStateException("phone not ringing");
    }
}

switchWaitingOrHoldingAndActive - 切换通话

// 源码: GsmCdmaCallTracker.java:643
public void switchWaitingOrHoldingAndActive() throws CallStateException {
    if (mRingingCall.getState() == GsmCdmaCall.State.INCOMING) {
        throw new CallStateException("cannot be in the incoming state");
    } else {
        if (isPhoneTypeGsm()) {
            // GSM: 发送 AT+CHLD=2
            mCi.switchWaitingOrHoldingAndActive(
                obtainCompleteMessage(EVENT_SWITCH_RESULT));
        } else {
            // CDMA: 发送 Flash 命令
            if (mForegroundCall.getConnectionsCount() > 1) {
                flashAndSetGenericTrue();
            } else {
                mCi.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
            }
        }
    }
}

3.3 呼叫轮询机制 (pollCalls)

GsmCdmaCallTracker 通过轮询机制同步 Modem 的呼叫状态:

RIL 上报 EVENT_CALL_STATE_CHANGE
         │
         ▼
pollCallsWhenSafe() → pollCalls()
         │
         ▼
mCi.getCurrentCalls() → 发送 AT+CLCC
         │
         ▼
EVENT_POLL_CALLS_RESULT → handlePollCalls()
         │
         ▼
updateCallsFromNewCallList()
    ├── 新连接 → 创建 GsmCdmaConnection
    ├── 连接状态变化 → 更新 Call 对象
    └── 连接消失 → 处理断开

3.4 PhoneConstants.State 与 Call.State 的关系

// PhoneConstants.State: 整体电话状态 (4 种)
IDLE        // 无通话
RINGING     // 有来电
OFFHOOK     // 通话中

// GsmCdmaCall.State: 单个 Call 的状态 (7 种)
IDLE        // 空 Call
ACTIVE      // 活跃通话
HOLDING     // 保持中
DIALING     // 拨号中
ALERTING    // 对方振铃
INCOMING    // 来电
WAITING     // 来电等待
DISCONNECTED // 已断开

// 映射关系:
// PhoneConstants.State.IDLE     ← 所有 Call 都是 IDLE
// PhoneConstants.State.RINGING  ← mRingingCall 是 INCOMING 或 WAITING
// PhoneConstants.State.OFFHOOK  ← 其他任何非 IDLE 状态

四、服务状态与信号管理

4.1 ServiceStateTracker - 网络状态核心

ServiceStateTracker.java 是网络注册状态的核心管理器:

// 源码: ServiceStateTracker.java
public class ServiceStateTracker extends Handler {
    protected CommandsInterface mCi;          // RIL 接口
    private ServiceState mSS;                 // 当前服务状态
    private ServiceState mNewSS;              // 新服务状态 (待合并)
    
    // 关键事件
    static final int EVENT_NETWORK_STATE_CHANGED = 1;
    static final int EVENT_GET_SIGNAL_STRENGTH = 2;
    static final int EVENT_POLL_STATE_REGISTRATION = 4;
    static final int EVENT_POLL_STATE_GPRS = 5;
    static final int EVENT_POLL_STATE_OPERATOR = 6;
    static final int EVENT_NITZ_TIME = 7;
}

服务状态更新流程

RIL 上报 EVENT_NETWORK_STATE_CHANGED
         │
         ▼
ServiceStateTracker.handleMessage()
         │
         ▼
pollState() → 并行发送多个 RIL 请求:
    ├── mCi.getVoiceRegistrationState()   // 语音注册状态
    ├── mCi.getDataRegistrationState()    // 数据注册状态
    ├── mCi.getOperator()                 // 运营商信息
    └── mCi.getNetworkSelectionMode()     // 选网模式
         │
         ▼
EVENT_POLL_STATE_* 回调 → pollStateDone()
         │
         ▼
合并 mNewSS → mSS (去重过滤)
         │
         ▼
通知注册者:
    ├── mVoiceRegStateRegistrants
    ├── mDataRegStateRegistrants
    ├── mServiceStateRegistrants
    └── mPhone.notifyServiceStateChanged()

4.2 ServiceState 数据结构

// ServiceState 包含完整的网络状态信息
public class ServiceState implements Parcelable {
    // 网络注册状态
    private int mVoiceRegState;      // 语音注册状态
    private int mDataRegState;       // 数据注册状态
    
    // 运营商信息
    private String mOperatorAlphaLong;    // "China Mobile"
    private String mOperatorAlphaShort;   // "CMCC"
    private String mOperatorNumeric;      // MCC/MNC "46000"
    
    // 网络注册信息 (Android 12+)
    private List<NetworkRegistrationInfo> mNetworkRegistrationInfos;
    
    // 特殊状态
    private boolean mIsEmergencyOnly;
    private boolean mIsManualNetworkSelection;
    private int mNrFrequencyRange;        // 5G 频段: FR1/FR2/mmWave
    
    // 状态常量
    public static final int STATE_IN_SERVICE = 0;
    public static final int STATE_OUT_OF_SERVICE = 1;
    public static final int STATE_EMERGENCY_ONLY = 2;
    public static final int STATE_POWER_OFF = 3;
}

4.3 NetworkRegistrationInfo - 分域注册信息

// NetworkRegistrationInfo 将语音和数据注册状态分离管理
public class NetworkRegistrationInfo {
    // 域类型
    public static final int DOMAIN_CS = 1;     // Circuit Switch (语音)
    public static final int DOMAIN_PS = 2;     // Packet Switch (数据)
    
    // 传输类型
    public static final int TRANSPORT_TYPE_WWAN = 1;  // 蜂窝
    public static final int TRANSPORT_TYPE_WLAN = 2;  // WiFi
    
    // 注册状态
    public static final int REGISTRATION_STATE_NOT_REGISTERED = 0;
    public static final int REGISTRATION_STATE_HOME = 1;
    public static final int REGISTRATION_STATE_SEARCHING = 2;
    public static final int REGISTRATION_STATE_DENIED = 3;
    public static final int REGISTRATION_STATE_UNKNOWN = 4;
    public static final int REGISTRATION_STATE_ROAMING = 5;
    
    // 关键字段
    private int mDomain;
    private int mTransportType;
    private int mRegistrationState;
    private int mAccessNetworkTechnology;  // NETWORK_TYPE_LTE, NR 等
    private int mRejectCause;              // 注册拒绝原因
}

4.4 SignalStrength 信号强度

// 源码: SignalStrength.java
public class SignalStrength implements Parcelable {
    // 信号强度等级 (0-4)
    public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
    public static final int SIGNAL_STRENGTH_POOR = 1;       // 1格
    public static final int SIGNAL_STRENGTH_MODERATE = 2;   // 2格
    public static final int SIGNAL_STRENGTH_GOOD = 3;       // 3格
    public static final int SIGNAL_STRENGTH_GREAT = 4;      // 4格
    
    // 5G NR 信号等级判定 (基于 SS-RSRP):
    // dBm >= -110 → GREAT (4格)
    // -110 > dBm >= -118 → GOOD (3格)
    // -118 > dBm >= -123 → MODERATE (2格)
    // -123 > dBm → POOR (1格)
}

4.5 TelephonyDisplayInfo - 网络显示信息

// Android 11+ 新增,用于状态栏网络图标显示
TelephonyDisplayInfo {
    networkType: NETWORK_TYPE_LTE,        // 真实网络类型
    overrideNetworkType: OVERRIDE_NETWORK_TYPE_NR_ADVANCED  // 显示覆盖类型
}

// 常见覆盖类型:
// OVERRIDE_NETWORK_TYPE_NONE           → 显示 4G/LTE
// OVERRIDE_NETWORK_TYPE_LTE_CA         → 显示 4G+ (LTE 载波聚合)
// OVERRIDE_NETWORK_TYPE_NR_ADVANCED    → 显示 5G+ (NR 毫米波)
// OVERRIDE_NETWORK_TYPE_NR_NSA         → 显示 5G (NSA)
// OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO → 显示 4G+ Pro

五、短信系统

5.1 InboundSmsHandler 状态机

InboundSmsHandler.java 使用状态机管理短信接收:

// 源码: InboundSmsHandler.java
public abstract class InboundSmsHandler extends StateMachine {
    // 三个核心状态
    private final IdleState mIdleState = new IdleState();
    private final DeliveringState mDeliveringState = new DeliveringState();
    private final WaitingState mWaitingState = new WaitingState();
    
    // 状态层级:
    // DefaultState
    //   ├── IdleState
    //   └── DeliveringState
    //         └── WaitingState
}

短信接收状态转移

┌──────────┐  EVENT_NEW_SMS  ┌────────────────┐  广播发送  ┌──────────────┐
│ IdleState ├───────────────→│ DeliveringState ├─────────→│ WaitingState │
└─────┬────┘                 └────────────────┘           └──────┬───────┘
      │                          │     ↑                       │
      │ EVENT_RELEASE_WAKELOCK   │     │ EVENT_BROADCAST_SMS   │
      │ (释放 WakeLock)          │     │ (新消息到达)          │
      │                          │     │                       │
      │                     EVENT_RETURN_TO_IDLE               │
      │                          │                             │
      │◄─────────────────────────┘    EVENT_BROADCAST_COMPLETE│
      │                               (广播完成)              │
      │◄─────────────────────────────────────────────────────┘

IdleState 处理逻辑

// 源码: InboundSmsHandler.java:472
private class IdleState extends State {
    @Override
    public void enter() {
        sendMessageDelayed(EVENT_RELEASE_WAKELOCK, getWakeLockTimeout());
    }
    
    @Override
    public void exit() {
        mWakeLock.acquire();  // 离开 Idle 时获取 WakeLock
    }
    
    @Override
    public boolean processMessage(Message msg) {
        switch (msg.what) {
            case EVENT_NEW_SMS:
            case EVENT_INJECT_SMS:
            case EVENT_BROADCAST_SMS:
                deferMessage(msg);           // 延迟处理
                transitionTo(mDeliveringState);
                return HANDLED;
            case EVENT_RELEASE_WAKELOCK:
                mWakeLock.release();         // 释放 WakeLock
                return HANDLED;
        }
    }
}

DeliveringState 处理逻辑

// 源码: InboundSmsHandler.java
private class DeliveringState extends State {
    @Override
    public boolean processMessage(Message msg) {
        switch (msg.what) {
            case EVENT_NEW_SMS:
                handleNewSms((AsyncResult) msg.obj);  // 处理新短信
                sendMessage(EVENT_RETURN_TO_IDLE);
                return HANDLED;
            case EVENT_BROADCAST_SMS:
                InboundSmsTracker tracker = (InboundSmsTracker) msg.obj;
                if (processMessagePart(tracker)) {
                    transitionTo(mWaitingState);  // 有广播要发送
                } else {
                    sendMessage(EVENT_RETURN_TO_IDLE);  // 无广播
                }
                return HANDLED;
        }
    }
}

5.2 短信发送流程

SmsManager.sendTextMessage()
    │
    ├─ 权限检查 (SEND_SMS)
    │
    ├─ 获取 ISms.aidl (Binder 接口)
    │
    ├─ IccSmsInterfaceManager.sendTextForSubscriber()
    │   ├─ 权限再检查
    │   ├─ 载波短信过滤 (CarrierMessagingService)
    │   └─ SMSDispatcher.sendText()
    │       ├─ 创建 SubmitPDU
    │       └─ mCi.sendSMS(smscPDU, pdu, response)
    │           └─ RIL → Modem → SMSC
    │
    └─ 触发 sentIntent 回调
        ├─ RESULT_OK (成功)
        ├─ RESULT_ERROR_GENERIC_FAILURE
        ├─ RESULT_ERROR_RADIO_OFF
        ├─ RESULT_ERROR_NULL_PDU
        └─ RESULT_ERROR_NO_SERVICE

5.3 短信接收完整流程

Modem 收到 SMS_PDU
    │
    ▼
RIL 上报 EVENT_NEW_SMS
    │
    ▼
GsmInboundSmsHandler (extends InboundSmsHandler)
    │
    ├─ 1. 解析 PDU (SmsMessage.createFromPdu)
    │     ├─ 提取: originatingAddress, messageBody, timestamp
    │     └─ 检查: 是否为 Class 0 (闪信)
    │
    ├─ 2. 写入 Raw 表 (content://sms/raw)
    │     └─ 用于多部分短信重组和崩溃恢复
    │
    ├─ 3. 多部分短信处理
    │     ├─ 检查是否所有分段已到达
    │     ├─ 重组: 按顺序拼接所有分段 PDU
    │     └─ 超时清理: 30秒未完成的多部分短信
    │
    ├─ 4. 载波过滤 (CarrierMessagingService)
    │     └─ 运营商可拦截/修改短信
    │
    ├─ 5. 广播分发
    │     ├─ SMS_DELIVER_ACTION → 默认短信应用 (高优先级)
    │     ├─ SMS_RECEIVED_ACTION → 所有监听者 (低优先级)
    │     └─ 数据短信 → DATA_SMS_RECEIVED_ACTION
    │
    └─ 6. 写入 SMS 数据库
          └─ content://sms/inbox

六、SIM 卡管理系统

6.1 UICC 类层次结构

UiccController.java 的源码注释中给出了完整的类图:

// 源码: UiccController.java 注释
//
//                       UiccController (单例)
//                            │
//                        UiccSlot[]          ← 物理卡槽
//                            │
//                        UiccCard            ← 物理卡
//                            │
//                        UiccPort[]          ← 逻辑端口 (eSIM 多端口)
//                            │
//                       UiccProfile          ← 配置文件
//                          │   │
//                          │   └──── CatService     ← SIM Toolkit
//                          │
//                    UiccCardApplication      ← 卡应用 (USIM/CSIM/ISIM)
//                          │   │
//                          │   └── IccFileHandler  ← 文件系统访问
//                          │       ├── SIMFileHandler
//                          │       ├── UsimFileHandler
//                          │       ├── RuimFileHandler
//                          │       ├── CsimFileHandler
//                          │       └── IsimFileHandler
//                          │
//                          └── IccRecords       ← 卡数据记录
//                              ├── SIMRecords   (GSM SIM)
//                              ├── RuimRecords  (CDMA RUIM)
//                              └── IsimUiccRecords (IMS ISIM)

6.2 UiccController 核心功能

// 源码: UiccController.java
public class UiccController extends Handler {
    private CommandsInterface[] mCis;       // RIL 接口数组
    public UiccSlot[] mUiccSlots;           // 物理卡槽数组
    private int[] mPhoneIdToSlotId;         // Phone → Slot 映射
    
    // 应用族类型
    public static final int APP_FAM_3GPP = 1;   // GSM/UMTS/LTE (USIM)
    public static final int APP_FAM_3GPP2 = 2;  // CDMA (CSIM/RUIM)
    public static final int APP_FAM_IMS = 3;     // IMS (ISIM)
    
    // 关键事件
    private static final int EVENT_ICC_STATUS_CHANGED = 1;
    private static final int EVENT_SLOT_STATUS_CHANGED = 2;
    private static final int EVENT_GET_ICC_STATUS_DONE = 3;
    private static final int EVENT_GET_SLOT_STATUS_DONE = 4;
    private static final int EVENT_RADIO_ON = 5;
    private static final int EVENT_SIM_REFRESH = 8;
    private static final int EVENT_EID_READY = 9;
    private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 10;
}

6.3 SIM 卡状态变化处理流程

RIL 上报 EVENT_ICC_STATUS_CHANGED (SIM 状态变化)
         │
         ▼
UiccController.handleMessage()
         │
         ▼
mCi.getIccCardStatus() → EVENT_GET_ICC_STATUS_DONE
         │
         ▼
onGetIccCardStatusDone()
    ├── 获取/创建 UiccSlot
    ├── 获取/创建 UiccCard
    ├── 获取/创建 UiccProfile
    ├── 创建 UiccCardApplication (根据 AppType)
    │     ├── APPTYPE_USIM → SIMRecords + UsimFileHandler
    │     ├── APPTYPE_CSIM → RuimRecords + CsimFileHandler
    │     └── APPTYPE_ISIM → IsimUiccRecords + IsimFileHandler
    │
    └── 通知注册者 mIccChangedRegistrants
          └── GsmCdmaPhone.updateIccRecords()
                ├── 更新 mIccRecords (SIM 数据记录)
                └── 触发 SIM 状态广播

6.4 UiccController 关键 API

// 获取 SIM 数据记录
public IccRecords getIccRecords(int phoneId, int family) {
    UiccCardApplication app = getUiccCardApplication(phoneId, family);
    return app != null ? app.getIccRecords() : null;
}

// 获取 SIM 文件处理器
public IccFileHandler getIccFileHandler(int phoneId, int family) {
    UiccCardApplication app = getUiccCardApplication(phoneId, family);
    return app != null ? app.getIccFileHandler() : null;
}

// 获取 UiccSlot
public UiccSlot getUiccSlotForPhone(int phoneId) {
    int slotId = getSlotIdFromPhoneId(phoneId);
    return mUiccSlots[slotId];
}

// 注册 SIM 状态变化监听
public void registerForIccChanged(Handler h, int what, Object obj)

6.5 SIM 卡状态

// IccCardConstants.State
UNKNOWN       // 未知
ABSENT        // 无卡
PIN_REQUIRED  // 需要 PIN
PUK_REQUIRED  // 需要 PUK
NETWORK_LOCKED // 网络锁
READY         // 就绪
NOT_READY     // 未就绪
PERM_DISABLED // 永久禁用
CARD_IO_ERROR // 卡 IO 错误
CARD_RESTRICTED // 卡受限
LOADED        // 已加载 (Android 13+)
}

七、RIL 通信层

7.1 CommandsInterface 接口

CommandsInterface.java 定义了与 Modem 通信的所有接口:

// 源码: CommandsInterface.java
public interface CommandsInterface {
    // 呼叫控制
    void dial(String address, boolean isEmergencyCall, ...);
    void acceptCall(Message result);
    void rejectCall(Message result);
    void hangupConnection(int gsmIndex, Message result);
    void hangupWaitingOrBackground(Message result);
    void hangupForegroundResumeBackground(Message result);
    void switchWaitingOrHoldingAndActive(Message result);
    void conference(Message result);
    void explicitCallTransfer(Message result);
    
    // 数据连接
    void setupDataCall(int accessNetworkType, DataProfile dataProfile,
            boolean isRoaming, boolean allowRoaming, int reason,
            LinkProperties linkProperties, int pduSessionId,
            NetworkSliceInfo sliceInfo, TrafficDescriptor trafficDescriptor,
            boolean matchAllRuleAllowed, Message result);
    void deactivateDataCall(int cid, int reason, Message result);
    
    // 短信
    void sendSMS(String smscPDU, String pdu, Message response);
    void sendSMSExpectMore(String smscPDU, String pdu, Message response);
    
    // SIM 卡
    void getIMSI(Message result);
    void getIccCardStatus(Message result);
    void supplyPin(String pin, Message result);
    void supplyPuk(String puk, String newPin, Message result);
    
    // 网络
    void setRadioPower(boolean on, Message response);
    void getVoiceRegistrationState(Message result);
    void getDataRegistrationState(Message result);
    void getOperator(Message result);
    void setNetworkSelectionModeAutomatic(Message response);
    void selectNetworkManually(...);
    
    // 呼叫转发/限制
    // CF_ACTION_DISABLE/ENABLE/REGISTRATION/ERASURE
    // CF_REASON_UNCONDITIONAL/BUSY/NO_REPLY/NOT_REACHABLE
    void setCallForward(int action, int cfReason, int serviceClass,
            String number, int timeSeconds, Message result);
    
    // CLIR (Calling Line Identification Restriction)
    static final int CLIR_DEFAULT = 0;
    static final int CLIR_INVOCATION = 1;   // 限制号码显示
    static final int CLIR_SUPPRESSION = 2;  // 允许号码显示
}

7.2 RIL.java - CommandsInterface 的实现

CommandsInterface (接口)
        │
        ▼
    RIL.java (实现)
        │
        ├── IRadio HIDL/AIDL 接口
        │   ├── IRadio 1.0 ~ 1.6 (HIDL)
        │   └── IRadio AIDL (Android 13+)
        │
        ├── IRadioConfig
        │   └── 设备级配置 (Slot 映射等)
        │
        └── IRadioResponse / IRadioIndication
            ├── 响应回调
            └── 主动上报 (网络状态、新短信、来电等)

7.3 RIL 请求/响应模型

┌──────────────┐    请求     ┌──────────────┐    HIDL/AIDL    ┌──────────────┐
│  Telephony   ├───────────→│    RIL.java   ├──────────────→│   Modem HAL  │
│  Framework   │             │              │               │              │
│              │◄───────────┤              │◄──────────────┤              │
└──────────────┘   响应/上报  └──────────────┘   响应/上报    └──────────────┘

请求流程:
RIL.setupDataCall() → serialNumber++ → IRadio.setupDataCall_1_6()
    → Modem 处理 → IRadioResponse.setupDataCallResponse()
    → RIL.processResponse() → Message.sendToTarget()

上报流程:
Modem 主动上报 → IRadioIndication.networkStateChanged()
    → RIL.processIndication() → mNetworkStateRegistrants.notifyRegistrant()

八、IMS 与 VoLTE/VoWiFi

8.1 IMS 架构

┌──────────────────────────────────────────────────────────────┐
│                    ImsPhone 架构                              │
│                                                              │
│  ImsPhone                                                    │
│  ├── ImsPhoneCallTracker                                     │
│  │   ├── ImsPhoneCall (前景/背景/来电)                       │
│  │   └── ImsPhoneConnection                                  │
│  │                                                           │
│  ├── ImsManager (IMS 服务管理)                               │
│  │   ├── ImsRegistration (IMS 注册)                          │
│  │   ├── ImsConfig (IMS 配置)                                │
│  │   └── ImsCallProfile (呼叫配置)                           │
│  │                                                           │
│  └── 功能支持                                                │
│      ├── VoLTE (Voice over LTE)                              │
│      ├── VoWiFi (WiFi Calling)                               │
│      ├── VoNR (Voice over NR, 5G 语音)                      │
│      ├── RTT (Real-Time Text, 实时文本)                      │
│      ├── SRVCC (IMS → CS 切换)                               │
│      └── WPS (Wireless Priority Service)                     │
└──────────────────────────────────────────────────────────────┘

8.2 IMS 与 CS 呼叫的协同

// GsmCdmaPhone 中的 IMS 优先策略:
// 1. 来电: ImsPhone 优先接听
public void acceptCall(int videoState) {
    if (mImsPhone != null && mImsPhone.getRingingCall().isRinging()) {
        mImsPhone.acceptCall(videoState);  // IMS 来电
    } else {
        mCT.acceptCall();                  // CS 来电
    }
}

// 2. 会议: ImsPhone 优先
public void conference() {
    if (mImsPhone != null && mImsPhone.canConference()) {
        mImsPhone.conference();  // IMS 会议 (支持视频)
        return;
    }
    mCT.conference();  // GSM 会议 (仅语音)
}

// 3. SRVCC: IMS → CS 无缝切换
// 当 IMS 通话中离开 LTE 覆盖区:
// Modem 上报 SRVCC → ImsPhoneCallTracker.handleSrvcc()
// → 将 ImsPhoneConnection 转为 GsmCdmaConnection
// → 通话不中断

8.3 VoLTE/VoWiFi 优势

特性CS 语音VoLTEVoWiFi
编码AMR-NB (8kHz)AMR-WB (16kHz)AMR-WB/EVS
接通时间5-10秒1-3秒1-3秒
并发数据不支持 (2G/3G)支持支持
覆盖要求蜂窝信号LTE 信号WiFi
紧急呼叫支持支持 (eCall)部分支持
视频通话不支持支持 (ViLTE)支持 (ViWiFi)

九、TelephonyManager 与回调机制

9.1 TelephonyManager - 应用层 API 入口

// TelephonyManager 是应用访问 Telephony 功能的主要入口
// 通过 ITelephony.aidl 与 PhoneInterfaceManager 通信

// 关键 API 分类:

// 1. 设备信息
public String getDeviceId()           // IMEI (需 READ_PHONE_STATE)
public String getImei(int slotIndex)  // IMEI (Android 10+)
public String getSubscriberId()       // IMSI (需 READ_PHONE_STATE)
public String getSimOperatorName()    // 运营商名称
public String getSimOperator()        // MCC+MNC

// 2. 网络状态
public int getDataState()             // DATA_DISCONNECTED/CONNECTING/CONNECTED/SUSPENDED
public int getDataNetworkType()       // NETWORK_TYPE_LTE/NR 等
public ServiceState getServiceState()
public SignalStrength getSignalStrength()

// 3. 呼叫管理 (通过 TelecomManager)
public boolean isOffhook()
public boolean isRinging()
public boolean isCallStateIdle()

// 4. SIM 卡
public int getSimState()              // SIM_STATE_READY/ABSENT 等
public String getSimSerialNumber()    // ICCID
public int getActiveModemCount()      // 活跃 Modem 数量

// 5. 数据连接
public int getApnType()               // APN 类型
public String getNetworkSpecifier()   // 网络标识

9.2 TelephonyCallback 回调体系

// Android 12+ 替代 PhoneStateListener
public abstract class TelephonyCallback {
    // 服务状态变化
    public interface ServiceStateListener {
        void onServiceStateChanged(ServiceState state);
    }
    
    // 信号强度变化
    public interface SignalStrengthsListener {
        void onSignalStrengthsChanged(SignalStrength signalStrength);
    }
    
    // 数据连接状态
    public interface DataConnectionStateListener {
        void onDataConnectionStateChanged(int state, int networkType);
    }
    
    // 数据活动方向
    public interface DataActivityListener {
        void onDataActivity(int direction);  // NONE/IN/OUT/INOUT/DORMANT
    }
    
    // 呼叫状态 (精细)
    public interface PreciseCallStateListener {
        void onPreciseCallStateChanged(PreciseCallState callState);
    }
    
    // 显示信息 (5G 图标等)
    public interface DisplayInfoListener {
        void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo);
    }
    
    // SIM 状态
    public interface SimStateListener {
        void onSimStateChanged(int simState);
    }
    
    // 载波网络变化
    public interface CarrierNetworkListener {
        void onCarrierNetworkChange(boolean active);
    }
}

// 注册方式:
TelephonyManager tm = context.getSystemService(TelephonyManager.class);
tm.registerTelephonyCallback(executor, callback);
tm.unregisterTelephonyCallback(callback);

9.3 PhoneStateListener (已废弃但仍广泛使用)

// Android 12 之前的回调方式 (已废弃)
PhoneStateListener listener = new PhoneStateListener() {
    @Override
    public void onServiceStateChanged(ServiceState serviceState) {}
    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {}
    @Override
    public void onDataConnectionStateChanged(int state, int networkType) {}
    @Override
    public void onCallStateChanged(int state, String phoneNumber) {}
};

// 需要权限: READ_PHONE_STATE
tm.listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE 
    | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

十、Telecom 集成

10.1 Telecom 框架架构

┌──────────────────────────────────────────────────────────────┐
│                    应用层                                     │
│  Dialer / InCallService / CallScreeningService               │
└────────────────────────┬─────────────────────────────────────┘
                         │ TelecomManager API
┌────────────────────────▼─────────────────────────────────────┐
│              TelecomService (系统服务)                        │
│  - 呼叫路由和选择                                             │
│  - PhoneAccount 管理                                         │
│  - 呼叫阻断 (CallScreening)                                  │
│  - 音频路由管理                                               │
│  - 通话录音管理                                               │
└────────────────────────┬─────────────────────────────────────┘
                         │ ConnectionService API
┌────────────────────────▼─────────────────────────────────────┐
│          TelephonyConnectionService                          │
│  - 桥接 Telecom 和 Telephony                                 │
│  - 创建/管理 TelephonyConnection                             │
│  - 处理 Telecom 命令 (answer/disconnect/hold/conference)     │
└────────────────────────┬─────────────────────────────────────┘
                         │
┌────────────────────────▼─────────────────────────────────────┐
│          GsmCdmaPhone / ImsPhone                             │
│  - 实际的呼叫控制                                             │
└──────────────────────────────────────────────────────────────┘

10.2 拨号完整流程

应用: TelecomManager.placeCall(uri)
    │
    ▼
TelecomService
    ├── 1. 权限检查 (CALL_PHONE)
    ├── 2. 选择 PhoneAccount
    │     ├── SIM1 → TelephonyConnectionService
    │     ├── SIM2 → TelephonyConnectionService
    │     └── 其他 → 第三方 ConnectionService
    ├── 3. 创建 Call 对象
    └── 4. 绑定 ConnectionService
         │
         ▼
TelephonyConnectionService.onCreateOutgoingConnection()
    │
    ├── 创建 TelephonyConnection
    └── GsmCdmaPhone.dial(dialString, dialArgs)
         │
         ├── 检查电话状态 (IDLE?)
         ├── 创建 GsmCdmaConnection
         ├── mCi.dial() → RIL → ATD 命令
         │
         └── RIL 上报 CALL_STATE_CHANGE
              │
              ├── pollCallsWhenSafe()
              ├── handlePollCalls()
              ├── 状态: DIALING → ALERTING → ACTIVE
              └── 通知 Telecom → 通知 InCallService → UI 更新

10.3 来电完整流程

Modem 上报来电
    │
    ▼
RIL 上报 CALL_STATE_CHANGE
    │
    ▼
GsmCdmaCallTracker
    ├── pollCallsWhenSafe()
    ├── mCi.getCurrentCalls() (AT+CLCC)
    ├── handlePollCalls()
    │   ├── 创建 GsmCdmaConnection
    │   └── 更新 mRingingCall → State.INCOMING
    │
    ├── mPhone.notifyNewRingingConnection()
    └── mPhone.notifyCallStateChanged()
         │
         ▼
TelephonyConnectionService
    ├── onCreateIncomingConnection()
    ├── 创建 TelephonyConnection
    └── TelecomService
         ├── 显示来电 UI (InCallService)
         └── 用户操作:
              ├── 接听 → onAnswer() → mCT.acceptCall() → mCi.acceptCall()
              └── 拒接 → onDisconnect() → mCT.rejectCall() → mCi.rejectCall()

十一、权限模型

11.1 Telephony 权限分类

权限功能级别Android 版本
READ_PHONE_STATE读取电话状态危险1.0+
READ_CALL_LOG读取通话记录危险1.0+
READ_SMS读取短信危险1.0+
RECEIVE_SMS接收短信危险1.0+
SEND_SMS发送短信危险1.0+
CALL_PHONE拨号危险1.0+
READ_PHONE_NUMBERS读取电话号码危险8.0+
ANSWER_PHONE_CALLS接听电话危险8.0+
MODIFY_PHONE_STATE修改电话状态系统1.0+
DUMP导出调试信息系统1.0+

11.2 权限版本变化

  • Android 6.0: 运行时权限请求,READ_PHONE_STATE 变为危险权限
  • Android 9.0: READ_PHONE_STATE 不再返回 IMEI/IMSI,需 READ_PRIVILEGED_PHONE_STATE
  • Android 10: 设备标识符访问进一步限制,getDeviceId() 抛出异常
  • Android 11: 一次性权限支持
  • Android 12: PhoneStateListener 废弃,迁移到 TelephonyCallback

十二、关键源码文件索引

文件路径职责
Phone.java.../internal/telephony/Phone 抽象基类
GsmCdmaPhone.java.../internal/telephony/GSM/CDMA Phone 主实现
ImsPhone.java.../internal/telephony/imsphone/IMS Phone 实现
GsmCdmaCallTracker.java.../internal/telephony/CS 呼叫状态追踪
ImsPhoneCallTracker.java.../internal/telephony/imsphone/IMS 呼叫状态追踪
ServiceStateTracker.java.../internal/telephony/网络服务状态追踪
SignalStrength.java.../telephony/SignalStrength.java信号强度数据结构
InboundSmsHandler.java.../internal/telephony/短信接收状态机
UiccController.java.../internal/telephony/uicc/SIM 卡管理
CommandsInterface.java.../internal/telephony/RIL 接口定义
RIL.java.../internal/telephony/RIL 实现
TelephonyManager.java.../telephony/TelephonyManager.java应用 API 入口
DataNetworkController.java.../internal/telephony/data/数据网络控制器
PhoneInterfaceManager.javapackages/services/Telephony/ITelephony Binder 实现
TelephonyConnectionService.javapackages/services/Telephony/Telecom 集成

十三、Android 版本演进关键变更

版本变更
5.0引入 Multi-SIM 支持 (基础)
6.0运行时权限模型
7.0多 SIM API 正式化
8.0ANSWER_PHONE_CALLS 权限,NotificationChannel
9.0设备标识符限制,通话录音权限收紧
10getDeviceId() 废弃,5G NSA 支持
11一次性权限,5G SA 基础支持
12TelephonyCallback 替代 PhoneStateListenerTelephonyDisplayInfo
13新数据栈 (DataNetworkController),eSIM 多激活配置文件
145G URSP/TrafficDescriptor 完整支持,卫星通信 API

十四、面试核心知识点

✅ 必须掌握

Phone 框架

  • Phone 接口 vs GsmCdmaPhone 实现的关系
  • ImsPhone 何时创建、何时接管呼叫
  • PhoneFactory 如何管理多 SIM Phone 实例

Call 管理

  • 三个 Call 对象 (mRingingCall/mForegroundCall/mBackgroundCall) 的用途
  • GsmCdmaCall.State 与 PhoneConstants.State 的映射
  • Connection 与 Call 的关系 (Connection 是 Call 的组成部分)
  • pollCalls 轮询机制的工作原理

ServiceState

  • 四种注册状态的含义 (IN_SERVICE/OUT_OF_SERVICE/EMERGENCY_ONLY/POWER_OFF)
  • NetworkRegistrationInfo 的分域管理 (CS/PS)
  • 语音和数据注册状态可以不同 (如 LTE 数据在网但 CS 不在网)

短信系统

  • InboundSmsHandler 三状态机 (Idle → Delivering → Waiting)
  • 多部分短信重组机制
  • Raw 表的作用 (崩溃恢复)

SIM 卡管理

  • UICC 类层次结构 (UiccController → UiccSlot → UiccCard → UiccProfile → UiccCardApplication)
  • IccRecords 与 IccFileHandler 的职责分离
  • eSIM 与物理 SIM 的统一管理

RIL 通信

  • CommandsInterface 接口的请求/响应模型
  • RIL.java 的 HIDL/AIDL 双实现
  • 主动上报 (Indication) 与响应 (Response) 的区别

IMS/VoLTE

  • VoLTE 优势 (AMR-WB 编码、快速接通、并发数据)
  • SRVCC 切换机制 (IMS → CS)
  • ImsPhone 与 GsmCdmaPhone 的协同 (IMS 优先策略)

权限模型

  • 危险权限列表和运行时请求

  • 设备标识符访问的版本变化

  • 系统权限 vs 特权权限

toolName: todo_write

status: success

Todos updated: 10 items

以上是基于 AOSP 源码对原文的全面完善。相比原文,主要补充和深化了以下内容:

核心补充

  1. Phone 接口体系深度解析:基于 GsmCdmaPhone.java 源码,详细说明了 IMS 优先策略(acceptCall/conference 中 IMS 优先委托)、GSM/CDMA 双模式切换机制

  2. GsmCdmaCallTracker 源码级分析:基于 GsmCdmaCallTracker.java 源码,补充了 acceptCall 对 INCOMING 和 WAITING 的不同处理、CDMA Flash 命令、pollCalls 轮询机制

  3. InboundSmsHandler 状态机:基于 InboundSmsHandler.java 源码,完整解析了 Idle → Delivering → Waiting 三状态机、WakeLock 管理、多部分短信重组

  4. UICC 类层次结构:基于 UiccController.java 源码注释,补充了完整的 UICC 类图、SIM 状态变化处理流程、eSIM 多端口支持

  5. CommandsInterface 接口:基于 CommandsInterface.java 源码,详细列出了呼叫控制、数据连接、短信、SIM 卡等全部 RIL 接口方法

  6. ServiceStateTracker:基于 ServiceStateTracker.java 源码,补充了网络状态更新流程(并行 RIL 请求 → 合并去重 → 通知注册者)

  7. Android 版本演进:新增了从 Android 5.0 到 14 的 Telephony 系统关键变更时间线