先上一张流程图

Settings.apk 在Settings ->  Data Usage Summary中的某个SIM tab下开启数据开关 android/ packages/apps/Settings/src/com/android/settings/DataUsageSummary.java
setMobileDataEnabled (true);
                                                                        private View.OnClickListener mDataEnabledListener = new View.OnClickListener() {                                                                                    @Override                                                                                    public void onClick(View v) {                                                                                        if (mBinding) return;                                                                                                                                                                     final boolean dataEnabled = !mDataEnabled.isChecked();                                                                                        final String currentTab = mCurrentTab;                                                                                        if (TAB_MOBILE.equals(currentTab) || currentTab.startsWith(TAB_SIM)) {                                                                                            if (dataEnabled) {                                                                                                setMobileDataEnabled(true);                                                                                                if (mPolicyEditor.getPolicyWarningBytes(mTemplate) == WARNING_DISABLED) {                                                                                                    mPolicyEditor.setPolicyWarningBytes(mTemplate, 2 * GB_IN_BYTES);                                                                                                }                                                                                            } else {                                                                                                // disabling data; show confirmation dialog which eventually                                                                                                // calls setMobileDataEnabled() once user confirms.                                                                                                ConfirmDataDisableFragment.show(DataUsageSummary.this);                                                                                            }                                                                                        }                                                                                                                                                                     updatePolicy(false);                                                                                    }                                                                                };                                            

下面这部根据phoneId获得了当前获得了SubId mTelephonyManager . setDataEnabled ( subId [ 0 ], enabled );
                                                                                                                                                         private void setMobileDataEnabled(boolean enabled) {                                                                                    if (LOGD) Log.d(TAG, "setMobileDataEnabled()");                                                                                    // How about exposing sub based API like TelephonyManager.setDataEnabled(int subId);                                                                                    if (mCurrentTab.startsWith(TAB_SIM)) {                                                                                        int phoneId = multiSimGetCurrentSub();                                                                                                                                                                     // as per phone, set the individual flag                                                                                        android.provider.Settings.Global.putInt(getActivity().getContentResolver(),                                                                                                android.provider.Settings.Global.MOBILE_DATA + phoneId, enabled ? 1 : 0);                                                                                                                                                                     int[] subId = SubscriptionManager.getSubId(phoneId);                                                                                        mTelephonyManager.setDataEnabled(subId[0], enabled);                                                                                    } else {                                                                                        mTelephonyManager.setDataEnabled(enabled);                                                                                        mMobileDataEnabled = enabled;                                                                                    }                                                                                    updatePolicy(false);                                                                                }                                            


frameworks/base
数据开关都会调用到TelephonyManager.setDataEnabled(),不管是从流量使用情况还是从下拉的“快速设置”(Quick Setting)里打开(这里会在后面补充说明)
android/frameworks/base/telephony/java/android/telephony/TelephonyManager.java
getITelephony (). setDataEnabled ( subId , enable );
                                                                            /** @hide */                                                                                @SystemApi                                                                                public void setDataEnabled(int subId, boolean enable) {                                                                                    try {                                                                                        AppOpsManager appOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);                                                                                        if (enable) {                                                                                            if (appOps.noteOp(AppOpsManager.OP_DATA_CONNECT_CHANGE) != AppOpsManager.MODE_ALLOWED) {                                                                                                Log.w(TAG, "Permission denied by user.");                                                                                                return;                                                                                            }                                                                                        }                                                                                        Log.d(TAG, "setDataEnabled: enabled=" + enable);                                                                                        getITelephony().setDataEnabled(subId, enable);                                                                                    } catch (RemoteException e) {                                                                                        Log.e(TAG, "Error calling setDataEnabled", e);                                                                                    }                                                                                }                                            

android/ packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
到这里才是设置phone的数据开启 phone . setDataEnabled ( enable );
                                                                                                                                                         /**                                                                                 * Set mobile data enabled                                                                                 * Used by the user through settings etc to turn on/off mobile data                                                                                 *                                                                                 * @param enable {@code true} turn turn data on, else {@code false}                                                                                 */                                                                                @Override                                                                                public void setDataEnabled(int subId, boolean enable) {                                                                                    enforceModifyPermission();                                                                                    int phoneId = mSubscriptionController.getPhoneId(subId);                                                                                    log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);                                                                                    Phone phone = PhoneFactory.getPhone(phoneId);                                                                                    if (phone != null) {                                                                                        log("setDataEnabled: subId=" + subId + " enable=" + enable);                                                                                        phone.setDataEnabled(enable);                                                                                    } else {                                                                                        loge("setDataEnabled: no phone for subId=" + subId);                                                                                    }                                                                                }                                            

android/ frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GSMPhone.java
mDcTracker . setDataEnabled ( enable );
                                                                            @Override                                                                                public void setDataEnabled(boolean enable) {                                                                                    mDcTracker.setDataEnabled(enable);                                                                                }                                            
  android/rameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTrackerBase.java   
发送打开数据开关的消息CMD_SET_USER_DATA_ENABLE Message msg = obtainMessage ( DctConstants . CMD_SET_USER_DATA_ENABLE );
                                                                            /**                                                                                 * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.                                                                                 */                                                                                public void setDataEnabled(boolean enable) {                                                                                    Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);                                                                                    msg.arg1 = enable ? 1 : 0;                                                                                    sendMessage(msg);                                                                                }                                            
处理消息 onSetUserDataEnabled ( enabled );
                                                                            @Override                                                                                public void handleMessage(Message msg) {                                                                                    switch (msg.what) {                                                                                        case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {                                                                                            log("DISCONNECTED_CONNECTED: msg=" + msg);                                                                                            DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;                                                                                            mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());                                                                                            dcac.disconnected();                                                                                            break;                                                                                        }                                                                                        ...                                                                                        case DctConstants.CMD_SET_USER_DATA_ENABLE: {                                                                                            final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;                                                                                            if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);                                                                                            onSetUserDataEnabled(enabled);                                                                                            break;                                                                                        }                                                                            ...                                            
onTrySetupData ( Phone . REASON_DATA_ENABLED );
                                                                            protected void onSetUserDataEnabled(boolean enabled) {                                                                                    synchronized (mDataEnabledLock) {                                                                                        if (mUserDataEnabled != enabled) {                                                                                            mUserDataEnabled = enabled;                                                                                            Settings.Global.putInt(mPhone.getContext().getContentResolver(),                                                                                                    Settings.Global.MOBILE_DATA + mPhone.getPhoneId(), enabled ? 1 : 0);                                                                                            if (getDataOnRoamingEnabled() == false &&                                                                                                    mPhone.getServiceState().getRoaming() == true) {                                                                                                if (enabled) {                                                                                                    notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);                                                                                                } else {                                                                                                    notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);                                                                                                }                                                                                            }                                                                                                                                                                         if (enabled) {                                                                                                onTrySetupData(Phone.REASON_DATA_ENABLED);                                                                                            } else {                                                                                                onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);                                                                                            }                                                                                        }                                                                                    }                                                                                }                                            

android/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.java setupDataOnConnectableApns ( reason );
                                                                            @Override                                                                                // TODO: We shouldnt need this.                                                                                protected boolean onTrySetupData(String reason) {                                                                                    if (DBG) log("onTrySetupData: reason=" + reason);                                                                                    setupDataOnConnectableApns(reason);                                                                                    return true;                                                                                }                                            
trySetupData ( apnContext );
                                                                            private void setupDataOnConnectableApns(String reason) {                                                                                    if (DBG) log("setupDataOnConnectableApns: " + reason);                                                                                                                                                                 for (ApnContext apnContext : mPrioritySortedApnContexts) {                                                                                        if (DBG) log("setupDataOnConnectableApns: apnContext " + apnContext);                                                                                        if (apnContext.getState() == DctConstants.State.FAILED) {                                                                                            apnContext.setState(DctConstants.State.IDLE);                                                                                        }                                                                                        if (apnContext.isConnectable()) {                                                                                            log("setupDataOnConnectableApns: isConnectable() call trySetupData");                                                                                            apnContext.setReason(reason);                                                                                            trySetupData(apnContext);                                                                                        }                                                                                    }                                                                                }                                            
下面这个方法比较长,有很多条件的检查 boolean retValue = setupData ( apnContext , radioTech );
                                                                                                                                                         private boolean trySetupData(ApnContext apnContext) {                                                                                    ...                                                                                                                        if                                                         (                            apnContext                            .                            isConnectable                            ()                                                         &&                                                         (                            isEmergencyApn                             ||                                                                                                                         (isDataAllowed(apnContext) &&                                                                                            getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) {                                                                                        if (apnContext.getState() == DctConstants.State.FAILED) {                                                                                            if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");                                                                                            apnContext.setState(DctConstants.State.IDLE);                                                                                        }                                                                                        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();                                                                                        if (apnContext.getState() == DctConstants.State.IDLE) {                                                                                                                                                                         ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType(),                                                                                                    radioTech);                                                                                            if (waitingApns.isEmpty()) {                                                                                                notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);                                                                                                notifyOffApnsOfAvailability(apnContext.getReason());                                                                                                if (DBG) log("trySetupData: X No APN found retValue=false");                                                                                                return false;                                                                                            } else {                                                                                                apnContext.setWaitingApns(waitingApns);                                                                                                if (DBG) {                                                                                                    log ("trySetupData: Create from mAllApnSettings : "                                                                                                                + apnListToString(mAllApnSettings));                                                                                                }                                                                                            }                                                                                        }                                                                                                                                                                     if (DBG) {                                                                                            log("trySetupData: call setupData, waitingApns : "                                                                                                    + apnListToString(apnContext.getWaitingApns()));                                                                                        }                                                                                        boolean retValue = setupData(apnContext, radioTech);//7                                                                                        notifyOffApnsOfAvailability(apnContext.getReason());                                                                                                                                                                     if (DBG) log("trySetupData: X retValue=" + retValue);                                                                                        return retValue;                                                                                    } else {                                                                                        if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)                                                                                                && apnContext.isConnectable()) {                                                                                            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());                                                                                        }                                                                                        notifyOffApnsOfAvailability(apnContext.getReason());                                                                                        if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");                                                                                        return false;                                                                                    }                                                                                }                                            
dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation, msg );
                                                                         private boolean setupData(ApnContext apnContext, int radioTech) {                                                                                    if (DBG) log("setupData: apnContext=" + apnContext);                                                                                    ApnSetting apnSetting;                                                                                    DcAsyncChannel dcac = null;                                                                                                                                                                 apnSetting = apnContext.getNextWaitingApn();                                                                                    if (apnSetting == null) {                                                                                        if (DBG) log("setupData: return for no apn found!");                                                                                        return false;                                                                                    }                                                                                                                                                                 int profileId = apnSetting.profileId;                                                                                    if (profileId == 0) {                                                                                        profileId = getApnProfileID(apnContext.getApnType());                                                                                    }                                                                                                                                                                 // On CDMA, if we're explicitly asking for DUN, we need have                                                                                    // a dun-profiled connection so we can't share an existing one                                                                                    // On GSM/LTE we can share existing apn connections provided they support                                                                                    // this type.                                                                                    if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||                                                                                            teardownForDun() == false) {                                                                                        dcac = checkForCompatibleConnectedApnContext(apnContext);                                                                                        if (dcac != null) {                                                                                            // Get the dcacApnSetting for the connection we want to share.                                                                                            ApnSetting dcacApnSetting = dcac.getApnSettingSync();                                                                                            if (dcacApnSetting != null) {                                                                                                // Setting is good, so use it.                                                                                                apnSetting = dcacApnSetting;                                                                                            }                                                                                        }                                                                                    }                                                                                    if (dcac == null) {                                                                                        if (isOnlySingleDcAllowed(radioTech)) {                                                                                            if (isHigherPriorityApnContextActive(apnContext)) {                                                                                                if (DBG) {                                                                                                    log("setupData: Higher priority ApnContext active.  Ignoring call");                                                                                                }                                                                                                return false;                                                                                            }                                                                                                                                                                         // Only lower priority calls left.  Disconnect them all in this single PDP case                                                                                            // so that we can bring up the requested higher priority call (once we receive                                                                                            // repsonse for deactivate request for the calls we are about to disconnect                                                                                            if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {                                                                                                // If any call actually requested to be disconnected, means we can't                                                                                                // bring up this connection yet as we need to wait for those data calls                                                                                                // to be disconnected.                                                                                                if (DBG) log("setupData: Some calls are disconnecting first.  Wait and retry");                                                                                                return false;                                                                                            }                                                                                                                                                                         // No other calls are active, so proceed                                                                                            if (DBG) log("setupData: Single pdp. Continue setting up data call.");                                                                                        }                                                                                                                                                                     dcac = findFreeDataConnection();                                                                                                                                                                     if (dcac == null) {                                                                                            dcac = createDataConnection();                                                                                        }                                                                                                                                                                     if (dcac == null) {                                                                                            if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");                                                                                            return false;                                                                                        }                                                                                    }                                                                                    if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);                                                                                                                                                                 apnContext.setDataConnectionAc(dcac);                                                                                    apnContext.setApnSetting(apnSetting);                                                                                    apnContext.setState(DctConstants.State.CONNECTING);                                                                                    mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());                                                                                                                                                                 Message msg = obtainMessage();                                                                                    msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;                                                                                    msg.obj = apnContext;                                                                                    dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,                                                                                            msg);//8                                                                                                                                                                 if (DBG) log("setupData: initing!");                                                                                    return true;                                                                                }                                            

android/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java
sendMessage
                                                                            /**                                                                                 * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.                                                                                 * Used for cellular networks that use Acesss Point Names (APN) such                                                                                 * as GSM networks.                                                                                 *                                                                                 * @param apnContext is the Access Point Name to bring up a connection to                                                                                 * @param initialMaxRetry the number of retires for initial bringup.                                                                                 * @param profileId for the conneciton                                                                                 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.                                                                                 *        With AsyncResult.userObj set to the original msg.obj,                                                                                 *        AsyncResult.result = FailCause and AsyncResult.exception = Exception().                                                                                 */                                                                                public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId,                                                                                        int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) {                                                                                    if (DBG) {                                                                                        log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry                                                                                            + " onCompletedMsg=" + onCompletedMsg);                                                                                    }                                                                                    sendMessage(DataConnection.EVENT_CONNECT,//9                                                                                                new ConnectionParams(apnContext, initialMaxRetry, profileId,                                                                                                        rilRadioTechnology, retryWhenSSChange, onCompletedMsg));                                                                                }                                            


android/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java 这其实是个状态即机 StateMachine,这个类或者或机制,本身也比较复杂,以后看明白了以后会单独在写一篇文章 现在是进入其中一个状态 DcInactiveState。 DcInactiveState processmesssage
onConnect ( mConnectionParams );
                                                                             /**                                                                                                 * The state machine is inactive and expects a EVENT_CONNECT.                                                                                                     */                                                                                                     private class DcInactiveState extends State {                                                                                                     ...                                                                                                                                                                                                          @Override                                                                                                     public boolean processMessage(Message msg) {                                                                                               ...                                                                                                                                                                                                                                                        case EVENT_CONNECT:                                                                                                if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT");                                                                                                ConnectionParams cp = (ConnectionParams) msg.obj;                                                                                                if (initConnection(cp)) {                                                                                                    onConnect(mConnectionParams);//10                                                                                                    transitionTo(mActivatingState);                                                                                                } else {                                                                                                    if (DBG) {                                                                                                        log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed");                                                                                                    }                                                                                                    notifyConnectCompleted(cp, DcFailCause.UNACCEPTABLE_NETWORK_PARAMETER,                                                                                                            false);                                                                                                }                                                                                                retVal = HANDLED;                                                                                                break;                                            
mPhone . mCi . setupDataCall
                                                                                                                                                         /**                                                                                 * Begin setting up a data connection, calls setupDataCall                                                                                 * and the ConnectionParams will be returned with the                                                                                 * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.                                                                                 *                                                                                 * @param cp is the connection parameters                                                                                 */                                                                                private void onConnect(ConnectionParams cp) {                                                                                    if (DBG) log("onConnect: carrier='" + mApnSetting.carrier                                                                                            + "' APN='" + mApnSetting.apn                                                                                            + "' proxy='" + mApnSetting.proxy + "' port='" + mApnSetting.port + "'");                                                                                                                                                                 // Check if we should fake an error.                                                                                    if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter  > 0) {                                                                                       ...                                                                                                                                                                }                                                                                                                                                                 mCreateTime = -1;                                                                                    mLastFailTime = -1;                                                                                    mLastFailCause = DcFailCause.NONE;                                                                                                                                                                 // The data profile's profile ID must be set when it is created.                                                                                    int dataProfileId;                                                                                    if (mApnSetting.getApnProfileType() == ApnProfileType.PROFILE_TYPE_OMH) {                                                                                        dataProfileId = mApnSetting.getProfileId() + RILConstants.DATA_PROFILE_OEM_BASE;                                                                                        log("OMH profile, dataProfile id = " + dataProfileId);                                                                                    } else {                                                                                        dataProfileId = cp.mProfileId;                                                                                    }                                                                                                                                                                 // msg.obj will be returned in AsyncResult.userObj;                                                                                    Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);                                                                                    msg.obj = cp;                                                                                                                                                                 int authType = mApnSetting.authType;                                                                                    if (authType == -1) {                                                                                        authType = TextUtils.isEmpty(mApnSetting.user) ? RILConstants.SETUP_DATA_AUTH_NONE                                                                                                : RILConstants.SETUP_DATA_AUTH_PAP_CHAP;                                                                                    }                                                                                                                                                                 String protocol;                                                                                    if (mPhone.getServiceState().getRoaming()) {                                                                                        protocol = mApnSetting.roamingProtocol;                                                                                    } else {                                                                                        protocol = mApnSetting.protocol;                                                                                    }                                                                                                                                                                 mPhone.mCi.setupDataCall(//11                                                                                            Integer.toString(cp.mRilRat + 2),                                                                                            Integer.toString(dataProfileId),                                                                                            mApnSetting.apn, mApnSetting.user, mApnSetting.password,                                                                                            Integer.toString(authType),                                                                                            protocol, msg);                                                                                }                                            

android/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java


--------------

更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. python起点网月票榜字体反爬案例
  3. Android进度条、自动提示框、下拉框动态数据加载
  4. Android(安卓)Adapter详解
  5. Android应用程序组件Content Provider在应用程序之间共享数据的
  6. Android(安卓)API开发之OpenGL开发之Android(安卓)OpenGL之使用G
  7. Android(安卓)- 小功能 - android手动开启或者关闭输入法
  8. android 摄像头图像数据YUV转Bitmap, 再转Base64
  9. Android之ScrollView嵌套ListView

随机推荐

  1. iOS 7 需要再和 Android(安卓)比什么
  2. Android后台保活套路分析
  3. Android(安卓)GpioService从app到驱动
  4. Android(安卓)SurfaceView小解
  5. Android(安卓)视频开发浅析
  6. 【Android您问我讲】Android(安卓)2.x中
  7. Android(安卓)Camera学习总结:如何在andro
  8. 自定义实现圆形播放进度条(android,飞一般
  9. “加一”项目总结--android使用篇(一)
  10. android AsyncTask用法简单简绍