Android JB的reboot流程

  JB的Power的source比起之前的版本有有了一些改動,不過總的來說整個流程還是沒有怎麼變,只是一些文件和路徑變了。沒有辦法,剛看完一個部份的代碼,Google又在新的版本中做了改動,唯一的辦法就只能是把代碼的思路和流程弄清,至于code是怎麼碼的是其實,因為代碼是不斷的變而思想一般來說變化并不是那么大。今天就把power部份的reboot的一個流程給理一下。Shutdonw和reboot其實是差不多的。

1,首先我們就從PowerManager開始吧,一般來說,我們要想在代碼中調用重啟,我們可以通過下面的代碼來實現

PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);

pm.reboot(null);//些處我們給的是null,如果我們給的是recovery,發么系統就會重啟進入到recovery模式


2,接下我們就跟進/frameworks/base/core/java/android/os/PowerManager.java

在PowerManager.java中有如下代碼

 public void reboot(String reason)
    {
        try {
            mService.reboot(reason);//些處的mService就是PowerManagerService
        } catch (RemoteException e) {
        }
    }

 

3.于是我們來到了/frameworks/base/services/java/com/android/server/PowerManagerService.java

在PowerManagerService中的reboot如下,我們看到其實它是調用了ShutdownThread的reboot.

public void reboot(String reason)
    {
        .......
        Runnable runnable = new Runnable() {
            public void run() {
                synchronized (this) {
                    ShutdownThread.reboot(mContext, finalReason, false);//調用ShutdownThread的reboot
                }

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

4,讓我們跟進/frameworks/base/services/java/com/android/server/pm/ShutdownThread.java

我們看到其調用了shutdownInner函數

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

5shutdownInner函數如下,其調用了beginShutdownSequence(context);

static void shutdownInner(final Context context, boolean confirm) {
      ....
 if (confirm) {
            final CloseDialogReceiver closer = new CloseDialogReceiver(context);
            final AlertDialog dialog = new AlertDialog.Builder(context)
                    .setTitle(mRebootSafeMode
                            ? com.android.internal.R.string.reboot_safemode_title
                            : com.android.internal.R.string.power_off)
                    .setMessage(resourceId)
                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            beginShutdownSequence(context);//調用beginShutdownSequence
                        }
                    })
                    .setNegativeButton(com.android.internal.R.string.no, null)
                    .create();
            closer.dialog = dialog;
            dialog.setOnDismissListener(closer);
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
            dialog.show();
        } else {
            beginShutdownSequence(context);
        }
    }

6 beginShutdownSequence如下

 private static void beginShutdownSequence(Context context) {
        
		......
        sInstance.start();//從這兒就會開始調用到run()方法
    }

7在run()方法中也會做一些reboot之前的清除工作,關掉要關的服務等。基最終會調用
 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();
            }
        };

              ......省略
        // Set initial variables and time out time.
        mActionDone = false;
        final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
        synchronized (mActionDoneSync) {
            try {
                final IMountService mount = IMountService.Stub.asInterface(
                       ServiceManager.checkService("mount"));
                if (mount != null) {
                    mount.shutdown(observer);
               } else {
                    Log.w(TAG, "MountService unavailable for shutdown");
                }
            } catch (Exception e) {
                Log.e(TAG, "Exception during MountService shutdown", e);
            }
            while (!mActionDone) {
                long delay = endShutTime - SystemClock.elapsedRealtime();
                if (delay <= 0) {
                    Log.w(TAG, "Shutdown wait timed out");
                    break;
                }
                try {
                    mActionDoneSync.wait(delay);
                } catch (InterruptedException e) {
                }
            }
       }

        rebootOrShutdown(mReboot, mRebootReason);//又繞到rebootOrShutdown函數
    }

8在rebootOrShutdown函數中會根據reboot參數來決定是重啟還是關機
487    public static void rebootOrShutdown(boolean reboot, String reason) {
488        if (reboot) {
489            Log.i(TAG, "Rebooting, reason: " + reason);
490            try {
491                PowerManagerService.lowLevelReboot(reason);//我們偉進來的reboot參數為true,所以走這一支
492            } catch (Exception e) {
493                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
494            }
495        } else if (SHUTDOWN_VIBRATE_MS > 0) {
496            // vibrate before shutting down
497            Vibrator vibrator = new SystemVibrator();
498            try {
499                vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
500            } catch (Exception e) {
501                // Failure to vibrate shouldn't interrupt shutdown.  Just log it.
502                Log.w(TAG, "Failed to vibrate during shutdown.", e);
503            }
504
505            // vibrator is asynchronous so we need to wait to avoid shutting down too soon.
506            try {
507                Thread.sleep(SHUTDOWN_VIBRATE_MS);
508            } catch (InterruptedException unused) {
509            }
510        }
511
512        // Shutdown power
513        Log.i(TAG, "Performing low-level shutdown...");
514        PowerManagerService.lowLevelShutdown();//如果我們偉進來的reboot為false那就是關機
515    }
516}

9從上面的代碼我們又回到了PowerManagerService.其實就是要開一個線程來在reboot之前把要做的一些工作先做完。好吧,我們來看一下lowLevelReboot.
723    public static void lowLevelReboot(String reason) throws IOException {
724        nativeReboot(reason);//哈哈,還是要進入到時JNI
725    }

10我們繞來繞去其實最終還是要通過JNI和下邊交流。讓我們來看一下/frameworks/base/services/jni/com_android_server_PowerManagerService.cpp中的natievReboot是怎麼樣的
199static void nativeReboot(JNIEnv *env, jobject clazz, jstring reason) {
200    if (reason == NULL) {
201        android_reboot(ANDROID_RB_RESTART, 0, 0);//這兒是直接重啟,因為沒有偉reason,
202    } else {
203        const char *chars = env->GetStringUTFChars(reason, NULL);
204        android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);//這兒一般是上面偉入了recovery而重啟進入recovery,主要是oat或手機重置
205        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
206    }
207    jniThrowIOException(env, errno);
208}

11上面的anddroid_reboot在/system/core/libcutils/android_reboot.c中。接下來我們就看一下android_reboot()又做些什麽。
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://shutdown走的是這兒,其實reboot和shutdown就很相似,從powermanagerservice中才都是call了nativeReboot
120            ret = reboot(RB_POWER_OFF);
121            break;
122
123        case ANDROID_RB_RESTART2://當一開始偉入了recovery時會走這兒
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}
134

12上面的 reboot(RB_AUTOBOOT)又會call到/bionic/libc/unistd/reboot.c
int reboot (int  mode)
{
    return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL );
	//這兒的__reboot和上面的case ANDROID_RB_RESTART2的__reboot就是一樣的
}

13__reboot就到了/bionic/libc/arch-arm/syscalls/__reboot.S
這兒是一個內聯彙編的函數。通過swi軟中斷來重啟設備。到此android部份的代碼重啟流程就大致完成。其實我們剛才也注意到shutdown和reboot差不多走一樣的路線下來。
5ENTRY(__reboot)
6    .save   {r4, r7}
7    stmfd   sp!, {r4, r7}
8    ldr     r7, =__NR_reboot
9    swi     #0
10    ldmfd   sp!, {r4, r7}
11    movs    r0, r0
12    bxpl    lr
13    b       __set_syscall_errno
14END(__reboot)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值