Android关机流程解析---从reboot说起

转自:http://blog.sina.com.cn/s/blog_6695f9eb0101hse4.html


Android关机流程解析

在PowerManager的API文档中,给出了一个关机/重启接口:


public void reboot (String reason)
对于这个接口的描述很简单,就是几句话。

接口的作用就是重启设备,而且,就算重启成功了也没有返回值。

需要包含REBOOT权限,也就是android.permission.REBOOT

唯一参数reason代表需要的特定重启模式,比如recovery,当然也可以为null。


--------------------------------上层空间--------------------------------

1.frameworks/base/core/java/android/os/PowerManager.java

[java] 
 * Reboot the device.  Will not return if the reboot is
 * successful.  Requires the {@link android.Manifest.permission#REBOOT}
 * permission.
 *
 * @param reason code to pass to the kernel (e.g., "recovery") to
 *               request special boot modes, or null.
 */ 
public void reboot(String reason) 
{    
    try { 
        mService.reboot(reason); 
    } catch (RemoteException e) { 
    }    
}  

   
    public void reboot(String reason)
    {  
        try {
            mService.reboot(reason);
        } catch (RemoteException e) {
        }  
    }
mService为IPowerManager Binder接口服务。


[java] 
 
public PowerManager(IPowerManager service, Handler handler) 

    mService = service; 
    mHandler = handler; 

   
    public PowerManager(IPowerManager service, Handler handler)
    {
        mService = service;
        mHandler = handler;
    }


2.frameworks/base/core/java/android/os/IPowerManager.aidl

[java]
interface IPowerManager 

... 
void reboot(String reason); 
... 

interface IPowerManager
{
...
void reboot(String reason);
...
}

3.frameworks/base/services/java/com/android/server/PowerManagerService.java

[java] 
 
public void reboot(String reason) 
{     
    mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); 
 
    if (mHandler == null || !ActivityManagerNative.isSystemReady()) { 
        throw new IllegalStateException("Too early to call reboot()"); 
    }     
 
    final String finalReason = reason; 
    Runnable runnable = new Runnable() { 
        public void run() { 
            synchronized (this) { 
                ShutdownThread.reboot(getUiContext(), finalReason, false); 
            }     
 
        }     
    };    
    // ShutdownThread must run on a looper capable of displaying the UI.  
    mHandler.post(runnable); 
 
    // PowerManager.reboot() is documented not to return so just wait for the inevitable.  
    synchronized (runnable) { 
        while (true) { 
            try { 
                runnable.wait(); 
            } catch (InterruptedException e) {  
            }     
        }     
    }     

   
    public void reboot(String reason)
    {   
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

        if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
            throw new IllegalStateException("Too early to call reboot()");
        }   

        final String finalReason = reason;
        Runnable runnable = new Runnable() {
            public void run() {
                synchronized (this) {
                    ShutdownThread.reboot(getUiContext(), finalReason, false);
                }   

            }   
        };  
        // ShutdownThread must run on a looper capable of displaying the UI.
        mHandler.post(runnable);

        // PowerManager.reboot() is documented not to return so just wait for the inevitable.
        synchronized (runnable) {
            while (true) {
                try {
                    runnable.wait();
                } catch (InterruptedException e) {
                }   
            }   
        }   
    }

4.frameworks/base/services/java/com/android/server/pm/ShutdownThread.java

[java]
 
public static void reboot(final Context context, String reason, boolean confirm) { 
    mReboot = true; 
    mRebootSafeMode = false; 
    mRebootReason = reason; 
    shutdownInner(context, confirm); 

   
    public static void reboot(final Context context, String reason, boolean confirm) {
        mReboot = true;
        mRebootSafeMode = false;
        mRebootReason = reason;
        shutdownInner(context, confirm);
    }
这里说明是需要重启,且不是安全模式,重启参数为传递下来的reason,shutdownInner的confirm参数是用来设置是否有确认提示框的,通过reboot接口调用重启是没有的,为false。

重启的实现在run()中,因为ShutdownThread是Thread的扩展,所以run会自动运行。


[java]
  
public void run() { 
    BroadcastReceiver br = new BroadcastReceiver() { 
        @Override public void onReceive(Context context, Intent intent) { 
            // We don't allow apps to cancel this, so ignore the result.  
            actionDone(); 
        } 
    }; 
 
      
    {    
        String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : ""); 
        SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason); 
    } 
 
      
    if (mRebootSafeMode) { 
        SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1"); 
    } 
    ... 
    rebootOrShutdown(mReboot, mRebootReason); 
}  

   
    public void run() {
        BroadcastReceiver br = new BroadcastReceiver() {
            @Override public void onReceive(Context context, Intent intent) {
                // We don't allow apps to cancel this, so ignore the result.
                actionDone();
            }
        };

       
        {  
            String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
            SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
        }

       
        if (mRebootSafeMode) {
            SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
        }
        ...
        rebootOrShutdown(mReboot, mRebootReason);
    }

在重启前会将重启原因写入sys.shutdown.requested,如果没有则为空,如果是安全模式还会将persist.sys.safemode置1,之后会进行一些关机前的预处理,关闭ActivityManager以及MountService,最终调用rebootOrShutdown进行关机操作。


[java] 
     
    public static void rebootOrShutdown(boolean reboot, String reason) { 
        if (reboot) { 
            Log.i(TAG, "Rebooting, reason: " + reason);  
            try { 
                PowerManagerService.lowLevelReboot(reason); 
            } catch (Exception e) { 
                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e); 
            }  
        } else if (SHUTDOWN_VIBRATE_MS > 0) { 
            // vibrate before shutting down  
            Vibrator vibrator = new SystemVibrator(); 
            try { 
                vibrator.vibrate(SHUTDOWN_VIBRATE_MS); 
            } catch (Exception e) { 
                // Failure to vibrate shouldn't interrupt shutdown.  Just log it.  
                Log.w(TAG, "Failed to vibrate during shutdown.", e); 
            }    
                 
            // vibrator is asynchronous so we need to wait to avoid shutting down too soon.  

你可能感兴趣的:(Android系统)