android ndc,Android M shutdown流程

第一部分:关机事件的捕获

1,PhoneWindowManager捕获POWER按键

publicintinterceptKeyBeforeQueueing(KeyEventevent,intpolicyFlags){

...

caseKeyEvent.KEYCODE_POWER:{

...

result&=~ACTION_PASS_TO_USER;

isWakeKey=false;// wake-up will be handled separately

if(down){

interceptPowerKeyDown(event,interactive);

}else{

time_record=time_now;//Letv-U4 UFO-2382 :20160812

interceptPowerKeyUp(event,interactive,canceled);

}

break;

}

...

2,进入interceptPowerKeyDown处理,进入interactive mode

...

if(hasLongPressOnPowerBehavior()){

Messagemsg=mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

msg.setAsynchronous(true);

mHandler.sendMessageDelayed(msg,

ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());

}

...

MSG_POWER_LONG_PRESS MESSAGE,通过mHandler将由另外一个线程处理,mHandler是PolicyHandler的实例。来看mHandler的handleMessager怎么处理。

caseMSG_POWER_LONG_PRESS:

powerLongPress();

break;

3,进入powerLongPress,

privatevoidpowerLongPress(){

finalintbehavior=getResolvedLongPressOnPowerBehavior();

switch(behavior){

...

caseLONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:

mPowerKeyHandled=true;

performHapticFeedbackLw(null,HapticFeedbackConstants.LONG_PRESS,false);

sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);//关掉系统对话框

mWindowManagerFuncs.shutdown(behavior==LONG_PRESS_POWER_SHUT_OFF);

break;

}

}

从xml config可知,behavior为3,即LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM

./core/res/res/values/config.xml:721:    3

这里的mWindowManagerFuncs是在PhoneWindowManager的init()处赋值的

publicvoidinit(Contextcontext,IWindowManagerwindowManager,

WindowManagerFuncswindowManagerFuncs){

mContext=context;

mWindowManager=windowManager;

mWindowManagerFuncs=windowManagerFuncs;

...

到底谁调用了?

在WindowManagerService的构造函数中,调用initPolicy(),这里调用PhoneWindowManager的init

privatevoidinitPolicy(){

UiThread.getHandler().runWithScissors(newRunnable(){

@Override

publicvoidrun(){

WindowManagerPolicyThread.set(Thread.currentThread(),Looper.myLooper());

mPolicy.init(mContext,WindowManagerService.this,WindowManagerService.this);

}

},0);

}

由此可知,mWindowManagerFuncs.shutdown即为WindowManagerService.shutdown

即:

// Called by window manager policy. Not exposed externally.

@Override

publicvoidshutdown(booleanconfirm){

ShutdownThread.shutdown(mContext,confirm);

}

即进入,ShutdownThread这里面集中处理关机流程。

第二部分:ShutdownThread的处理

1,先看整体的关机流程

95ee04afe5463c09075b32786c9753bf.png

2,没什么太大疑问,主要分析MountService的关机流程。即上面流程的第9步流程

2.1,new出一个IMountShutdownObserver observer,等会mountService调用shutdown需要用到

2.2,mount.shutdown(observer);

进入mountService

@Override

publicvoidshutdown(finalIMountShutdownObserverobserver){

Slog.i(TAG,"Shutting down");

mHandler.obtainMessage(H_SHUTDOWN,observer).sendToTarget();

}

2.3,交由MountService的MountServiceHanler处理

caseH_SHUTDOWN:{

finalIMountShutdownObserverobs=(IMountShutdownObserver)msg.obj;

booleansuccess=false;

try{

success=mConnector.execute("volume","shutdown").isClassOk();

}catch(NativeDaemonConnectorExceptionignored){

}

if(obs!=null){

try{

obs.onShutDownComplete(success?0:-1);

}catch(RemoteExceptionignored){

}

}

break;

}

obs就是ShutdownThread传过来的。调用onShutDownComplete反馈状态给ShutdownThread,如果successful,打印如下:

W/ShutdownThread( 3630): Result code 0 from MountService.shutdown

这个返回值是底层执行”volume” “shutdown”的结果。关机超时,有时候是mount Service执行volume shutdown超时,此时可以跟踪Connector的打印

}

03-15 09:52:28.681 E/VoldConnector( 3630): NDC Command {8 volume shutdown} took too long (11412ms)

2.4,再回到ShutdownThread,执行到MountService的shutdown会回调observer的onShutdownComplete函数,会调用actionDone(),这是用于线程同步用的

voidactionDone(){

synchronized(mActionDoneSync){

mActionDone=true;

mActionDoneSync.notifyAll();

}

}

mActionDoneSync就是一个Object, private final Object mActionDoneSync = new Object();

调用到actionDone时,所有wait在这个变量上的进程,都继续执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值