android 关机 流程_Android O关机流程

本文详细分析了Android O系统中关机流程,从Power键按下到设备关闭的每个步骤,包括Power键处理、GlobalActions对话框显示以及关机线程的执行。通过理解这一流程,解决了关机过程中Power键导致的屏幕熄屏、亮屏问题。
摘要由CSDN通过智能技术生成

Android O关机流程

问题起因

*今天测试提出了一个问题,关机过程中(播放关机动画)按Power键可以熄屏、亮屏。

解决方案

*首先我想应该从关机流程开始吧,然后自己一步步跟进代码,修改framework代码逻辑,在关机时,禁用Power键

关机流程

想必都很清楚正常关机是如何操作的,按Power键来确定关机,这里首先来分析一下PhoneWindowManager这个类,这个类Power、volum等事件处理

PhoneWindowManager.java

public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {

...

switch (keyCode) {

...

case KeyEvent.KEYCODE_POWER: {

// Any activity on the power button stops the accessibility shortcut

cancelPendingAccessibilityShortcutAction();

result &= ~ACTION_PASS_TO_USER;

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

if (down) {

interceptPowerKeyDown(event, interactive);

} else {

interceptPowerKeyUp(event, interactive, canceled);

}

break;

}

...

}

}

因为是按下Power走的interceptPowerKeyDown这个函数。

private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {

...

if (!mPowerKeyHandled) {

if (interactive) {

// When interactive, we're already awake.

// Wait for a long press or for the button to be released to decide what to do.

if (hasLongPressOnPowerBehavior()) {

Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

msg.setAsynchronous(true);

mHandler.sendMessageDelayed(msg,

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

}

} else {

wakeUpFromPowerKey(event.getDownTime());

if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {

Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

msg.setAsynchronous(true);

mHandler.sendMessageDelayed(msg,

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

mBeganFromNonInteractive = true;

} else {

final int maxCount = getMaxMultiPressPowerCount();

if (maxCount <= 1) {

mPowerKeyHandled = true;

} else {

mBeganFromNonInteractive = true;

}

}

}

}

}

直接看关键部分,判断是否是LongPress,是的话就通过Handler发送消息处理,追踪到mHandler,handlemessage里面调用powerLongPress()这个私有函数来处理长按power。

private void powerLongPress() {

final int behavior = getResolvedLongPressOnPowerBehavior();

switch (behavior) {

case LONG_PRESS_POWER_NOTHING:

break;

case LONG_PRESS_POWER_GLOBAL_ACTIONS:

mPowerKeyHandled = true;

if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {

performAuditoryFeedbackForAccessibilityIfNeed();

}

showGlobalActionsInternal();

break;

case LONG_PRESS_POWER_SHUT_OFF:

case LONG_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;

}

}

将mPowerKeyHandled设置为true表示这个行为已经被处理了,其实是正在处理。showGlobalActionsInternal()这个函数我想应该就是处理长按power显示的对话框吧。

void showGlobalActionsInternal() {

sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);

if (mGlobalActions == null) {

mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);

}

final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();

mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());

if (keyguardShowing) {

// since it took two seconds of long press to bring this up,

// poke the wake lock so they have some time to see the dialog.

mPowerManager.userActivity(SystemClock.uptimeMillis(), false);

}

}

果不其然,创建了GlobalActions类对象,而从注释该类介绍来看是一个创建全局对话框的帮助类,构造方法中获得各种系统服务,其中有AudioManager、WindowManagerFuncs,其中关机我们应该看的是WindowManagerFuncs这个服务,他获取的是WindowManagerService。再来看showDialog这个方法。

public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {

mKeyguardShowing = keyguardShowing;

mDeviceProvisioned = isDeviceProvisioned;

if (mDialog != null) {

mDialog.dismiss();

mDialog = null;

// Show delayed, so that the dismiss of the previous dialog completes

mHandler.sendEmptyMessage(MESSAGE_SHOW);

} else {

handleShow();

}

}

private GlobalActionsDialog createDialog() {

...

if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {

mItems.add(new PowerAction());

} else if (GLOBAL_ACTION_KEY_REBOOT.equals(actionKey)) {

mItems.add(new RebootAction());

}

...

}

其中handleShow方法最终调用createDialog();这个方法来创建GlobalActionsDialog这个对话框对象,其中利用各种参数Action来控制item的各种行为,我们这里要看的就是PowerAction

private final class PowerAction extends SinglePressAction implements LongPressAction {

...

@Override

public void onPress() {

mWindowManagerFuncs.shutdown(true/* confirm */);

}

}

看到这里就都明白了,通过对话框关机,这里调用的是mWindowManagerFuncs.shutdown,这个方法,这里mWindowManagerFuncs也就是WindowManagerService这个服务

@Override

public void shutdown(boolean confirm) {

ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);

}

其中通过名字可以知道调用了一个关机线程来处理,简单点的话就可以直接追踪到run方法。这里就不知道看代码了,通过打印信息来看看做了什么

11-18 20:00:17.061 1361-5920/system_process I/ShutdownThread: Sending shutdown broadcast...

11-18 20:00:18.710 1361-5920/system_process I/ShutdownThread: Shutting down activity manager...

11-18 20:00:18.913 1361-5920/system_process I/ShutdownThread: Shutting down package manager...

11-18 20:00:18.937 1361-6051/system_process W/ShutdownThread: Turning off cellular radios...

11-18 20:00:18.953 1361-6051/system_process I/ShutdownThread: Waiting for NFC, Bluetooth and Radio...

11-18 20:00:19.455 1361-6051/system_process I/ShutdownThread: Radio turned off.

11-18 20:00:19.455 1361-6051/system_process I/ShutdownThread: NFC, Radio and Bluetooth shutdown complete.

11-18 20:00:19.459 1361-5920/system_process I/ShutdownThread: Shutting down MountService

11-18 20:00:20.461 1361-5920/system_process W/ShutdownThread: Shutdown wait timed out

11-18 20:00:20.504 1361-5920/system_process I/ShutdownThread: waitShutdownAnimation true

11-18 20:00:20.510 1361-5920/system_process I/ShutdownThread: wait SHUTDOWN_ANIMATION_SERVICE completed. time out 14

11-18 20:00:20.836 1361-1712/system_process W/ShutdownThread: Result code 0 from MountService.shutdown

11-18 20:00:21.510 1361-5920/system_process I/ShutdownThread: wait SHUTDOWN_ANIMATION_SERVICE completed. time out 13

11-18 20:00:22.511 1361-5920/system_process I/ShutdownThread: wait SHUTDOWN_ANIMATION_SERVICE completed. time out 12

11-18 20:00:23.511 1361-5920/system_process I/ShutdownThread: wait SHUTDOWN_ANIMATION_SERVICE completed. time out 11

11-18 20:00:24.512 1361-5920/system_process I/ShutdownThread: wait SHUTDOWN_ANIMATION_SERVICE completed. time out 10

11-18 20:00:26.014 1361-5920/system_process I/ShutdownThread: Performing low-level shutdown...

首先发送关机广播,关闭一系列服务AMS、PKMS、radio、NFC等等等,等待关机动画完成。

流程理清楚了,解决起来就很简单了,在ShutdownThread设置一个静态成员变量 public static boolean isShutDowning = false; ,执行run方法就将这个标示设为true

然后在PhoneWindowManager的powerPress函数中添加判断是否禁用Power。

验证了也确实OK

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值