正常关机流程
来源:互联网 发布:淘宝免费代收货服务 编辑:程序博客网 时间:2024/05/01 22:56
/****************************************************************************************/
1.]从long power key到出现关机界面
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
}
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_POWER_LONG_PRESS:
powerLongPress();
break;
}
}
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
showGlobalActionsInternal();
break;
}
}
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);
}
}
/****************************************************************************************/
2.]按下reboot 按键
调用powermanagerservice的reboot 接口
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
/**
* Reboots the device.
*
* @param confirm If true, shows a reboot confirmation dialog.
* @param reason The reason for the reboot, or null if none.
* @param wait If true, this call waits for the reboot to complete and does not return.
*/
@Override // Binder call
public void reboot(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
}
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(false, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
throw new IllegalStateException("Too early to call shutdown() or reboot()");
}
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
if (shutdown) {
ShutdownThread.shutdown(mContext, confirm);
} else {
ShutdownThread.reboot(mContext, reason, confirm);
}
}
}
};
/****************************************************************************************/
3.]从powermanagerservice到shutdown thread
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java:
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
* @param context Context used to display the shutdown progress dialog.
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
mRebootSafeMode = false;
mRebootUpdate = false;
mRebootReason = reason;
shutdownInner(context, confirm);
}
08-15 16:55:49.358 554 2615 W System.err: java.lang.Exception: ShutdownThread: reboot
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.power.ShutdownThread.reboot(ShutdownThread.java:228)
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.power.PowerManagerService$3.run(PowerManagerService.java:2329)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Handler.handleCallback(Handler.java:739)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Looper.loop(Looper.java:148)
08-15 16:55:49.359 554 2615 W System.err: at android.os.HandlerThread.run(HandlerThread.java:61)
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.ServiceThread.run(ServiceThread.java:46)
08-15 16:55:49.360 554 2615 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
然后调进了shutdownThread的run函数,栈并没有显示怎样调进去的。
08-15 16:55:49.360 554 2615 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
08-15 16:55:49.403 554 2615 D InputDispatcher: channel 'fa020be (server)' ~ registerInputChannel - monitor=false
08-15 16:55:49.403 554 2615 D InputDispatcher: setInputWindows
08-15 16:55:49.403 554 2615 D InputDispatcher: Focus left window: Window{8e3e186 u0 GlobalActions}
08-15 16:55:49.403 554 2615 D InputDispatcher: Focus entered window: Window{fa020be u0 android}
08-15 16:55:49.408 554 5868 W System.err: java.lang.Exception: shutdownThread: run
08-15 16:55:49.408 554 5868 W System.err: at com.android.server.power.ShutdownThread.run(ShutdownThread.java:384)
/****************************************************************************************/
4.]从shutdown thread再到powermanager service的lowlevel
/****************************************************************************************/
run -> rebootOrShutdown(mContext, mReboot, mRebootReason);
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
deviceRebootOrShutdown(reboot, reason);
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
PowerManagerService.lowLevelReboot(reason);
Log.e(TAG, "Reboot failed, will attempt shutdown instead");
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown();
}
这里又调入:PowerManagerService
public static void lowLevelReboot(String reason) {
if (reason == null) {
reason = "";
}
if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
// If we are rebooting to go into recovery, instead of
// setting sys.powerctl directly we'll start the
// pre-recovery service which will do some preparation for
// recovery and then reboot for us.
SystemProperties.set("ctl.start", "pre-recovery");
} else {
SystemProperties.set("sys.powerctl", "reboot," + reason);
}
}
/****************************************************************************************/
5.]触发property:sys.powerctl改变对应的处理函数
/****************************************************************************************/
SystemProperties.set(sys.powerctl, xxx);
sys.powerctl属性触发开关在init.rc定义
on property:sys.powerctl=* powerctl ${sys.powerctl}
我们来解读这句话,on property:sys.powerctl=*表示当属性sys.powerctl设置为任何值是都会跑到这里,
触发动作是powerctl ${sys.powerctl},这个动作的意思是调用powerctl指令,并把sys.powerctl的值传给它。
powerctl指令在init进程会执行。
从下面的表可知,powerctl对应的操作是do_powerctl
[system/core/init/keywords.h]
KEYWORD(powerctl, COMMAND, 1, do_powerctl)
do_powerctl的实现
代码如下:
[system/core/init/builtins.c]
int do_powerctl(int nargs, char **args) { .... return android_reboot(cmd, 0, reboot_target); }
它调用android_reboot()函数,实现如下:
[system/core/libcutils/android_reboot.c]
1.]从long power key到出现关机界面
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
}
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_POWER_LONG_PRESS:
powerLongPress();
break;
}
}
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
showGlobalActionsInternal();
break;
}
}
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);
}
}
/****************************************************************************************/
2.]按下reboot 按键
调用powermanagerservice的reboot 接口
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
/**
* Reboots the device.
*
* @param confirm If true, shows a reboot confirmation dialog.
* @param reason The reason for the reboot, or null if none.
* @param wait If true, this call waits for the reboot to complete and does not return.
*/
@Override // Binder call
public void reboot(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
}
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(false, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
throw new IllegalStateException("Too early to call shutdown() or reboot()");
}
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
if (shutdown) {
ShutdownThread.shutdown(mContext, confirm);
} else {
ShutdownThread.reboot(mContext, reason, confirm);
}
}
}
};
/****************************************************************************************/
3.]从powermanagerservice到shutdown thread
/****************************************************************************************/
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java:
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
* @param context Context used to display the shutdown progress dialog.
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
mRebootSafeMode = false;
mRebootUpdate = false;
mRebootReason = reason;
shutdownInner(context, confirm);
}
08-15 16:55:49.358 554 2615 W System.err: java.lang.Exception: ShutdownThread: reboot
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.power.ShutdownThread.reboot(ShutdownThread.java:228)
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.power.PowerManagerService$3.run(PowerManagerService.java:2329)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Handler.handleCallback(Handler.java:739)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
08-15 16:55:49.359 554 2615 W System.err: at android.os.Looper.loop(Looper.java:148)
08-15 16:55:49.359 554 2615 W System.err: at android.os.HandlerThread.run(HandlerThread.java:61)
08-15 16:55:49.359 554 2615 W System.err: at com.android.server.ServiceThread.run(ServiceThread.java:46)
08-15 16:55:49.360 554 2615 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
然后调进了shutdownThread的run函数,栈并没有显示怎样调进去的。
08-15 16:55:49.360 554 2615 D ShutdownThread: Notifying thread to start shutdown longPressBehavior=1
08-15 16:55:49.403 554 2615 D InputDispatcher: channel 'fa020be (server)' ~ registerInputChannel - monitor=false
08-15 16:55:49.403 554 2615 D InputDispatcher: setInputWindows
08-15 16:55:49.403 554 2615 D InputDispatcher: Focus left window: Window{8e3e186 u0 GlobalActions}
08-15 16:55:49.403 554 2615 D InputDispatcher: Focus entered window: Window{fa020be u0 android}
08-15 16:55:49.408 554 5868 W System.err: java.lang.Exception: shutdownThread: run
08-15 16:55:49.408 554 5868 W System.err: at com.android.server.power.ShutdownThread.run(ShutdownThread.java:384)
/****************************************************************************************/
4.]从shutdown thread再到powermanager service的lowlevel
/****************************************************************************************/
run -> rebootOrShutdown(mContext, mReboot, mRebootReason);
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
deviceRebootOrShutdown(reboot, reason);
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
PowerManagerService.lowLevelReboot(reason);
Log.e(TAG, "Reboot failed, will attempt shutdown instead");
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown();
}
这里又调入:PowerManagerService
public static void lowLevelReboot(String reason) {
if (reason == null) {
reason = "";
}
if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
// If we are rebooting to go into recovery, instead of
// setting sys.powerctl directly we'll start the
// pre-recovery service which will do some preparation for
// recovery and then reboot for us.
SystemProperties.set("ctl.start", "pre-recovery");
} else {
SystemProperties.set("sys.powerctl", "reboot," + reason);
}
}
/****************************************************************************************/
5.]触发property:sys.powerctl改变对应的处理函数
/****************************************************************************************/
SystemProperties.set(sys.powerctl, xxx);
sys.powerctl属性触发开关在init.rc定义
on property:sys.powerctl=* powerctl ${sys.powerctl}
我们来解读这句话,on property:sys.powerctl=*表示当属性sys.powerctl设置为任何值是都会跑到这里,
触发动作是powerctl ${sys.powerctl},这个动作的意思是调用powerctl指令,并把sys.powerctl的值传给它。
powerctl指令在init进程会执行。
从下面的表可知,powerctl对应的操作是do_powerctl
[system/core/init/keywords.h]
KEYWORD(powerctl, COMMAND, 1, do_powerctl)
do_powerctl的实现
代码如下:
[system/core/init/builtins.c]
int do_powerctl(int nargs, char **args) { .... return android_reboot(cmd, 0, reboot_target); }
它调用android_reboot()函数,实现如下:
[system/core/libcutils/android_reboot.c]
0 0
- 正常关机流程
- 关机流程
- 关机流程
- 电脑不能正常关机
- 电脑不能正常关机
- Windows的正常关机
- Linux的正常关机
- Linux正常关机命令
- linux 正常关机
- Windows98不能正常关机解决
- Ubuntu 12.04无法正常关机
- 电脑不能正常关机解决办法
- 关于win10无法正常关机
- Linux的关机流程
- android系统关机流程
- android系统关机流程
- android 关机 流程分析
- android 关机 流程分析
- python连接数据库
- 百度地图集成(纯干货,个人笔记)
- Reverse String 字符串反转
- 结构体 共同体 枚举
- MySQL5.6安装步骤(windows7/8_64位)
- 正常关机流程
- OC_文件NSData NSMutableData
- HDU 1517 A Multiplication Game (博弈 NP图)
- 字典树与三向字典树-java实现
- GCC 中的编译器堆栈保护技术
- CSS3
- linux 下安装rz、sz插件
- python学习笔记(五):正则表达式
- java常量池