android long power key流程

長按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}
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章