【从应用层到Framework】移动网络开启关闭数据访问流程

本文转自:http://blog.sina.com.cn/s/blog_40d475e901016t41.html


最近整理下启用数据和关闭数据连接的代码,将流程发出来,方便查看

 

下面是在真机上抓到的log,机器是锐合的X9,平台厂商是Marvell。(给公司打个广告【从应用层到Framework】移动网络开启关闭数据访问流程

通过log的TAG,相信各位很容易就找的到对应的源码文件,这里就不提供源码文件路径了

本文主要体现业务流程,具体函数功能就不详细介绍了,相信大家就是光看函数名也能猜到用途

 

D/GsmUmtsOptions( 1477): preferenceTreeClick: return false

D/NetworkSettings( 1477): onPreferenceTreeClick: preference == mButtonDataEnabled.

D/ConnectivityService( 1396): setMobileDataEnabled(false)

D/ConnectivityService( 1396): tearing down Mobile data state: CONNECTED

D/DataConnectionTracker( 1477): disableApnType(default)

D/DataConnectionTracker( 1477): setEnabled(0, false) with old state = true and enabledCount = 1

D/DataConnectionTracker( 1477): GSMDataConnTrack handleMessage { what=23 when=-30ms }

D/DataConnectionTracker( 1477): EVENT_APN_ENABLE_REQUEST 0, 0
D/DataConnectionTracker( 1477):  dataEnabled = true, enabledCount = 1, isApnTypeActive = true

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] Clean up connection due to dataDisabled
D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] cleanUpConnection: teardown, call conn.disconnect

D/GSM     ( 1519): [GsmDataConnection-1] DcActiveState msg.what=EVENT_DISCONNECT
D/GSM     ( 1519): [GsmDataConnection-1] tearDownData radio is on, call deactivateDataCall

D/RILJ    ( 1519): [0100]> DEACTIVATE_DATA_CALL 1

 

下面就是data call的代码流程了,本文以去激活为例,即disable

1、在设置中取消“已启用数据”的选中状态

D/GsmUmtsOptions( 1477): preferenceTreeClick: return false

D/NetworkSettings( 1477): onPreferenceTreeClick: preference == mButtonDataEnabled.
cm.setMobileDataEnabled(mButtonDataEnabled.isChecked());

 

2、进入Framework了,如何从ConnectivityManager到ConnectivityService,请大家参考源码

D/ConnectivityService( 1396): setMobileDataEnabled(false)
    public void setMobileDataEnabled(boolean enabled) {
        enforceChangePermission();
        if (DBG) Slog.d(TAG, "setMobileDataEnabled(" + enabled + ")");

        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
            (enabled ? ENABLED : DISABLED), 0));
}

                case EVENT_SET_MOBILE_DATA:
                {
                    boolean enabled = (msg.arg1 == ENABLED);
                    handleSetMobileData(enabled);
                    break;
                }

 

3、收到EVENT_SET_MOBILE_DATA消息,调用tear down
D/ConnectivityService( 1396): tearing down Mobile data state: CONNECTED

                case EVENT_SET_MOBILE_DATA:
                {
                    boolean enabled = (msg.arg1 == ENABLED);
                    handleSetMobileData(enabled);
                    break;
                }

    private void handleSetMobileData(boolean enabled) {
        if (getMobileDataEnabled() == enabled) return;

        Settings.Secure.putInt(mContext.getContentResolver(),
                Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);

        if (enabled) {
            if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
                if (DBG) {
                    Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]);
                }
                mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect();
            }
            if (mNetTrackers[ConnectivityManager.TYPE_WIMAX] != null) {
                if (DBG) {
                    Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_WIMAX]);
                }
                mNetTrackers[ConnectivityManager.TYPE_WIMAX].reconnect();
            }
        } else {
            for (NetworkStateTracker nt : mNetTrackers) {
                if (nt == null) continue;
                int netType = nt.getNetworkInfo().getType();
                if (mNetAttributes[netType].mRadio == ConnectivityManager.TYPE_MOBILE && mNetAttributes[netType].isDefault()) {
                    if (DBG) Slog.d(TAG, "tearing down " + nt);
                    nt.teardown();
                }
            }
            if (mNetTrackers[ConnectivityManager.TYPE_WIMAX] != null) {
                mNetTrackers[ConnectivityManager.TYPE_WIMAX].teardown();
            }
        }
}

 

4、进入MobileDataStateTracker

public class MobileDataStateTracker extends NetworkStateTracker {
    public boolean teardown() {
        // since we won't get a notification currently (TODO - per APN notifications)
        // we won't get a disconnect message until all APN's on the current connection's
        // APN list are disabled.  That means privateRoutes for DNS and such will remain on -
        // not a problem since that's all shared with whatever other APN is still on, but
        // ugly.
        setTeardownRequested(true);
        return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
}

    private int setEnableApn(String apnType, boolean enable) {
        getPhoneService(false);
       
        for (int retry = 0; retry < 2; retry++) {
            if (mPhoneService == null) {
                Log.w(TAG,
                    "Ignoring feature request because could not acquire PhoneService");
                break;
            }

            try {
                if (enable) {
                    return mPhoneService.enableApnType(apnType);
                } else {
                    return mPhoneService.disableApnType(apnType);
                }
            } catch (RemoteException e) {
                if (retry == 0) getPhoneService(true);
            }
        }

        Log.w(TAG, "Could not " + (enable ? "enable" : "disable")
                + " APN type "" + apnType + """);
        return Phone.APN_REQUEST_FAILED;
    }
}

 

5、进入DataConnectionTracker,从mPhoneService到PhoneBase,PhoneBase中调用DataConnectionTracker的disableApnType


D/DataConnectionTracker( 1477): disableApnType(default)

    public synchronized int disableApnType(String type) {
        if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");
        int id = apnTypeToId(type);
        if (id == APN_INVALID_ID) {
            return Phone.APN_REQUEST_FAILED;
        }
        if (isEnabled(id)) {
            setEnabled(id, false);
            return Phone.APN_REQUEST_STARTED;
        } else {
            return Phone.APN_REQUEST_FAILED;
        }
}

 

6、发送EVENT_ENABLE_NEW_APN
D/DataConnectionTracker( 1477): setEnabled(0, false) with old state = true and enabledCount = 1


    private void setEnabled(int id, boolean enable) {
        if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = " +
                dataEnabled[id] + " and enabledCount = " + enabledCount[id]);

     if(isApnTypeActive(apnIdToType(id))==false) {
           enabledCount[id] = 0;
           dataEnabled[id] = false;
        }

        Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);
        msg.arg1 = id;
        msg.arg2 = (enable ? ENABLED : DISABLED);
        sendMessage(msg);
}

 

7、处理EVENT_ENABLE_NEW_APN消息,调用onEnableApn,再调用onCleanUpConnection,再调用cleanUpConnection
D/DataConnectionTracker( 1477): GSMDataConnTrack handleMessage { what=23 when=-30ms }

            case EVENT_ENABLE_NEW_APN:
                onEnableApn(msg.arg1, msg.arg2);
                break;

 

D/DataConnectionTracker( 1477): EVENT_APN_ENABLE_REQUEST 0, 0
D/DataConnectionTracker( 1477):  dataEnabled = true, enabledCount = 1, isApnTypeActive = true

    protected synchronized void onEnableApn(int apnId, int enabled) {
        if (DBG) {
            Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);
            Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] +
      ", enabledCount = " + enabledCount[apnId] +
                    ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));

        }
        if (enabled == ENABLED) {
            if (!dataEnabled[apnId]) {
                dataEnabled[apnId] = true;
                enabledCount[apnId] = 1;
            } else {
                enabledCount[apnId]++;
            }

            String type = apnIdToType(apnId);
            if (enabledCount[apnId] == 1) { //first time to enable this apn
                onEnableNewApn(apnId);
            }
            Log.d(LOG_TAG, "updated after enabled: dataEnabled = " + dataEnabled[apnId] +
      ", enabledCount = " + enabledCount[apnId] +
                    ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
        } else {
            // disable
            if (dataEnabled[apnId]) {
                    enabledCount[apnId] = 0;
                    dataEnabled[apnId] = false;
                    onCleanUpConnection(apnId, Phone.REASON_DATA_DISABLED);
            }
            Log.d(LOG_TAG, "updated after disabled: dataEnabled = " + dataEnabled[apnId] +
      ", enabledCount = " + enabledCount[apnId] +
                    ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
        }
}

    protected void onCleanUpConnection(int apnId, String reason) {
        cleanUpConnection(apnId, reason);
    }

 

8、 调用disconnect

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] Clean up connection due to dataDisabled
D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] cleanUpConnection: teardown, call conn.disconnect

    private void cleanUpConnection(int apnId, String reason) {
        if (DBG) log("Clean up connection due to " + reason);

        if (perPdpState[apnId]== State.DISCONNECTING) {
        if (DBG) log("cleanUpConnection: linda check State is Disconnecting, not set disconnecting again");
            return;
        }

        if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
        if(mActivePdp[apnId] != null) {
            setState(apnId,State.DISCONNECTING);
            requestParams para = new requestParams(apnId, reason);
            if(!isActivePdpShared(apnId)) {
                if (DBG) log("cleanUpConnection: conn.disconnect");
                removeFromActiveApnList(mActivePdp[apnId].getApn());
                mActivePdp[apnId].disconnect(obtainMessage(EVENT_DISCONNECT_DONE, para));
                mActivePdp[apnId] = null;
           } else {
               if (DBG) log("cleanUpConnection: conn is shared, don't disconnect it");
               setState(apnId,State.IDLE);
               mActivePdp[apnId] = null;
               phone.notifyDataConnection(reason);
           }
        } else {
          setState(apnId,State.IDLE);
          phone.notifyDataConnection(reason);
        }
   }

 

9、发送消息EVENT_DISCONNECT,调用tearDownData,调用deactivateDataCall
D/GSM     ( 1519): [GsmDataConnection-1] DcActiveState msg.what=EVENT_DISCONNECT
D/GSM     ( 1519): [GsmDataConnection-1] tearDownData radio is on, call deactivateDataCall


public abstract class DataConnection extends HierarchicalStateMachine {
    public void disconnect(Message onCompletedMsg) {
    sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(onCompletedMsg)));
}

                case EVENT_DISCONNECT:
                    if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT");
                    DisconnectParams dp = (DisconnectParams) msg.obj;
                    dp.tag = mTag;
                    tearDownData(dp);
                    transitionTo(mDisconnectingState);
                    retVal = true;
                    break;

 

    private void tearDownData(Object o) {
        if (phone.mCM.getRadioState().isOn()) {
            if (DBG) log("tearDownData radio is on, call deactivateDataCall");
          phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, o));
        } else {
            if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");
            AsyncResult ar = new AsyncResult(o, null, null);
            sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, ar));
        }
    }

}

 

10、调用RIL的deactivateDataCall,发送原语RIL_REQUEST_DEACTIVATE_DATA_CALL

D/RILJ    ( 1519): [0100]> DEACTIVATE_DATA_CALL 1

public final class RIL extends BaseCommands implements CommandsInterface {
    public void
    deactivateDataCall(int cid, Message result) {
        RILRequest rr
                = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);

        rr.mp.writeInt(1);
        rr.mp.writeString(Integer.toString(cid));

        if (RILJ_LOGD) riljLog(rr.serialString() + "> " +
                requestToString(rr.mRequest) + " " + cid);

        send(rr);
    }
}


11、下面的流程就是各个厂商要实现的RIL部分,即AT命令实现部分了,这部分代码就不放上去了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值