Android 16 卫星通信原理架构(源码级完整版)

7 阅读20分钟

一、架构总览

卫星通信框架遵循"能力查询 → 请求权限 → 发送消息"的严格流程,其核心是隐私与资源保护。

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(如 requestIsSupportedregisterStateChangeListener)仅需 READ_PHONE_STATEREAD_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_RESTRICTED0仅支持受限数据用例(如 RCS 消息)
SATELLITE_DATA_SUPPORT_CONSTRAINED1支持受限互联网,仅限声明了 PROPERTY_SATELLITE_DATA_OPTIMIZED 的优化应用
SATELLITE_DATA_SUPPORT_UNCONSTRAINED2无限制互联网,所有应用可用

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 值说明
UnavailableStateSATELLITE_MODEM_STATE_UNAVAILABLE (5)设备不支持卫星时的初始状态
PowerOffStateSATELLITE_MODEM_STATE_OFF (4)卫星 Modem 关闭
EnablingStateSATELLITE_MODEM_STATE_ENABLING_SATELLITE (8)卫星正在启用中
DisablingStateSATELLITE_MODEM_STATE_DISABLING_SATELLITE (9)卫星正在关闭中
IdleStateSATELLITE_MODEM_STATE_IDLE (0)卫星已启用但无数据传输
TransferringStateSATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING (2)正在收发数据报
ListeningStateSATELLITE_MODEM_STATE_LISTENING (1)监听入站数据报
NotConnectedStateSATELLITE_MODEM_STATE_NOT_CONNECTED (6)NB-IoT NTN 模式下已启用但未附着
ConnectedStateSATELLITE_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

已附着到卫星小区。进入时:

  1. 通知状态变化为 SATELLITE_MODEM_STATE_CONNECTED
  2. 启动 NB-IoT 不活跃计时器
  3. 评估并启动 ESOS 不活跃计时器(默认 600 秒)
  4. 评估并启动 P2P SMS 不活跃计时器(默认 180 秒)
  5. 主动更新并通知 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 ID
    • niddApn — 非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_UNKNOWN0未知
DATAGRAM_TYPE_SOS_MESSAGE1SOS 紧急消息
DATAGRAM_TYPE_LOCATION_SHARING2位置共享
DATAGRAM_TYPE_KEEP_ALIVE3保活消息,维持卫星连接或检查入站消息
DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP4最后一条 SOS 消息(仍需帮助)
DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED5最后一条 SOS 消息(不再需要帮助)
DATAGRAM_TYPE_SMS6P2P 短信
DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS7检查待接收的入站 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 → SatelliteServiceISatelliteListener.onNtnSignalStrengthChanged()
路径B:运营商 NTN 漫游模式Carrier Roaming NB-IoT NTNIRadio AIDL → RILJ → PhoneSignalStrengthController → 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_NONE0不可用
NTN_SIGNAL_STRENGTH_POOR1
NTN_SIGNAL_STRENGTH_MODERATE2一般
NTN_SIGNAL_STRENGTH_GOOD3
NTN_SIGNAL_STRENGTH_GREAT4极好

九、卫星网络与地面网络切换

9.1 切换决策因素

  • 地面网络可用性(onTerrestrialNetworkAvailableChanged
  • 蜂窝 ServiceState 变化
  • CarrierConfig 配置
  • 当前是否为紧急模式
  • P2P SMS 是否已建立通信

9.2 切换流程

地面网络恢复 → ISatelliteListener.onTerrestrialNetworkAvailableChanged(true)
→ SatelliteController
→ 评估是否应关闭卫星
→ 若 CarrierConfig 允许自动切换:
    → requestSatelliteEnabled(false)
    → SatelliteSessionController 状态机回退到 PowerOff
→ 若需手动确认:
    → 发送通知提示用户

IdleState 中,当检测到蜂窝 ServiceState 变为 IN_SERVICEEMERGENCY_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_SOS1SOS 模式:消息发送给 SOS 提供商,再转发给紧急服务
EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T9112T911 模式:消息直接发送给本地紧急服务提供商

切换类型通过 CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT 配置。

11.3 通信限制原因体系

通信限制原因 (SatelliteCommunicationRestrictionReason):

原因说明
RESTRICTION_REASON_USER0用户限制
RESTRICTION_REASON_GEOLOCATION1地理围栏限制(基于运营商提供的地理围栏输入)
RESTRICTION_REASON_ENTITLEMENT2权利服务器限制(基于 EntitlementStatus 值)

不允许原因 (SatelliteDisallowedReason):

原因说明
NOT_SUPPORTED0设备不支持
NOT_PROVISIONED1未开通
NOT_IN_ALLOWED_REGION2不在允许区域
UNSUPPORTED_DEFAULT_MSG_APP3默认短信应用不支持
LOCATION_DISABLED4位置服务未开启

十二、卫星短信收发

基于 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.NaN
  • mBandList — 频段列表(最多 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

NtnCapabilityResolverNetworkRegistrationInfo 中标记当前网络是否为非地面网络:

public static void resolveNtnCapability(
        NetworkRegistrationInfo networkRegistrationInfo, int subId) {
    // 检查注册的 PLMN 是否为卫星 PLMN
    // 如果是,设置 setIsNonTerrestrialNetwork(true)
    // 并设置该 PLMN 支持的 availableServices
}

上层应用可通过 NetworkRegistrationInfo.isNonTerrestrialNetwork() 判断当前是否连接到卫星网络,通过 getAvailableServices() 获取该卫星网络支持的服务类型。


十六、错误码体系

Android 16 定义了完整的卫星通信错误码:

错误码说明
SATELLITE_RESULT_SUCCESS0成功
SATELLITE_RESULT_ERROR1通用错误
SATELLITE_RESULT_SERVER_ERROR2服务器错误
SATELLITE_RESULT_SERVICE_ERROR3厂商服务错误
SATELLITE_RESULT_MODEM_ERROR4Modem 错误
SATELLITE_RESULT_NETWORK_ERROR5网络错误
SATELLITE_RESULT_INVALID_TELEPHONY_STATE6Telephony 状态无效
SATELLITE_RESULT_INVALID_MODEM_STATE7Modem 状态无效
SATELLITE_RESULT_INVALID_ARGUMENTS8参数无效
SATELLITE_RESULT_REQUEST_FAILED9请求失败
SATELLITE_RESULT_RADIO_NOT_AVAILABLE10Radio 不可用
SATELLITE_RESULT_REQUEST_NOT_SUPPORTED11请求不支持
SATELLITE_RESULT_NO_RESOURCES12无资源
SATELLITE_RESULT_SERVICE_NOT_PROVISIONED13服务未开通
SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS14开通进行中
SATELLITE_RESULT_REQUEST_ABORTED15请求中止
SATELLITE_RESULT_ACCESS_BARRED16接入被拒
SATELLITE_RESULT_NETWORK_TIMEOUT17网络超时
SATELLITE_RESULT_NOT_REACHABLE18网络不可达
SATELLITE_RESULT_NOT_AUTHORIZED19未授权
SATELLITE_RESULT_NOT_SUPPORTED20设备不支持
SATELLITE_RESULT_REQUEST_IN_PROGRESS21请求进行中
SATELLITE_RESULT_MODEM_BUSY22Modem 忙碌
SATELLITE_RESULT_ILLEGAL_STATE23非法状态
SATELLITE_RESULT_MODEM_TIMEOUT24Modem 超时
SATELLITE_RESULT_LOCATION_DISABLED25位置设置关闭
SATELLITE_RESULT_LOCATION_NOT_AVAILABLE26位置不可用
SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS27紧急呼叫进行中
SATELLITE_RESULT_DISABLE_IN_PROGRESS28正在禁用
SATELLITE_RESULT_ENABLE_IN_PROGRESS29正在启用
SATELLITE_RESULT_NO_VALID_SATELLITE_SUBSCRIPTION30无有效卫星订阅

十七、无线电技术类型

技术说明
NT_RADIO_TECHNOLOGY_UNKNOWN0未知
NT_RADIO_TECHNOLOGY_NB_IOT_NTN13GPP NB-IoT over NTN
NT_RADIO_TECHNOLOGY_NR_NTN23GPP 5G NR over NTN
NT_RADIO_TECHNOLOGY_EMTC_NTN33GPP eMTC over NTN
NT_RADIO_TECHNOLOGY_PROPRIETARY4厂商专有技术

十八、关键源码文件索引

文件路径职责
SatelliteManager.javaframeworks/base/telephony/java/android/telephony/satellite/公共 API 入口
SatelliteController.javaframeworks/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.aidlframeworks/base/telephony/java/android/telephony/satellite/stub/HAL AIDL 接口
ISatelliteListener.aidl同上HAL 回调接口
ISatelliteGateway.aidl同上Gateway 服务接口
SatelliteGatewayService.java同上Gateway 服务基类
SatelliteCapabilities.javaframeworks/base/telephony/java/android/telephony/satellite/卫星能力数据类
NtnSignalStrength.java同上NTN 信号强度数据类
SatelliteInfo.java同上卫星信息数据类
SatelliteAccessConfiguration.java同上卫星接入配置数据类
SystemSelectionSpecifier.java同上系统选网参数数据类
EnableRequestAttributes.java同上启用请求属性
SatelliteModemEnableRequestAttributes.java同上Modem 启用请求属性
SatelliteSubscriptionInfo.java同上卫星订阅信息