一、框架总览
1.1 分层架构图
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 应用层 (Application Layer) 🟦 蓝色 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐│
│ │ 系统设置 │ │ 短信应用 │ │ 紧急SOS │ │ 位置分享 │ │ 运营商应用 ││
│ │Settings │ │Messages │ │Emergency │ │Location │ │Carrier App ││
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────────────┘│
└───────┼──────────────┼────────────┼────────────┼──────────────┼──────────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 框架公共API层 (Public API) 🟩 绿色 │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐│
│ │ SatelliteManager (SystemService) ││
│ │ ┌─requestSatelliteEnabled() ──┐ ┌─sendDatagram() ──┐ ││
│ │ │ requestSatelliteCapabilities()│ │ registerForIncomingDatagram()│ ││
│ │ │ provisionSatelliteService()──┘ │ startTransmissionUpdates()──┘ ││
│ │ ├─registerForModemStateChanged() ├─registerForNtnSignalStrengthChanged()│
│ │ │ registerForCapabilitiesChanged()│ requestNtnSignalStrength() ││
│ │ └─isSatelliteProvisioned() └─isSatelliteSupported() ││
│ └───────────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────────────┘
│ [Binder IPC]
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Telephony框架内部层 (Internal Framework) 🟧 橙色 │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐│
│ │ SatelliteController (中央控制器 · extends Handler) ││
│ │ ││
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐││
│ │ │Datagram │ │Satellite │ │SatelliteModem│ │PointingApp │││
│ │ │Controller │ │Session │ │Interface │ │Controller │││
│ │ │┌Dispatcher │ │Controller │ │(Binder客户端 │ │(对星UI管理) │││
│ │ │└Receiver │ │(状态机) │ │ 代理) │ │ │││
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘││
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐││
│ │ │SatelliteSOS │ │SatelliteConfig│ │DemoSimulator │ │SatelliteOptimized│││
│ │ │Message │ │Parser │ │(演示模式) │ │Applications │││
│ │ │Recommender │ │ │ │ │ │Tracker │││
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘││
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ││
│ │ │NtnCapability │ │Satellite │ │CarrierRoaming│ ││
│ │ │Resolver │ │ServiceUtils │ │Satellite │ ││
│ │ │ │ │(类型转换) │ │SessionStats │ ││
│ │ └──────────────┘ └──────────────┘ └──────────────┘ ││
│ └───────────────────────────────────────────────────────────────────────────┘│
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐│
│ │ Phone / SignalStrengthController / DeviceStateMonitor (现有Telephony) ││
│ │ DefaultPhoneNotifier → TelephonyRegistryManager → TelephonyRegistry ││
│ └───────────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────────────┘
│ [Binder IPC]
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 厂商服务层 (Vendor Service) 🟥 红色 │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐│
│ │ SatelliteService (厂商实现 · 独立APK进程) ││
│ │ 实现 ISatellite.aidl 接口 ││
│ │ ┌─requestSatelliteEnabled() ──┐ ┌─sendSatelliteDatagram() ──┐ ││
│ │ │ startSendingNtnSignalStrength()│ │ pollPendingDatagrams() │ ││
│ │ │ setSatelliteListener()──────┘ └─requestSignalStrength()──┘ ││
│ │ └─requestSatelliteMode() ││
│ └───────────────────────────────────────────────────────────────────────────┘│
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐│
│ │ SatelliteGatewayService (消息编解码服务) ││
│ │ 实现 ISatelliteGateway.aidl 接口 ││
│ │ 负责卫星消息的编码(发送前)和解码(接收后) ││
│ └───────────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────────────┘
│ [QMI/AT/共享内存]
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Modem/硬件层 🟫 棕色 │
│ 卫星Modem固件 · GNSS接收机 · NTN协议栈 · 射频前端 │
└─────────────────────────────────────────────────────────────────────────────────┘
1.2 模块依赖关系
SatelliteManager (公共API)
│
└──► SatelliteController (中央控制器)
│
├──► SatelliteModemInterface (Modem通信代理)
│ └──► ISatellite.aidl [Binder] → SatelliteService(厂商)
│
├──► DatagramController (数据报管理)
│ ├──► DatagramDispatcher (发送调度)
│ │ └──► SatelliteModemInterface.sendSatelliteDatagram()
│ └──► DatagramReceiver (接收处理)
│ └──► SatelliteModemInterface.pollPendingSatelliteDatagrams()
│
├──► SatelliteSessionController (会话状态机)
│ └──► SatelliteGatewayService [Binder] → ISatelliteGateway
│
├──► PointingAppController (对星UI)
│
├──► DeviceStateMonitor (省电策略)
│ └──► 信号上报启停控制
│
├──► Phone / SignalStrengthController (蜂窝信号)
│ └──► TelephonyRegistryManager → TelephonyRegistry → 应用
│
└──► DemoSimulator (演示模式)
└──► ISatelliteListener (模拟回调)
二、核心模块详解
2.1 SatelliteManager(公共 API)
职责:面向应用和系统服务的卫星通信公共入口,运行在应用进程。
关键方法分类:
| 类别 | 方法 | 说明 |
|---|---|---|
| 模式控制 | requestSatelliteEnabled(enable, demoMode, isEmergency, callback) | 开启/关闭卫星模式 |
isSatelliteEnabled() | 查询卫星是否启用 | |
isSatelliteSupported() | 查询设备是否支持卫星 | |
| 数据报通信 | sendDatagram(type, datagram, needFullScreenUI, callback) | 发送卫星数据报 |
registerForIncomingDatagram(callback) | 注册接收数据报回调 | |
pollPendingSatelliteDatagrams(callback) | 主动拉取待接收数据报 | |
| 信号与状态 | registerForModemStateChanged(callback) | 注册Modem状态变化 |
registerForNtnSignalStrengthChanged(callback) | 注册NTN信号强度变化 | |
requestNtnSignalStrength(result) | 查询当前信号强度 | |
| 能力查询 | requestSatelliteCapabilities(callback) | 查询卫星能力 |
registerForCapabilitiesChanged(callback) | 注册能力变化回调 | |
| 配置管理 | provisionSatelliteService(token, callback) | 开通卫星服务 |
isSatelliteProvisioned() | 查询是否已开通 | |
requestSatelliteAccessConfiguration() | 获取卫星接入配置 | |
| 对星引导 | startTransmissionUpdates(callback) | 启动对星UI更新 |
stopTransmissionUpdates(callback) | 停止对星UI更新 |
通信方式:SatelliteManager 通过 Binder IPC 与 com.android.phone 进程中的 SatelliteController 通信。
2.2 SatelliteController(中央控制器)
职责:卫星通信的中央控制器,运行在 com.android.phone 进程,是 SatelliteManager 的后端实现。
核心设计:
- 继承
Handler,所有请求通过消息队列串行处理 - 单例模式(
sInstance) - 管理 90+ 种消息类型(CMD_xxx / EVENT_xxx / REQUEST_xxx)
关键状态管理:
| 状态变量 | 类型 | 说明 |
|---|---|---|
mSatelliteModemState | @SatelliteModemState | Modem当前状态 |
mIsDemoModeEnabled | AtomicBoolean | 演示模式开关 |
mIsEmergency | AtomicBoolean | 紧急模式标志 |
mNtnSignalStrength | NtnSignalStrength | 缓存的NTN信号强度 |
mSatelliteCapabilities | SatelliteCapabilities | 缓存的卫星能力 |
mIsRadioOn | AtomicBoolean | Radio是否开启 |
mIsSatelliteSupported | Boolean | 设备是否支持卫星 |
多客户端管理:使用 ConcurrentHashMap<IBinder, Callback> 管理多个注册者,遍历通知时自动清理已死亡的回调。
2.3 DatagramController / DatagramDispatcher / DatagramReceiver
DatagramController(DatagramController.java):
职责:卫星数据报的发送和接收管理器,协调 Dispatcher 和 Receiver。
关键设计:
- 使用
AtomicInteger跟踪发送/接收状态(mSendDatagramTransferState,mReceiveDatagramTransferState) - 管理发送队列和接收回调
- 支持多种数据报类型:SMS、SOS_MESSAGE、KEEP_ALIVE、CHECK_PENDING_INCOMING_SMS
DatagramDispatcher(DatagramDispatcher.java):
职责:卫星数据报发送调度器。
关键流程:
CMD_SEND_SATELLITE_DATAGRAM
→ 检查Demo模式 → 若Demo且不下发Modem则模拟延迟
→ 否则调用 SatelliteModemInterface.sendSatelliteDatagram()
→ 启动发送超时定时器
→ EVENT_SEND_SATELLITE_DATAGRAM_DONE
→ 成功:通知DatagramController更新状态
→ 失败:根据错误码决定重试或终止
重试机制:发送失败时,数据报保留在队列中,等待 retrySendingDatagrams() 被调用时重新发送。
DatagramReceiver(DatagramReceiver.java):
职责:卫星数据报接收处理器。
关键流程:
CMD_POLL_PENDING_SATELLITE_DATAGRAMS
→ SatelliteModemInterface.pollPendingSatelliteDatagrams()
→ EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE
→ 成功:解析数据报,通过ISatelliteDatagramCallback通知应用
→ 失败:记录错误,等待下次poll
接收数据报存储:接收到的卫星短信通过 ContentResolver 写入 Telephony Provider(content://sms)。
2.4 SatelliteSessionController(会话状态机)
源码位置:SatelliteSessionController.java
职责:管理卫星会话的生命周期状态转换。
状态机拓扑:
┌─────────────┐
│ Unavailable │ ← 设备不支持卫星
└─────────────┘
│
┌─────▼──────┐
│ PowerOff │ ← 卫星关闭
└─────┬──────┘
│ requestSatelliteEnabled(true)
┌─────▼──────┐
│ Enabling │ ← 正在启用
└─────┬──────┘
│ Modem上报CONNECTED
┌─────▼──────┐
│ Connected │ ← 已连接
└──┬───┬───┬─┘
│ │ │
┌────────────┘ │ └────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────┐ ┌──────────────┐
│NotConnected │ │ Idle │ │Transferring │
└─────────────┘ └────┬─────┘ └──────────────┘
│
┌──────▼──────┐
│ Listening │ ← 等待接收
└─────────────┘
关键定时器:
| 定时器 | 默认值 | 说明 |
|---|---|---|
SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS | 180秒 | 发送后保持监听的时间 |
SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS | 30秒 | 接收后保持监听的时间 |
NB_IOT_INACTIVITY_TIMEOUT | CarrierConfig | NB-IoT不活动超时 |
SCREEN_OFF_INACTIVITY_TIMEOUT | 30秒 | 屏幕关闭不活动超时 |
ESOS_INACTIVITY_TIMEOUT | 600秒 | 紧急SOS不活动超时 |
P2P_SMS_INACTIVITY_TIMEOUT | 180秒 | 点对点短信不活动超时 |
SatelliteGatewayService 集成:SessionController 绑定 SatelliteGatewayService(厂商实现的消息编解码服务),通过 ISatelliteGateway.aidl 接口进行消息编码/解码。
2.5 SatelliteModemInterface(Modem通信代理)
源码位置:SatelliteModemInterface.java
职责:Framework 与厂商 SatelliteService 之间的 Binder IPC 客户端代理。
核心机制:
- 服务绑定:通过
SatelliteServiceConnection绑定厂商 SatelliteService - 指数退避重连:
ExponentialBackoff(初始2秒,最大64秒,倍数2) - 双监听器:
VendorListener(真实模式)和DemoListener(演示模式),通过notifyResultIfExpectedListener()过滤 - RegistrantList 模式:将 AIDL 回调转换为 Android Registrant 通知模式
关键方法:
| 方法 | 对应 ISatellite.aidl | 说明 |
|---|---|---|
requestSatelliteEnabled() | requestSatelliteMode() | 开启/关闭卫星 |
sendSatelliteDatagram() | sendSatelliteDatagram() | 发送数据报 |
pollPendingSatelliteDatagrams() | pollPendingDatagrams() | 拉取待接收数据 |
startSendingNtnSignalStrength() | startSendingNtnSignalStrength() | 启动信号上报 |
stopSendingNtnSignalStrength() | stopSendingNtnSignalStrength() | 停止信号上报 |
requestNtnSignalStrength() | requestSignalStrength() | 查询当前信号 |
2.6 NtnCapabilityResolver
源码位置:NtnCapabilityResolver.java
职责:解析 NTN 网络能力,将卫星 PLMN 信息注入 NetworkRegistrationInfo。
关键逻辑:当终端注册到卫星 PLMN 时,设置 isNonTerrestrialNetwork=true 并标记可用服务类型(SMS/数据等),使 ConnectivityService 能正确识别卫星网络。
三、关键流程
3.1 卫星模式开关流程
用户点击"开启卫星"
│
▼
SatelliteManager.requestSatelliteEnabled(true, false, false, 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.requestSatelliteMode(attributes, callback)
│ │ [厂商RIL → Modem]
│ ▼
│ Modem 启用卫星射频 → 上报状态变化
│
▼
EVENT_SET_SATELLITE_ENABLED_DONE
│
├── 成功:
│ ├── 更新卫星启用状态
│ ├── 启动信号上报 (updateNtnSignalStrengthReporting)
│ ├── 通知 SessionController
│ └── callback.accept(SUCCESS)
│
└── 失败:
├── abortSatelliteEnableAttributesUpdateRequest()
├── 通知 SessionController
└── callback.accept(errorCode)
3.2 发送卫星消息流程
App: SatelliteManager.sendDatagram(SMS, datagram, true, callback)
│ [Binder IPC]
▼
SatelliteController.sendDatagram()
│
├── evaluateOemSatelliteRequestAllowed() → 权限检查
├── 若需对星: PointingAppController.startPointingUI()
│
▼
DatagramController.sendSatelliteDatagram()
│
▼
DatagramDispatcher.sendDatagram()
│
├── 排入发送队列 (LinkedHashMap)
├── CMD_SEND_SATELLITE_DATAGRAM
│
▼
SatelliteModemInterface.sendSatelliteDatagram()
│ [Binder IPC]
▼
ISatellite.sendSatelliteDatagram(datagram, isEmergency, callback)
│ [厂商RIL → Modem]
▼
Modem 通过卫星上行链路发送
│
▼
EVENT_SEND_SATELLITE_DATAGRAM_DONE
│
├── 成功:更新发送状态 → SEND_SUCCESS
│ → 通知 DatagramController → 回调 App
│
└── 失败:保留在队列 → 等待 retrySendingDatagrams()
→ 超时:SATELLITE_RESULT_MODEM_TIMEOUT
3.3 接收卫星消息流程
Modem 收到卫星下行数据
│
▼
ISatelliteListener.onPendingDatagrams(count)
│ [Binder IPC 回调]
▼
SatelliteModemInterface → SatelliteController.EVENT_PENDING_DATAGRAMS
│
▼
DatagramController → DatagramReceiver.pollPendingSatelliteDatagrams()
│
▼
SatelliteModemInterface.pollPendingSatelliteDatagrams()
│ [Binder IPC]
▼
ISatellite.pollPendingDatagrams(callback)
│ [厂商RIL → Modem]
▼
Modem 返回待接收数据报
│
▼
EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE
│
├── 解析 SatelliteDatagram
├── 若为SMS类型:写入 Telephony Provider (content://sms)
├── 通知 ISatelliteDatagramCallback 注册者
└── 更新接收状态 → RECEIVE_SUCCESS
3.4 信号变化上报流程
(详见前次分析,此处总结关键路径)
路径A(OEM卫星):
Modem → Vendor RIL → SatelliteService
→ ISatelliteListener.onNtnSignalStrengthChanged()
→ SatelliteModemInterface → SatelliteController
→ 分支1: INtnSignalStrengthCallback (应用层)
→ 分支2: Phone → TelephonyRegistryManager → TelephonyRegistry → SystemUI
路径B(运营商NTN漫游):
Modem → IRadio AIDL → RILJ → SignalStrengthController
→ SatelliteController.EVENT_SIGNAL_STRENGTH_CHANGED
→ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify()
→ Phone → TelephonyRegistry → 应用层
3.5 卫星网络与地面网络切换
切换决策因素:
| 因素 | 说明 |
|---|---|
ServiceState.isUsingNonTerrestrialNetwork() | 当前是否在NTN网络 |
onTerrestrialNetworkAvailableChanged() | 地面网络可用性通知 |
KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT | 连接滞后时间(防抖) |
KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT | 连接类型(自动/手动) |
isConcurrentTnScanningSupported() | 是否支持并发地面扫描 |
切换流程:
地面网络恢复 → ISatelliteListener.onTerrestrialNetworkAvailableChanged(true)
→ SatelliteController
→ 评估是否应关闭卫星
→ 若 CarrierConfig 允许自动切换:
→ requestSatelliteEnabled(false)
→ SatelliteSessionController 状态机回退到 PowerOff
→ 若需手动确认:
→ 发送通知提示用户
并发地面扫描:在 IdleState 中,若 isConcurrentTnScanningSupported() 为 true,Framework 会调用 enableCellularModemWhileSatelliteModeIsOn(true) 允许 Modem 同时扫描地面网络。
四、数据结构与协议
4.1 SatelliteDatagram
// android.telephony.satellite.SatelliteDatagram
public class SatelliteDatagram implements Parcelable {
private byte[] mData; // 卫星数据报原始字节
public SatelliteDatagram(@NonNull byte[] data) { mData = data; }
public @NonNull byte[] getSatelliteDatagram() { return mData; }
}
数据报类型:
| 类型常量 | 值 | 说明 |
|---|---|---|
DATAGRAM_TYPE_UNKNOWN | 0 | 未知 |
DATAGRAM_TYPE_SOS_MESSAGE | 1 | 紧急SOS消息 |
DATAGRAM_TYPE_SMS | 2 | 卫星短信 |
DATAGRAM_TYPE_KEEP_ALIVE | 3 | 保活消息 |
DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS | 4 | 检查待接收短信 |
4.2 SatelliteCapabilities
// android.telephony.satellite.SatelliteCapabilities
public classCapabilities implements Parcelable {
private int mMaxDatagramSizeBytes; // 最大数据报大小(字节)
private boolean mIsPointingRequired; // 是否需要对星引导
private int mMaxCharactersPerMessage; // 每条消息最大字符数
private List<Integer> mSupportedRadioTechnologies; // 支持的无线电技术
}
4.3 SatelliteModemState(状态枚举)
| 状态 | 值 | 说明 |
|---|---|---|
SATELLITE_MODEM_STATE_UNKNOWN | 0 | 未知 |
SATELLITE_MODEM_STATE_OFF | 1 | 关闭 |
SATELLITE_MODEM_STATE_NOT_CONNECTED | 2 | 未连接 |
SATELLITE_MODEM_STATE_CONNECTED | 3 | 已连接 |
SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING | 4 | 数据传输中 |
SATELLITE_MODEM_STATE_DATAGRAM_RETRYING | 5 | 数据重传中 |
SATELLITE_MODEM_STATE_LISTENING | 6 | 监听中 |
SATELLITE_MODEM_STATE_IDLE | 7 | 空闲 |
SATELLITE_MODEM_STATE_UNAVAILABLE | 8 | 不可用 |
SATELLITE_MODEM_STATE_ENABLING_SATELLITE | 9 | 正在启用 |
4.4 NtnSignalStrength
// android.telephony.satellite.NtnSignalStrength
public class NtnSignalStrength implements Parcelable {
public static final int NTN_SIGNAL_STRENGTH_NONE = 0;
public static final int NTN_SIGNAL_STRENGTH_LOW = 1;
public static final int NTN_SIGNAL_STRENGTH_MEDIUM = 2;
public static final int NTN_SIGNAL_STRENGTH_HIGH = 3;
public static final int NTN_SIGNAL_STRENGTH_GOOD = 4;
private final int mLevel;
}
4.5 ISatellite.aidl 关键方法
interface ISatellite {
// 基础控制
oneway void requestSatelliteMode(in SatelliteModemEnableRequestAttributes attributes,
IIntegerConsumer callback);
oneway void setSatelliteListener(ISatelliteListener listener);
// 数据报
oneway void sendSatelliteDatagram(in SatelliteDatagram datagram,
boolean isEmergency, IIntegerConsumer callback);
oneway void pollPendingDatagrams(IIntegerConsumer callback);
// 信号
oneway void requestSignalStrength(IIntegerConsumer callback,
INtnSignalStrengthConsumer consumer);
oneway void startSendingNtnSignalStrength(IIntegerConsumer callback);
oneway void stopSendingNtnSignalStrength(IIntegerConsumer callback);
// 能力
oneway void requestSatelliteCapabilities(IIntegerConsumer callback,
ISatelliteCapabilitiesConsumer consumer);
// 订阅
oneway void updateSatelliteSubscription(in SatelliteSubscriptionInfo info,
IIntegerConsumer callback);
oneway void provisionSatelliteService(in SatelliteSubscriberInfo info,
IIntegerConsumer callback);
oneway void deprovisionSatelliteService(in SatelliteSubscriberInfo info,
IIntegerConsumer callback);
// 系统
oneway void enableCellularModemWhileSatelliteModeIsOn(boolean enable,
IIntegerConsumer callback);
oneway void updateSystemSelectionChannels(in List<SystemSelectionSpecifier> specifiers,
IIntegerConsumer callback);
}
4.6 ISatelliteListener.aidl 回调
oneway interface ISatelliteListener {
void onSatelliteModemStateChanged(int state);
void onSatellitePositionInfoChanged(in PointingInfo pointingInfo);
void onNtnSignalStrengthChanged(in NtnSignalStrength ntnSignalStrength);
void onSatelliteCapabilitiesChanged(in SatelliteCapabilities capabilities);
void onPendingDatagrams(int count);
void onDatagramTransferStateChanged(int state);
void onSatelliteSupportedStateChanged(boolean supported);
void onRegistrationFailure(int causeCode);
void onTerrestrialNetworkAvailableChanged(boolean isAvailable);
}
五、厂商扩展指南
5.1 ISatellite HAL 实现
厂商需实现 SatelliteService(继承 android.telephony.satellite.stub.SatelliteService),该服务运行在独立 APK 进程中。
实现步骤:
- 创建 SatelliteService 子类:
public class VendorSatelliteService extends SatelliteService {
@Override
public void requestSatelliteMode(SatelliteModemEnableRequestAttributes attributes,
IIntegerConsumer callback) {
// 转换为厂商私有命令 → 通过 QMI/AT 下发 Modem
int result = vendorRil.enableSatellite(attributes);
callback.accept(result);
}
@Override
public void sendSatelliteDatagram(SatelliteDatagram datagram, boolean isEmergency,
IIntegerConsumer callback) {
// 编码数据报 → 通过厂商RIL发送
vendorRil.sendSatelliteData(datagram.data, isEmergency);
callback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS);
}
// ... 其他方法
}
- 在 AndroidManifest.xml 中注册:
<service android:name=".VendorSatelliteService"
android:exported="true">
<intent-filter>
<action android:name="android.telephony.satellite.SatelliteService" />
</intent-filter>
</service>
- 厂商特有功能扩展点:
| 扩展点 | 实现方式 | 示例 |
|---|---|---|
| 波束切换 | 在 requestSatelliteMode() 中处理 | 高通 QCRIL 的 qcril_sat_beam_switch |
| 对星引导 | 通过 onSatellitePositionInfoChanged() 上报 | 天通一号的方位角/仰角 |
| 省电模式 | 在 startSendingNtnSignalStrength() 中控制上报频率 | 屏幕关闭时降低上报频率 |
| 多星座支持 | 在 requestSatelliteCapabilities() 中报告 | 同时支持天通+北斗 |
5.2 RIL 扩展
高通 QCRIL:
qcril_sat模块处理卫星相关 QMI 消息- 通过
QMI_SAT_SERVICE_ID与 Modem 通信 - 支持
qmi_sat_indication_register注册卫星事件
联发科 MTK RIL:
- 通过 CCCI (Cross Chip Communication Interface) 与 Modem 通信
mtksat模块处理卫星命令
5.3 CarrierConfig 配置
CarrierConfig 是运营商定制卫星行为的核心机制:
| 配置键 | 类型 | 说明 |
|---|---|---|
KEY_SATELLITE_ATTACH_SUPPORTED_BOOL | boolean | 是否支持卫星附着 |
KEY_SATELLITE_ESOS_SUPPORTED_BOOL | boolean | 是否支持紧急SOS |
KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL | boolean | 是否支持点对点短信 |
KEY_SATELLITE_DATA_SUPPORT_MODE_INT | int | 数据支持模式 |
KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL | boolean | 是否支持资格检查 |
KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT | int | 连接类型(自动/手动) |
KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT | int | 连接滞后时间(秒) |
KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY | string[] | 支持的消息应用白名单 |
KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT | int | SOS最大数据报大小 |
KEY_SATELLITE_DISPLAY_NAME_STRING | string | 卫星网络显示名称 |
KEY_SATELLITE_NIDD_APN_NAME_STRING | string | NIDD APN名称 |
KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY | int[] | 默认支持的卫星服务 |
KEY_REGIONAL_SATELLITE_EARFCN_BUNDLE | PersistableBundle | 区域卫星EARFCN配置 |
KEY_SATELLITE_CONFIGS_PER_PLMN_BUNDLE | PersistableBundle | 按PLMN的卫星配置 |
KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT | int | 屏幕关闭不活动超时 |
KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT | int | SOS不活动超时 |
KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT | int | P2P短信不活动超时 |
KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT | int | 紧急呼叫到卫星切换类型 |
KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT | int | T911切换超时 |
5.4 卫星应用白名单
通过 KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY 配置允许使用卫星通信的应用包名列表。SatelliteOptimizedApplicationsTracker 追踪标记了 satellite-optimized 的应用,这些应用在卫星模式下可获得优先处理。
六、调试与测试
6.1 ADB 调试命令
# 卫星框架状态转储
adb shell dumpsys satellite
# 连接服务状态(含卫星网络信息)
adb shell dumpsys connectivity
# 电话注册表(含NTN信号强度)
adb shell dumpsys telephony-registry
# Logcat 过滤
adb logcat -s SatelliteController:D SatelliteSessionController:D DatagramController:D
adb logcat -s SatelliteModemInterface:D DatagramDispatcher:D DatagramReceiver:D
# 卫星模式开关(需root)
adb shell settings put global satellite_mode_enabled 1
# 卫星模式无线电配置
adb shell settings get global satellite_mode_radios
# Demo模式控制
adb shell settings put global satellite_demo_mode_enabled 1
6.2 DemoSimulator(演示模式)
DemoSimulator 是内置的卫星功能模拟器,无需真实卫星硬件即可测试卫星通信流程:
- 模拟状态转换:PowerOff → NotConnected → Connected → Transferring
- 模拟信号变化:
NtnSignalStrength在状态转换时自动更新 - 模拟数据报收发:发送的数据报会被缓存并在接收时回传
- 模拟对星引导:自动模拟设备对齐事件
启用方式:SatelliteManager.requestSatelliteEnabled(true, true/*demoMode*/, ...)
6.3 CTS 测试
Android 16 提供了专门的 CTS 测试用例,关键测试类:
| 测试类 | 覆盖范围 |
|---|---|
SatelliteManagerTest | 公共API功能测试 |
SatelliteControllerTest | 控制器逻辑测试 |
DatagramControllerTest | 数据报收发测试 |
SatelliteSessionControllerTest | 状态机转换测试 |
CTS 可覆盖的超时配置(通过 overrideTimeout() 方法):
| 类型 | 说明 |
|---|---|
TIMEOUT_TYPE_WAIT_FOR_SATELLITE_ENABLING_RESPONSE | 卫星启用响应超时 |
TIMEOUT_TYPE_DEMO_POINTING_ALIGNED_DURATION_MILLIS | Demo对齐持续时间 |
TIMEOUT_TYPE_DATAGRAM_WAIT_FOR_CONNECTED_STATE | 数据报等待连接超时 |
TIMEOUT_TYPE_WAIT_FOR_DATAGRAM_SENDING_RESPONSE | 数据报发送响应超时 |
6.4 PersistentLogger
所有卫星模块使用 PersistentLogger 记录关键事件,可通过 dumpsys satellite 查看:
mPersistentLogger.log("EVENT_NTN_SIGNAL_STRENGTH_CHANGED: level=" + level);
mPersistentLogger.log("CMD_SEND_SATELLITE_DATAGRAM: type=" + type);
七、版本差异与未来演进
7.1 Android 版本差异
| 特性 | Android 14 | Android 15 | Android 16 |
|---|---|---|---|
| 卫星框架 | 初始版本,仅SOS | 增加P2P SMS | 完整框架 |
| Carrier Roaming NTN | ❌ | 基础支持 | ✅ 完整支持 |
| NB-IoT NTN | ❌ | ❌ | ✅ carrierRoamingNbIotNtn FeatureFlag |
| NTN信号强度 | ❌ | 基础 | ✅ NtnSignalStrength + 回调 |
| 紧急呼叫切换 | SOS only | SOS only | ✅ T911切换 |
| 卫星数据 | ❌ | ❌ | KEY_SATELLITE_DATA_SUPPORT_MODE_INT |
| 多线程优化 | ❌ | ❌ | ✅ satelliteImproveMultiThreadDesign Flag |
| 卫星订阅管理 | 简单 | 增强 | ✅ SatelliteSubscriptionInfo |
| NTN能力解析 | ❌ | ❌ | ✅ NtnCapabilityResolver |
| 应用优化追踪 | ❌ | ❌ | ✅ SatelliteOptimizedApplicationsTracker |
| ESOS优先级 | ❌ | ❌ | ✅ evaluateESOSProfilesPrioritization() |
| 系统选频信道 | ❌ | ❌ | ✅ updateSystemSelectionChannels() |
7.2 当前已知限制
- 不支持卫星语音通话:当前框架仅支持数据报(短信/SOS),不支持实时语音
- 数据报大小受限:SOS消息通常限制在几十到几百字节
- 单向通信延迟大:LEO卫星延迟约20-40ms,GEO卫星延迟约250-600ms
- 并发限制:卫星模式与蜂窝模式通常不能同时工作(取决于硬件)
- 功耗问题:卫星发射功率大,长时间使用会显著消耗电量
- Demo模式限制:DemoSimulator 不经过真实 Modem,无法测试底层问题
7.3 Android 16+ 预期演进方向
| 方向 | 说明 | 预期版本 |
|---|---|---|
| NTN宽带数据 | 支持 3GPP R17 NR-NTN 的宽带数据连接 | Android 16+ |
| 低功耗唤醒 | 卫星低功耗监听模式,仅在收到寻呼时唤醒 | Android 17 |
| 卫星语音 | 基于NR-NTN的VoNR卫星通话 | Android 17+ |
| 多SIM卫星 | 双卡设备同时支持不同运营商的卫星服务 | Android 17 |
| 自适应编码 | 根据信道条件动态调整编码率 | Android 17+ |
| 卫星切换 | LEO卫星间的无缝切换(如 Starlink 卫星间) | Android 18+ |
| D2D卫星 | 设备到设备的卫星直连通信 | 远期 |
7.4 FeatureFlag 机制
Android 16 使用 FeatureFlag 控制新特性的启用:
| FeatureFlag | 说明 |
|---|---|
carrierRoamingNbIotNtn() | 运营商NB-IoT NTN漫游功能 |
satelliteImproveMultiThreadDesign() | 卫星多线程优化 |
satelliteEntitlementStatus() | 卫星资格状态检查 |
securityAlgorithmsUpdateIndications() | 安全算法更新指示 |
cellularIdentifierDisclosureIndications() | 蜂窝标识披露指示 |
这些 Flag 允许 OEM 和运营商按需启用功能,确保向后兼容性。
toolName: todo_write
status: success
Todos updated: 8 items
以上报告已基于 Android 16 AOSP 源码完成全部七个维度的分析。核心要点总结:
-
架构核心:SatelliteController 作为中央控制器,通过 SatelliteModemInterface(Binder代理)与厂商 SatelliteService 通信,向下管理 DatagramController/SessionController/PointingAppController 三个子系统。
-
双路径设计:OEM 卫星模式(通过 ISatellite.aidl)和运营商 NTN 漫游模式(通过 IRadio AIDL + RILJ)两条独立的信号/状态上报路径,在 SatelliteController 层汇合。
-
状态机驱动:SatelliteSessionController 的 9 状态状态机管理卫星会话生命周期,配合多种不活动定时器实现自动省电回退。
-
厂商扩展:通过 SatelliteService(实现 ISatellite.aidl)和 SatelliteGatewayService(实现 ISatelliteGateway.aidl)两个独立 APK 进程,厂商可完全定制 Modem 交互逻辑和消息编解码。
-
CarrierConfig 深度定制:20+ 个卫星相关配置键,允许运营商控制从连接类型、超时时间到服务白名单的几乎所有行为。