正常关机流程

    xiaoxiao2025-11-28  6

    /****************************************************************************************/ 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]
    转载请注明原文地址: https://ju.6miu.com/read-1304480.html
    最新回复(0)