長按power key
1、android framework(for android 4.3)
/frameworks/base/core/res/res/values/config.xml...
404 <!-- Control the behavior when the user long presses the power button.
405 0 - Nothing
406 1 - Global actions menu
407 2 - Power off (with confirmation)
408 -->
409 <integer name="config_longPressOnPowerBehavior">1</integer>
/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
private final Runnable mPowerLongPress = new Runnable() {
695 @Override
696 public void run() {
697 // The context isn't read
698 if (mLongPressOnPowerBehavior < 0) {
699 mLongPressOnPowerBehavior = mContext.getResources().getInteger(
700 com.android.internal.R.integer.config_longPressOnPowerBehavior);
701 }
702 int resolvedBehavior = mLongPressOnPowerBehavior;
703 if (FactoryTest.isLongPressOnPowerOffEnabled()) {
704 resolvedBehavior = LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
705 }
706
707 switch (resolvedBehavior) {
708 case LONG_PRESS_POWER_NOTHING:
709 break;
710 case LONG_PRESS_POWER_GLOBAL_ACTIONS:
711 mPowerKeyHandled = true;
712 if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
713 performAuditoryFeedbackForAccessibilityIfNeed();
714 }
715 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
716 showGlobalActionsDialog();
717 break;
718 case LONG_PRESS_POWER_SHUT_OFF:
719 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
720 mPowerKeyHandled = true;
721 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
722 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
723 mWindowManagerFuncs.shutdown(resolvedBehavior == LONG_PRESS_POWER_SHUT_OFF);
724 break;
725 }
726 }
727 };
/frameworks/base/services/java/com/android/server/power/ShutdownThread.java
101 public static void shutdown(final Context context, boolean confirm) {
102 mReboot = false;
103 mRebootSafeMode = false;
104 shutdownInner(context, confirm);
105 }
483 /**
484 * Do not call this directly. Use {@link #reboot(Context, String, boolean)}
485 * or {@link #shutdown(Context, boolean)} instead.
486 *
487 * @param reboot true to reboot or false to shutdown
488 * @param reason reason for reboot
489 */
490 public static void rebootOrShutdown(boolean reboot, String reason) {
491 if (reboot) {
492 Log.i(TAG, "Rebooting, reason: " + reason);
493 try {
494 PowerManagerService.lowLevelReboot(reason);
495 } catch (Exception e) {
496 Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
497 }
498 } else if (SHUTDOWN_VIBRATE_MS > 0) {
499 // vibrate before shutting down
500 Vibrator vibrator = new SystemVibrator();
501 try {
502 vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
503 } catch (Exception e) {
504 // Failure to vibrate shouldn't interrupt shutdown. Just log it.
505 Log.w(TAG, "Failed to vibrate during shutdown.", e);
506 }
507
508 // vibrator is asynchronous so we need to wait to avoid shutting down too soon.
509 try {
510 Thread.sleep(SHUTDOWN_VIBRATE_MS);
511 } catch (InterruptedException unused) {
512 }
513 }
514
515 // Shutdown power
516 Log.i(TAG, "Performing low-level shutdown...");
517 PowerManagerService.lowLevelShutdown();
518 }
519}
以下是lowLevelReboot的調用過程
/frameworks/base/services/java/com/android/server/power/PowerManagerService.java
2176 /**
2177 * Low-level function to reboot the device.
2178 *
2179 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2180 * @throws IOException if reboot fails for some reason (eg, lack of
2181 * permission)
2182 */
2183 public static void lowLevelReboot(String reason) throws IOException {
2184 nativeReboot(reason);
2185 }
static JNINativeMethod gPowerManagerServiceMethods[] = {
211 /* name, signature, funcPtr */
212 { "nativeInit", "()V",
213 (void*) nativeInit },
214 { "nativeSetPowerState", "(ZZ)V",
215 (void*) nativeSetPowerState },
216 { "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
217 (void*) nativeAcquireSuspendBlocker },
218 { "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
219 (void*) nativeReleaseSuspendBlocker },
220 { "nativeSetInteractive", "(Z)V",
221 (void*) nativeSetInteractive },
222 { "nativeSetAutoSuspend", "(Z)V",
223 (void*) nativeSetAutoSuspend },
224 { "nativeShutdown", "()V",
225 (void*) nativeShutdown },
226 { "nativeReboot", "(Ljava/lang/String;)V",
227 (void*) nativeReboot },
228};
196static void nativeReboot(JNIEnv *env, jclass clazz, jstring reason) {
197 if (reason == NULL) {
198 android_reboot(ANDROID_RB_RESTART, 0, 0);
199 } else {
200 const char *chars = env->GetStringUTFChars(reason, NULL);
201 android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);
202 env->ReleaseStringUTFChars(reason, chars); // In case it fails.
203 }
204 jniThrowIOException(env, errno);
205}
/system/core/libcutils/android_reboot.c
104int android_reboot(int cmd, int flags, char *arg)
105{
106 int ret;
107
108 if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
109 sync();
110
111 if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
112 remount_ro();
113
114 switch (cmd) {
115 case ANDROID_RB_RESTART:
116 ret = reboot(RB_AUTOBOOT);
117 break;
118
119 case ANDROID_RB_POWEROFF:
120 ret = reboot(RB_POWER_OFF);
121 break;
122
123 case ANDROID_RB_RESTART2:
124 ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
125 LINUX_REBOOT_CMD_RESTART2, arg);
126 break;
127
128 default:
129 ret = -1;
130 }
131
132 return ret;
133}
/bionic/libc/bionic/reboot.c
31int reboot (int mode)
32{
33 return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL );
34}
/bionic/libc/arch-arm/syscalls/__reboot.S
1/* autogenerated by gensyscalls.py */
2#include <asm/unistd.h>
3#include <linux/err.h>
4#include <machine/asm.h>
5
6ENTRY(__reboot)
7 mov ip, r7
8 ldr r7, =__NR_reboot
9 swi #0
10 mov r7, ip
11 cmn r0, #(MAX_ERRNO + 1)
12 bxls lr
13 neg r0, r0
14 b __set_errno
15END(__reboot)
2、linux kernel
for kernel 3.4
/kernel/sys.c
421/*
422 * Reboot system call: for obvious reasons only root may call it,
423 * and even root needs to set up some magic numbers in the registers
424 * so that some mistake won't make this reboot the whole machine.
425 * You can also set the meaning of the ctrl-alt-del-key here.
426 *
427 * reboot doesn't sync: do that yourself before calling this.
428 */
429 SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
430 void __user *, arg)
431{
432 char buffer[256];
433 int ret = 0;
434
435 /* We only trust the superuser with rebooting the system. */
436 if (!capable(CAP_SYS_BOOT))
437 return -EPERM;
438
439 /* For safety, we require "magic" arguments. */
440 if (magic1 != LINUX_REBOOT_MAGIC1 ||
441 (magic2 != LINUX_REBOOT_MAGIC2 &&
442 magic2 != LINUX_REBOOT_MAGIC2A &&
443 magic2 != LINUX_REBOOT_MAGIC2B &&
444 magic2 != LINUX_REBOOT_MAGIC2C))
445 return -EINVAL;
446
447 /*
448 * If pid namespaces are enabled and the current task is in a child
449 * pid_namespace, the command is handled by reboot_pid_ns() which will
450 * call do_exit().
451 */
452 ret = reboot_pid_ns(task_active_pid_ns(current), cmd);
453 if (ret)
454 return ret;
455
456 /* Instead of trying to make the power_off code look like
457 * halt when pm_power_off is not set do it the easy way.
458 */
459 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
460 cmd = LINUX_REBOOT_CMD_HALT;
461
462 mutex_lock(&reboot_mutex);
463 switch (cmd) {
464 case LINUX_REBOOT_CMD_RESTART:
465 kernel_restart(NULL);
466 break;
467
468 case LINUX_REBOOT_CMD_CAD_ON:
469 C_A_D = 1;
470 break;
471
472 case LINUX_REBOOT_CMD_CAD_OFF:
473 C_A_D = 0;
474 break;
475
476 case LINUX_REBOOT_CMD_HALT:
477 kernel_halt();
478 do_exit(0);
479 panic("cannot halt");
480
481 case LINUX_REBOOT_CMD_POWER_OFF:
482 kernel_power_off();
483 do_exit(0);
484 break;
485
486 case LINUX_REBOOT_CMD_RESTART2:
487 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
488 ret = -EFAULT;
489 break;
490 }
491 buffer[sizeof(buffer) - 1] = '\0';
492
493 kernel_restart(buffer);
494 break;
495
496#ifdef CONFIG_KEXEC
497 case LINUX_REBOOT_CMD_KEXEC:
498 ret = kernel_kexec();
499 break;
500#endif
501
502#ifdef CONFIG_HIBERNATION
503 case LINUX_REBOOT_CMD_SW_SUSPEND:
504 ret = hibernate();
505 break;
506#endif
507
508 default:
509 ret = -EINVAL;
510 break;
511 }
512 mutex_unlock(&reboot_mutex);
513 return ret;
514}
365void kernel_restart(char *cmd)
366{
367 kernel_restart_prepare(cmd);
368 if (!cmd)
369 printk(KERN_EMERG "Restarting system.\n");
370 else
371 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
372 kmsg_dump(KMSG_DUMP_RESTART);
373 machine_restart(cmd);
374}
317void kernel_restart_prepare(char *cmd)
318{
319 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
320 system_state = SYSTEM_RESTART;
321 usermodehelper_disable();
322 device_shutdown();
323 syscore_shutdown();
324}
/arch/arm/kernel/process.c
326void machine_restart(char *cmd)
327{
328 machine_shutdown();
329
330 /* Flush the console to make sure all the relevant messages make it
331 * out to the console drivers */
332 arm_machine_flush_console();
333
334 arm_pm_restart(reboot_mode, cmd); //調用芯片的restart方法,如msm_restart()
335
336 /* Give a grace period for failure to restart of 1s */
337 mdelay(1000);
338
339 /* Whoops - the platform was unable to reboot. Tell the user! */
340 printk("Reboot failed -- System halted\n");
341 while (1);
342}
297void machine_shutdown(void)
298{
299#ifdef CONFIG_SMP
300 /*
301 * Disable preemption so we're guaranteed to
302 * run to power off or reboot and prevent
303 * the possibility of switching to another
304 * thread that might wind up blocking on
305 * one of the stopped CPUs.
306 */
307 preempt_disable();
308
309 smp_send_stop();
310#endif
311}
/arch/arm/kernel/setup.c
931void __init setup_arch(char **cmdline_p)
932{
933 struct machine_desc *mdesc;
934
935 setup_processor();
936 mdesc = setup_machine_fdt(__atags_pointer);
937 if (!mdesc)
938 mdesc = setup_machine_tags(machine_arch_type);
939 machine_desc = mdesc;
940 machine_name = mdesc->name;
941
942#ifdef CONFIG_ZONE_DMA
943 if (mdesc->dma_zone_size) {
944 extern unsigned long arm_dma_zone_size;
945 arm_dma_zone_size = mdesc->dma_zone_size;
946 }
947#endif
948 if (mdesc->restart_mode)
949 reboot_setup(&mdesc->restart_mode);
950
951 init_mm.start_code = (unsigned long) _text;
952 init_mm.end_code = (unsigned long) _etext;
953 init_mm.end_data = (unsigned long) _edata;
954 init_mm.brk = (unsigned long) _end;
955
956 /* populate cmd_line too for later use, preserving boot_command_line */
957 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
958 *cmdline_p = cmd_line;
959
960 parse_early_param();
961
962 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
963 sanity_check_meminfo();
964 arm_memblock_init(&meminfo, mdesc);
965
966 paging_init(mdesc);
967 request_standard_resources(mdesc);
968
969 if (mdesc->restart)
970 arm_pm_restart = mdesc->restart;
971
972 unflatten_device_tree();
973
974#ifdef CONFIG_SMP
975 if (is_smp())
976 smp_init_cpus();
977#endif
978 reserve_crashkernel();
979
980 tcm_init();
981
982#ifdef CONFIG_MULTI_IRQ_HANDLER
983 handle_arch_irq = mdesc->handle_irq;
984#endif
985
986#ifdef CONFIG_VT
987#if defined(CONFIG_VGA_CONSOLE)
988 conswitchp = &vga_con;
989#elif defined(CONFIG_DUMMY_CONSOLE)
990 conswitchp = &dummy_con;
991#endif
992#endif
993
994 if (mdesc->init_early)
995 mdesc->init_early();
996}