Android 关机umount

本文深入探讨了Android系统中的关机(umount)过程,从Java层的Power类开始,通过jni层的android_os_Power.cpp,到系统库cutils的android_reboot.c。详细介绍了如何调用android_reboot函数来执行关机和重启操作,包括同步、挂载读取只读等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
      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;
      }
      典型的,/proc/mounts 内容示例如下:
      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;
      






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值