Explains the android shutdown sequence in detail.
First Step: Press and hold the power button for half a second (500ms).
Second step: after that, Phonewindowmanager.java will capture the event of long press the power button and call the "interceptkeybeforequeueing" method.
Here is the code snippet that handles the long press power key event
1/** {@inheritDoc} */2 @Override 3 public int interceptkeybeforequeueing (keyevent event, int policyflags, Boolean Isscreenon) {4 .... 5 ..... 6 ..... 7 Case Keyevent.keycode_power: {8 result &= ~action_pass_to_user; 9 if (down) {Ten if (Isscreenon &&!mpowerkeytriggered && (E Vent.getflags () & keyevent.flag_fallback) = = 0) {mpowerkeytriggered = true; 13 Mpowerkeytime = Event.getdowntime (); Interceptscreenshotchord (); Itelephony Telephonyservice = Gettelephonyservice (); + Boolean hungup = false; if (telephonyservice! = null) {try {if (Te Lephonyservice.isringing ()) {21//If the Power key is pressed when the incoming call is ringing, the system will turn off the call prompt 22 Telephonyservice.silenceringer (); All else if (Mincallpowerbehavior & Settings.secur E.incall_power_button_behavior_hangup)! = 0 && telephonyservice.isoffhook ()) {26//If you are on a call and the Power key hangs option is enabled, pressing the Power key will end the current call Hungup = Tele Phonyservice.endcall (); (RemoteException ex) {Lo G.W (TAG, "Itelephony threw RemoteException", ex); Interceptpowerkeydown (!isscreenon | | Hungup 34 || mvolumedownkeytriggered | | mvolumeupkeytriggered); n} else {mpowerkeytriggered = false; PNs Cancelpendingscreenshot Chordaction (); if (Interceptpowerkeyup (canceled | | mpendingpowerkeyupcanceled)) {# result = (Result & ~action_wake_up) | Action_go_to_sleep; mpendingpowerkeyupcanceled = false; ; 44} 45 .... 46 ..... 47 ..... 48}
The above code contains the processing of long press power key times in various situations, such as silent call ringing, screen, and power off. The system will determine how the current user action is handled appropriately based on the length of time the power key is pressed and the usage of the relevant key. When the power key is pressed and no screenshot is triggered, the interceptpowerkeydown will be called, while other key responses (other button responses refer to other cases in interceptkeybeforequeueing) will not be triggered.
The following code shows the contents of the Interceptpowerkeydown function, which registers a callback function that starts when a 500-millisecond timeout event (Viewconfiguration#getglobalactionkeytimeout ()) is triggered. Mpowerlongpress thread.
1 private void Interceptpowerkeydown (Boolean handled) {2 mpowerkeyhandled = handled; 3 if (!handled) {4
mhandler.postdelayed (Mpowerlongpress, Viewconfiguration.getglobalactionkeytimeout ()); 5 } 6
The implementation of the mpowerlongpress thread is as follows:
1 private final Runnable mpowerlongpress = new Runnable () {2 @Override 3 public void Run () {4//the context isn ' t read 5 if (Mlongpressonpowerbehavior < 0) {6 Mlongpressonpowerbehavior = Mcontext.getresources (). Getinteger (7 Com.android.interna L.r.integer.config_longpressonpowerbehavior); 8} 9 int resolvedbehavior = Mlongpressonpowerbehavior; Ten if (factorytest.islongpressonpoweroffenabled ()) {One resolvedbehavior = Long_press_ power_shut_off_no_confirm; (Resolvedbehavior) {Long_press_power_noth Ing:16 break; Long_press_power_global_actions:18 mpowerkeyhandled = true; if (!PERFORMHAPTICFEEDBACKLW (null, Hapticfeedbackconstants.long_Press, False)) {performauditoryfeedbackforaccessibilityifneed (); 21} 22 Sendclosesystemwindows (system_dialog_reason_global_actions); Showglobalactionsdialog (); break; Case long_press_power_shut_off:26 Case long_press_power_shut_off_no_confirm:27 Mpowerkeyhandled = true; PERFORMHAPTICFEEDBACKLW (null, hapticfeedbackconstants.long_press, FALSE); Sendclosesystemwindows (system_dialog_reason_global_actions); Mwindowmanagerfuncs.shutdown (Resolvedbehavior = = Long_press_power_shut_off); break; 32} 33} 34};
The third step: The switch branch of the above code shows that when the program goes in Long_press_power_global_options control will be handed over to the Globalactions class, the module is responsible for displaying the Shutdown Options dialog box, These options vary across Android distributions (OEM-customized Android systems, different phone models and different versions of Android), usually including power off, airplane mode, and screen. Some other option keys may also be included. The Globalactions class implements a ShowDialog method that creates this dialog box based on the menu content currently supported by the system.
1 void Showglobalactionsdialog () { 2 if (mglobalactions = = null) { 3 mglobalactions = new Globalactions ( Mcontext, Mwindowmanagerfuncs); 4 } 5 final Boolean keyguardshowing = KEYGUARDISSHOWINGTQ (); 6 Mglobalactions.showdialog (keyguardshowing, isdeviceprovisioned ()); 7 if (keyguardshowing) { 8 //Because the activation shutdown dialog needs to press and hold the Power key for more than two seconds, when the dialog box is displayed, the wake-up status of the screen is locked to facilitate the user to browse the contents of the dialog box 9 mkeyguardmediator.useractivity (); 10
Fourth Step: If the user chooses "power off", then the control of the system will be handed back to Phonewindowmanager, then the shutdown process can be initiated by Phonewindowmanager.
Fifth Step: The entire shutdown process starts with the Shutdowninner method in the Shutdownthread module. This method first creates a confirmation dialog box to the user, who can choose to confirm the shutdown or cancel the shutdown operation. If the user chooses to confirm, the system will actually enter the shutdown process.
Sixth step: as described above, when the user clicks the Confirm button, the Beginshutdownsequence method will be called to start the shutdown sequence.
1 private static void Beginshutdownsequence (context context) {2 synchronized (Sisstartedguard) {3 if (sisstarted) {4 log.d (TAG, "Shutdown sequence already running, returning."); 5 return; 6} 7 sisstarted = true; 8} 9 10//Displays the dialog that is shutting down the power supply progressdialog PD = new ProgressDialog (context); Pd.settitle (Context.gettext (Com.android.internal.r.string.power_off)); Pd.setmessage (Context.gettext (com.android.internal.r.string.shutdown_progress)); Pd.setindeterminate (TRUE); Pd.setcancelable (FALSE); Pd.getwindow (). SetType (WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); Pd.show (); Sinstance.mcontext = context; Sinstance.mpowermanager = (PowerManager) context.getsystemservice (Context.power_service); 21//Block CPU AccessSleep state: Sinstance.mcpuwakelock = null; try {sinstance.mcpuwakelock = SInstance.mPowerManager.newWakeLock (25 Powermanager.partial_wake_lock, TAG + "-cpu"); SInstance.mCpuWakeLock.setReferenceCounted (FALSE); SInstance.mCpuWakeLock.acquire (); (SecurityException e) {LOG.W (TAG, "No permission to acquire Wake Lock", e); 30 Sinstance.mcpuwakelock = null; 31} 32//Keep the screen awake until the power is turned off to improve user experience sinstance.mscreenwakelock = null; if (SInstance.mPowerManager.isScreenOn ()) {try {Sinstance.mscre Enwakelock = SInstance.mPowerManager.newWakeLock (PNs powermanager.full_wake_lock, TAG + "-scre En "); SInstance.mScreenWakeLock.setReferenceCounted (FALSE); Sinstance.mscreenwakeloCk.acquire (); (SecurityException e) {LOG.W (TAG, "No permission to acquire Wake Lock", e); Sinstance.mscreenwakelock = null; 43} 44} 45//start thread responsible for shutdown sequence Sinstance.mhandler = new Handler () {47 }; Sinstance.start (); 49}
Run the function to start the actual shutdown process
1 public void Run () {2 broadcastreceiver br = new Broadcastreceiver () {3 @Override public void OnReceive (context context, Intent Intent) {4//We don ' t allow apps to cancel this, so Ignore the result. 5 Actiondone (); 6} 7}; 8 9/* 10 * Write a system parameter to prevent system Server 11 * (one running on Dalvik virtual machine and real system in Android) The server between the cores, which is responsible for the virtual machine's communication with the kernel, completes the reboot before the real hardware restarts. 12 * When the above occurs, retry the restart operation before the system server finishes booting. (+/-) {String reason = (mreboot? "1": "0") + (Mrebootreason! = null? Mrebootreason: ""); Systemproperties.set (shutdown_action_property, reason); 17} 18 19/* 20 * Write a system parameter to reboot and enter Safe Mode * * F (mrebootsafemode) {Systemproperties.set (Reboot_safemode_property, "1"); LOG.I (TAG, "Sending shutdown broadcast ..."); 27 28//Turn off mobile communication Mactiondone = false; Intent Intent = new Intent (Intent.action_shutdown); Intent.addflags (Intent.flag_receiver_foreground); Mcontext.sendorderedbroadcastasuser (Intent, Userhandle.all, NULL, BR, Mhandler, 0, NULL, NULL); The final long endTime = Systemclock.elapsedrealtime () + max_broadcast_time; Synchronized (Mactiondonesync) {Notoginseng while (!mactiondone) {a long de Lay = Endtime-systemclock.elapsedrealtime (); if (delay <= 0) {LOG.W (TAG, "Shutdown broadcast timed out"); a break; A try {mactiondonesync.wait (delay); The catch(Interruptedexception e) {LOG.I} (TAG, "shutting down AC Tivity Manager ... "); Wuyi final Iactivitymanager am = Activitymanagernative.asinterface (servicemanager. Checkservice ("activity")); if (AM = null) {Am.shutdown (max_broadcast_time); RemoteException} catch (e) {58} 59} 60 61//Turn off move Communication Shutdownradios (Max_radio_wait_time); 63 64//Secure removal of external memory card imountshutdownobserver Observer = new Imountshutdownobserver.stub () {$ public void onshutdowncomplete (int statusCode) throws RemoteException {. W (TAG, "Result code" + StatusCode + "from Mountservice.shutdown"); Actiondone (); 69} 70 }; LOG.I (TAG, "shutting down Mountservice"); 73 74//Initialize variable and set shutdown timeout time Mactiondone = false; The final long endshuttime = Systemclock.elapsedrealtime () + max_shutdown_wait_time; Synchronized (mactiondonesync) {% try {final Imountservice Moun t = IMountService.Stub.asInterface (Servicemanager.checkservice ("mount")); Bayi if (mount! = null) {MOUNT.SHUTDOWN (Observer); LOG.W} else {(TAG, "Mountservice unavailable for Shutdown"); Exception} catch (e) {log.e (TAG, "Exception during Mountservice shutdown ", e); (!mactiondone) {a long delay = ENDSHUTTIME-SYSTEMC Lock.elapsedrealtime (); 91 if (delay <= 0) {LOG.W (TAG, "Shutdown wait timed out"); a break; 94} try {mactiondonesync.wait (delay); Interruptedexception} catch (E) {98} 99} 100 } 101 102 Rebootorshutdown (Mreboot, Mrebootreason); 103}
Seventh Step: when the Rebootorshutdown method is called, the system control is first transferred to the underlying function Nativeshutdown (in Com_android_server_power_powermanagerservice. CPP) and ultimately call the Android_reboot function (defined in android_reboot.c) to complete the entire shutdown sequence
1 static void Nativeshutdown (JNIEnv *env, Jclass clazz) {2 android_reboot (android_rb_poweroff, 0, 0); 3 }
Note: The current Android version of Rebootorshutdown is actually different from the above. is through the use of Powermanagerservice.lowlevelshutdown () to modify the value of the "Sys.powerctl" in fact. You can refer to: device-driven-----android shutdown Process Summary
Finish.
Deep analysis of Android shutdown