下面是简单的流程图,从Java到kernel层。
ShutdownThread.java文件
stop playing music,因为后面可能要playing shutdown music.
代码如下:(我在Android6.0上沒有看到調用requestAudioFocus的代碼)
private static void beginShutdownSequence(Context context) {
....
//acquire audio focus to make the other apps to stop playing muisc
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(null,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
show system dialog to indicate phone is shutting down,如果没有关机动画的话,要show一个关机提示出来。
代码如下:
1 if (!checkAnimationFileExist()) {
2 // throw up an indeterminate system dialog to indicate radio is
3 // shutting down.
4 ProgressDialog pd = new ProgressDialog(context);
5 pd.setTitle(context.getText(com.android.internal.R.string.power_off));
6 pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
7 pd.setIndeterminate(true);
8 pd.setCancelable(false);
9 pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
10
11 pd.show();
12 }
Hold the wakelock,make sure we never fall asleep again,抓锁防止机器关机过程中休眠
代码如下:
1 sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(
2 PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu");//这个只是锁住cpu不进入休眠,但screen是off的,需full锁来保证screen常亮
3 sInstance.mCpuWakeLock.setReferenceCounted(false);
4 sInstance.mCpuWakeLock.acquire();
make sure the screen stays on,再抓一个full锁,防止屏幕半暗
代码如下:
1 sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(
2 PowerManager.FULL_WAKE_LOCK, TAG + "-screen");//保持srceen常亮
3 sInstance.mScreenWakeLock.setReferenceCounted(false);
4 sInstance.mScreenWakeLock.acquire();
sending shutdown broadcast,发出广播,通知各app该保存数据赶紧的,我要关机了
代码如下:
1 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
2 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
3 mContext.sendOrderedBroadcastAsUser(intent,//发广播
4 UserHandle.ALL, null, br, mHandler, 0, null, null);
shutdown activity manager,关闭activity manager,即关闭AppOpsService,UsageStatsService,BatteryStatsService
注意:Android L 与KK在关闭UsageStatsService上有所区别
代码如下:
[ActivityManagerService.java]
1 final IActivityManager am =
2 ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
3 if (am != null) {
4 try {
5 am.shutdown(MAX_BROADCAST_TIME);
6 } catch (RemoteException e) {
7 }
8 }
shutdown package manager,保存app使用时间到 disk里,这是android L新增的功能。
代码如下:
[PackageManagerService.java]
1 final PackageManagerService pm = (PackageManagerService)
2 ServiceManager.getService("package");
3 if (pm != null) {
4 pm.shutdown();
5 }
show shutdown animation,播放关机动画了
代码如下:
1 private static void showShutdownAnimation() {
2 /*
3 * When boot completed, "service.bootanim.exit" property is set to 1.
4 * Bootanimation checks this property to stop showing the boot animation.
5 * Since we use the same code for shutdown animation, we
6 * need to reset this property to 0. If this is not set to 0 then shutdown
7 * will stop and exit after displaying the first frame of the animation
8 */
9 SystemProperties.set("service.bootanim.exit", "0");
10
11 SystemProperties.set("ctl.start", "bootanim");//也是用bootanim进程,跟开关动画一样的方式。
12 }
shutdown radio[NFC,BT,MODEM],注意这里关闭modem这块与andorid KK的不一样。
代码如下:
shutdownRadios(MAX_RADIO_WAIT_TIME);
shutdown MountService,特别这里会导致关机失败。
代码如下:
1 // Set initial variables and time out time.
2 mActionDone = false;
3 final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
4 synchronized (mActionDoneSync) {
5 try {
6 fina