一、架构总览
卫星通信框架遵循"能力查询 → 请求权限 → 发送消息"的严格流程,其核心是隐私与资源保护。
1.1 核心入口类
SatelliteManager:卫星通信的统一入口点,通过 Context.SATELLITE_SERVICE 获取,要求设备具有 PackageManager.FEATURE_TELEPHONY_SATELLITE 特性。
SatelliteCapabilities:描述设备卫星能力,包含以下字段:
supportedRadioTechnologies— 支持的无线电技术集合(NB-IoT NTN / NR NTN / eMTC NTN / Proprietary)isPointingRequired— 是否需要用户对准卫星maxBytesPerOutgoingDatagram— 每个出站数据报的最大字节数antennaPositionMap— 天线位置映射(按设备握持姿势分:竖持/左横/右横)
1.2 权限模型
权限名称为 SATELLITE_COMMUNICATION(非 USE_SATELLITE),属于系统级权限(@SystemApi)。
关键点:
- 首次使用会触发系统弹窗,明确告知用户此操作可能收费、耗时且仅用于紧急情况
- 部分查询 API(如
requestIsSupported、registerStateChangeListener)仅需READ_PHONE_STATE或READ_BASIC_PHONE_STATE权限 - 具有 carrier privileges 的应用也可访问部分 API
1.3 消息限制
- 消息长度受
SatelliteCapabilities.maxBytesPerOutgoingDatagram限制 - 内容需为纯文本或预定义的紧急数据结构
- 在
SATELLITE_DATA_SUPPORT_RESTRICTED模式下禁止传输媒体文件或任意二进制流 - 在
SATELLITE_DATA_SUPPORT_UNCONSTRAINED模式下可提供无限制互联网访问
1.4 卫星消息类型
| 类型 | 示例 | 传输机制 | 是否需要 IP |
|---|---|---|---|
| SMS over Satellite | 天通短信、北斗短报文 | 控制平面信令通道 | 不需要 |
| Datagram 消息 | SOS 报警、位置分享、保活消息 | 独立数据报协议 | 不需要 |
| IP 应用层消息 | 微信、邮件(经 Starlink) | 用户面 IP 数据包 | 需要 |
1.5 卫星数据支持模式分级
Android 16 新增 SatelliteDataSupportMode,定义了卫星数据的分级支持:
| 模式 | 值 | 含义 |
|---|---|---|
SATELLITE_DATA_SUPPORT_UNKNOWN | -1 | 未知或不支持 |
SATELLITE_DATA_SUPPORT_RESTRICTED | 0 | 仅支持受限数据用例(如 RCS 消息) |
SATELLITE_DATA_SUPPORT_CONSTRAINED | 1 | 支持受限互联网,仅限声明了 PROPERTY_SATELLITE_DATA_OPTIMIZED 的优化应用 |
SATELLITE_DATA_SUPPORT_UNCONSTRAINED | 2 | 无限制互联网,所有应用可用 |
在 CONSTRAINED 模式下,只有通过 SatelliteOptimizedApplicationsTracker 追踪到的、在 AndroidManifest 中声明了 PROPERTY_SATELLITE_DATA_OPTIMIZED 元数据的应用才能使用卫星数据网络:
<meta-data
android:name="android.telephony.PROPERTY_SATELLITE_DATA_OPTIMIZED"
android:value="<package-name>"/>
二、SatelliteSessionController 状态机
2.1 完整状态定义
SatelliteSessionController 是一个基于 StateMachine 的状态机,管理卫星会话的完整生命周期。Android 16 中共有 9 个状态:
| 状态 | Modem State 值 | 说明 |
|---|---|---|
UnavailableState | SATELLITE_MODEM_STATE_UNAVAILABLE (5) | 设备不支持卫星时的初始状态 |
PowerOffState | SATELLITE_MODEM_STATE_OFF (4) | 卫星 Modem 关闭 |
EnablingState | SATELLITE_MODEM_STATE_ENABLING_SATELLITE (8) | 卫星正在启用中 |
DisablingState | SATELLITE_MODEM_STATE_DISABLING_SATELLITE (9) | 卫星正在关闭中 |
IdleState | SATELLITE_MODEM_STATE_IDLE (0) | 卫星已启用但无数据传输 |
TransferringState | SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING (2) | 正在收发数据报 |
ListeningState | SATELLITE_MODEM_STATE_LISTENING (1) | 监听入站数据报 |
NotConnectedState | SATELLITE_MODEM_STATE_NOT_CONNECTED (6) | NB-IoT NTN 模式下已启用但未附着 |
ConnectedState | SATELLITE_MODEM_STATE_CONNECTED (7) | 已附着到卫星小区 |
2.2 状态迁移图
设备不支持卫星
│
▼
┌─────────────┐
│ Unavailable │
│ State │
└─────────────┘
设备支持卫星
│
▼
┌─────────────┐
┌─────│ PowerOff │◄──────────────────────────────┐
│ │ State │ │
│ └──────┬──────┘ │
│ │ requestEnabled(true) │
│ ▼ │
│ ┌─────────────┐ 启用失败 │
│ │ Enabling │────────────────────────────────┘
│ │ State │
│ └──────┬──────┘
│ │ 启用成功
│ ├───────────── isSatelliteAttachRequired()=true ──┐
│ │ ▼
│ │ isSatelliteAttachRequired()=false ┌──────────────┐
│ ▼ │ NotConnected │
│ ┌─────────────┐ │ State │
│ │ Idle │◄──────────────────────────────└──────┬───────┘
│ │ State │◄─────────── NB-IoT 不活跃超时 │
│ └──────┬──────┘ │
│ │ 开始收发数据 卫星附着成功 │
│ ▼ │
│ ┌──────────────┐ │
│ │ Transferring │ │
│ │ State │ │
│ └──────┬───────┘ │
│ │ 收发完成 │
│ ├──── NB-IoT NTN ────► ConnectedState ◄──────┘
│ │
│ ▼ 非 NB-IoT NTN
│ ┌──────────────┐
│ │ Listening │
│ │ State │
│ └──────┬───────┘
│ │ 超时 / 无新数据
│ ▼
│ ┌──────────────┐
│ │ Idle │
│ │ State │
│ └──────────────┘
│
│ requestEnabled(false)
│ 任何状态均可转入:
│ ┌──────────────┐
└────►│ Disabling │──── 禁用完成 ───► PowerOffState
│ State │
└──────────────┘
2.3 关键状态详解
UnavailableState
设备不支持卫星功能时的初始状态。此状态下忽略所有事件,不会处理任何卫星请求。
PowerOffState
卫星 Modem 关闭状态。进入时:
- 调用
SatelliteController.moveSatelliteToOffStateAndCleanUpResources()清理资源 - 解绑
SatelliteGatewayService - 停止所有不活跃计时器
- 通知
DemoSimulator卫星模式关闭
退出时(即开始启用卫星时):
- 绑定
SatelliteGatewayService
EnablingState
卫星正在启用中。启用成功后根据 isSatelliteAttachRequired() 分流:
- true(NB-IoT NTN 模式)→ 转入
NotConnectedState,等待卫星网络附着 - false(非 NB-IoT NTN 模式,如 Proprietary 模式)→ 直接转入
IdleState
如果 Modem 在启用过程中上报 OFF 状态,直接转回 PowerOffState。
DisablingState
卫星正在关闭中。此状态处理禁用请求期间的复杂场景:
- 如果禁用失败,根据
mPreviousState回退到之前的状态 - 如果同时收到启用失败事件,回退到
PowerOffState
NotConnectedState(NB-IoT NTN 专属)
卫星已启用但尚未附着到卫星小区。此状态下:
- 启动 NB-IoT 不活跃计时器
- 评估是否启动 ESOS 不活跃计时器
- 评估是否启动 P2P SMS 不活跃计时器
- 当 Modem 上报
SATELLITE_MODEM_STATE_CONNECTED时转入ConnectedState
IdleState
卫星已启用但无数据传输。进入时:
- 如果配置允许,调用
enableCellularModemWhileSatelliteModeIsOn(true)允许同时扫描地面网络 - 如果支持并发 TN 扫描,IdleState 对客户端隐藏(不通知状态变化)
退出时:
- 调用
enableCellularModemWhileSatelliteModeIsOn(false)停止地面网络扫描
当检测到地面网络恢复(ServiceState 变为 IN_SERVICE 或 EMERGENCY_ONLY)时,自动请求禁用卫星并回退到地面网络。
TransferringState
正在收发数据报。收发完成后:
- NB-IoT NTN 模式 → 转入
ConnectedState - 非 NB-IoT NTN 模式:
- 发送/接收失败 → 转入
IdleState - 成功 → 转入
ListeningState
- 发送/接收失败 → 转入
ListeningState
监听入站数据报。超时时间取决于触发来源:
- 从发送转入:
DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS= 180 秒 - 从接收转入:
DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS= 30 秒 - Demo 模式:
DEMO_MODE_SATELLITE_STAY_AT_LISTENING_MILLIS= 3 秒
进入时调用 requestSatelliteListeningEnabled(true, timeout) 启用监听模式,退出时调用 requestSatelliteListeningEnabled(false, 0) 关闭。
ConnectedState
已附着到卫星小区。进入时:
- 通知状态变化为
SATELLITE_MODEM_STATE_CONNECTED - 启动 NB-IoT 不活跃计时器
- 评估并启动 ESOS 不活跃计时器(默认 600 秒)
- 评估并启动 P2P SMS 不活跃计时器(默认 180 秒)
- 主动更新并通知 NTN 信号强度
SATELLITE_MODEM_STATE_CONNECTED 的真实含义:
- 表示卫星网络附着/注册完成(类似蜂窝网络的 Registered 状态)
- 不等于 PDN 连接建立
- 不分配 IP 地址
- 仅表示控制面链路可用,可以收发信令和 datagram
三、卫星启用流程
3.1 应用层发起
Android 16 使用新的 EnableRequestAttributes API:
EnableRequestAttributes attributes = new EnableRequestAttributes.Builder(true)
.setDemoMode(false)
.setEmergencyMode(true)
.build();
satelliteManager.requestEnabled(attributes, executor, resultListener);
EnableRequestAttributes 封装了三个参数:
isEnabled— 是否启用卫星isDemoMode— 是否启用演示模式(禁用时忽略)isEmergencyMode— 是否为紧急模式(禁用时忽略)
3.2 框架服务层处理
SatelliteManager.requestEnabled(attributes, executor, callback)
│ [Binder IPC]
▼
ITelephony.requestSatelliteEnabled(isEnabled, isDemoMode, isEmergencyMode, errorCallback)
│
▼
SatelliteController.handleRequestSatelliteEnabled()
│
├── evaluateOemSatelliteRequestAllowed() → 权限检查
├── 检查 Radio 状态 (mIsRadioOn)
├── 检查卫星是否已启用
├── 禁用冲突无线电 (BT/WiFi/NFC/UWB per Settings.Global.SATELLITE_MODE_RADIOS)
├── selectBindingSatelliteSubscription() → 选择卫星订阅
│
▼
SatelliteController.handleSatelliteEnabled()
│
├── SatelliteSessionController.onSatelliteEnablementStarted(true)
│ → 状态机转入 EnablingState
│
├── SatelliteModemInterface.requestSatelliteEnabled(attributes, onCompleted)
│ │ [Binder IPC]
│ ▼
│ ISatellite.requestSatelliteEnabled(SatelliteModemEnableRequestAttributes, callback)
│ │ [厂商 SatelliteService → Modem]
│ ▼
│ Modem 启用卫星射频 → 上报状态变化
│
▼
EVENT_SET_SATELLITE_ENABLED_DONE
│
├── 成功:
│ ├── 更新卫星启用状态
│ ├── 启动信号上报 (updateNtnSignalStrengthReporting)
│ ├── 通知 SessionController
│ └── callback.accept(SUCCESS)
│
└── 失败:
├── abortSatelliteEnableAttributesUpdateRequest()
├── 通知 SessionController
└── callback.accept(errorCode)
3.3 SatelliteModemEnableRequestAttributes
传递给 Modem HAL 的启用请求属性,包含:
isEnabled— 是否启用isForDemoMode— 是否为演示模式isForEmergencyMode— 是否为紧急模式satelliteSubscriptionInfo— 卫星订阅信息,包含:iccId— 用于卫星附着的 ICC IDniddApn— 非IP数据(NIDD) APN 名称(如satellite.com)
框架在启用过程中可能多次发送 requestSatelliteEnabled 来更新会话属性(如切换订阅),Modem 需要将新属性应用到当前会话,并立即上报当前状态和信号强度。
四、卫星数据连接建立流程
阶段1:应用发起请求
应用通过 ConnectivityManager.requestNetwork() 发起网络请求,指定 TRANSPORT_SATELLITE 传输类型:
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build();
connectivityManager.requestNetwork(request, networkCallback);
阶段2:ConnectivityService 分发请求
ConnectivityService 收到 NetworkRequest 后,调用 onNetworkNeeded(),将该请求分发给已注册的 NetworkProvider。对于卫星传输,对应的 Provider 是 TelephonyNetworkProvider(卫星通信在 Android 框架中常作为蜂窝的一种特殊承载)。
阶段3:Telephony 层请求评估与路由
PhoneSwitcher 负责选择当前激活的 Phone 对象(多卡场景下选正确的 SIM/卫星模组)。TelephonyNetworkProvider 通过 addNetworkRequest() 将请求传递给 DataNetworkController。
阶段4:卫星数据策略与 APN 选择
调用 canConnectivityTransportSatisfyRequest() 判断当前注册的卫星网络是否满足请求。若满足,则选择对应的 DataProfile,包含:
- APN(即
SatelliteSubscriptionInfo.niddApn,如satellite.com) - 协议类型(IPv4v6)
- 承载类型标记为
INFRASTRUCTURE_SATELLITE
阶段5:DataNetwork 状态机建立数据呼叫
DataNetworkController 驱动状态机进入 ConnectingState:
setupData()→DataServiceManager.setupDataCall()DataServiceManager通过 AIDL 调用 Modem 的IRadioData.setupDataCall()- 传递参数包括 APN、鉴权信息、PDN 类型、卫星特有参数
阶段6:Modem 响应与状态转换
Modem 完成卫星链路的 RRC 连接、PDP 上下文激活后,返回 setupDataCallResponse:
- 成功:解析 IP 地址、DNS、网关,状态机切换到 ConnectedState
- 失败:获取失败原因码,状态机进入 DisconnectedState,根据策略触发重试
阶段7:网络能力注册与路由配置
NetworkAgent 调用 markConnected(),将卫星网络注册到 ConnectivityService,携带:
- 传输类型
TRANSPORT_SATELLITE - 卫星特有能力集(高延迟、低带宽、按流量计费等)
ConnectivityService 据此配置路由表、防火墙规则、DNS 设置,并通过 onConnected() 回调通知应用。
五、发送卫星消息(基于 Datagram 机制)
5.1 Datagram 类型
Android 16 定义了 8 种 Datagram 类型:
| 类型 | 值 | 说明 |
|---|---|---|
DATAGRAM_TYPE_UNKNOWN | 0 | 未知 |
DATAGRAM_TYPE_SOS_MESSAGE | 1 | SOS 紧急消息 |
DATAGRAM_TYPE_LOCATION_SHARING | 2 | 位置共享 |
DATAGRAM_TYPE_KEEP_ALIVE | 3 | 保活消息,维持卫星连接或检查入站消息 |
DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP | 4 | 最后一条 SOS 消息(仍需帮助) |
DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED | 5 | 最后一条 SOS 消息(不再需要帮助) |
DATAGRAM_TYPE_SMS | 6 | P2P 短信 |
DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS | 7 | 检查待接收的入站 SMS |
5.2 完整时序图
App: SatelliteManager.sendDatagram(subId, datagramType, datagram, needFullScreenPointingUI, callback)
│ [Binder IPC]
▼
SatelliteController.sendSatelliteDatagram()
│
├── evaluateOemSatelliteRequestAllowed() → 权限检查
├── 若需对星: PointingAppController.startPointingUI()
│
▼
DatagramController.sendSatelliteDatagram()
│
▼
DatagramDispatcher.sendDatagram()
│
├── 排入发送队列 (LinkedHashMap)
├── CMD_SEND_SATELLITE_DATAGRAM
│
▼
DatagramDispatcher.handleMessage(CMD_SEND_SATELLITE_DATAGRAM)
│
├── 检查 mIsDemoMode:
│ ├── Demo模式:延迟模拟发送成功
│ └── 真实模式:
│ ├── 检查设备是否对准卫星 (mIsAligned)
│ ├── 检查 Modem 是否处于 Connected 状态
│ ├── 若未连接:等待连接超时
│ └── 若已连接:
│
▼
SatelliteModemInterface.sendSatelliteDatagram(datagram, isSosMessage, needFullScreenPointingUI, onCompleted)
│ [Binder IPC]
▼
ISatellite.sendSatelliteDatagram(datagram, isEmergency, callback)
│ [厂商 SatelliteService → Modem]
▼
Modem 通过卫星上行链路发送
│
▼
EVENT_SEND_SATELLITE_DATAGRAM_DONE
│
├── 成功:更新发送状态 → SEND_SUCCESS
│ → 通知 DatagramController → 回调 App
│
└── 失败:保留在队列 → 等待 retrySendingDatagrams()
→ 超时:SATELLITE_RESULT_MODEM_TIMEOUT
5.3 发送流程详解
1. 应用层发起
Gateway App / Messages App 调用:
SatelliteManager.sendDatagram(subId, DATAGRAM_TYPE_SOS_MESSAGE,
datagram, needFullScreenPointingUI, executor, callback)
2. SatelliteManager 通过 ITelephony 转发
3. 框架服务层处理
SatelliteController.sendSatelliteDatagram()
→ DatagramController.sendSatelliteDatagram()
→ DatagramDispatcher.sendDatagram()
→ 封装 SendSatelliteDatagramArgument(datagramId, datagramType, datagram, ...)
→ 发送 CMD_SEND_SATELLITE_DATAGRAM 消息
4. Dispatcher 发送处理
DatagramDispatcher 维护两个发送队列:
mPendingEmergencyDatagramsMap— 紧急数据报队列mPendingNonEmergencyDatagramsMap— 非紧急数据报队列
5. HAL 层交互
SatelliteModemInterface.sendSatelliteDatagram()
→ ISatellite.sendSatelliteDatagram(
SatelliteServiceUtils.toSatelliteDatagram(datagram),
isSosMessage,
IIntegerConsumer callback)
→ Vendor SatelliteService
→ Satellite HAL (AIDL)
→ 卫星 Modem 固件
→ 射频发送
6. 结果回调
Modem 发送完成
→ HAL 回调
→ ISatelliteListener (Vendor Listener)
→ SatelliteModemInterface.mSatelliteDatagramsReceivedRegistrants
→ DatagramDispatcher.handleMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE)
→ 更新 mPendingEmergencyDatagramsMap / mPendingNonEmergencyDatagramsMap
→ DatagramController.updateSendStatus()
→ SatelliteSessionController.onDatagramTransferStateChanged()
→ PointingAppController.updateSendDatagramTransferState()
→ callback.accept(error) // 回调应用层
7. 会话状态流转
SatelliteSessionController 状态变化:
IdleState → TransferringState (开始发送)
→ ListeningState (发送完成,等待接收)
→ 启动 Listening 超时计时器 (180s from sending / 30s from receiving)
→ 超时或收到新数据 → IdleState
六、接收卫星消息流程
Modem 收到卫星下行数据
│
▼
ISatelliteListener.onPendingDatagrams()
│ [Binder IPC 回调]
▼
SatelliteModemInterface → SatelliteController.EVENT_PENDING_DATAGRAMS
│
▼
DatagramController → DatagramReceiver.pollPendingSatelliteDatagrams()
│
▼
SatelliteModemInterface.pollPendingSatelliteDatagrams()
│ [Binder IPC]
▼
ISatellite.pollPendingSatagrams(callback)
│ [厂商 SatelliteService → Modem]
▼
Modem 返回待接收数据报
│
▼
EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE
│
├── 解析 SatelliteDatagram
├── 若为 SMS 类型:写入 Telephony Provider (content://sms)
├── 通知 ISatelliteDatagramCallback 注册者
└── 更新接收状态 → RECEIVE_SUCCESS
DatagramReceiver 还维护了一个 mPendingAckCountHashMap,追踪每个数据报的确认回执计数,确保所有注册的监听器都确认收到后才完成处理。
七、卫星模式开关流程
7.1 启用流程
用户点击"开启卫星" / 应用调用 requestEnabled
│
▼
SatelliteManager.requestEnabled(EnableRequestAttributes, executor, callback)
│ [Binder IPC]
▼
SatelliteController.handleRequestSatelliteEnabled()
│
├── evaluateOemSatelliteRequestAllowed() → 权限检查
├── 检查 Radio 状态 (mIsRadioOn)
├── 检查卫星是否已启用
├── 禁用冲突无线电 (BT/WiFi/NFC/UWB per Settings.Global.SATELLITE_MODE_RADIOS)
├── selectBindingSatelliteSubscription() → 选择卫星订阅
│
▼
SatelliteController.handleSatelliteEnabled()
│
├── SatelliteSessionController.onSatelliteEnablementStarted(true)
│ → 状态机转入 EnablingState
│
├── SatelliteModemInterface.requestSatelliteEnabled(attributes, onCompleted)
│ │ [Binder IPC]
│ ▼
│ ISatellite.requestSatelliteEnabled(SatelliteModemEnableRequestAttributes, callback)
│ │ [厂商 SatelliteService → Modem]
│ ▼
│ Modem 启用卫星射频 → 上报状态变化
│
▼
EVENT_SET_SATELLITE_ENABLED_DONE
│
├── 成功:
│ ├── 更新卫星启用状态
│ ├── 启动信号上报 (updateNtnSignalStrengthReporting)
│ ├── 通知 SessionController
│ └── callback.accept(SUCCESS)
│
└── 失败:
├── abortSatelliteEnableAttributesUpdateRequest()
├── 通知 SessionController
└── callback.accept(errorCode)
7.2 禁用流程
禁用时状态机转入 DisablingState。如果禁用失败,根据 mPreviousState 回退:
- 之前在
ConnectedState/TransferringState/ListeningState→ 回退到ConnectedState - 之前在
EnablingState→ 回退到EnablingState - 之前在
PowerOffState→ 回退到PowerOffState - 其他 → 回退到
NotConnectedState
八、Modem 上报卫星信号变化通知流程
Android 16 中卫星信号变化通知存在两条并行路径:
| 路径 | 模式 | 触发源 | 通知链路 |
|---|---|---|---|
| 路径A:OEM 卫星模式 | 独立卫星(如 SOS 紧急通信) | ISatellite HAL → SatelliteService | ISatelliteListener.onNtnSignalStrengthChanged() |
| 路径B:运营商 NTN 漫游模式 | Carrier Roaming NB-IoT NTN | IRadio AIDL → RILJ → Phone | SignalStrengthController → TelephonyRegistryManager |
路径A:OEM 卫星模式
Modem固件 ──[QMI/AT/共享内存]──► Vendor RIL (rild)
│ │
│ 卫星信号测量值变化 │ 解析为 stub.NtnSignalStrength
│ ▼
│ SatelliteService (厂商实现)
│ │
│ [Binder IPC]
│ │
│ ▼
│ ISatelliteListener.onNtnSignalStrengthChanged()
│ │
│ ▼
│ SatelliteModemInterface.VendorListener
│ │
│ [Registrant.notifyResult]
│ │
│ ▼
│ SatelliteController.EVENT_NTN_SIGNAL_STRENGTH_CHANGED
│ │
│ ┌──────────────┴──────────────┐
│ ▼ ▼
│ handleEventNtnSignalStrengthChanged() updateLastNotifiedCarrierRoaming
│ (缓存+回调INtnSignalStrength NtnSignalStrengthAndNotify()
│ StrengthCallback注册者) │
│ ▼
│ Phone.notifyCarrierRoamingNtnSignalStrengthChanged()
│ │
│ ▼
│ DefaultPhoneNotifier → TelephonyRegistryManager
│ │
│ [Binder IPC]
│ │
│ ▼
│ TelephonyRegistry (系统服务进程)
│ │
│ [Binder回调]
│ │
│ ▼
│ ITelephonyListener.onCarrierRoamingNtnSignalStrengthChanged()
│ │
│ ┌─────────────┼─────────────┐
│ ▼ ▼ ▼
│ SystemUI 卫星应用 ConnectivityService
路径B:运营商 NTN 漫游模式
Modem固件 ──[IRadio AIDL]──► RILJ (RIL.java)
│ │
│ 3GPP R17 NTN信号测量 │ RIL_UNSOL_SIGNAL_STRENGTH
│ ▼
│ SignalStrengthController
│ │
│ [Registrant通知]
│ │
│ ┌───────────────┼───────────────┐
│ ▼ ▼
│ SatelliteController Phone.notifySignalStrength()
│ EVENT_SIGNAL_STRENGTH_CHANGED │
│ │ ▼
│ ▼ TelephonyRegistryManager
│ updateLastNotifiedCarrierRoaming │
│ NtnSignalStrengthAndNotify() [Binder IPC]
│ │
│ ▼
│ TelephonyRegistry → 应用层
NTN 信号强度等级
NtnSignalStrength 定义了 5 个等级:
| 等级 | 值 | 含义 |
|---|---|---|
NTN_SIGNAL_STRENGTH_NONE | 0 | 不可用 |
NTN_SIGNAL_STRENGTH_POOR | 1 | 差 |
NTN_SIGNAL_STRENGTH_MODERATE | 2 | 一般 |
NTN_SIGNAL_STRENGTH_GOOD | 3 | 好 |
NTN_SIGNAL_STRENGTH_GREAT | 4 | 极好 |
九、卫星网络与地面网络切换
9.1 切换决策因素
- 地面网络可用性(
onTerrestrialNetworkAvailableChanged) - 蜂窝 ServiceState 变化
- CarrierConfig 配置
- 当前是否为紧急模式
- P2P SMS 是否已建立通信
9.2 切换流程
地面网络恢复 → ISatelliteListener.onTerrestrialNetworkAvailableChanged(true)
→ SatelliteController
→ 评估是否应关闭卫星
→ 若 CarrierConfig 允许自动切换:
→ requestSatelliteEnabled(false)
→ SatelliteSessionController 状态机回退到 PowerOff
→ 若需手动确认:
→ 发送通知提示用户
在 IdleState 中,当检测到蜂窝 ServiceState 变为 IN_SERVICE 或 EMERGENCY_ONLY 时:
- 如果是紧急模式且已建立紧急通信,不自动切换
- 如果
turnOffSatelliteSessionForEmergencyCall允许,自动请求禁用卫星 - 禁用成功后记录
addCountOfAutoExitDueToTnNetwork()指标
9.3 并发地面扫描
在 IdleState 中,如果 isTnScanningAllowedDuringSatelliteSession() 为 true,Framework 会调用 enableCellularModemWhileSatelliteModeIsOn(true) 允许 Modem 同时扫描地面网络。
isConcurrentTnScanningSupported() 判断硬件是否支持卫星和地面网络并发:
- 支持:IdleState 对客户端隐藏,Modem 状态变化仍通知但不影响内部状态
- 不支持:进入 IdleState 时启用地面扫描,退出时禁用
十、多层不活跃计时器机制
Android 16 定义了 4 种不活跃计时器,通过 CarrierConfig 可配置:
| 计时器 | 默认超时 | CarrierConfig Key | 作用 |
|---|---|---|---|
| Screen Off 不活跃计时器 | 30 秒 | KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT | 屏幕关闭后自动退出卫星会话 |
| P2P SMS 不活跃计时器 | 180 秒 | KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT | 无 SMS 活动后退出 |
| ESOS 不活跃计时器 | 600 秒 | KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT | 无紧急 SOS 活动后退出 |
| NB-IoT 不活跃计时器 | 可配置 | — | NB-IoT NTN 模式下的不活跃超时 |
计时器之间的优先级关系:
- ESOS 和 P2P SMS 计时器可以共存,P2P SMS 计时器运行时 ESOS 超时不会触发状态转换
- 设备对准卫星时(
setDeviceAlignedWithSatellite(true)),停止 ESOS 和 P2P SMS 计时器 - 设备未对准卫星时,评估是否启动 ESOS 和 P2P SMS 计时器
- Datagram 传输期间停止所有不活跃计时器
十一、紧急呼叫到卫星的切换
11.1 SatelliteSOSMessageRecommender
SatelliteSOSMessageRecommender 负责在紧急呼叫期间监控蜂窝和 IMS 状态,当无法找到任何网络时通知 Dialer 提示用户切换到卫星消息。
11.2 切换类型
| 类型 | 值 | 说明 |
|---|---|---|
EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS | 1 | SOS 模式:消息发送给 SOS 提供商,再转发给紧急服务 |
EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911 | 2 | T911 模式:消息直接发送给本地紧急服务提供商 |
切换类型通过 CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT 配置。
11.3 通信限制原因体系
通信限制原因 (SatelliteCommunicationRestrictionReason):
| 原因 | 值 | 说明 |
|---|---|---|
RESTRICTION_REASON_USER | 0 | 用户限制 |
RESTRICTION_REASON_GEOLOCATION | 1 | 地理围栏限制(基于运营商提供的地理围栏输入) |
RESTRICTION_REASON_ENTITLEMENT | 2 | 权利服务器限制(基于 EntitlementStatus 值) |
不允许原因 (SatelliteDisallowedReason):
| 原因 | 值 | 说明 |
|---|---|---|
NOT_SUPPORTED | 0 | 设备不支持 |
NOT_PROVISIONED | 1 | 未开通 |
NOT_IN_ALLOWED_REGION | 2 | 不在允许区域 |
UNSUPPORTED_DEFAULT_MSG_APP | 3 | 默认短信应用不支持 |
LOCATION_DISABLED | 4 | 位置服务未开启 |
十二、卫星短信收发
基于 Android 16 代码分析,卫星短信不走传统 SmsDispatcher 路径,而是通过 SatelliteManager.sendDatagram() 以 Datagram 方式收发。这意味着卫星短信与地面 SMS 是完全独立的通道。
核心特点
- Datagram 承载:短信被编码为
SatelliteDatagram(byte[]),通过sendDatagram()发送,而非SmsManager.sendTextMessage() - 高延迟:卫星 RTT 500ms~数秒,Android 引入
SATELLITE_MODEM_STATE_DATAGRAM_RETRYING状态处理重试 - 受限长度:
SatelliteCapabilities.maxBytesPerOutgoingDatagram限制每条数据报最大字节数 - 需要指向:
isPointingRequired标识是否需要用户对准卫星 - 存储转发:支持
pollPendingDatagrams()主动拉取待接收消息 - MT SMS 轮询节流:
DatagramDispatcher实现了 MT SMS 轮询节流机制,避免频繁轮询
短信收发时序
App (Gateway/短信应用)
│
│ 1. SatelliteManager.sendDatagram(DATAGRAM_TYPE_SMS, datagram, ...)
↓
SatelliteManager
│
│ 2. ITelephony.sendDatagram(datagramType, datagram, needFullScreenPointingUI, callback)
↓
Telephony Service (ITelephony AIDL)
│
│ 3. 调用 ISatellite.sendSatelliteDatagram(datagram, isEmergency, callback)
↓
Vendor SatelliteService → Satellite HAL → Modem
│
│ 4. Modem 通过卫星上行链路发送
↓
EVENT_SEND_SATELLITE_DATAGRAM_DONE
│
│ 5. 回调应用层
↓
App 收到发送结果
对于接收:
Modem 收到卫星下行 SMS 数据
→ ISatelliteListener.onPendingDatagrams()
→ DatagramReceiver.pollPendingSatelliteDatagrams()
→ ISatellite.pollPendingSatagrams()
→ Modem 返回待接收数据
→ 若为 SMS 类型:写入 Telephony Provider (content://sms)
→ 通知 ISatelliteDatagramCallback 注册者
十三、语音通话
AOSP Android 16 原生不支持卫星语音通话,框架仅支持数据报模式的短消息。主要原因在于 Android 16 的原生卫星通信框架是为"窄带非地面网络 (NB-NTN)"设计的,这种技术专为发送小数据包优化,带宽低、延迟高,只适合短信和紧急求救信号,无法承载高质量、低延迟的双向实时语音。
十四、HAL 接口层
14.1 双服务架构
Android 16 卫星通信采用双服务绑定架构:
ISatellite 服务(由 SatelliteModemInterface 绑定):
- 负责与 Modem 的所有交互
- 包名通过
config_satellite_service_package配置 - 绑定失败时使用指数退避重试(2s → 64s)
SatelliteGatewayService(由 SatelliteSessionController 绑定):
- 当卫星启用时绑定,禁用时解绑
- 包名通过
config_satellite_gateway_service_package配置 ISatelliteGateway接口为空,仅用于生命周期管理- Gateway 应用可在
onCreate()/onDestroy()中执行初始化和清理
14.2 ISatellite AIDL 接口方法
| 方法 | 说明 |
|---|---|
setSatelliteListener(listener) | 注册回调接口 |
requestSatelliteListeningEnabled(enable, timeout, callback) | 启用/禁用监听模式 |
enableTerrestrialNetworkScanWhileSatelliteModeIsOn(enabled, callback) | 卫星模式下扫描地面网络 |
requestSatelliteEnabled(enableAttributes, callback) | 启用/禁用卫星(使用新属性对象) |
requestIsSatelliteEnabled(resultCallback, callback) | 查询卫星启用状态 |
requestIsSatelliteSupported(resultCallback, callback) | 查询卫星支持状态 |
requestSatelliteCapabilities(resultCallback, callback) | 查询卫星能力 |
startSendingSatellitePointingInfo(callback) | 开始上报卫星指向信息 |
stopSendingSatellitePointingInfo(callback) | 停止上报卫星指向信息 |
pollPendingSatelliteDatagrams(callback) | 拉取待接收数据报 |
sendSatelliteDatagram(datagram, isEmergency, callback) | 发送数据报 |
requestSatelliteModemState(resultCallback, callback) | 查询 Modem 状态 |
requestTimeForNextSatelliteVisibility(resultCallback, callback) | 查询下次卫星可见时间 |
setSatellitePlmn(simSlot, carrierPlmnList, allSatellitePlmnList, callback) | 设置卫星 PLMN 列表 |
setSatelliteEnabledForCarrier(simSlot, satelliteEnabled, callback) | 按运营商启用/禁用卫星 |
requestIsSatelliteEnabledForCarrier(simSlot, resultCallback, callback) | 查询运营商卫星启用状态 |
requestSignalStrength(resultCallback, callback) | 查询信号强度 |
startSendingNtnSignalStrength(callback) | 开始上报 NTN 信号强度 |
stopSendingNtnSignalStrength(callback) | 停止上报 NTN 信号强度 |
14.3 ISatelliteListener 回调接口
| 回调 | 说明 |
|---|---|
onSatelliteDatagramReceived(datagram, pendingCount) | 收到新数据报 |
onPendingDatagrams() | 有待拉取的数据报 |
onSatellitePositionChanged(pointingInfo) | 卫星指向信息变化 |
onSatelliteModemStateChanged(state) | Modem 状态变化 |
onNtnSignalStrengthChanged(ntnSignalStrength) | NTN 信号强度变化 |
onSatelliteCapabilitiesChanged(capabilities) | 卫星能力变化 |
onSatelliteSupportedStateChanged(supported) | 卫星支持状态变化 |
onRegistrationFailure(causeCode) | 卫星注册失败(causeCode 遵循 3GPP TS 24.301 Sec 9.9.3.9) |
onTerrestrialNetworkAvailableChanged(isAvailable) | 地面网络可用性变化 |
14.4 Demo 模式与真实模式的双监听器
SatelliteModemInterface 维护两个 SatelliteListener 实例:
mVendorListener— 真实模式监听器mDemoListener— Demo 模式监听器
通过 notifyResultIfExpectedListener() 确保只有当前模式对应的监听器处理事件。但 onSatelliteModemStateChanged 例外 — OFF 和 UNAVAILABLE 状态无论哪个监听器都会通知。
十五、卫星精确选网机制
15.1 SatelliteInfo
SatelliteInfo 存储单颗卫星的精确信息:
mId(UUID) — 卫星唯一标识mPosition(SatellitePosition) — 卫星位置(经度、高度),无效时为DOUBLE.NaNmBandList— 频段列表(最多 8 个)mEarfcnRangeList— EARFCN 频率范围列表(最多 8 个)
15.2 SatelliteAccessConfiguration
封装当前区域的卫星接入配置:
mSatelliteInfoList— 可用卫星列表mTagIdList— 区域标签 ID(OEM 可映射到区域专属配置)mCarrierIdList— 运营商 ID 列表
15.3 SystemSelectionSpecifier
定义 Modem 选网所需的全部参数:
mMccMnc— PLMN 标识mBands— 频段(最多 8 个)mEarfcns— EARFCN 信道号(最多 32 个)mSatelliteInfos— 卫星信息列表mTagIds— OEM 自定义标签 ID
这些类使框架能够根据用户位置动态选择最优卫星和频段,Modem 可以有针对性地搜索特定卫星而非全频段盲扫。
15.4 NtnCapabilityResolver
NtnCapabilityResolver 在 NetworkRegistrationInfo 中标记当前网络是否为非地面网络:
public static void resolveNtnCapability(
NetworkRegistrationInfo networkRegistrationInfo, int subId) {
// 检查注册的 PLMN 是否为卫星 PLMN
// 如果是,设置 setIsNonTerrestrialNetwork(true)
// 并设置该 PLMN 支持的 availableServices
}
上层应用可通过 NetworkRegistrationInfo.isNonTerrestrialNetwork() 判断当前是否连接到卫星网络,通过 getAvailableServices() 获取该卫星网络支持的服务类型。
十六、错误码体系
Android 16 定义了完整的卫星通信错误码:
| 错误码 | 值 | 说明 |
|---|---|---|
SATELLITE_RESULT_SUCCESS | 0 | 成功 |
SATELLITE_RESULT_ERROR | 1 | 通用错误 |
SATELLITE_RESULT_SERVER_ERROR | 2 | 服务器错误 |
SATELLITE_RESULT_SERVICE_ERROR | 3 | 厂商服务错误 |
SATELLITE_RESULT_MODEM_ERROR | 4 | Modem 错误 |
SATELLITE_RESULT_NETWORK_ERROR | 5 | 网络错误 |
SATELLITE_RESULT_INVALID_TELEPHONY_STATE | 6 | Telephony 状态无效 |
SATELLITE_RESULT_INVALID_MODEM_STATE | 7 | Modem 状态无效 |
SATELLITE_RESULT_INVALID_ARGUMENTS | 8 | 参数无效 |
SATELLITE_RESULT_REQUEST_FAILED | 9 | 请求失败 |
SATELLITE_RESULT_RADIO_NOT_AVAILABLE | 10 | Radio 不可用 |
SATELLITE_RESULT_REQUEST_NOT_SUPPORTED | 11 | 请求不支持 |
SATELLITE_RESULT_NO_RESOURCES | 12 | 无资源 |
SATELLITE_RESULT_SERVICE_NOT_PROVISIONED | 13 | 服务未开通 |
SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS | 14 | 开通进行中 |
SATELLITE_RESULT_REQUEST_ABORTED | 15 | 请求中止 |
SATELLITE_RESULT_ACCESS_BARRED | 16 | 接入被拒 |
SATELLITE_RESULT_NETWORK_TIMEOUT | 17 | 网络超时 |
SATELLITE_RESULT_NOT_REACHABLE | 18 | 网络不可达 |
SATELLITE_RESULT_NOT_AUTHORIZED | 19 | 未授权 |
SATELLITE_RESULT_NOT_SUPPORTED | 20 | 设备不支持 |
SATELLITE_RESULT_REQUEST_IN_PROGRESS | 21 | 请求进行中 |
SATELLITE_RESULT_MODEM_BUSY | 22 | Modem 忙碌 |
SATELLITE_RESULT_ILLEGAL_STATE | 23 | 非法状态 |
SATELLITE_RESULT_MODEM_TIMEOUT | 24 | Modem 超时 |
SATELLITE_RESULT_LOCATION_DISABLED | 25 | 位置设置关闭 |
SATELLITE_RESULT_LOCATION_NOT_AVAILABLE | 26 | 位置不可用 |
SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS | 27 | 紧急呼叫进行中 |
SATELLITE_RESULT_DISABLE_IN_PROGRESS | 28 | 正在禁用 |
SATELLITE_RESULT_ENABLE_IN_PROGRESS | 29 | 正在启用 |
SATELLITE_RESULT_NO_VALID_SATELLITE_SUBSCRIPTION | 30 | 无有效卫星订阅 |
十七、无线电技术类型
| 技术 | 值 | 说明 |
|---|---|---|
NT_RADIO_TECHNOLOGY_UNKNOWN | 0 | 未知 |
NT_RADIO_TECHNOLOGY_NB_IOT_NTN | 1 | 3GPP NB-IoT over NTN |
NT_RADIO_TECHNOLOGY_NR_NTN | 2 | 3GPP 5G NR over NTN |
NT_RADIO_TECHNOLOGY_EMTC_NTN | 3 | 3GPP eMTC over NTN |
NT_RADIO_TECHNOLOGY_PROPRIETARY | 4 | 厂商专有技术 |
十八、关键源码文件索引
| 文件 | 路径 | 职责 |
|---|---|---|
| SatelliteManager.java | frameworks/base/telephony/java/android/telephony/satellite/ | 公共 API 入口 |
| SatelliteController.java | frameworks/opt/telephony/src/java/com/android/internal/telephony/satellite/ | 后端服务核心控制器 |
| SatelliteSessionController.java | 同上 | 会话状态机 |
| SatelliteModemInterface.java | 同上 | HAL 接口管理 |
| DatagramController.java | 同上 | 数据报收发控制器 |
| DatagramDispatcher.java | 同上 | 数据报发送调度器 |
| DatagramReceiver.java | 同上 | 数据报接收处理器 |
| PointingAppController.java | 同上 | 卫星指向 UI 控制器 |
| SatelliteSOSMessageRecommender.java | 同上 | 紧急呼叫卫星推荐器 |
| NtnCapabilityResolver.java | 同上 | NTN 能力解析器 |
| SatelliteOptimizedApplicationsTracker.java | 同上 | 卫星优化应用追踪器 |
| DemoSimulator.java | 同上 | Demo 模式模拟器 |
| SatelliteServiceUtils.java | 同上 | 工具类 |
| SatelliteConfig.java | 同上 | 配置管理 |
| ISatellite.aidl | frameworks/base/telephony/java/android/telephony/satellite/stub/ | HAL AIDL 接口 |
| ISatelliteListener.aidl | 同上 | HAL 回调接口 |
| ISatelliteGateway.aidl | 同上 | Gateway 服务接口 |
| SatelliteGatewayService.java | 同上 | Gateway 服务基类 |
| SatelliteCapabilities.java | frameworks/base/telephony/java/android/telephony/satellite/ | 卫星能力数据类 |
| NtnSignalStrength.java | 同上 | NTN 信号强度数据类 |
| SatelliteInfo.java | 同上 | 卫星信息数据类 |
| SatelliteAccessConfiguration.java | 同上 | 卫星接入配置数据类 |
| SystemSelectionSpecifier.java | 同上 | 系统选网参数数据类 |
| EnableRequestAttributes.java | 同上 | 启用请求属性 |
| SatelliteModemEnableRequestAttributes.java | 同上 | Modem 启用请求属性 |
| SatelliteSubscriptionInfo.java | 同上 | 卫星订阅信息 |