Android Long Press power button off the whole process small learning
Recently studied the Android shutdown and restart function, looked at some long press the power button to the pop-up shutdown dialog, to the real shutdown of a series of processing procedures.
First of all, let's see what this long press power button has done. In general, the power keys are received on the PMU, PMU to judge is long press also short press, when there is a key message generated, the system will be interrupted, and then read the status of PMU can know what is. The author of the AXP209 platform for a small discussion, first paste the key code:
static int axp_battery_event (struct notifier_block *nb, unsigned long event, void *data) {struct Axp_charger *charge R =container_of (NB, struct axp_charger, NB); uint8_t w[9];w[0] = (uint8_t) ((event) & 0xFF); w[1] = power20_intsts2;w[2] = (uint8_t) ((Event >> 8) & 0xFF) ; w[3] = power20_intsts3;w[4] = (uint8_t) ((Event >>) & 0xFF); w[5] = power20_intsts4;w[6] = (uint8_t) (event >>) & 0xFF); W[7] = power20_intsts5;w[8] = (uint8_t) (((uint64_t) event >> +) & 0xFF); if (Event & ; (axp20_irq_batin| Axp20_irq_batre)) {axp_capchange (charger);} if (Event & (axp20_irq_acin| axp20_irq_usbin| axp20_irq_acov| axp20_irq_usbov| axp20_irq_chaov| Axp20_irq_chast| axp20_irq_temov| Axp20_irq_temlo)) {axp_change (charger);} if (Event & (axp20_irq_acre| Axp20_irq_usbre)) {axp_change (charger);} if (event & Axp20_irq_peklo) {Axp_presslong (charger);} if (event & Axp20_irq_peksh) {axp_pressshort (charger);} Dbg_psy_msg ("event = 0x%x\n", (int) event); Axp_writES (charger->master,power20_intsts1,9,w); return 0;}
Short press and long press the specific is reported delay difference, as follows:
static void Axp_presslong (struct Axp_charger *charger) {dbg_psy_msg ("press long\n"); Input_report_key (Powerkeydev, key _power, 1); Input_sync (Powerkeydev); Ssleep (2);D bg_psy_msg ("Press long up\n"); Input_report_key (Powerkeydev, Key_ POWER, 0); Input_sync (Powerkeydev);} static void Axp_pressshort (struct Axp_charger *charger) {dbg_psy_msg ("press short\n"); Input_report_key (Powerkeydev, Key_power, 1); Input_sync (Powerkeydev); Msleep (Input_report_key, Powerkeydev, 0); Key_power ( Powerkeydev);}
In the inputmanager inside again to resolve the long press or short press, to do the corresponding treatment. If it is a long press, pop-up dialog box, before the popup dialog, there are several passes, or Activitymanger and WINDOWSMANAGERSERVICE do macro-control, the final message to the bitter force of Shutdownthread, But Shutdownthread is not difficult to get. /*****************************************************************************************************/
Disclaimer: The content of this blog is by http://blog.csdn.net/sundesheng125 original, reproduced please indicate the source, thank you!
/*****************************************************************************************************/
First of all, in Shutdownthread there is a closedialogreceiver to focus on intent.action_close_system_dialogs, it will close this dialog box when it receives this message. What's up with the dialog box? Please see the following source code:
 
if (confirm) {final Closedialogreceiver closer = new Closedialogreceiver (context); Final Alertdialog Dialog = new Alertdialog.builder (context). Settitle (Com.android.internal.r.string.pow Er_off). Setmessage (ResourceId). Setpositivebutton (Com.android.internal.r.string.yes , new Dialoginterface.onclicklistener () {public void OnClick (Dialoginterface dialog, int which) { Beginshutdownsequence (context); }}). Setnegativebutton (com.android.internal.r.string.no, NULL). Create (); Closer.dialog = Dialog; Dialog.setondismisslistener (Closer); Dialog.getwindow (). SetType (WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); Dialog.show (); } else {beginshutdownsequence (context); }
In fact, is a alertdialog, there is nothing new, just in Setpositivebutton when registered Clicklistener to monitor whether you press, press the direct execution beginshutdownsequence. The beginshutdownsequence also pops up a progress dialog box with the following code:
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 ();
It will also call two very important power.shutdown () and power.reboot (reason) to see if you are restarting or shutting down.
/** * Low-level function turn the device off immediately, without trying * to is clean . Most people should use * {@link android.internal.app.ShutdownThread} for a clean shutdown. * * @deprecated * @hide * * /@Deprecated shutdown(); /** * Reboot the device. * @param reason code to pass to the kernel (e.g. "recovery"), or null. * * @throws IOException If reboot fails for some reason (eg, lack of * permission) */public Stat IC void reboot (String reason) throws IOException { rebootnative(reason); } private static native void Rebootnative (String reason) throws IOException;
And then down,
static void Android_os_power_shutdown (JNIEnv *env, Jobject clazz) { android_reboot (android_rb_poweroff, 0, 0);} extern int go_recovery (void), static void Android_os_power_reboot (JNIEnv *env, Jobject clazz, jstring reason) { if ( Reason = = NULL) { android_reboot (android_rb_restart, 0, 0); } else { const char *chars = Env->getstringutf Chars (reason, NULL); Android_reboot (Android_rb_restart2, 0, (char *) chars); Go_recovery (); Android_reboot (android_rb_restart, 0, 0); Env->releasestringutfchars (reason, chars); In case it fails. } Jnithrowioexception (env, errno);}
Therefore, the whole process is good, learning to understand the process, most of them are source code, it is also beneficial to make it clear.