Android11 移动数据开关流程——DcTracker解析
该章只分析DcTracker部分逻辑
前言
Android移动数据上网是通过打开apn,三大运营商都有不同apn配置,如果需要上专网也要自行配置相关的apn配置。
该文主要是解析打开apn时DcTracker部分的流程,也是apn上网在framework中比较核心的一个地方。
一、DataEnabledSettings
frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
先看一下在此之前是怎么调到DcTracker里面的接口的
这个基本就是可以暴露给用户使用的打开数据流量开关的接口
最终往下进行走的是 updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
/**
* @param notifyMultiSimSettingController if setUserDataEnabled is already from propagating
* from MultiSimSettingController, don't notify MultiSimSettingController again.
* For example, if sub1 and sub2 are in the same group and user enables data for sub
* 1, sub 2 will also be enabled but with propagateToGroup = false.
*/
public synchronized void setUserDataEnabled(boolean enabled,
boolean notifyMultiSimSettingController) {
// Can't disable data for stand alone opportunistic subscription.
//判断是否是受限的subid,也就是订阅的卡槽
if (isStandAloneOpportunistic(mPhone.getSubId(), mPhone.getContext()) && !enabled) return;
boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(), //设置上setting值
Settings.Global.MOBILE_DATA, mPhone.getSubId(), (enabled ? 1 : 0));
if (changed) {
localLog("UserDataEnabled", enabled);
mPhone.notifyUserMobileDataStateChanged(enabled);//通知给上层开关状态改变
updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED); //1
if (notifyMultiSimSettingController) {
MultiSimSettingController.getInstance().notifyUserDataEnabled(
mPhone.getSubId(), enabled);
}
}
}
updateDataEnabledAndNotify
这个方法很简单就是执行了两个方法
private synchronized void updateDataEnabledAndNotify(int reason) {
boolean prevDataEnabled = mIsDataEnabled;
updateDataEnabled();//1
if (prevDataEnabled != mIsDataEnabled) {
notifyDataEnabledChanged(!prevDataEnabled, reason);//2
}
}
updateDataEnabled
先看第一个
private synchronized void updateDataEnabled() {
if (isProvisioning()) {
//一般开机引导完事之后都是false
mIsDataEnabled = isProvisioningDataEnabled();
} else {
//更新上层状态
mIsDataEnabled = mInternalDataEnabled && (isUserDataEnabled() || mDataEnabledOverride
.shouldOverrideDataEnabledSettings(mPhone, ApnSetting.TYPE_ALL))
&& mPolicyDataEnabled && mCarrierDataEnabled;
}
}
notifyDataEnabledChanged
private void notifyDataEnabledChanged(boolean enabled, int reason) {
mOverallDataEnabledChangedRegistrants.notifyResult(new Pair<>(enabled, reason));
}
mOverallDataEnabledChangedRegistrants这个变量是DcTracker构造方法内执行的注册近来的回调
因为DcTracker就是一个Handler
所以开始分析其内部接收到回调之后的操作
二、DcTracker
1.引入库
frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
这个就是其注册的代码
连同接收的地方一起写下
mDataEnabledSettings.registerForDataEnabledChanged(this,
DctConstants.EVENT_DATA_ENABLED_CHANGED, null);
case DctConstants.EVENT_DATA_ENABLED_CHANGED:
ar = (AsyncResult) msg.obj;
if (ar.result instanceof Pair) {
Pair<Boolean, Integer> p = (Pair<Boolean, Integer>) ar.result;
boolean enabled = p.first;
int reason = p.second;
onDataEnabledChanged(enabled, reason);//1
}
break;
onDataEnabledChanged
private void onDataEnabledChanged(boolean enable,
@DataEnabledChangedReason int enabledChangedReason) {
if (DBG) {
log("onDataEnabledChanged: enable=" + enable + ", enabledChangedReason="
+ enabledChangedReason);
}
if (enable) {
//打开和关闭数据流量还不一样的流程
reevaluateDataConnections();//1
setupDataOnAllConnectableApns(Phone.REASON_DATA_ENABLED, RetryFailures.ALWAYS);//2
} else {
String cleanupReason;
switch (enabledChangedReason) {
//根据不同原因,在执行清除连接方法的时候作为入参传进去
case DataEnabledSettings.REASON_INTERNAL_DATA_ENABLED:
cleanupReason = Phone.REASON_DATA_DISABLED_INTERNAL;
break;
case DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER:
cleanupReason = Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN;
break;
case DataEnabledSettings.REASON_USER_DATA_ENABLED:
case DataEnabledSettings.REASON_POLICY_DATA_ENABLED:
case DataEnabledSettings.REASON_PROVISIONED_CHANGED:
case