Android 关机时的radio相关关闭流程

针对插单卡,开数据业务情况下radio关机流程分析。

先贴一下ShutdownThread的log:

05-24 03:48:17.226  1354  1354 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
05-24 03:48:17.298  1354  4205 I ShutdownThread: Sending shutdown broadcast...
05-24 03:48:17.422  1354  4205 I ShutdownThread: Shutting down activity manager...
05-24 03:48:17.500  1354  4205 I ShutdownThread: Shutting down package manager...
05-24 03:48:17.511  1354  4213 W ShutdownThread: Turning off cellular radios...
05-24 03:48:17.516  1354  4213 I ShutdownThread: Waiting for Radio...
05-24 03:48:18.422  1354  4213 I ShutdownThread: Radio turned off.
05-24 03:48:18.422  1354  4213 I ShutdownThread: Radio shutdown complete.
05-24 03:48:19.226  1354  4205 I ShutdownThread: Shutdown critical subsyslist is :modem : 
05-24 03:48:19.226  1354  4205 I ShutdownThread: Waiting for a maximum of 10000ms
05-24 03:48:19.227  1354  4205 I ShutdownThread: Vendor subsystem(s) shutdown successful
05-24 03:48:19.734  1354  4205 I ShutdownThread: Performing low-level shutdown...

每一步的耗时时间:

05-24 03:48:17.422  1354  4205 D ShutdownTiming: SendShutdownBroadcast took to complete: 124ms
05-24 03:48:17.500  1354  4205 D ShutdownTiming: ShutdownActivityManager took to complete: 77ms
05-24 03:48:17.509  1354  4205 D ShutdownTiming: ShutdownPackageManager took to complete: 9ms
05-24 03:48:18.422  1354  4213 D ShutdownTiming: ShutdownRadio took to complete: 911ms
05-24 03:48:18.422  1354  4205 D ShutdownTiming: ShutdownRadios took to complete: 914ms
//在rebootorShutdown函数前的每一步耗时
05-24 03:48:18.422  1354  4205 D ShutdownTiming: SystemServerShutdown took to complete: 1133ms

ShutdownThread.shutdown()

Notifying thread to start shutdown longPressBehavior=1 打印出现在shutdownInner函数中。当重启或关机时会分别触发shutdown或reboot函数。最终都会走到shutdownInner函数。shutdownInner函数会触发ShutdownThread 中static实例的start函数。因为其继承自thread,所以会触发run函数。

关机画面

shutdownInner中调用beginShutdownSequence
确保此函数只进入一次。在这里插入图片描述
接着调用showShutdwonDialog()判断是否去显示关机动画。
在这里插入图片描述
然后触发ShutdownThread.run()

在这里插入图片描述

ShutdownThread.run()

发送广播

在这里插入图片描述
注意其在调用sendOrderedBraodcastAsUser的参数br,即在发送广播的同时,br会成为此广播的最后一个接受者。br的作用是为了确保所有上层应用都收到关机广播再走下面的流程。

等待广播发送完毕

br最后收到广播,将mActionDone设置为true。 run函数中轮询mActionDone,为true时退出,走下面的流程。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

关闭ActivityManager和PackageManager

在这里插入图片描述

关闭radio

调用shutdownRadio函数
在这里插入图片描述
shutdownRadio函数启动一个thread执行关闭radio的操作。

shutdownRadio

首先判断radio是否需要shutdown,若是则调用phone.shutdownMobileRadios来关闭radio。
在这里插入图片描述
然后轮询needMobileRadioShutdown()状态。如果radiooff则走下一步。
在这里插入图片描述

关闭radio

接下来针对关闭radio 重点分析一下流程。

判断是否需要关闭radio

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从上面截图可以知道,就是判断RIL.java的mState变量值。如果是RADIO_UNAVAILABLE则认为不需要关机,否则需要关机。

mState状态如何转变为UNAVAILABLE

有两个情况会变为UNAVAILBALBE:

radioIndication.java 被通知radioStateChanged时

在这里插入图片描述
对应log:

05-24 03:48:19.179  2128  2287 D RILJ    : [UNSL]< UNSOL_RESPONSE_RADIO_STATE_CHANGED radioStateChanged: RADIO_UNAVAILABLE [SUB0]
05-24 03:48:19.184  2128  2287 D RILJ    : [UNSL]< UNSOL_RESPONSE_RADIO_STATE_CHANGED radioStateChanged: RADIO_UNAVAILABLE [SUB1]

RIL_REQUEST_SHUTDOWN请求返回时

详细流程如下:
RILC 返回response时通过RadioResponse的对应接口返回。
对应RIL_REQUEST_SHUTDOWN是requestShutdownResponse().
在这里插入图片描述
在这里插入图片描述
在responseVoid函数中,先通过RIL.java的processResponse做一些处理。
然后通过sendMessageResponse通知AP上层的发送方,命令执行情况。
最后通过processResponseDone来打印收到的response信息。
在这里插入图片描述
在这里插入图片描述
对应log:

05-24 03:48:18.120  2128  2128 D RILJ    : [4151]> RIL_REQUEST_SHUTDOWN [SUB1]
05-24 03:48:18.124  2128  2128 D RILJ    : [4152]> RIL_REQUEST_SHUTDOWN [SUB1]
05-24 03:48:18.134  2128  2287 D RILJ    : [4151]< RIL_REQUEST_SHUTDOWN  [SUB1]
05-24 03:48:18.149  2128  2287 D RILJ    : [4152]< RIL_REQUEST_SHUTDOWN  [SUB1]
05-24 03:48:18.212  2128  2128 D RILJ    : [4153]> RIL_REQUEST_SHUTDOWN [SUB0]
05-24 03:48:18.214  2128  2128 D RILJ    : [4154]> RIL_REQUEST_SHUTDOWN [SUB0]
05-24 03:48:18.374  2128  2287 D RILJ    : [4153]< RIL_REQUEST_SHUTDOWN  [SUB0]
05-24 03:48:19.108  2128  2287 D RILJ    : [4154]< RIL_REQUEST_SHUTDOWN  [SUB0]

关闭radio

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
对应log:

05-24 03:48:17.513   SST   : [0] mDeviceShuttingDown=true, mDesiredPowerState=false, getRadioState=RADIO_ON, mPowerOffDelayNeed=true, mAlarmSwitch=false, mRadioDisabledByCarrier=false
05-24 03:48:17.515   SST   : [1] mDeviceShuttingDown=true, mDesiredPowerState=false, getRadioState=RADIO_ON, mPowerOffDelayNeed=true, mAlarmSwitch=false, mRadioDisabledByCarrier=false

当插单卡,开数据业务,接着调用poweOffRadioSafely()

开数据业务情况下poweOffRadioSafely流程

在这里插入图片描述
调用流程如下:
ShutDownThread.shutdownRadios()-》phone.shutdownMobileRadios (ITelephone–>PhoneInterfaceManager)->PhoneInterfaceManager.shutdownRadiosUsingID()->Phone.shutdownRadio()->ServiceStateTracker.requestShutDown()->setPowerStateToDesired()->powerOffRadioSafely->DcTracker.clearUpAllConnections() 同事registerForAllDataDisconnected(EVENT_All_DATA_DISCONNECTED)

即使 插单卡,只要有数据业务,两个sub都会调用dcTracker.cleanUpAllConnections()。 无卡的那个sub还会关注EVENT_All_DATA_DISCONNECTED。
在cleanUpAllConnections()中,针对每一个APN调用一次cleanUpConnection。mDisconnectPendingCount 在cleanUpConnection ()中会自加1.
在这里插入图片描述
cleanUpConnection 中tearDown apn。 mDisconnectPendingCount 自加1. 关闭成功后收到EVENT_DISCONNECT_DONE.
在这里插入图片描述
无卡sub 的cleanUpAllConnections中,直接调用notifyAllDataDisconnected().
数据业务sub data断开后触发onDisconnectDone,mDisconnectPendingCount 减1至0后,也调用notifyAllDataDisconnected。

数据业务卡是在onDisconnectDone中触发processPendingRadioPowerOffAfterDataOff().进而调用hangupAndPowerOff。
非数据业务卡,或无卡sub,在SST(serviceStateTracker) 处理EVENT_ALL_DATA_DISCONNTECD时调用hangupAndPowerOff
在这里插入图片描述
无卡sub等待EVENT_All_DATA_DISCONNECTED
在这里插入图片描述

log:

//不插卡,或无数据业务的卡。等待另一张卡关数据业务
05-24 03:48:17.516  2128  2412 D SST     : [1] Data is active on DDS.  Wait for all data disconnect

//两个sub 都等待30s,都会设置mPendingPowerOffAfterDataOff
05-24 03:48:17.514  2128  2412 D SST     : [0] Wait upto 30s for data to disconnect, then turn off radio.
05-24 03:48:17.516  2128  2412 D SST     : [1] Wait upto 30s for data to disconnect, then turn off radio.

//两个sub,一个无卡mDisconnectPendingCount 为0,一个volte和data两个apn,所以mDisconnectPendingCount = 2
05-24 03:48:17.515  2128  2128 D QtiDCT  : [0]cleanUpConnection: tearing down using gen#1apnContext={mApnType=default mState=CONNECTED mWaitingApns={[[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true}
05-24 03:48:17.515  2128  2128 D QtiDCT  : [0]cleanUpConnection: tearing down using gen#1apnContext={mApnType=ims mState=CONNECTED mWaitingApns={[[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true}
05-24 03:48:17.523  2128  2128 D QtiDCT  : [0]cleanUpConnection: mDisconnectPendingCount = 2
05-24 03:48:17.535  2128  2128 D QtiDCT  : [1]cleanUpConnection: mDisconnectPendingCount = 0

//使能数据业务的sub log,分别关闭数据和volte的apn
//QtiDcTracker.java继承自DcTracker.java,由于多态,调用基本是DcTracker的函数
05-24 03:48:17.568  2128  2128 D QtiDCT  : [0]getValidApnContext (onDisconnectDone) on {mApnType=ims mState=DISCONNECTING mWaitingApns={[[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true} got 1 vs 1
05-24 03:48:17.568  2128  2128 D QtiDCT  : [0]onDisconnectDone: EVENT_DISCONNECT_DONE apnContext={mApnType=ims mState=DISCONNECTING mWaitingApns={[[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] China Mobile (IMS), 2466, 46002, ims, , , , , , -1, ims, IPV4V6, IPV4V6, true, 0, 0, 2, true, 1023, 0, 300, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true}
05-24 03:48:17.583  2128  2128 D QtiDCT  : [0]onDisconnectDone: not retrying
05-24 03:48:17.600  2128  2128 D QtiDCT  : [0]getValidApnContext (onDisconnectDone) on {mApnType=default mState=DISCONNECTING mWaitingApns={[[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true} got 1 vs 1
05-24 03:48:17.600  2128  2128 D QtiDCT  : [0]onDisconnectDone: EVENT_DISCONNECT_DONE apnContext={mApnType=default mState=DISCONNECTING mWaitingApns={[[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0]} mApnSetting={[ApnSettingV5] APN_NAME_CMNET, 2463, 46002, cmnet, , , , , , -1, default | net | supl, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0} mReason=radioTurnedOff mDataEnabled=true mDependencyMet=true}
05-24 03:48:17.606  2128  2128 D SST     : [0] Process pending request to turn radio off.
05-24 03:48:17.608  2128  2128 D QtiDCT  : [0]onDisconnectDone: radio will be turned off, no retries

//数据业务sub调用hangupAndPowerOff
05-24 03:48:17.606  2128  2128 D SST     : [0] Process pending request to turn radio off.

//非数据业务sub调用hangupAndPowerOff
05-24 03:48:17.610  2128  2128 D SST     : [1] EVENT_ALL_DATA_DISCONNECTED, turn radio off now.

hangupAndPoweroff

最终是向ril发送RIL_REQUEST_RADIO_POWER
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
qcril_qmi_nas_request_power
在这里插入图片描述
对应log:

05-24 03:48:17.608  2128  2128 D RILJ    : [4127]> RADIO_POWER on = false [SUB0]
05-24 03:48:17.612  2128  2128 D RILJ    : [4128]> RADIO_POWER on = false [SUB1]
05-24 03:48:17.997  2128  2287 D RILJ    : [4128]< RADIO_POWER  [SUB1]
05-24 03:48:18.003  2128  2287 D RILJ    : [4127]< RADIO_POWER  [SUB0]
05-24 03:48:18.117  2128  2128 D SST     : [1] EVENT_RADIO_POWER_OFF_DONE
05-24 03:48:18.210  2128  2128 D SST     : [0] EVENT_RADIO_POWER_OFF_DONE

成功power radio后的流程:

SST会收到EVENT_RADIO_POWER_OFF_DONE。
在这里插入图片描述
调用requestShutDown。又会走到ril。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

里面涉及到一个shutdown的状态机。
在这里插入图片描述
这个状态机如何触发ril内部模块shutdown呢?以内部的关卡状态为例。

在这里插入图片描述
在这里将UimCardPowerReqMsg命令发出。
在这里插入图片描述
最终UimModule模块处理。
在这里插入图片描述

在这里插入图片描述
最终发送出去,由UimModemEndpointModule处理:
在这里插入图片描述
在这里插入图片描述
最终通过qmi发送QMI_UIM_POWER_DOWN_REQ命令给modem。真是一个弯弯曲曲的流程。
在这里插入图片描述

在这里插入图片描述

RIL_REQUEST_SHUTDOWN执行完毕

不管ril内部的复杂流程。当执行完后,会通知上层么?
从代码看,调用是没有提供参数。所以不会通知上层。但是后续radio状态机会发生变化。
在这里插入图片描述
并且RIL_REQUEST_SHUTDOWN 处理完毕后 ,RIl.java 会处理。也会将Radio状态设置为unavailable。所以发送shutdown后,终端在radio还没有到unavailabe时,ril层就提前转到unavialable了。
在这里插入图片描述

05-24 03:48:18.120  2128  2128 D RILJ    : [4151]> RIL_REQUEST_SHUTDOWN [SUB1]
05-24 03:48:18.124  2128  2128 D RILJ    : [4152]> RIL_REQUEST_SHUTDOWN [SUB1]
05-24 03:48:18.134  2128  2287 D RILJ    : [4151]< RIL_REQUEST_SHUTDOWN  [SUB1]
05-24 03:48:18.149  2128  2287 D RILJ    : [4152]< RIL_REQUEST_SHUTDOWN  [SUB1]
05-24 03:48:18.212  2128  2128 D RILJ    : [4153]> RIL_REQUEST_SHUTDOWN [SUB0]
05-24 03:48:18.214  2128  2128 D RILJ    : [4154]> RIL_REQUEST_SHUTDOWN [SUB0]
05-24 03:48:18.374  2128  2287 D RILJ    : [4153]< RIL_REQUEST_SHUTDOWN  [SUB0]
// radio state 变为 unavialable是 03:48:19.175,但是由于RIL_REQUEST_SHUTDOWN  03:48:18.374时已经都执行完了。所以ShutdownThread的轮询认为radio turned off。在shutdownRadios中出现如下打印
05-24 03:48:18.422  1354  4213 I ShutdownThread: Radio turned off.
05-24 03:48:18.422  1354  4213 I ShutdownThread: Radio shutdown complete.
05-24 03:48:19.108  2128  2287 D RILJ    : [4154]< RIL_REQUEST_SHUTDOWN  [SUB0]
05-24 03:48:18.001  1208  1269 D RILC    : radioStateChangedInd: radioState 0
05-24 03:48:18.006  1193  1255 D RILC    : radioStateChangedInd: radioState 0
05-24 03:48:19.175  1193  1255 D RILC    : radioStateChangedInd: radioState 1
05-24 03:48:19.182  1208  1269 D RILC    : radioStateChangedInd: radioState 1

最后一步 rebootOrShutdown

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章