Java layer
- Helper Java Power class : framework/base/core/java/android/os/power.java
public class Power { // can't instantiate this class private Power() { } /** * Wake lock that ensures that the CPU is running. The screen might * not be on. */ public static final int PARTIAL_WAKE_LOCK = 1; /** * Wake lock that ensures that the screen is on. */ public static final int FULL_WAKE_LOCK = 2; public static native void acquireWakeLock(int lock, String id); public static native void releaseWakeLock(String id); /** * Brightness value for fully off */ public static final int BRIGHTNESS_OFF = 0; /** * Brightness value for dim backlight */ public static final int BRIGHTNESS_DIM = 20; /** * Brightness value for fully on */ public static final int BRIGHTNESS_ON = 255; /** * Brightness value to use when battery is low */ public static final int BRIGHTNESS_LOW_BATTERY = 10; /** * Threshold for BRIGHTNESS_LOW_BATTERY (percentage) * Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD */ public static final int LOW_BATTERY_THRESHOLD = 10; /** * Turn the screen on or off * * @param on Whether you want the screen on or off */ public static native int setScreenState(boolean on); public static native int setLastUserActivityTimeout(long ms); /** * Low-level function turn the device off immediately, without trying * to be clean. Most people should use * {@link android.internal.app.ShutdownThread} for a clean shutdown. * * @deprecated * @hide */ @Deprecated public static native void 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)
static JNINativeMethod method_table[] = { { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, };
*/ public static void reboot(String reason) throws IOException { rebootNative(reason); } private static native void rebootNative(String reason) throws IOException ;}
JNI layer
- frameworks/base/core/jni/android_os_Power.cpp
static JNINativeMethod method_table[] = { { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, }; static void android_os_Power_shutdown(JNIEnv *env, jobject clazz) { android_reboot(ANDROID_RB_POWEROFF, 0, 0); } 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->GetStringUTFChars(reason, NULL); android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars); env->ReleaseStringUTFChars(reason, chars); // In case it fails. } jniThrowIOException(env, errno); }
System lib cutils/android_reboot.h
- system/core/libcutils/android_reboot.c
- android_reboot()
int android_reboot(int cmd, int flags, char *arg) { int ret; //Gozone start BID 11184 chenglong: for reboot status capture save_reboot_log(cmd, flags, arg); //Gozone end BID 11184 if (!(flags & ANDROID_RB_FLAG_NO_SYNC)) sync(); if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO)) remount_ro(); switch (cmd) { case ANDROID_RB_RESTART: ret = reboot(RB_AUTOBOOT); break; case ANDROID_RB_POWEROFF: ret = reboot(RB_POWER_OFF); break; case ANDROID_RB_RESTART2: ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg); break; default: ret = -1; } return ret; }
- remount_ro_done()
check to see if /proc/mounts contains any writable file systems; return TRUE
典型的,/proc/mounts 内容示例如下:static int remount_ro_done(void) { FILE *f; char mount_dev[256]; char mount_dir[256]; char mount_type[256]; char mount_opts[256]; int mount_freq; int mount_passno; int match; int found_rw_fs = 0; f = fopen("/proc/mounts", "r"); if (! f) { /* If we can't read /proc/mounts, just give up */ return 1; } do { match = fscanf(f, "%255s %255s %255s %255s %d %d\n", mount_dev, mount_dir, mount_type, mount_opts, &mount_freq, &mount_passno); mount_dev[255] = 0; mount_dir[255] = 0; mount_type[255] = 0; mount_opts[255] = 0; if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw")) { found_rw_fs = 1; break; } } while (match != EOF); fclose(f); return !found_rw_fs; }
root@android:/proc # cat mounts cat mounts rootfs / rootfs ro,relatime 0 0 tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0 devpts /dev/pts devpts rw,relatime,mode=600 0 0 proc /proc proc rw,relatime 0 0 sysfs /sys sysfs rw,relatime 0 0 none /acct cgroup rw,relatime,cpuacct 0 0 tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0 tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0 none /dev/cpuctl cgroup rw,relatime,cpu 0 0 /dev/block/platform/sdhci.1/by-name/system /system ext4 rw,relatime,user_xattr,barrier=1,data=ordered 0 0 /dev/block/platform/sdhci.1/by-name/userdata /data ext4 rw,nosuid,nodev,noatime,user_xattr,barrier=1,data=ordered 0 0 /dev/block/platform/sdhci.1/by-name/cache /cache ext4 rw,nosuid,noatime,user_xattr,barrier=1,data=ordered 0 0 /sys/kernel/debug /sys/kernel/debug debugfs rw,relatime 0 0 /dev/block/vold/179:27 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0002,dmask=0002, allow_utime=0020,codepage=cp437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 0 /dev/block/vold/179:27 /mnt/secure/asec vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0002,dmask= 0002,allow_utime=0020,codepage=cp437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 0 tmpfs /mnt/sdcard/.android_secure tmpfs ro,relatime,size=0k,mode=000 0 0 root@android:/proc #
- remount_ro()
static void remount_ro(void) { int fd, cnt = 0; /* Trigger the remount of the filesystems as read-only, * which also marks them clean. */ fd = open("/proc/sysrq-trigger", O_WRONLY); if (fd < 0) { return; } write(fd, "u", 1); close(fd); /* Now poll /proc/mounts till it's done */ while (!remount_ro_done() && (cnt < 50)) { usleep(100000); cnt++; } return;
- android_reboot()