android 5.1

在Java层,Radio只有三种状态:

    enum RadioState {        RADIO_OFF,         /* Radio explicitly powered off (eg CFUN=0) */        RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */        RADIO_ON;          /* Radio is on */        public boolean isOn() /* and available...*/ {            return this == RADIO_ON;        }        public boolean isAvailable() {            return this != RADIO_UNAVAILABLE;        }    }

在C层,radio有多个状态:

状态转换在RIL.java中的getRadioStateFromInt方法中


第一,在rild和RILJ中,radio初始状态都是UNAVAILABLE

rild进程启动时,radio的状态默认会设置为RADIO_STATE_UNAVAILABLE

reference-ril.c

static RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;


RILJ初始化时,Radio状态为RADIO_UNAVAILABLE

BaseCommands.java

protected RadioState mState = RadioState.RADIO_UNAVAILABLE;


第二,rild进程初始化过程中,设置radio状态为OFF

1. rild.cpp main()

rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");funcs = rilInit(&s_rilEnv, argc, rilArgv);

2. reference-ril.c

ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);static void initializeCallback(void *param __unused)setRadioState (RADIO_STATE_OFF);

第三,rild中,radio状态切换为OFF后,会通知RILJ

        RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,                                    NULL, 0);        // Sim state can change as result of radio state change        RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,                                    NULL, 0);

第四,RILJ收到radio的新状态,会去通知关心RadioStateChange和RadioAvailable的订阅者

case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:    /* has bonus radio state int */    RadioState newState = getRadioStateFromInt(p.readInt());    if (RILJ_LOGD) unsljLogMore(response, newState.toString());    switchToRadioState(newState);private void switchToRadioState(RadioState newState) {    setRadioState(newState);}protected void setRadioState(RadioState newState) {    mRadioStateChangedRegistrants.notifyRegistrants();    if (mState.isAvailable() && !oldState.isAvailable()) {        mAvailRegistrants.notifyRegistrants();        onRadioAvailable();    }}

第五,只有ServiceStateTracker关心RadioStateChange,它会请求RILJ去打开radio

忽略RadioAvailable的订阅者,同时也忽略CDMA,只关注GSM

GsmServiceStateTracker.java

public GsmServiceStateTracker(GSMPhone phone) {    mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);    // system setting property AIRPLANE_MODE_ON is set in Settings.    int airplaneMode = Settings.Global.getInt(            phone.getContext().getContentResolver(),            Settings.Global.AIRPLANE_MODE_ON, 0);    mDesiredPowerState = ! (airplaneMode > 0);}case EVENT_RADIO_STATE_CHANGED:    // This will do nothing in the radio not    // available case    setPowerStateToDesired();    pollState();    break;protected void setPowerStateToDesired() {    // If we want it on and it's off, turn it on    if (mDesiredPowerState && mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {        mCi.setRadioPower(true, null);    }}

第六,RILJ去和rild通信,请求打开radio:RIL_REQUEST_RADIO_POWER

注意:GSMSST虽然通过RILJ向rild发送request,但它并不关心返回的结果,所以Msg是null,它是通过订阅来得到相应的结果

setRadioPower(boolean on, Message result) {    RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);    rr.mParcel.writeInt(1);    rr.mParcel.writeInt(on ? 1 : 0);    send(rr);}

第七,rild去打开radio

通过AT命令打开radio:AT+CFUN=1

检查radio当前的状态:AT+CFUN?

最重要的是setRadioState(RADIO_STATE_ON);

它会通知到RILJ,radio状态又改变啦

RILJ向rild的每个Request,rild都会发回RESPONSE_SOLICITED给RILJ,但对于radio,RILJ不关心SOLICITE,只关心RESPONSE_UNSOLICITED

reference-ril.cstatic void onRequest (int request, void *data, size_t datalen, RIL_Token t){case RIL_REQUEST_RADIO_POWER:requestRadioPower(data, datalen, t);break;}static void requestRadioPower(void *data, size_t datalen, RIL_Token t){    int onOff = ((int *)data)[0];    if (onOff > 0 && sState == RADIO_STATE_OFF) {        err = at_send_command("AT+CFUN=1", &p_response);        if (err < 0|| p_response->success == 0) {            // Some stacks return an error when there is no SIM,            // but they really turn the RF portion on            // So, if we get an error, let's check to see if it            // turned on anyway            if (isRadioOn() != 1) {                goto error;            }        }        setRadioState(RADIO_STATE_ON);    }    at_response_free(p_response);    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);    return;}/** returns 1 if on, 0 if off, and -1 on error */static int isRadioOn(){    err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);    line = p_response->p_intermediates->line;    err = at_tok_start(&line);    err = at_tok_nextbool(&line, &ret);    return (int)ret;}

第八,rild又要去通知RILJ

于之前setradio OFF不同的是,此时可以去获取SIM卡的状态啦

static void setRadioState(RIL_RadioState newState){RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);if (sState == RADIO_STATE_ON) {onRadioPowerOn();}}static void onRadioPowerOn(){pollSIMState(NULL);}

第九,RILJ要把事件发给订阅radostatechanged的和radioon的

protected void setRadioState(RadioState newState) {    mRadioStateChangedRegistrants.notifyRegistrants();    if (mState.isOn() && !oldState.isOn()) {        mOnRegistrants.notifyRegistrants();    }}
但这一回,GSMSST什么也没必要干了,除了再重新去pollState()


说说关心radio avaliable的吧:GSMPhone.java

在radio avaliable之后,去获取一些重要信息:BasebandVersion,IMEI,IMEISV,RadioCapability

mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);case EVENT_RADIO_AVAILABLE: {    mCi.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));    mCi.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE));    mCi.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE));    mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));}

说说关心radio on的吧:UiccController.java

这是SIM卡管理的核心类,看这注释你就直到它有多重要

 * Following is class diagram for uicc classes: * *                       UiccController *                            # *                            | *                        UiccCard *                          #   # *                          |   ------------------ *                    UiccCardApplication    CatService *                      #            # *                      |            | *                 IccRecords    IccFileHandler *                 ^ ^ ^           ^ ^ ^ ^ ^ *    SIMRecords---- | |           | | | | ---SIMFileHandler *    RuimRecords----- |           | | | ----RuimFileHandler *    IsimUiccRecords---           | | -----UsimFileHandler *                                 | ------CsimFileHandler *                                 ----IsimFileHandler

可以说,所有关于SIM相关的最重要的类,都在这里管理


更多相关文章

  1. Android(安卓)--- Activity生命周期
  2. Android设置通知栏/状态栏透明改变通知栏颜色和app最上部分颜色
  3. Android(安卓)热点开关状态的判断和获取热点ssid
  4. Android的网络状态判断
  5. Selector、shape详解(一)
  6. android 面试题集
  7. Android中获取屏幕相关信息(屏幕大小,状态栏、标题栏高度)
  8. Android电量和插拔电源状态广播监听
  9. Android(安卓)SDK自带教程之BluetoothChat

随机推荐

  1. android 广播的知识积累
  2. Android执行打开文件(PDF,PPT,WORD,EXCEL
  3. Android客户端通过GET和POST向服务器发送
  4. android之在启动运用程序的时候彻底隐藏T
  5. Android(安卓)RxJava创建操作符Timer的方
  6. android -------- 安装APK报错:Installati
  7. Android(安卓)App的国际化-代码里实现
  8. Android(安卓)8.1 【FriendlyARM】读取 B
  9. Android(安卓)打正式包报错:Execution fai
  10. Intent.ACTION_TIME_TICK的正确用法