一、系统整体架构
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 关键源码路径
| 模块 | 源码路径 |
|---|---|
| 公开 API | frameworks/base/telephony/java/android/telephony/ |
| Telephony 服务 | packages/services/Telephony/ |
| 核心业务逻辑 | frameworks/opt/telephony/src/java/com/android/internal/telephony/ |
| IMS 电话 | frameworks/opt/telephony/.../imsphone/ |
| UICC/SIM | frameworks/opt/telephony/.../uicc/ |
| 数据连接 | frameworks/opt/telephony/.../data/ |
| RIL | frameworks/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 语音 | VoLTE | VoWiFi |
|---|---|---|---|
| 编码 | 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.java | packages/services/Telephony/ | ITelephony Binder 实现 |
| TelephonyConnectionService.java | packages/services/Telephony/ | Telecom 集成 |
十三、Android 版本演进关键变更
| 版本 | 变更 |
|---|---|
| 5.0 | 引入 Multi-SIM 支持 (基础) |
| 6.0 | 运行时权限模型 |
| 7.0 | 多 SIM API 正式化 |
| 8.0 | ANSWER_PHONE_CALLS 权限,NotificationChannel |
| 9.0 | 设备标识符限制,通话录音权限收紧 |
| 10 | getDeviceId() 废弃,5G NSA 支持 |
| 11 | 一次性权限,5G SA 基础支持 |
| 12 | TelephonyCallback 替代 PhoneStateListener,TelephonyDisplayInfo |
| 13 | 新数据栈 (DataNetworkController),eSIM 多激活配置文件 |
| 14 | 5G 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 源码对原文的全面完善。相比原文,主要补充和深化了以下内容:
核心补充
-
Phone 接口体系深度解析:基于 GsmCdmaPhone.java 源码,详细说明了 IMS 优先策略(
acceptCall/conference中 IMS 优先委托)、GSM/CDMA 双模式切换机制 -
GsmCdmaCallTracker 源码级分析:基于 GsmCdmaCallTracker.java 源码,补充了
acceptCall对 INCOMING 和 WAITING 的不同处理、CDMA Flash 命令、pollCalls 轮询机制 -
InboundSmsHandler 状态机:基于 InboundSmsHandler.java 源码,完整解析了 Idle → Delivering → Waiting 三状态机、WakeLock 管理、多部分短信重组
-
UICC 类层次结构:基于 UiccController.java 源码注释,补充了完整的 UICC 类图、SIM 状态变化处理流程、eSIM 多端口支持
-
CommandsInterface 接口:基于 CommandsInterface.java 源码,详细列出了呼叫控制、数据连接、短信、SIM 卡等全部 RIL 接口方法
-
ServiceStateTracker:基于 ServiceStateTracker.java 源码,补充了网络状态更新流程(并行 RIL 请求 → 合并去重 → 通知注册者)
-
Android 版本演进:新增了从 Android 5.0 到 14 的 Telephony 系统关键变更时间线