双卡双待手机有DSDS(DualSim Dual Standby)和DSDA(Dual SIM dual active)方案,早期产品使用DSDA方案比较多,随着多模、多频段、CA、MIMO等技术出现,硬件射频复杂度大大增加,再加上双卡双通的实际使用场景并不多,DSDS就成为了目前市场的主流方案。
DSDS只有一张卡能够占有PS业务栈或Radio resource,故引入了DDS(Default DataSIM)概念。双SIM卡手机,只有一张卡能进行数据业务,称为主卡,另一张卡则称为副卡。若进行主副卡切换,则副卡切为DDS主卡;
DDS切换流程
手动DDS切换
通过setting-双卡与移动网络,选择默认上网卡。
DDS状态会保存在telephony的DB中,对应为Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION。
可通过adb shell getprop settings list multi_sim_data_call进行查看。
frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionController.java
public void setDefaultDataSubId(int subId) {
enforceModifyPhoneState("setDefaultDataSubId");String flexMapSupportType =
SystemProperties.get("persist.radio.flexmap_type", "nw_mode");
if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
throw new RuntimeException("setDefaultDataSubId called with DEFAULT_SUB_ID");
}
updateAllDataConnectionTrackers();
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
broadcastDefaultDataSubIdChanged(subId);
}
DDS切换Log参考
部分log如下,主要是PS domain/pdp建立。
//Setting UI set DDS
MobileNetworkSettings: Default Data SubId [1]
//telephony-fwk subscription module detect DDS switch
SubscriptionMonitor:Default changed 1->2
SubscriptionMonitor: newDefaultDataPhoneId=1
SubscriptionMonitor: Default phoneId changed 0->1, 1,1 registrants
TelephonyNetworkFactory[0]: onDefaultChange(true,false)
TelephonyNetworkFactory[1]: onDefaultChange(false,true)
//set PS domain switch cmd to RIL
PhoneSwitcher: InformDdsToRil rild= 1, DDS=1RILJ : [4184]> RIL_REQUEST_ALLOW_DATA allowed: false [SUB0]
RILJ : [4185]> RIL_REQUEST_ALLOW_DATA allowed: true [SUB1]
RILJ : [4184]< RIL_REQUEST_ALLOW_DATA [SUB0]
RILJ : [4185]< RIL_REQUEST_ALLOW_DATA [SUB1]
//PS domain camp on
QtiGsmDCT: [1]onDataConnectionAttached
//try setup pdp
TelephonyNetworkFactory[1]: onActivePhoneSwitch(true, true)
TelephonyNetworkFactory[1]: onReleaseNetworkFor NetworkRequest [ id=8, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ]
TelephonyNetworkFactory[0]: not releasing - isApp=false, isAct=false NetworkRequest [ id=8, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ]
RILJ : [4260]> SETUP_DATA_CALL 14 0 cmnet 0 IPV4V6 [SUB1]
RILJ : [4260]< SETUP_DATA_CALL DataCallResponse: {version=11 status=0 retry=-1 cid=0 active=2 type=IPV4V6 ifname=rmnet_data0 mtu=1500 addresses=[10.148.243.195/29] dnses=[211.136.112.50,211.136.150.66] gateways=[10.148.243.196] pcscf=[]} [SUB1]
TelephonyNetworkFactory[1]: got request NetworkRequest [ id=10, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ] with score 0
TelephonyNetworkFactory[0]: got request NetworkRequest [ id=10, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ] with score 0
TelephonyNetworkFactory[1]: onNeedNetworkFor NetworkRequest [ id=10, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ]
TelephonyNetworkFactory[0]: not acting - isApp=false, isAct=false NetworkRequest [ id=10, legacyType=-1, [ Transports: CELLULAR Capabilities: IMS&TRUSTED&NOT_VPN] ]
RILJ : [4279]> SETUP_DATA_CALL 14 2 ims 0 IPV4V6 [SUB1]
RILJ : [4279]< SETUP_DATA_CALL DataCallResponse: {version=11 status=0 retry=-1 cid=1 active=2 type=IPV4V6 ifname=rmnet_data7 mtu=1500 addresses=[2409:8804:8010:17cc:db16:6730:30b2:383c/64] dnses=[] gateways=[fe80:0000:0000:0000:e1cc:541a:ab8c:f1bf] pcscf=[]} [SUB1]
动态DDS切换
除了用户手动设置DDS外,特定的场景还可以进行DDS动态切换。
当subInfo/network request/radio state/数据开关/通话状态等改变时,都会触发onEvaluate方法,判断当前应该将DDS切换到哪张卡上。
当然,动态DDS切换的场景还有很多,例如信号强度、网络注册状态、吞吐量等等,手机厂家可以使用更优的算法进行更智能化切换,让数据建立在性能更优的SIM卡上,满足用户的流畅体验。