Android 13 卫星通信 vs Android 16 AOSP 原生实现 — 对比分析报告

12 阅读38分钟

一、总体结论

Kylin 在 Android 13 上的卫星通信移植是一套面向中国星网的全业务定制方案,以 TelephonyManager XW扩展(~750行@hide方法)+ 独立 XwosTeleService 进程(5个子服务)+ 私有 IXwRadio/IXwRadioVoice HAL 的三层架构,实现了语音通话、数据业务、位置上报、通话统计等完整功能。Android 16 AOSP 以 SatelliteManager 公开API + SatelliteController/SatelliteSessionController 9态状态机 + DatagramController/Dispatcher/Receiver 消息三件套 + 标准化 ISatellite HAL 的模块化架构,聚焦紧急SOS消息和低带宽数据报传输,并深度集成NTN信号上报、地面/卫星智能切换、TRANSPORT_SATELLITE 数据连接、运行时配置管理、全链路Metrics等能力。

核心差异:Kylin 功能更全(语音/数据/位置/统计/安全/自定义扩展)但架构封闭、无状态机、无 消息队列 重试机制; AOSP 架构开放、9态状态机严谨、消息流程完整、功耗管理精细但仅支持 窄带 消息场景。

在流量统计维度上:Android 16 已在 NetworkStatsService/NetworkTemplate/NetworkIdentity 中搭建了卫星流量识别的基础架构——通过 mTransportTypesBits 中的 TRANSPORT_SATELLITE 位区分卫星流量,通过 NetworkTemplate.Builder.setTransportType() 构建卫星专用查询模板,getMobileUidStats() 合并统计蜂窝与卫星流量——但尚无独立的卫星流量统计 API 或专属统计策略。Kylin Android 13 则完全缺失卫星流量统计能力,NetworkIdentity 不含 TRANSPORT_SATELLITE 位,NetworkTemplate 无法按传输类型匹配,卫星流量会被混入移动网络流量中无法单独计量。

最关键优化方向:引入 SatelliteManager 适配层、实现 SatelliteSessionController 状态机、补充 Datagram 消息队列与重试机制、HAL 接口标准化、补充紧急SOS功能、增加卫星流量统计支持

二、架构对比

2.1 分层设计对比

┌──────────────────────────────────────────────────────────────────────────────┐
│                  Android 16 AOSP 卫星通信架构                                 │
├──────────────────────────────────────────────────────────────────────────────┤
│  应用层:  Emergency SOS App / Gateway App(Messages) / Satellite Hub          │
│           ↓ Context.SATELLITE_SERVICE                                        │
│  API层:   SatelliteManager (公开SDK, 部分SystemApi)                           │
│           ├── SatelliteCapabilities (能力查询, 运行时动态)                     │
│           ├── SatelliteDatagram (数据报封装)                                  │
│           ├── NtnSignalStrength (NTN信号强度, 5级离散模型)                    │
│           ├── SatelliteSubscriberProvisionStatus (订阅状态)                   │
│           ├── AntennaPosition / PointingInfo / SatelliteInfo                 │
│           └── SatelliteManager.SatelliteModemState (9态注解)                  │
│           ↓ ITelephony [Binder]                                              │
│  服务层:  SatelliteController (com.android.phone进程, 90+消息类型)             │
│           ├── SatelliteSessionController (9态状态机)                          │
│           │   UnavailableState / PowerOffState / EnablingState               │
│           │   DisablingState / IdleState / TransferringState                 │
│           │   ListeningState / NotConnectedState / ConnectedState            │
│           ├── DatagramController → DatagramDispatcher → DatagramReceiver     │
│           │   (LinkedHashMap双优先级队列 + 重试 + MT轮询 + 节流)              │
│           ├── SatelliteModemInterface (HAL交互, ExponentialBackoff重连)      │
│           ├── PointingAppController (对星UI, 全屏/小窗口)                     │
│           ├── SatelliteSOSMessageRecommender (紧急SOS推荐, T911/SOS双模式)   │
│           ├── NtnCapabilityResolver (NTN能力解析, PLMN匹配+服务类型)          │
│           ├── SatelliteConfigParser (配置解析, protobuf格式)                  │
│           ├── SatelliteOptimizedApplicationsTracker (优化App追踪)             │
│           ├── DemoSimulator (Demo模式独立状态机)                              │
│           ├── SatelliteServiceUtils (类型转换工具)                            │
│           ├── SatelliteConstants (常量/注解定义)                              │
│           ├── SatelliteConfig (配置管理)                                      │
│           └── Metrics体系 (7个类):                                           │
│               ControllerMetricsStats / SessionMetricsStats                   │
│               ProvisionMetricsStats / EntitlementMetricsStats                │
│               CarrierRoamingSatelliteSessionStats                            │
│               CarrierRoamingSatelliteControllerStats                         │
│               AccessControllerMetricsStats                                   │
│           ↓ ISatellite AIDL [Binder]                                         │
│  HAL层:   ISatellite.aidl + ISatelliteListener.aidl (标准化HAL)              │
│           ├── SatelliteImplBase (厂商抽象基类, 零默认实现)                    │
│           ├── requestSatelliteMode() / sendSatelliteDatagram()               │
│           ├── pollPendingDatagrams() / setSatellitePlmn()                    │
│           └── onNtnSignalStrengthChanged / onPendingDatagrams / ...          │
│           ↓                                                                  │
│  Connectivity层: SatelliteAccessController (packages/modules/Connectivity)   │
│           ├── 卫星网络访问权限管理                                             │
│           ├── requestIsCommunicationAllowedForCurrentLocation()              │
│           └── updateSystemSelectionChannels()                                │
│           ↓                                                                  │
│  数据路径: ConnectivityManager.requestNetwork(TRANSPORT_SATELLITE)            │
│           → ConnectivityService → TelephonyNetworkProvider                   │
│           → DataNetworkController → DataServiceManager → IRadioData          │
│           → Modem setupDataCall → NetworkAgent注册                           │
│           ↓                                                                  │
│  流量统计层: NetworkStatsService (packages/modules/Connectivity)              │
│           ├── 卫星接口被识别为移动网络(isMobile含TRANSPORT_SATELLITE)          │
│           ├── mAllMobileIfacesSinceBoot 集合包含卫星接口                      │
│           ├── NetworkIdentity.mTransportTypesBits 含 TRANSPORT_SATELLITE 位  │
│           ├── NetworkTemplate.Builder.setTransportType(TRANSPORT_SATELLITE)  │
│           │   可构建卫星专用查询模板(受FLAG_NETSTATS_TRANSPORT_TYPE控制)       │
│           ├── getMobileUidStats() 合并统计蜂窝+卫星流量                       │
│           ├── 卫星网络标记为metered(NET_CAPABILITY_NOT_METERED缺失)           │
│           └── 底层: eBPF数据采集(已完全替代xt_qtaguid)                        │
│               ├── TrafficStats: 无卫星相关API变更, JNI读取eBPF               │
│               ├── NetworkStatsFactory: 从eBPF maps读取, 不感知传输类型       │
│               └── 卫星流量与蜂窝共享同一套eBPF管道, 区分依赖上层匹配         │
│           ↓                                                                  │
│  Modem:   3GPP NTN 协议栈 (NB-IoT NTN / NR NTN / eMTC NTN / Proprietary)   │
└──────────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────────┐
│                  Kylin Android 13 XWOS 卫星通信架构                           │
├──────────────────────────────────────────────────────────────────────────────┤
│  应用层:  星网定制App / Settings扩展(ProcessorInfoPreferenceController)        │
│           ↓ TelephonyManager.getXw...() / XwTelephonyManager                 │
│  API层:   TelephonyManager XW扩展方法 (全部@hide, L17086-L17844, ~750行)      │
│           + XwTelephonyManager (vendor封装)                                   │
│           ├── XwCallStateListener (通话状态监听)                              │
│           ├── CustomEventListener (自定义事件监听)                            │
│           ├── CustomRequestCallback (自定义请求回调)                           │
│           └── CallState (Parcelable通话状态, dir/stat/mode/rate全为int)       │
│           ↓ ITelephony.aidl [Binder] (16个XW扩展方法)                        │
│  服务层:  PhoneInterfaceManager (com.android.phone进程)                       │
│           ├── XWRadioState (int, L420) + mXWSlotId + mIsXWRadioState         │
│           └── XwRadioReceiver (BroadcastReceiver, L12334)                    │
│           + XwosTeleService (独立进程: com.starkylin.xwos.teleservice)        │
│           ├── TeleVoiceService → RadioVoiceConnection (语音HAL交互)          │
│           ├── TeleDataService → TRANSPORT_SATELLITE + ApnServer              │
│           ├── TeleLocationService → LocationManager                          │
│           ├── TeleStatsService → Room数据库 (主叫/被叫/掉话/单双通)          │
│           └── AudioStreamer → JNI (语音编解码, 共享内存)                     │
│           ↓ IXwRadio.aidl / IXwRadioVoice.aidl [Binder]                     │
│  HAL层:   vendor.xwos.hardware.radio.* (私有HAL AIDL)                        │
│           ├── IXwRadio: setRadioPowerXW/dialXW/getPostimeXW/...             │
│           ├── IXwRadioVoice: sendUplinkVoiceData/acquireVoiceDataBuffer/... │
│           └── IXwRadioIndication: xwRadioStateChanged/callStateChanged/...  │
│           ↓                                                                  │
│  RIL层:   vendor/cnt/RilXW (私有RIL实现 + mock模式)                          │
│           ├── RIL_XW_REQUEST_BASE = 80000 (18个请求码)                       │
│           └── RIL_XW_UNSOL_RESPONSE_BASE = 90000 (5个主动上报码)             │
│           ↓                                                                  │
│  数据路径: TeleDataService监听TRANSPORT_SATELLITE网络                         │
│           → ApnServer管理卫星APN → DataNetwork添加TRANSPORT_SATELLITE        │
│           → ConnectivityService → 卫星数据连接建立                            │
│           ↓                                                                  │
│  流量统计层: 无卫星流量统计支持                                             │
│           ├── NetworkIdentity 使用 mType(int) 而非 mTransportTypesBits(long)  │
│           ├── NetworkTemplate 无 MATCH_ALL/setTransportType,仅支持传统规则   │
│           ├── getMobileUidStats() 已存在但不包含卫星流量                      │
│           │   (isMobile仅含TRANSPORT_CELLULAR,卫星接口不在mAllMobileIfaces)  │
│           ├── getUidStatsForTransport(TRANSPORT_SATELLITE) 会抛出异常        │
│           ├── 卫星流量混入移动网络流量,无法单独计量                           │
│           └── 底层: eBPF/xt_qtaguid采集(Android 13仍使用xt_qtaguid)          │
│               ├── TrafficStats: 无卫星相关API                                 │
│               └── NetworkStatsFactory: 不感知传输类型, 卫星流量混入移动统计  │
│           ↓                                                                  │
│  CP:      星网卫星通信处理器 (高轨/低轨双模)                                   │
└──────────────────────────────────────────────────────────────────────────────┘

2.2 关键架构差异

维度Android 16 AOSPKylin Android 13影响
API入口SatelliteManager(公开SDK,Context.SATELLITE_SERVICE)TelephonyManager XW扩展(@hide,~750行)+ XwTelephonyManagerAOSP可被第三方App调用;Kylin仅系统App可用
服务进程Phone进程内(SatelliteController)Phone进程 + 独立XwosTeleService进程Kylin双进程架构增加复杂度但隔离性好
状态机SatelliteSessionController 9态严格状态机XwRadioState 6枚举值,无状态机类AOSP状态转换有守卫;Kylin状态转换无约束
消息机制DatagramDispatcher + LinkedHashMap双优先级队列 + 重试 + 超时 + MT轮询节流无消息队列,语音数据直接透传HALAOSP有可靠消息投递;Kylin无重试机制
HAL接口ISatellite 标准HAL + SatelliteImplBase 抽象基类IXwRadio/IXwRadioVoice 私有HAL(全业务)Kylin无法兼容其他卫星星座
数据连接TRANSPORT_SATELLITE + 标准DataCall 7阶段框架TRANSPORT_SATELLITE + ApnServer私有APN管理两者均使用TRANSPORT_SATELLITE;AOSP走标准DataCall框架;Kylin通过ApnServer私有APN管理
信号上报双路径:OEM卫星模式 + 运营商NTN漫游模式,5级离散模型+滞后滤波仅通过customRequest(RSSI/SNR)主动查询AOSP信号上报体系完整
网络切换onTerrestrialNetworkAvailableChanged + 自动/手动 + 并发地面扫描无自动切换AOSP支持智能地面/卫星切换
对星UIPointingAppController 独立管理 + 全屏/小窗口对星无对星引导AOSP有完整对星体验
权限模型USE_SATELLITE权限 + 系统弹窗告知收费无独立卫星权限AOSP隐私保护更完善
配置管理SatelliteConfigParser(protobuf) + CarrierConfigManager(按PLMN) + SatelliteNetworkInfo(PLMN+服务策略+计费)XWRadioConstants编译时固定常量AOSP运行时动态配置;Kylin编译时固定
可观测性7个Metrics类 + PersistentLogger + SatelliteStatsTeleStatsService(Room数据库,仅通话统计)AOSP全链路可观测;Kylin仅通话统计
NTN能力解析NtnCapabilityResolver(PLMN匹配+服务类型自动识别)AOSP自动识别NTN网络能力
优化App追踪SatelliteOptimizedApplicationsTracker(PROPERTY_SATELLITE_DATA_OPTIMIZED)AOSP区分卫星优化/非优化App
Demo模式DemoSimulator独立状态机(PowerOff→NotConnected→Connected) + Mock ModemisRilMockEnabled RIL mockAOSP更完善的测试框架
功耗管理灭屏30s超时 + 分级会话超时(180s/600s) + 干扰源自动禁用 + 并发地面扫描无功耗管理策略AOSP远优于Kylin
代码侵入零侵入,独立模块修改TelephonyManager(+750行)、ITelephony.aidl(+16方法)、RIL.java(+XW请求)、PhoneInterfaceManager(+XW实现)、DataNetwork.java(+TRANSPORT_SATELLITE)AOSP远优于Kylin
卫星流量统计NetworkStatsService识别卫星为移动网络变体 + NetworkTemplate.Builder.setTransportType(TRANSPORT_SATELLITE) 可构建卫星专用查询模板 + getMobileUidStats() 合并统计无卫星流量统计支持:NetworkIdentity 使用 mType(int) 而非 mTransportTypesBits(long),NetworkTemplate 无 MATCH_ALL/setTransportType(),getMobileUidStats() 已存在但不包含卫星流量(isMobile 仅含 TRANSPORT_CELLULAR),getUidStatsForTransport(TRANSPORT_SATELLITE) 会抛异常AOSP有基础识别架构(但无独立API);Kylin完全缺失

2.3 核心类映射关系

Android 16 AOSP职责Kylin Android 13 对应差异
SatelliteManager公开API入口TelephonyManager XW方法 + XwTelephonyManagerAOSP公开SDK;Kylin @hide
SatelliteController卫星服务总控(90+消息)PhoneInterfaceManager XW部分AOSP专类专责;Kylin混在PIM
SatelliteSessionController9态状态机无对应类(仅XwRadioState枚举)Kylin缺失状态机
DatagramController数据报收发控制无对应类Kylin无消息队列
DatagramDispatcher发送队列+重试+MT轮询无对应类Kylin无重试机制
DatagramReceiver接收轮询+SMS写入Provider无对应类Kylin无消息拉取
SatelliteModemInterfaceHAL交互+指数退避重连(2s→64s)RadioVoiceConnection(仅语音HAL)Kylin仅封装语音HAL
SatelliteSOSMessageRecommender紧急SOS推荐(T911/SOS)无对应类Kylin缺失
PointingAppController对星UI管理(全屏/小窗口)无对应类Kylin缺失
SatelliteAccessController接入权限控制无对应类Kylin缺失
NtnCapabilityResolverNTN能力解析(PLMN匹配)无对应类Kylin缺失
SatelliteConfigParserprotobuf配置解析无对应类Kylin缺失
SatelliteOptimizedApplicationsTracker优化App追踪无对应类Kylin缺失
DemoSimulatorDemo模式状态机isRilMockEnabledAOSP更完善
SatelliteServiceUtils类型转换工具无对应类Kylin缺失
SatelliteConstants常量/注解定义XWRadioConstants(编译时常量)AOSP运行时注解;Kylin编译时固定
SatelliteConfig配置管理无对应类Kylin缺失
SatelliteNetworkInfoPLMN+服务策略+计费模型无对应类Kylin缺失
NetworkStatsService流量统计服务(含卫星识别)NetworkStatsService(isMobile仅含CELLULAR,卫星接口不在mAllMobileIfacesSinceBoot)AOSP识别卫星为移动网络变体;Kylin不识别卫星接口
NetworkTemplate.Builder流量查询模板构建(含setTransportType)NetworkTemplate.Builder(无setTransportType,需@TemplateMatchRule参数)AOSP可构建卫星专用查询模板;Kylin无此能力
NetworkIdentity网络身份识别(含mTransportTypesBits+TRANSPORT_SATELLITE位)NetworkIdentity(使用mType(int)而非mTransportTypesBits(long),无TRANSPORT_SATELLITE)AOSP通过mTransportTypesBits区分卫星;Kylin无法区分
TrafficStats流量统计工具类(无卫星相关变更)TrafficStats(无变更)两者均无卫星相关API;底层均通过eBPF采集
NetworkStatsFactory底层统计数据采集(无卫星相关变更)NetworkStatsFactory(无变更)两者底层均从eBPF maps读取,不感知传输类型
ISatellite HAL标准化HAL接口IXwRadio + IXwRadioVoice接口设计理念不同
ISatelliteListenerHAL事件回调IXwRadioIndication + IXwRadioVoiceIndicationAOSP事件语义更清晰
SatelliteCapabilities能力查询(运行时)XWRadioConstants(编译时常量)AOSP运行时查询;Kylin编译时固定
Metrics (7个类)全链路可观测性TeleStatsService(仅通话统计)AOSP更全面
语音通话TeleVoiceService + AudioStreamerKylin独有
位置上报TeleLocationServiceKylin独有
通话统计TeleStatsService(Room数据库)Kylin独有
APN管理ApnServerKylin独有
TRANSPORT_SATELLITE数据网络DataNetwork.java(添加TRANSPORT_SATELLITE支持)Kylin独有修改,AOSP原生已包含
语音编解码AudioStreamer(JNI+共享内存)Kylin独有
安全卡getSectfXw()Kylin独有
摇晕摇毙executeStunXw/executeKillXwKylin独有
载波模式setCarrierMode/getCarrierModeKylin独有
自定义扩展customRequest()(107个ID) + ICustomEventListenerKylin独有

三、功能对比表

功能领域Android 16 AOSPKylin Android 13差异说明
卫星模式开关requestSatelliteEnabled() + 9态状态机 + 冲突无线电禁用(BT/WiFi/NFC/UWB)setRadioPowerXw() 直接控制CPAOSP有完整状态机+自动禁用干扰源;Kylin直接开关CP
紧急SOS消息核心功能,DATAGRAM_TYPE_SOS_MESSAGE + SatelliteSOSMessageRecommender + T911/SOS双模式 + ESOS Profile无独立SOS接口AOSP首要场景;Kylin未实现
卫星短消息sendDatagram() + 队列+重试+超时+MT轮询节流无公开SMS接口AOSP完整消息流程;Kylin缺失
消息接收pollPendingDatagrams() 拉取模式 + SMS写入Provider + SharedPreferences去重无消息接收机制AOSP有存储转发;Kylin缺失
卫星语音通话明确不支持(NB-NTN窄带设计)dialXw() + IXwRadioVoice HAL + AudioStreamer JNIKylin独有,800bps/2.4kbps/4.8kbps
语音编解码不支持AudioStreamer JNI + 共享内存Kylin独有
卫星数据业务TRANSPORT_SATELLITE + 标准DataCall 7阶段 + 卫星网络标记为metered(NET_CAPABILITY_NOT_METERED缺失)TRANSPORT_SATELLITE + TeleDataService + ApnServer两者均使用TRANSPORT_SATELLITE;AOSP走标准DataCall框架且卫星网络标记为metered;Kylin通过ApnServer私有APN管理,DataNetwork.java已添加TRANSPORT_SATELLITE支持
位置上报位置共享(SOS场景,Datagram承载)+ startSatellitePositionUpdatesTeleLocationService + PosTimeKylin更完整(GNSS/ECEF/时间同步/距离阈值)
信号强度查询双路径信号上报(OEM+NTN漫游)+ 5级离散模型 + 滞后滤波 + 上报频率控制仅通过customRequest(RSSI/SNR)主动查询AOSP体系完整;Kylin缺少独立API
地面/卫星切换onTerrestrialNetworkAvailableChanged + 自动切换 + 并发地面扫描无自动切换AOSP独有
对星引导PointingAppController + 全屏/小窗口对星UI + AntennaPosition无对星引导AOSP独有
权限控制USE_SATELLITE权限 + 系统弹窗无独立卫星权限AOSP独有
卫星流量统计基础支持:NetworkTemplate.Builder.setTransportType(TRANSPORT_SATELLITE) 可构建卫星专用查询模板(受Feature Flag控制),getMobileUidStats() 合并统计蜂窝+卫星流量,NetworkStatsService 将卫星接口识别为移动网络变体;无独立API(无 getSatelliteUidStats() / querySummaryForSatellite()),无专属统计策略完全缺失:NetworkIdentity 不含 TRANSPORT_SATELLITE 位(使用 mType 而非 mTransportTypesBits),NetworkTemplate 无法按传输类型匹配(无 MATCH_ALL/setTransportType()),getMobileUidStats() 已存在但不包含卫星流量(isMobile 仅含 TRANSPORT_CELLULAR,卫星接口不在 mAllMobileIfacesSinceBoot 中),getUidStatsForTransport(TRANSPORT_SATELLITE) 会抛出异常,卫星流量混入移动网络流量无法单独计量AOSP有基础识别架构但尚不完整;Kylin完全缺失,用户/应用无法精确计量卫星数据消耗
流量计费属性卫星网络标记为metered(NET_CAPABILITY_NOT_METERED缺失),系统可区分计费/非计费网络无卫星流量计费属性管理AOSP支持计费感知;Kylin无此能力
卫星流量调试adb shell dumpsys netstats 输出包含卫星接口(在"All mobile interfaces"列表中);无 --satellite-stats 专用选项无卫星流量调试支持AOSP有基础调试能力;Kylin无
NTN能力解析NtnCapabilityResolver(PLMN匹配+服务类型自动识别)AOSP独有
优化App追踪SatelliteOptimizedApplicationsTrackerAOSP独有
配置管理SatelliteConfigParser(protobuf) + CarrierConfigManager + SatelliteNetworkInfoXWRadioConstants编译时固定AOSP运行时动态;Kylin编译时固定
Demo/测试模式DemoSimulator独立状态机 + CTS + @VisibleForTestingisRilMockEnabled RIL mockAOSP更完善
功耗管理灭屏30s超时 + 分级会话超时 + 干扰源自动禁用 + 并发地面扫描无功耗管理AOSP远优于Kylin
可观测性7个Metrics类 + PersistentLogger + SatelliteStatsTeleStatsService(仅通话统计)AOSP全链路可观测;Kylin仅通话统计

四、核心流程差异详解

4.1 卫星流量统计流程对比

Android 16 卫星流量统计机制

Android 16 在流量统计框架中为卫星通信搭建了基础识别架构,但尚未实现完整的卫星流量统计体系。核心流程如下:

1. 卫星流量识别

卫星网络注册 → ConnectivityService 创建 NetworkAgent(TRANSPORT_SATELLITE)
    → NetworkStatsService.handleNetworkStateChanged()
    → 判断 isMobile = (TRANSPORT_CELLULAR == displayTransport
                      || TRANSPORT_SATELLITE == displayTransport)
    → 卫星接口添加到 mAllMobileIfacesSinceBoot 集合
    → NetworkIdentity.Builder 构建 mTransportTypesBits(含 TRANSPORT_SATELLITE 位)
    → 卫星流量在 legacy type 字段中被标记为 TYPE_MOBILE

关键代码路径:

  • NetworkStatsService.java:2357-2360 — isMobile 判断逻辑

  • NetworkStatsService.java:2472-2480 — getSubIdForCellularOrSatellite()

  • NetworkIdentity.java:75,99 — mTransportTypesBits 字段及 Builder 中的 setTransportTypes()

2. 卫星流量查询

应用构建查询模板:
    NetworkTemplate template = new NetworkTemplate.Builder()
        .setTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)  // 受 FLAG_NETSTATS_TRANSPORT_TYPE 控制
        .build();
    NetworkStatsManager.querySummaryForDevice(template, start, end);
        → INetworkStatsService.getNetworkStatsForTemplate(template)
        → NetworkIdentity.matchesTransportTypes() 匹配
        → 仅返回 mTransportTypesBits 包含 TRANSPORT_SATELLITE 的记录

3. getMobileUidStats() 行为

NetworkStatsManager.getMobileUidStats()
    → mService.getUidStatsForTransport(TRANSPORT_CELLULAR)
    → getAllIfacesSinceBoot(TRANSPORT_CELLULAR) 返回 mAllMobileIfacesSinceBoot
    → mAllMobileIfacesSinceBoot 包含卫星接口(因 isMobile 判断包含 TRANSPORT_SATELLITE)
    → 返回结果 = 蜂窝流量 + 卫星流量(合并统计)

注意:getMobileUidStats() 的文档明确声明返回"cellular and satellite"统计。目前没有 getUidStatsForTransport(TRANSPORT_SATELLITE) 的公开调用入口,但 AIDL 接口 INetworkStatsService.getUidStatsForTransport(int transport) 理论上支持传入 TRANSPORT_SATELLITE。

4. 统计策略

策略维度Android 16 卫星流量
轮询频率与蜂窝相同,无独立策略
前台/后台区分与蜂窝相同(SET_FOREGROUND/SET_DEFAULT)
按波束/运营商统计不支持
低功耗模式统计延迟无特殊处理
计费标记卫星网络标记为 metered(NET_CAPABILITY_NOT_METERED 缺失)
流量阈值回调不支持

5. 与卫星框架的集成

集成点状态说明
SatelliteAccessController → NetworkStatsService无直接集成SAC 仅通过回调通知 ConnectivityService 更新网络偏好,不涉及流量统计
SatelliteAccessController → 流量统计重置/标记不存在启用/禁用卫星网络时不通知 NetworkStatsService
ConnectivityService 卫星网络请求 → 流量统计间接关联卫星网络通过 TRANSPORT_SATELLITE 注册到 ConnectivityService,NetworkStatsService 通过网络状态快照感知
卫星消息字节数记录不存在SatelliteController/DatagramDispatcher 中无流量统计调用

6. 调试支持

  • adb shell dumpsys netstats 输出中包含卫星接口(在"All mobile interfaces"列表中,mAllMobileIfacesSinceBoot 可见)

  • 无 --satellite-stats 专用选项

  • 无模拟卫星网络环境的测试钩子

7. 底层实现细节

组件卫星相关变更说明
TrafficStats无卫星相关API变更未新增卫星相关方法,底层仍通过JNI(framework-connectivity-tiramisu-jni)读取eBPF统计数据
NetworkStatsFactory无卫星相关变更底层仍从eBPF maps读取统计数据,不感知传输类型,卫星流量与蜂窝流量共享同一套eBPF管道
NetworkStats.Bucket/NetworkStats.Entry无TYPE_SATELLITE常量卫星流量通过NetworkIdentity.mTransportTypesBits区分,而非通过独立的网络类型字段
eBPF数据采集卫星流量与蜂窝共享同一套eBPF管道Android 16中eBPF已完全替代xt_qtaguid(xt_qtaguid已废弃),卫星流量的底层采集与蜂窝流量无差异,区分依赖于上层的NetworkIdentity匹配
getSubIdForCellularOrSatellite()新增同时处理蜂窝和卫星网络的订阅ID获取
getRatTypeForStateSnapshot()扩展同时检查TRANSPORT_CELLULAR和TRANSPORT_SATELLITE的RAT类型

关键发现:Android 16中没有 TYPE_SATELLITE 这样的独立网络类型常量。卫星网络在传统类型字段中仍被标记为 TYPE_MOBILE,但通过 NetworkIdentity.mTransportTypesBits 中的 TRANSPORT_SATELLITE 位进行区分。这意味着卫星流量被统计为移动网络流量的一部分,但可通过 NetworkTemplate.Builder().setTransportType(TRANSPORT_SATELLITE) 构建的模板专门匹配

重要:MATCH_MOBILE 模板不会自动匹配卫星流量。matchesMobile() 仅匹配 TYPE_MOBILE + 特定 RAT 类型,不匹配 TRANSPORT_SATELLITE。要查询卫星流量,必须使用 NetworkTemplate.Builder().setTransportType(TRANSPORT_SATELLITE) 构建专用模板(受 FLAG_NETSTATS_TRANSPORT_TYPE Feature Flag 控制)。

Kylin Android 13 卫星流量统计现状

Kylin Android 13 完全缺失卫星流量统计能力:

1. 识别层缺失

  • NetworkIdentity 使用 mType(int,legacy type)而非 mTransportTypesBits(long,位字段),不包含 TRANSPORT_SATELLITE 位

  • NetworkTemplate 无法按传输类型匹配,仅支持 MATCH_MOBILE/MATCH_WIFI/MATCH_ETHERNET/MATCH_CARRIER 等传统规则, MATCH_ALL(12) 规则

  • NetworkTemplate.Builder 构造函数需要 @TemplateMatchRule matchRule 参数, setTransportType()

  • 即使 TRANSPORT_SATELLITE 常量在 Android 13 API 33 中已定义,流量统计模块未使用该信息

2. API 层缺失

  • NetworkStatsManager.getMobileUidStats()已存在(Android 13 Tiramisu 模块中引入),但内部调用 getUidStatsForTransport(TRANSPORT_CELLULAR),而 getAllIfacesSinceBoot(TRANSPORT_CELLULAR) 返回 mAllMobileIfacesSinceBoot,该集合不包含卫星接口(因 isMobile 判断仅含 TRANSPORT_CELLULAR),因此 getMobileUidStats() 不包含卫星流量

  • INetworkStatsService.getUidStatsForTransport(int transport) 接口已存在,但 getAllIfacesSinceBoot() 仅支持 TRANSPORT_WIFI 和 TRANSPORT_CELLULAR,传入其他值(包括 TRANSPORT_SATELLITE)会抛出 IllegalArgumentException

  • NetworkTemplate.Builder setTransportType(),Builder 构造函数需要 @TemplateMatchRule matchRule 参数,仅支持 MATCH_MOBILE/MATCH_WIFI/MATCH_ETHERNET/MATCH_CARRIER 等传统规则, MATCH_ALL(12) 规则

  • 无任何卫星流量统计专用 API

3. 统计行为

  • 卫星数据连接通过 TeleDataService 建立,使用 TRANSPORT_SATELLITE 传输类型

  • 但 NetworkStatsService.handleNetworkStateChanged() 中 isMobile = (TRANSPORT_CELLULAR == displayTransport),不包含 TRANSPORT_SATELLITE,卫星接口不会被添加到 mAllMobileIfacesSinceBoot 集合

  • getMobileUidStats() 内部调用 getUidStatsForTransport(TRANSPORT_CELLULAR),返回 mAllMobileIfacesSinceBoot 中的接口统计,不包含卫星接口

  • getUidStatsForTransport(TRANSPORT_SATELLITE) 会抛出 IllegalArgumentException(getAllIfacesSinceBoot() 仅支持 TRANSPORT_WIFI 和 TRANSPORT_CELLULAR)

  • 卫星流量可能被混入移动网络流量统计中(如果卫星接口的 legacy type 被标记为 TYPE_MOBILE),但无法单独提取

  • TeleStatsService 仅统计通话数据(主叫/被叫/掉话/单双通),不涉及数据流量统计

4. Kylin 移植中未涉及的流量统计修改

  • 从代码分析推断,Kylin 移植未修改 NetworkStatsService、NetworkTemplate、NetworkIdentity 等流量统计相关类

  • TeleDataService 负责卫星数据连接建立,但未集成流量统计功能

对用户/应用的影响

影响维度Android 16 AOSPKylin Android 13
精确计量卫星数据消耗可通过 NetworkTemplate.Builder.setTransportType(TRANSPORT_SATELLITE) 查询卫星专用流量,但需启用 Feature Flag无法精确计量,卫星流量混入移动流量
流量计费感知卫星网络标记为 metered,系统设置可显示计费警告无计费属性区分
应用流量管理应用可通过 querySummaryForDevice() + 卫星模板查询,但无独立便捷 API应用无法获知卫星流量消耗
运营商计费对接getSubIdForCellularOrSatellite() 支持按订阅ID关联,但无按波束/运营商统计无运营商计费对接能力

兼容性影响

  1. 旧应用查询行为:针对 Android 13 开发的应用使用 querySummaryForDevice(TYPE_MOBILE, ...) 时,在 Android 16 上不会自动包含卫星流量(因为 MATCH_MOBILE 规则仅匹配 TYPE_MOBILE + RAT 类型,不匹配 TRANSPORT_SATELLITE)。

  2. 卫星流量误归类风险:由于卫星网络在 legacy type 字段中被标记为 TYPE_MOBILE,如果底层 telephony 将卫星接口注册为移动网络,则使用 MATCH_MOBILE 模板的旧查询可能包含卫星流量。当前代码中 isMobile = (TRANSPORT_CELLULAR == displayTransport || TRANSPORT_SATELLITE == displayTransport) 确保了卫星接口被添加到 mAllMobileIfacesSinceBoot。

  3. getMobileUidStats() 行为:该方法文档明确声明返回"cellular and satellite"统计,调用方需注意此合并行为。

  4. Feature Flag 依赖:NetworkTemplate.Builder.setTransportType() 受 FLAG_NETSTATS_TRANSPORT_TYPE Feature Flag 控制,设备需确认已启用此 Flag 才能使用卫星专用查询模板。

  5. OEM 适配要点

    1. 内核/HAL层:确保卫星网络接口被正确注册到 TelephonyNetworkSpecifier 中,包含正确的 subscriptionId;卫星 Modem 需要通过 PhoneStateListener 上报 RAT 类型;eBPF 程序无需修改,卫星流量通过标准网络接口采集

    2. Framework层:启用 FLAG_NETSTATS_TRANSPORT_TYPE Feature Flag 以支持基于传输类型的模板查询;在 getDisplayTransport() 实现中正确映射卫星传输类型;确保卫星网络的 NetworkCapabilities 包含 TRANSPORT_SATELLITE

    3. 流量统计区分:如需独立统计卫星流量,使用 NetworkTemplate.Builder().setTransportType(TRANSPORT_SATELLITE).build() 构建查询模板

4.2 公开 API 对比

Android 16 — SatelliteManager(公开 SDK API)

SatelliteManager sm = getSystemService(Context.SATELLITE_SERVICE);
sm.isSupported();                                                    // 能力查询
sm.requestSatelliteEnabled(enabled, enableDemoMode, ...);            // 开关卫星
sm.registerSatelliteStateChangeListener(executor, listener);         // 状态监听
sm.sendDatagram(subId, datagramType, datagram, needPointingUI, ...); // 发送数据报
sm.registerSatelliteDatagramCallback(executor, callback);            // 接收数据报
sm.requestSatelliteCapabilities(executor, callback);                 // 查询能力
sm.provisionSatelliteService(token, executor, callback);             // 配置服务
sm.isSatelliteProvisioned();                                         // 配置状态
sm.isSatelliteEnabledForCurrentCarrier();                            // 运营商支持
sm.startSatellitePositionUpdates(executor, callback);                // 卫星位置更新
sm.requestSatelliteAccessConfigurationForCurrentLocation(...);       // 接入配置

Kylin Android 13 — TelephonyManager XW 扩展(全部 @hide)

tm.setRadioPowerXw(true, executor, callback);         // 开关CP
tm.dialXw(number, type, rate, executor, callback);    // 卫星拨号
tm.getPostimeXwAsync(type, executor, receiver);        // 获取位置时间
tm.customRequest(request, data, executor, callback);   // 自定义请求(107个ID)
tm.registerCallStateListener(executor, listener);      // 通话状态监听
tm.setCommunicationTypeXw(type, executor, callback);   // 高低轨切换
tm.executeStunXwAsync(mode, value, executor, receiver); // 摇晕操作
tm.executeKillXwAsync(executor, receiver);              // 摇毙操作
tm.getSectfXw();                                        // 安全卡(同步)
tm.setCarrierMode(mode, executor, callback);            // 载波模式
tm.getSatellitePhoneId();                               // 卫星Phone ID

关键差异:

对比项Android 16Kylin Android 13
API 可见性公开 SDK (Context.SATELLITE_SERVICE)@hide,仅系统App
API 入口SatelliteManager 独立类TelephonyManager 扩展方法(~750行)
功能范围消息/状态/配置/能力查询/对星语音/数据/位置/电源/安全/自定义
异步模式统一 OutcomeReceiver混用 Consumer/ResultReceiver/AIDL回调
权限控制USE_SATELLITE + 系统弹窗无独立权限
消息类型DATAGRAM_TYPE_SOS_MESSAGE/SMS/KEEP_ALIVE无消息类型概念
语音通话不支持dialXw + ICallStateListener
代码侵入零侵入修改ITelephony.aidl(+16方法)

4.3 卫星模式开关状态机对比

Android 16 — SatelliteSessionController(9态严格状态机,源码确认):

UnavailableState ──(设备不支持)──→ 终态
    │
PowerOffState ──requestSatelliteEnabled(true)──→ EnablingState
                                                     │
                                           EVENT_SET_SATELLITE_ENABLED_DONE
                                                     │
                                    ┌────────────────┼────────────────┐
                                    ▼                ▼                ▼
                              IdleState      NotConnectedState   ConnectedState
                              (等待收发)      (已注册未连接)      (网络附着完成)
                                    │                                  │
                           sendDatagram()                     onPendingDatagrams()
                                    │                                  │
                                    ▼                                  ▼
                            TransferringState ←────────────────────────┘
                                    │
                           发送完成,等待接收
                                    ▼
                            ListeningState (发送后180s/接收后30s分级超时)
                                    │
                           超时或收到新数据
                                    ▼
                              IdleState

DisablingState ←── requestSatelliteEnabled(false) ←── 任何状态
    │ (清理资源、解绑GatewayService、禁用干扰源恢复)
    ▼
PowerOffState

关键实现细节(源码确认):

  • ExponentialBackoff 处理绑定SatelliteService失败(2s→4s→8s→16s→32s→64s,上限64s)

  • 灭屏30s自动进入省电模式(EVENT_SCREEN_OFF_TIMEOUT)

  • BT/WiFi/NFC/UWB自动禁用/恢复(EVENT_DISABLE_CONFLICTING_RADIO)

  • SatelliteModemEnableRequestAttributes 携带enableDemoMode/transportType/isCarrierRoaming

Kylin Android 13 — XwRadioState(6枚举值,无状态机类):

CLOSED ──setRadioPowerXw(true)──→ OPENNING (CP启动中,串口未ready)
                                      │
                                串口就绪
                                      │
                                      ▼
                                   OPENED (CP已启动,串口已ready)
                                      │
                                入网中
                                      │
                                      ▼
                                  CONNECTING (CP入网中)
                                      │
                                数据业务建立
                                      │
                                      ▼
                                  CONNECED (CP已建立数据业务) ← 注意: 拼写错误

UNAVAILABLE (CP不可用)

关键差异:

对比项Android 16Kylin Android 13
状态机实现SatelliteSessionController 专用类,State模式,9个State内部类无状态机类,仅6个枚举值
状态守卫enter()/exit() + 转换合法性检查无守卫,任何状态可任意切换
超时处理ListeningState 180s/30s分级超时自动回Idle无超时机制
传输状态TransferringState/ListeningState 区分收发无传输状态
错误状态UnavailableState + 错误处理和回退UNAVAILABLE枚举但无处理逻辑
Connected含义网络附着/注册完成,不分配IP数据业务已建立
禁用流程DisablingState 专门处理(清理资源、解绑GatewayService)直接关闭CP电源
指数退避ExponentialBackoff 处理绑定失败(2s→64s)无重连机制
屏幕感知灭屏30s自动进入省电模式无屏幕状态感知
干扰源管理自动禁用/恢复BT/WiFi/NFC/UWB无干扰源管理

4.4 消息发送流程对比

Android 16 — 完整Datagram发送流程:

App: SatelliteManager.sendDatagram(SMS, datagram, true, callback)
  │ [Binder IPC]
  ▼
SatelliteController.sendDatagram()
  ├── evaluateOemSatelliteRequestAllowed() → 权限检查
  ├── 若需对星: PointingAppController.startPointingUI()
  ▼
DatagramController.sendSatelliteDatagram()
  ▼
DatagramDispatcher.sendDatagram()
  ├── 排入发送队列 (LinkedHashMap<Long, DatagramItem>)
  ├── 紧急优先: mPendingEmergencyDatagramsMap > mPendingNonEmergencyDatagramsMap
  ├── CMD_SEND_SATELLITE_DATAGRAM (Handler消息)
  ▼
SatelliteModemInterface.sendSatelliteDatagram()
  │ [Binder IPC]
  ▼
ISatellite.sendSatelliteDatagram(datagram, isEmergency, needPointingUI, callback)
  │ [厂商RIL → Modem]
  ▼
Modem 通过卫星上行链路发送
  ▼
EVENT_SEND_SATELLITE_DATAGRAM_DONE
  ├── 成功:更新SendState → SEND_SUCCESS → 回调App
  │         DatagramReceiver.pollPendingSatelliteDatagrams() (触发MT轮询)
  └── 失败:保留在队列 → retrySendingDatagrams() → 超时: SATELLITE_RESULT_MODEM_TIMEOUT

MT SMS轮询流程:
  DatagramReceiver
  ├── CMD_POLL_PENDING_SATELLITE_DATAGRAMS (节流: 最小间隔10s)
  ├── EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE
  │   ├── 有新数据: 解析SatelliteDatagram → 写入SmsProvider → 通知App
  │   └── 无新数据: 结束轮询
  └── SharedPreferences记录datagramId去重

Kylin Android 13 — 无消息发送机制(语音通话流程):

App: TelephonyManager.dialXw(number, type, rate, callback)
  │ [Binder IPC via ITelephony.aidl]
  ▼
ITelephony.dialXw() → PhoneInterfaceManager
  │ [Binder IPC via IXwRadio.aidl]
  ▼
IXwRadio.dialXW(number, type, rate) → HAL
  │
  ▼
RIL_XW_REQUEST_DIAL → CP
  │
  ▼
IXwRadioIndication.callStateChanged() → ICallStateListener.onCallStateChanged()

语音数据通道:
  AudioStreamer (JNI) ←→ 共享内存 ←→ IXwRadioVoice.sendUplinkVoiceData()
  AudioStreamer (JNI) ←→ 共享内存 ←→ IXwRadioVoice.acquireVoiceDataBuffer()

关键差异:

  • AOSP有消息队列+重试+超时+紧急优先级;Kylin语音直接透传HAL,无队列无重试

  • AOSP有MT SMS轮询(节流控制+去重+写入SmsProvider);Kylin无消息接收

  • AOSP有Demo模式模拟(延迟发送、设备对齐模拟);Kylin仅有RIL mock

  • Kylin有语音数据通道(JNI+共享内存);AOSP无语音支持

4.5 信号上报流程对比

Android 16 — 双路径信号上报:

路径模式触发源通知链路
路径AOEM卫星模式ISatellite HAL → SatelliteServiceISatelliteListener.onNtnSignalStrengthChanged() → SatelliteModemInterface.VendorListener → SatelliteController → INtnSignalStrengthCallback + Phone.notifyCarrierRoamingNtnSignalStrengthChanged() → TelephonyRegistry → SystemUI/卫星应用/ConnectivityService
路径BCarrier NTN漫游IRadio AIDL → RILJRIL_UNSOL_SIGNAL_STRENGTH → SignalStrengthController → SatelliteController + Phone.notifySignalStrength() → TelephonyRegistry → 应用层

信号强度模型(5级离散化 + 滞后滤波):

NtnSignalStrength:
  ├── signalQuality: 0-4 (NONE/POOR/FAIR/GOOD/EXCELLENT)
  ├── signalStrength: 0-4
  ├── rssi: dBm值 (OEM卫星模式)
  ├── snr: dB值 (OEM卫星模式)
  └── 滞后滤波: 防止信号等级频繁跳变

Kylin Android 13:

  • 仅通过 customRequest(CUSTOM_REQUEST_GET_RSSI, ...) / customRequest(CUSTOM_REQUEST_GET_SNR, ...) 主动查询

  • 无信号变化主动推送机制

  • 无信号强度模型(5级离散化)、无滞后滤波、无上报频率控制

4.6 网络切换流程对比

Android 16:

地面网络恢复 → ISatelliteListener.onTerrestrialNetworkAvailableChanged(true)
  → SatelliteController → 评估是否应关闭卫星
  ├── 若CarrierConfig允许自动切换:
  │   → requestSatelliteEnabled(false)
  │   → SatelliteSessionController → DisablingState → PowerOffState
  └── 若需手动确认:
      → 发送通知提示用户

并发地面扫描: IdleState中,若isConcurrentTnScanningSupported()为true,
  Framework调用enableCellularModemWhileSatelliteModeIsOn(true)
  → 卫星模式运行期间保持地面Modem可用,地面网络恢复后快速切换

Kylin Android 13: 无自动切换机制,用户需手动开关卫星CP。

4.7 HAL 接口对比

Android 16 — ISatellite 标准HAL:

interface ISatellite {
    void setSatelliteListener(ISatelliteListener listener);
    void requestSatelliteEnabled(in SatelliteModemEnableRequestAttributes attributes,
                                 IIntegerConsumer callback);
    void requestSatelliteCapabilities(IIntegerConsumer callback);
    void sendSatelliteDatagram(in SatelliteDatagram datagram, boolean isEmergency,
                               boolean needPointingUI, IIntegerConsumer callback);
    void pollPendingDatagrams(IIntegerConsumer callback);
    void startSendingSatellitePointingInfo(IIntegerConsumer callback);
    void stopSendingSatellitePointingInfo(IIntegerConsumer callback);
    void setSatellitePlmn(in List<String> plmnList, IIntegerConsumer callback);
}

interface ISatelliteListener {
    void onSatelliteDatagramReceived(long datagramId, int count);
    void onSatellitePositionChanged(in PointingInfo pointingInfo);
    void onSatelliteModemStateChanged(int state);
    void onNtnSignalStrengthChanged(in NtnSignalStrength signalStrength);
    void onSatelliteCapabilitiesChanged(in SatelliteCapabilities capabilities);
    void onPendingDatagrams(int count);
    void onTerrestrialNetworkAvailableChanged(boolean isAvailable);
}

Kylin Android 13 — IXwRadio/IXwRadioVoice 私有HAL:

特点 :

  1. 接口定义完全由 XWOS 厂商控制 ,在 vendor.xwos.hardware.radio 包下
  2. 与 AOSP 标准 HAL 不兼容 ,无法直接复用 AOSP 的卫星框架
  3. 其他厂商无法直接复用 ,每个卫星厂商需要定义自己的私有 HAL
  4. 升级到新版本 Android 时可能需要重新适配 ,因为 AOSP 标准化接口可能变化
interface IXwRadio {
    void setRadioPowerXW(boolean on, IBooleanConsumer callback);
    void dialXW(String number, int type, int rate, IIntegerConsumer callback);
    void hangupXW(IIntegerConsumer callback);
    void answerXW(IIntegerConsumer callback);
    void getPostimeXW(int type, IIntegerConsumer callback);
    void setPostimeXW(int type, String data, IIntegerConsumer callback);
    void getSectfXW(IIntegerConsumer callback);
    void setSectfXW(String data, IIntegerConsumer callback);
    void executeStunXW(int mode, int value, int timeout, IIntegerConsumer callback);
    void executeKillXW(int timeout, IIntegerConsumer callback);
    void setCommunicationTypeXW(int type, IBooleanConsumer callback);
    void customRequest(int requestId, in byte[] data, ICustomRequestCallback callback);
}

interface IXwRadioVoice {
    void sendUplinkVoiceData(in byte[] data);
    byte[] acquireVoiceDataBuffer();
    void releaseVoiceDataBuffer();
}

interface IXwRadioIndication {
    void xwRadioStateChanged(int state);
    void callStateChanged(in CallState callState);
    void customEvent(int event, in byte[] data);
}

关键差异:

  • AOSP HAL 面向消息和状态,Kylin HAL 面向全业务(语音/数据/位置/安全/自定义)

  • AOSP 有地面网络可用性回调;Kylin 无此概念

  • AOSP 有卫星位置/对星信息回调;Kylin 无此概念

  • AOSP 有卫星能力动态回调;Kylin 无此概念

  • Kylin 有语音数据通道sendUplinkVoiceData/acquireVoiceDataBuffer);AOSP 无

  • Kylin 有自定义扩展接口customRequest/customEvent,107个ID);AOSP 无

  • AOSP 有SatelliteImplBase厂商抽象基类;Kylin 无抽象层

五、性能与功耗评估

指标Android 16 AOSPKylin Android 13评价
内存~200-400KB(24个类,40+原子变量,单例模式)~100-200KB(11个类+XwosTeleService独立进程)AOSP内存略高但功能更完整;Kylin额外进程开销
CPUHandler消息驱动+MT轮询(节流)+Metrics计数器无轮询,语音数据直接透传AOSP CPU略高但可控;Kylin语音JNI编解码有CPU峰值
功耗-灭屏灭屏30s自动超时+NB-IoT不活动超时无灭屏感知,CP可能长时间开启AOSP远优于Kylin
功耗-会话P2P SMS 180s/ESOS 600s分级超时无会话超时AOSP远优于Kylin
功耗-干扰自动禁用BT/WiFi/NFC/UWB无干扰源管理AOSP远优于Kylin
功耗-地面扫描并发地面扫描(避免反复开关卫星)不支持AOSP优于Kylin
功耗-指数退避SatelliteService绑定失败2s→64s退避无重连机制AOSP优于Kylin
流量统计开销需识别 TRANSPORT_SATELLITE 位,NetworkIdentity 匹配增加少量位运算开销;getMobileUidStats() 合并统计蜂窝+卫星接口,接口集合略大;整体CPU开销可忽略不计无额外流量统计开销(因功能缺失)AOSP有少量额外开销但可接受;Kylin零开销但功能缺失
响应时延-链路状态机Enabling→Idle→Connected,5-15sCP启动→入网→数据业务建立,10-30sAOSP更快(状态机优化)
响应时延-消息3-10s(队列+重试+超时)N/A(无消息功能)AOSP独有
时延统计SessionMetricsStats全链路追踪TeleStatsService仅通话统计AOSP更全面
语音时延N/A800bps/2.4kbps/4.8kbps编解码,高延迟Kylin独有但延迟高
可观测性7个Metrics类+PersistentLoggerTeleStatsService(仅通话)AOSP远优于Kylin

六、代码质量与可维护性分析

维度Android 16 AOSPKylin Android 13评价
包结构android.telephony.satellite + com.android.internal.telephony.satellite + packages/modules/Connectivityandroid.telephony.xwos + com.android.internal.telephony.xwos + vendor/xwosAOSP标准化;Kylin厂商命名
代码侵入零侵入,独立模块修改TelephonyManager(+750行)、ITelephony.aidl(+16方法)、RIL.java(+XW请求)、PhoneInterfaceManager(+XW实现)、DataNetwork.java(+TRANSPORT_SATELLITE)AOSP远优于Kylin
设计模式状态机(9态)+单例+观察者+Handler消息驱动+双优先级队列+指数退避+策略模式过程式调用,无状态机,无队列AOSP远优于Kylin
职责分离Controller/Dispatcher/Receiver/Metrics/PointingApp/ConfigParser/Resolver 分层清晰PhoneInterfaceManager承载所有XW方法+XwosTeleService 5个子服务AOSP更清晰
注释完整Javadoc + @VisibleForTesting + @GuardedBy + @NonNull/@Nullable中文注释,缺少Javadoc标准格式AOSP更规范
类型安全@SatelliteManager.SatelliteModemState 注解 + 强类型数据类CallState字段全部为int,缺少@IntDef;customRequest(int, byte[])裸byte[]AOSP远优于Kylin
线程安全40+ AtomicBoolean/AtomicInteger/AtomicLong,无锁并发sXwCallStateListeners(ConcurrentHashMap) vs sCustomEventListeners(HashMap+synchronized)风格不一致AOSP更一致
Binder生命周期完整IBinder.DeathRecipient处理registerCallStateListener有linkToDeath,registerForCustomEventListener无AOSP更完整
测试CTS + Demo模式 + Mock Modem + @VisibleForTesting无测试代码AOSP远优于Kylin
升级影响独立模块,Mainline APEX可独立更新修改核心AIDL(ITelephony),影响所有Telephony客户端AOSP远优于Kylin
Vendor隔离SatelliteImplBase抽象基类,Framework无需修改Vendor代码直接修改AOSP核心文件AOSP远优于Kylin
已知Bug无已知复制粘贴错误setPostimeXwAsync的catch日志写的是getPostimeXwAsyncKylin有已知Bug
进程架构单进程(Phone),模块间直接调用双进程(Phone+XwosTeleService),Binder跨进程通信AOSP更简单;Kylin隔离性更好

七、Android 13 移植的优化建议

高优先级

1. 引入状态机

  • 问题: XwRadioState 仅为6个枚举值,无状态机类,无转换守卫,无超时处理

  • 参考: Android 16 的 SatelliteSessionController 9态状态机

  • 建议: 实现 XwSatelliteSessionController,至少包含 PowerOff→Enabling→Idle→Transferring→Listening→Disabling,添加 enter()/exit() 守卫和转换合法性检查

  • 收益: 解决状态不一致问题,支持超时/重试/异常恢复

  • 实施:

    • public class XwSatelliteSessionController extends StateMachine {
          private final PowerOffState mPowerOffState = new PowerOffState();
          private final EnablingState mEnablingState = new EnablingState();
          private final IdleState mIdleState = new IdleState();
          private final TransferringState mTransferringState = new TransferringState();
          private final ListeningState mListeningState = new ListeningState();
          private final DisablingState mDisablingState = new DisablingState();
      
          class ListeningState extends State {
              private static final int TIMEOUT_MS = 180_000;
              @Override public void enter() { sendMessageDelayed(EVENT_TIMEOUT, TIMEOUT_MS); }
              @Override public boolean processMessage(Message msg) {
                  if (msg.what == EVENT_TIMEOUT) { transitionTo(mIdleState); return HANDLED; }
                  return NOT_HANDLED;
              }
          }
      }
      

2. 引入 SatelliteManager 适配层

  • 问题: 所有卫星API挂在TelephonyManager上,与AOSP升级冲突风险极高

  • 参考: Android 16 的 SatelliteManager 独立入口

  • 建议: 创建 XwSatelliteManager 适配层,内部委托给TelephonyManager XW方法

  • 收益: 为未来AOSP升级提供迁移路径,降低代码冲突

  • 实施:

    • public class XwSatelliteManager {
          public static final String SATELLITE_SERVICE = "xwos_satellite";
          public void requestSatelliteEnabled(boolean enabled, Executor exec,
                  OutcomeReceiver<Void, SatelliteException> callback);
          public void sendDatagram(int datagramType, byte[] data, Executor exec,
                  OutcomeReceiver<Void, SatelliteException> callback);
          public void registerSatelliteStateChangeListener(Executor exec,
                  SatelliteStateChangeListener listener);
          public boolean isSupported();
          // 内部委托: tm.setRadioPowerXw(), tm.dialXw(), tm.registerCallStateListener()
      }
      

3. 实现 Datagram 消息队列与重试机制

  • 问题: 无消息队列,语音/数据直接透传HAL,无重试、无超时、无紧急优先

  • 参考: Android 16 的 DatagramDispatcher(LinkedHashMap队列 + retrySendingDatagrams() + SATELLITE_RESULT_MODEM_TIMEOUT)

  • 建议: 新建 XwDatagramDispatcher 类,实现消息队列、重试、超时、紧急/普通分离

  • 收益: 消息投递可靠性大幅提升

  • 实施:

    • public class XwDatagramDispatcher extends Handler {
          private LinkedHashMap<Long, SendDatagramArgument> mPendingEmergencyDatagrams;
          private LinkedHashMap<Long, SendDatagramArgument> mPendingNonEmergencyDatagrams;
          private static final int SEND_TIMEOUT_MS = 30000;
      
          void sendDatagram(SendDatagramArgument arg) {
              if (arg.isEmergency) mPendingEmergencyDatagrams.put(arg.id, arg);
              else mPendingNonEmergencyDatagrams.put(arg.id, arg);
              sendMessage(obtainMessage(CMD_SEND_DATAGRAM, arg));
          }
      
          void retrySendingDatagrams() {
              for (SendDatagramArgument arg : mPendingEmergencyDatagrams.values()) {
                  sendMessage(obtainMessage(CMD_SEND_DATAGRAM, arg));
              }
              for (SendDatagramArgument arg : mPendingNonEmergencyDatagrams.values()) {
                  sendMessage(obtainMessage(CMD_SEND_DATAGRAM, arg));
              }
          }
      }
      

4. HAL 接口标准化

  • 问题: IXwRadio/IXwRadioVoice 完全私有,无法适配其他卫星星座

  • 参考: Android 16 的 ISatellite 标准HAL + SatelliteImplBase 抽象基类

  • 建议: 在 IXwRadio 之上增加 ISatelliteHardware 抽象层,实现类似 SatelliteImplBase 的厂商抽象基类

  • 收益: 支持多星座适配,与AOSP HAL演进对齐

5. 补充紧急SOS功能

  • 问题: 无独立SOS接口,dialXw未区分普通/紧急呼叫

  • 参考: Android 16 的 DATAGRAM_TYPE_SOS_MESSAGE + SatelliteSOSMessageRecommender + T911/SOS双模式 + ESOS Profile

  • 建议: 增加 emergencyDialXw() 和 sendSosDatagram(),实现紧急呼叫推荐机制

  • 收益: 满足3GPP紧急呼叫要求,与AOSP卫星SOS对齐

6. 增加卫星流量统计支持

  • 问题: 完全缺失卫星流量统计能力,卫星流量混入移动网络流量,用户/应用无法精确计量卫星数据消耗,无计费属性区分

  • 参考: Android 16 的 NetworkTemplate.Builder.setTransportType(TRANSPORT_SATELLITE) + NetworkIdentity.mTransportTypesBits + NetworkStatsService 卫星识别机制

  • 建议: 分层实现卫星流量统计支持:

    • 方案A(框架层修改,推荐) :参考 Android 16 机制,在 NetworkIdentity 中增加 TRANSPORT_SATELLITE 位支持,在 NetworkTemplate.Builder 中增加 setTransportType(),在 NetworkStatsService 中增加卫星接口识别逻辑(isMobile 判断包含 TRANSPORT_SATELLITE),实现 XwNetworkStatsManager 提供卫星专用流量查询接口
    • 方案B(应用层补偿) :若无法修改框架层,可在 TeleDataService 中自行记录卫星接口的 RX/TX 字节数,通过 TrafficStats.getUidRxBytes()/getUidTxBytes() 结合接口名称过滤,实现应用级卫星流量统计
    • 方案C(混合方案) :启用 Android 16 的 FLAG_NETSTATS_TRANSPORT_TYPE Feature Flag(如已回移),配合自定义 NetworkTemplate 构建卫星查询模板
  • 收益: 用户可精确计量卫星数据消耗,支持计费感知,为运营商计费对接提供基础

  • OEM适配要点:

    • 内核/HAL层:确保卫星网络接口被正确注册到TelephonyNetworkSpecifier中,包含正确的subscriptionId;卫星Modem需通过PhoneStateListener上报RAT类型;eBPF程序无需修改,卫星流量通过标准网络接口采集
    • Framework层:启用FLAG_NETSTATS_TRANSPORT_TYPE Feature Flag以支持基于传输类型的模板查询;在getDisplayTransport()实现中正确映射卫星传输类型;确保卫星网络的NetworkCapabilities包含TRANSPORT_SATELLITE
    • 流量统计区分:如需独立统计卫星流量,使用NetworkTemplate.Builder().setTransportType(TRANSPORT_SATELLITE).build()构建查询模板;注意此功能受Feature Flag控制,需确认设备已启用
  • 实施(方案A) :

    • // 1. NetworkIdentity 增加 TRANSPORT_SATELLITE 位
      public class NetworkIdentity {
          // 在 Builder.setTransportTypes() 中处理 TRANSPORT_SATELLITE
      }
      
      // 2. NetworkTemplate.Builder 增加 setTransportType
      public static class Builder {
          public Builder setTransportType(@Transport int transportType) {
              mTransportType = transportType;
              return this;
          }
      }
      
      // 3. NetworkStatsService 增加卫星识别
      // handleNetworkStateChanged() 中:
      final boolean isMobile = NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport
              || NetworkCapabilities.TRANSPORT_SATELLITE == displayTransport;
      
      // 4. XwNetworkStatsManager 提供便捷查询
      public class XwNetworkStatsManager {
          public NetworkStats.Bucket getSatelliteUsage(long start, long end) {
              NetworkTemplate template = new NetworkTemplate.Builder()
                  .setTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
                  .build();
              return mNsManager.querySummaryForDevice(template, start, end);
          }
      }
      

中优先级

7. 实现信号上报体系

  • 问题: 无信号变化事件上报,仅通过customRequest主动查询

  • 参考: Android 16 双路径信号上报(OEM卫星模式 + 运营商NTN漫游模式)+ 5级离散模型 + 滞后滤波

  • 建议: 在 IXwRadioIndication 中增加 onSignalStrengthChanged() 回调,实现5级离散信号模型+滞后滤波,支持 INtnSignalStrengthCallback 注册机制

  • 收益: 支持信号质量实时监控和UI展示

8. 实现地面/卫星自动切换

  • 问题: 无自动切换机制

  • 参考: Android 16 的 onTerrestrialNetworkAvailableChanged() + CarrierConfig自动切换 + 并发地面扫描

  • 建议: 在 TeleDataService 中增加地面网络恢复检测,根据配置自动切换

  • 收益: 用户体验提升,功耗优化

9. 类型安全增强

  • 问题: CallState 的 dir/stat/mode/rate 均为裸int

  • 建议: 添加 @IntDef 注解定义合法值集合

  • 收益: 编译期类型检查,防止非法值

10. 统一异步回调模式

  • 问题: 混用 Consumer/ResultReceiver/IIntegerConsumer/OutcomeReceiver

  • 参考: Android 16 统一使用 OutcomeReceiver

  • 建议: 统一为 OutcomeReceiver 模式,废弃 IIntegerConsumer/IBooleanConsumer

  • 收益: API一致性

11. 可观测性增强

  • 问题: 缺少消息发送时延统计、链路质量指标

  • 参考: Android 16 的7个Metrics类 + PersistentLogger

  • 建议: 在 TeleStatsService 中增加卫星消息时延、链路建立时延、错误率等指标;实现关键事件持久化

  • 收益: 支持运维监控和用户体验优化

12. CarrierConfig 集成

  • 问题: 无运行时配置机制

  • 参考: Android 16 的 CarrierConfigManager 按PLMN配置卫星策略

  • 建议: 通过 CarrierConfigManager 按PLMN配置超时、优先级、ESOS Profile、并发地面扫描等

  • 收益: 支持多运营商差异化配置

13. 动态配置管理

  • 问题: 编译时固定常量,无法OTA更新

  • 参考: Android 16 的 SatelliteConfigParser(protobuf) + SatelliteNetworkInfo

  • 建议: 实现 SatelliteConfigParser 类似功能,支持protobuf格式的OTA配置更新

  • 收益: 支持运行时配置更新,无需刷机

低优先级

14. 实现对星引导UI

  • 问题: 无对星引导

  • 参考: Android 16 的 PointingAppController + needFullScreenPointingUI 参数 + AntennaPosition

  • 建议: 增加 XwPointingController,在拨号/发送前引导用户对准卫星

15. 权限模型完善

  • 问题: 无独立卫星权限

  • 参考: Android 16 的 USE_SATELLITE 权限 + 系统弹窗

  • 建议: 定义 android.permission.USE_XW_SATELLITE 权限

16. Binder生命周期统一管理

  • 问题: registerCallStateListener 有 linkToDeath,registerForCustomEventListener 没有

  • 建议: 统一所有监听器注册的死亡通知处理;将 sCustomEventListeners 从 HashMap 改为 ConcurrentHashMap

17. 修复已知Bug

  • 问题: setPostimeXwAsync 的catch日志复制粘贴错误

  • 建议: 修正日志标签

18. 测试框架搭建

  • 问题: 无任何测试代码

  • 参考: Android 16 的 DemoSimulator + CTS + @VisibleForTesting

  • 建议: 为核心类编写单元测试,实现DemoMode测试模式

19. 位置服务功耗优化

  • 问题: 固定轮询策略(100s/1500m),GPS持续开启

  • 参考: Android 16 的 startSatellitePositionUpdates 按需模式

  • 建议: 引入自适应策略——CP入网后降低频率,运动检测触发上报

20. XwTelephonyManager 与 TelephonyManager 去重

  • 问题: 功能重复

  • 建议: 明确 XwTelephonyManager 定位为适配层,内部仅委托调用

21. 保留Kylin独有功能

  • 问题: 标准化后可能丢失差异化竞争力

  • 参考: Android 16 的 SatelliteImplBase 厂商扩展机制

  • 建议: 在标准化框架基础上,通过Vendor扩展命名空间保留语音通话、安全卡、摇晕摇毙、载波模式、CP电源管理等定制功能

八、总结与参考建议

核心差异总结

维度Android 16 AOSPKylin Android 13评价
定位全球通用卫星基础设施星网专用全业务方案互补而非替代
架构成熟度⭐⭐⭐⭐⭐ 模块化、9态状态机、消息队列、指数退避⭐⭐⭐ 功能完整但架构封闭、无状态机AOSP架构更优
功能完整度⭐⭐⭐ 仅消息/SOS/数据/信号/配置⭐⭐⭐⭐⭐ 语音+数据+位置+统计+安全+自定义Kylin功能更全
可靠性⭐⭐⭐⭐⭐ 队列+重试+超时+状态守卫+指数退避⭐⭐ 无队列无重试无超时AOSP远优于Kylin
可升级性⭐⭐⭐⭐⭐ Mainline APEX + 零侵入⭐⭐ 侵入frameworks + 私有HALAOSP远优于Kylin
多星座支持⭐⭐⭐⭐ 标准HAL抽象 + NTRadioTechnology枚举⭐ 仅星网(高轨/低轨)AOSP远优于Kylin
功耗管理⭐⭐⭐⭐⭐ 灭屏超时+分级会话+干扰源+并发扫描⭐⭐ 无功耗管理AOSP远优于Kylin
可观测性⭐⭐⭐⭐⭐ 7个Metrics类+PersistentLogger⭐⭐⭐ TeleStatsService(仅通话)AOSP更全面
代码质量⭐⭐⭐⭐⭐ 类型安全+线程安全+完整Javadoc+测试⭐⭐⭐ 部分类型不安全+线程风格不一致+无测试AOSP远优于Kylin
卫星流量统计⭐⭐⭐ 基础识别架构(TRANSPORT_SATELLITE位+模板查询+合并统计),无独立API/专属策略⭐ 完全缺失,卫星流量混入移动流量AOSP有基础但尚不完整;Kylin完全缺失

长期演进建议

  1. 短期(3-6个月) : 实施高优先级优化——状态机实现、SatelliteManager适配层、Datagram消息队列、HAL标准化、SOS功能、卫星流量统计支持

  2. 中期(6-12个月) : 实施中优先级优化——信号上报、自动切换、类型安全、回调统一、可观测性、CarrierConfig、动态配置

  3. 长期(12+个月) : 规划AOSP升级路径——当升级到Android 14+时,逐步将XWOS功能迁移到AOSP SatelliteManager框架,保留星网特有功能(语音通话、CP电源管理、安全卡、载波模式)作为Vendor扩展接口;同步推进流量统计能力标准化,确保卫星流量可独立查询、可计费关联、可按波束/运营商细分。具体方向包括:(1) 推动AOSP实现独立的卫星流量统计API(如getSatelliteUidStats());(2) 在NetworkStats.Entry中增加TYPE_SATELLITE网络类型常量;(3) 实现SatelliteAccessController与NetworkStatsService的集成,在卫星网络启用/禁用时触发流量统计标记;(4) 支持按波束/运营商的卫星流量细分统计;(5) 为卫星消息模块(DatagramController/DatagramDispatcher)增加流量统计调用

风险提示

  1. AOSP升级冲突: 当前侵入式修改 TelephonyManager 和 ITelephony.aidl 的方式,在升级到 Android 14+ 时将产生严重合并冲突。越早解耦,升级成本越低
  2. 状态机缺失风险: 无状态守卫可能导致CP在OPENNING状态收到dialXw请求,造成不可预期的行为。
  3. 消息丢失风险: 无队列无重试机制,在网络不稳定时消息可能丢失且无法恢复。
  4. 3GPP NTN标准化: 随着NTN标准成熟(Release 18/19),AOSP卫星框架将逐步支持语音和数据业务,Kylin的私有实现可能需要重写。
  5. customRequest迁移: 107个Custom Request ID需逐一映射到标准AIDL方法或Vendor扩展接口,工作量较大。
  6. XwosTeleService进程管理: 独立进程增加系统复杂度(进程间通信、生命周期管理、崩溃恢复),需评估是否可合并到Phone进程。
  7. CONNECED拼写错误: XwRadioState.CONNECED 应为 CONNECTED,此拼写错误已扩散到所有使用处,修正时需全局替换。
  8. 卫星流量统计缺失风险: 卫星通信按流量计费是典型场景,当前无法精确计量卫星数据消耗,可能导致用户产生意外高额费用,影响用户体验和运营商合作。