红米手机进入down the roadroad模式怎么恢复

当前位置: &
down the road中文是什么意思
中文翻译将来的某个时候&&&& down3 n. 1.(装被、褥等用的)鸭绒 ...&&&&n. 1.路,道路;街〔略 Rd.〕;公路;行车道;路程 ...&&&&骑著自行车沿路飞奔而去&&&&沿这条路笔直走下去&&&&路的尽头&&&&坦克轰隆轰隆地沿路开过&&&&无目的地在路上徘徊&&&&汉下白登道&&&&国有公路,一级公路; 一级公路&&&&香港人在广州&&&&丁子路口; 丁字路口&&&&a级公路; 级公路&&&&公路运输; 旁道; 由公路&&&&在路旁&&&&为了送行, 祝一路平安
例句与用法The dog flew down the road after the cat .狗在马路上飞跑着追赶猫。There is a bus-stop down the road .路的前方有一个公共汽车站。We saw him running down the road stark naked .我们看见他一丝不挂地沿着街跑。Her house is half a mile down the road .她的房子位于这条路往前走半英里的地方。He has just popped down the road to the shops .他刚才急匆匆地沿这条路去商店了。Tanks thundered down the road .坦克轰隆轰隆地沿路开过。No word was exchanged, and they set out in silence down the road .他们相互都没说话,默默地沿着大路出发了。Jack tore down the road like the wind, with the ogre after him .杰克像一阵风似的在大道上飞跑,妖魔在后边穷追不放。None of the trucks had lights and they were moving down the road in a long convoy .没有一辆卡车开着灯,长长一列车队沿路驶来。Far down the road the sun glared cruelly against a tin sign nailed to a barn .沿路而下,只见太阳猛烈地照射在一个谷仓门上的白铁招牌上。更多例句:&&1&&&&&&&&&&
相邻词汇热门词汇
down the road的中文翻译,down the road是什么意思,怎么用汉语翻译down the road,down the road的中文意思,发音,例句,用法和解释由查查在线词典提供,版权所有违者必究。
&&&&&&&&&&&&&&&&
Copyright &
(京ICP备号)
All rights reserved现在的位置:
>, , >正文
Android L的Stock Recovery原始恢复模式现在多了reboot to bootloader与power down两个新的功能选项
同比较流行的第三方选择相较,Google Android的Stock Recovery原始恢复模式一直都是漂亮的,然后又弱着。说它漂亮,是因为它够简洁。说它弱着,因为它有一个情理之中的限制,它只能为你服务完全官方的写入或安装工作。比起CWM与TWRP等第三方的Recovery可以为你写入许多你想要的自定义的改装或Rom,Stock Recovery只能是弱着的吧。尽管如此,Android的Stock Recovery可以让你更放心,因为它的限制实际上是一种保护,以防出错或失效的保护。因此,在Android中,Stock Recovery总是少不了的。从这层上讲,许多官方的升级或优化等固件包必须要通过官方的Stock Recovery才能安装。
因此,作为一个Stock Recovery,我们只能希望它的功能越来越丰富。虽然这是一种希望,但实际上,Google并没有让你失望,它总是在慢慢地改进着Android的Stock Recovery。在最新的中,Stock Recovery便被发现了新的改进。
随着的发布,Stock Recovery已被发现获得了一点新的改进,它多了两个新的挺有用功能选项:
reboot to bootloader,即重启到Bootloader引导模式
power down,即关机
两个新的选项并非是什么开创性的功能,但它们仍然非常有用,尤其是reboot to bootloader,它大大地方便了你从方面做某些写入的工作。
本文固定链接:
【上篇】【下篇】
您可能还会对这些文章感兴趣!Android恢复出厂设置流程分析
Android恢复出厂设置流程分析【Android源码解析十】
最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程;
在setting--&备份与重置---&恢复出厂设置---&重置手机---&清除全部内容---&手机关机---&开机---&进行恢复出厂的操作---&开机流程;
1:前面找settings中的布局我就省略了,这部分相对简单一些,直接到清除全部内容这个按钮的操作,
对应的java类是setting中的MasterClearConfirm.java这个类,
private&Button.OnClickListener&mFinalClickListener&=&new&Button.OnClickListener()&{
&&&&&&&&public&void&onClick(View&v)&{
&&&&&&&&&&&&if&(Utils.isMonkeyRunning())&{
&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&}
&&&&&&&&&&&&if&(mEraseSdCard)&{
&&&&&&&&&&&&&&&&Intent&intent&=&new&Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
&&&&&&&&&&&&&&&&intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
&&&&&&&&&&&&&&&&getActivity().startService(intent);
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&getActivity().sendBroadcast(new&Intent("android.intent.action.MASTER_CLEAR"));
&&&&&&&&&&&&&&&&//&Intent&handling&is&asynchronous&--&assume&it&will&happen&soon.
&&&&&&&&&&&&}
private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
public void onClick(View v) {
if (Utils.isMonkeyRunning()) {
if (mEraseSdCard) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
getActivity().startService(intent);
getActivity().sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
// Intent handling is asynchronous -- assume it will happen soon.
通过上述的代码,可以看出,实际上点击清除全部内容的时候,如果前面勾选上格式哈SD卡,就会执行mEraseSdCard为true里面的逻辑,如果没有勾选,就执行mEraseSdCard=false的逻辑,其实就是发送一个广播,
“android.intent.action.MASTER_CLEAR”&&
“android.intent.action.MASTER_CLEAR”
2:这个广播接受的地方,参见AndroidManifest.xml中的代码,如下:
&&/SPAN&receiver&android:name="com.android.server.MasterClearReceiver"&&
&&&&&&&&&&&&android:permission="android.permission.MASTER_CLEAR"&&
&&&&&&&&&&&&android:priority="100"&&&&
&&&&&&&&&&&&&&/SPAN&intent-filter&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&/SPAN&action&android:name="android.intent.action.MASTER_CLEAR"&/&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&/SPAN&action&android:name="com.google.android.c2dm.intent.RECEIVE"&/&&&
&&&&&&&&&&&&&&&&&&/SPAN&category&android:name="android.intent.category.MASTER_CLEAR"&/&&&
&&&&&&&&&&&&&/&/SPAN&intent-filter&&&
&&&&&&&&&/&/SPAN&receiver&&&
找这个MasterClearReceiver.java这个receiver,下面来看看这个onReceiver()里面做了什么操作:
public&void&onReceive(final&Context&context,&final&Intent&intent)&{
&&&&&&&&if&(intent.getAction().equals(Intent.ACTION_REMOTE_INTENT))&{
&&&&&&&&&&&&if&(!"".equals(intent.getStringExtra("from")))&{
&&&&&&&&&&&&&&&&Slog.w(TAG,&"Ignoring&master&clear&request&--&not&from&trusted&server.");
&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&}
&&&&&&&&Slog.w(TAG,&"!!!&FACTORY&RESET&!!!");
&&&&&&&&//&The&reboot&call&is&blocking,&so&we&need&to&do&it&on&another&thread.
&&&&&&&&Thread&thr&=&new&Thread("Reboot")&{
&&&&&&&&&&&&@Override&&
&&&&&&&&&&&&public&void&run()&{
&&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&&RecoverySystem.rebootWipeUserData(context);
&&&&&&&&&&&&&&&&&&&&Log.wtf(TAG,&"Still&running&after&master&clear?!");
&&&&&&&&&&&&&&&&}&catch&(IOException&e)&{
&&&&&&&&&&&&&&&&&&&&Slog.e(TAG,&"Can't&perform&master&clear/factory&reset",&e);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&};
&&&&&&&&thr.start();
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
if (!"".equals(intent.getStringExtra("from"))) {
Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");
Slog.w(TAG, "!!! FACTORY RESET !!!");
// The reboot call is blocking, so we need to do it on another thread.
Thread thr = new Thread("Reboot") {
public void run() {
RecoverySystem.rebootWipeUserData(context);
Log.wtf(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
thr.start();
这个里面主要的操作是:RecoverySystem.rebootWipeUserData(context);准备做重启的动作,告诉手机要清除userData的数据;
3:接着来看看RecoverySystem.rebootWipeUserData()这个方法做了哪些操作:
public&static&void&rebootWipeUserData(Context&context)&throws&IOException&{
&&&&&&&&final&ConditionVariable&condition&=&new&ConditionVariable();
&&&&&&&&Intent&intent&=&new&Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
&&&&&&&&context.sendOrderedBroadcastAsUser(intent,&UserHandle.OWNER,
&&&&&&&&&&&&&&&&android.Manifest.permission.MASTER_CLEAR,
&&&&&&&&&&&&&&&&new&BroadcastReceiver()&{
&&&&&&&&&&&&&&&&&&&&@Override&&
&&&&&&&&&&&&&&&&&&&&public&void&onReceive(Context&context,&Intent&intent)&{
&&&&&&&&&&&&&&&&&&&&&&&&condition.open();
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&},&null,&0,&null,&null);
&&&&&&&&//&Block&until&the&ordered&broadcast&has&completed.
&&&&&&&&condition.block();
&&&&&&&&bootCommand(context,&"--wipe_data\n--locale="&+&Locale.getDefault().toString());
public static void rebootWipeUserData(Context context) throws IOException {
final ConditionVariable condition = new ConditionVariable();
Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
context.sendOrderedBroadcastAsUser(intent, UserHandle.OWNER,
android.Manifest.permission.MASTER_CLEAR,
new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
condition.open();
}, null, 0, null, null);
// Block until the ordered broadcast has completed.
condition.block();
bootCommand(context, "--wipe_data\n--locale=" + Locale.getDefault().toString());
这个里面的广播可以先忽略不计,重点来看看bootCommand()这个方法,注意这个参数“--wipe_data\n--locale=”
private&static&void&bootCommand(Context&context,&String&arg)&throws&IOException&{
&&&&&&&&RECOVERY_DIR.mkdirs();&&//&In&case&we&need&it
&&&&&&&&COMMAND_FILE.delete();&&//&In&case&it's&not&writable
&&&&&&&&LOG_FILE.delete();
&&&&&&&&FileWriter&command&=&new&FileWriter(COMMAND_FILE);
&&&&&&&&try&{
&&&&&&&&&&&&command.write(arg);
&&&&&&&&&&&&command.write("\n");
&&&&&&&&}&finally&{
&&&&&&&&&&&&command.close();
&&&&&&&&//&Having&written&the&command&file,&go&ahead&and&reboot
&&&&&&&&PowerManager&pm&=&(PowerManager)&context.getSystemService(Context.POWER_SERVICE);
&&&&&&&&pm.reboot("recovery");
&&&&&&&&throw&new&IOException("Reboot&failed&(no&permissions?)");
private static void bootCommand(Context context, String arg) throws IOException {
RECOVERY_DIR.mkdirs();
// In case we need it
COMMAND_FILE.delete();
// In case it's not writable
LOG_FILE.delete();
FileWriter command = new FileWriter(COMMAND_FILE);
command.write(arg);
command.write("\n");
} finally {
command.close();
// Having written the command file, go ahead and reboot
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
pm.reboot("recovery");
throw new IOException("Reboot failed (no permissions?)");
这个方法的操作大致是“写节点/cache/recovery/command”,把传递过来的字符串写进去;然后调用PowerManager进行重启操作,reboot();
4:接着我们来看看PowerManager的reboot方法做了哪些操作:
public&void&reboot(String&reason)&{
&&&&&&try&{
&&&&&&&&&&mService.reboot(false,&reason,&true);
&&&&&&}&catch&(RemoteException&e)&{
public void reboot(String reason) {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
这个调用到了PowerManagerService.java这个类的reboot方法中了:
@Override&//&Binder&call
&&&&public&void&reboot(boolean&confirm,&String&reason,&boolean&wait)&{
&&&&&&&&mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT,&null);
&&&&&&&&final&long&ident&=&Binder.clearCallingIdentity();
&&&&&&&&try&{
&&&&&&&&&&&&shutdownOrRebootInternal(false,&confirm,&reason,&wait);
&&&&&&&&}&finally&{
&&&&&&&&&&&&Binder.restoreCallingIdentity(ident);
@Override // Binder call
public void reboot(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity();
shutdownOrRebootInternal(false, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
重点来看看shutdownOrRebootInternal()这个方法,
private&void&shutdownOrRebootInternal(final&boolean&shutdown,&final&boolean&confirm,
&&&&&&&&&&&&final&String&reason,&boolean&wait)&{
&&&&&&&&if&(mHandler&==&null&||&!mSystemReady)&{
&&&&&&&&&&&&throw&new&IllegalStateException("Too&early&to&call&shutdown()&or&reboot()");
&&&&&&&&Runnable&runnable&=&new&Runnable()&{
&&&&&&&&&&&&@Override&&
&&&&&&&&&&&&public&void&run()&{
&&&&&&&&&&&&&&&&synchronized&(this)&{
&&&&&&&&&&&&&&&&&&&&if&(shutdown)&{
&&&&&&&&&&&&&&&&&&&&&&&&ShutdownThread.shutdown(mContext,&confirm);
&&&&&&&&&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&&&&&&&&&ShutdownThread.reboot(mContext,&reason,&confirm);
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&};
&&&&&&&&//&ShutdownThread&must&run&on&a&looper&capable&of&displaying&the&UI.
&&&&&&&&Message&msg&=&Message.obtain(mHandler,&runnable);
&&&&&&&&msg.setAsynchronous(true);
&&&&&&&&mHandler.sendMessage(msg);
&&&&&&&&//&PowerManager.reboot()&is&documented&not&to&return&so&just&wait&for&the&inevitable.
&&&&&&&&if&(wait)&{
&&&&&&&&&&&&synchronized&(runnable)&{
&&&&&&&&&&&&&&&&while&(true)&{
&&&&&&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&&&&&&runnable.wait();
&&&&&&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
throw new IllegalStateException("Too early to call shutdown() or reboot()");
Runnable runnable = new Runnable() {
public void run() {
synchronized (this) {
if (shutdown) {
ShutdownThread.shutdown(mContext, confirm);
ShutdownThread.reboot(mContext, reason, confirm);
// ShutdownThread must run on a looper capable of displaying the UI.
Message msg = Message.obtain(mHandler, runnable);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
// PowerManager.reboot() is documented not to return so just wait for the inevitable.
if (wait) {
synchronized (runnable) {
while (true) {
runnable.wait();
} catch (InterruptedException e) {
由于传递过来的shutdown为false,所以执行ShutdownThread.reboot(mContext,
reason, confirm);reason:recevory
下面调用到ShutdownThread
5:这个追踪ShutdownThread.reboot()这个方法,这就有点像破案电影,一点一点查找罪犯的难点;
来窥视一下这个类:
public&static&void&reboot(final&Context&context,&String&reason,&boolean&confirm)&{
&&&&&&&mReboot&=&true;
&&&&&&&mRebootSafeMode&=&false;
&&&&&&&mRebootReason&=&
&&&&&&&Log.d(TAG,&"reboot");
&&&&&&&shutdownInner(context,&confirm);
public static void reboot(final Context context, String reason, boolean confirm) {
mRebootSafeMode =
mRebootReason =
Log.d(TAG, "reboot");
shutdownInner(context, confirm);
这个里面做的操作就是给这个变量mRebootReason复制“recevory”,重点调用shutdownInner()这个方法;
static&void&shutdownInner(final&Context&context,&boolean&confirm)&{
&&&&&&&&//&ensure&that&only&one&thread&is&trying&to&power&down.
&&&&&&&&//&any&additional&calls&are&just&returned
&&&&&&&&synchronized&(sIsStartedGuard)&{
&&&&&&&&&&&&if&(sIsStarted)&{
&&&&&&&&&&&&&&&&Log.d(TAG,&"Request&to&shutdown&already&running,&returning.");
&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&}
&&&&&&&&Log.d(TAG,&"Notifying&thread&to&start&radio&shutdown");
&&&&&&&&bConfirmForAnimation&=&
&&&&&&&&final&int&longPressBehavior&=&context.getResources().getInteger(
&&&&&&&&&&&&&&&&com.android.internal.R.integer.config_longPressOnPowerBehavior);
&&&&&&&&final&int&resourceId&=&mRebootSafeMode
&&&&&&&&&&&&?&com.android.internal.R.string.reboot_safemode_confirm
&&&&&&&&&&&&:&(longPressBehavior&==&2&&
&&&&&&&&&&&&&&&&&&&&?&com.android.internal.R.string.shutdown_confirm_question
&&&&&&&&&&&&&&&&&&&&:&com.android.internal.R.string.shutdown_confirm);
&&&&&&&&Log.d(TAG,&"Notifying&thread&to&start&shutdown&longPressBehavior="&+&longPressBehavior);
&&&&&&&&if&(confirm)&{
&&&&&&&&&&&&final&CloseDialogReceiver&closer&=&new&CloseDialogReceiver(context);
&&&&&&&&&&&&if&(sConfirmDialog&!=&null)&{
&&&&&&&&&&&&&&&&sConfirmDialog.dismiss();
&&&&&&&&&&&&}
&&&&&&&&&&&&if&(sConfirmDialog&==&null)&{
&&&&&&&&&&&&&&&&Log.d(TAG,&"PowerOff&dialog&doesn't&exist.&Create&it&first");
&&&&&&&&&&&&&&&&sConfirmDialog&=&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);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(sConfirmDialog&!=&null)&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&sConfirmDialog&=&null;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&})
&&&&&&&&&&&&&&&&.setNegativeButton(com.android.internal.R.string.no,&new&DialogInterface.OnClickListener()&{
&&&&&&&&&&&&&&&&&&&&&&&&public&void&onClick(DialogInterface&dialog,&int&which)&{
&&&&&&&&&&&&&&&&&&&&&&&&synchronized&(sIsStartedGuard)&{
&&&&&&&&&&&&&&&&&&&&&&&&sIsStarted&=&false;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&if&(sConfirmDialog&!=&null)&{
&&&&&&&&&&&&&&&&&&&&&&&&sConfirmDialog&=&null;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&})
&&&&&&&&&&&&&&&&.create();
&&&&&&&&&&&&&&&&sConfirmDialog.setCancelable(false);//blocking&back&key
&&&&&&&&&&&&&&&&sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&sConfirmDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
&&&&&&&&&&&&}
&&&&&&&&&&&&closer.dialog&=&sConfirmD
&&&&&&&&&&&&sConfirmDialog.setOnDismissListener(closer);
&&&&&&&&&&&&if&(!sConfirmDialog.isShowing())&{
&&&&&&&&&&&&&&&&sConfirmDialog.show();
&&&&&&&&&&&&}
&&&&&&&&}&else&{
&&&&&&&&&&&&beginShutdownSequence(context);
static void shutdownInner(final Context context, boolean confirm) {
// ensure that only one thread is trying to power down.
// any additional calls are just returned
synchronized (sIsStartedGuard) {
if (sIsStarted) {
Log.d(TAG, "Request to shutdown already running, returning.");
Log.d(TAG, "Notifying thread to start radio shutdown");
bConfirmForAnimation =
final int longPressBehavior = context.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
final int resourceId = mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_confirm
: (longPressBehavior == 2
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm);
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
if (sConfirmDialog != null) {
sConfirmDialog.dismiss();
if (sConfirmDialog == null) {
Log.d(TAG, "PowerOff dialog doesn't exist. Create it first");
sConfirmDialog = 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);
if (sConfirmDialog != null) {
sConfirmDialog =
.setNegativeButton(com.android.internal.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
synchronized (sIsStartedGuard) {
sIsStarted =
if (sConfirmDialog != null) {
sConfirmDialog =
.create();
sConfirmDialog.setCancelable(false);//blocking back key
sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
sConfirmDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
closer.dialog = sConfirmD
sConfirmDialog.setOnDismissListener(closer);
if (!sConfirmDialog.isShowing()) {
sConfirmDialog.show();
beginShutdownSequence(context);
看beginShutdownSequence()这个方法吧,重点调用到这个方法里面去了,来瞅瞅这个方法:
private&static&void&beginShutdownSequence(Context&context)&{
&&&&&&&&synchronized&(sIsStartedGuard)&{
&&&&&&&&&&&&if&(sIsStarted)&{
&&&&&&&&&&&&&&&&Log.e(TAG,&"ShutdownThread&is&already&running,&returning.");&&&&&&&&
&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&}
&&&&&&&&&&&&sIsStarted&=&true;
&&&&&&&&//&start&the&thread&that&initiates&shutdown
&&&&&&&&sInstance.mContext&=&
&&&&&&&&sInstance.mPowerManager&=&(PowerManager)context.getSystemService(Context.POWER_SERVICE);
&&&&&&&&sInstance.mHandler&=&new&Handler()&{
&&&&&&&&};&&&&
&&&&&&&&bPlayaudio&=&true;
&&&&&&&&if&(!bConfirmForAnimation)&{
&&&&&&&&&&&&if&(!sInstance.mPowerManager.isScreenOn())&{
&&&&&&&&&&&&&&&&bPlayaudio&=&false;
&&&&&&&&&&&&}
&&&&&&&&//&throw&up&an&indeterminate&system&dialog&to&indicate&radio&is
&&&&&&&&//&shutting&down.
&&&&&&&&beginAnimationTime&=&0;
&&&&&&&&boolean&mShutOffAnimation&=&false;
&&&&&&&&try&{
&&&&&&&&&&&&if&(mIBootAnim&==&null)&{
&&&&&&&&&&&&&&&&mIBootAnim&=&MediatekClassFactory.createInstance(IBootAnimExt.class);
&&&&&&&&&&&&}
&&&&&&&&}&catch&(Exception&e)&{
&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&int&screenTurnOffTime&=&mIBootAnim.getScreenTurnOffTime();
&&&&&&&&mShutOffAnimation&=&mIBootAnim.isCustBootAnim();
&&&&&&&&Log.e(TAG,&"mIBootAnim&get&screenTurnOffTime&:&"&+&screenTurnOffTime);
&&&&&&&&String&cust&=&SystemProperties.get("ro.operator.optr");
&&&&&&&&if&(cust&!=&null)&{
&&&&&&&&&&&&if&(cust.equals("CUST"))&{
&&&&&&&&&&&&&&&&mShutOffAnimation&=&true;
&&&&&&&&&&&&}
&&&&&&&&synchronized&(mEnableAnimatingSync)&{
&&&&&&&&&&&&if(!mEnableAnimating)&{
//&&&&&&&&&&&&&&&&sInstance.mPowerManager.setBacklightBrightness(PowerManager.BRIGHTNESS_DIM);
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&if&(mShutOffAnimation)&{
&&&&&&&&&&&&&&&&&&&&Log.e(TAG,&"mIBootAnim.isCustBootAnim()&is&true");
&&&&&&&&&&&&&&&&&&&&bootanimCust();
&&&&&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&&&&&pd&=&new&ProgressDialog(context);
&&&&&&&&&&&&&&&&&&&&pd.setTitle(context.getText(com.android.internal.R.string.power_off));
&&&&&&&&&&&&&&&&&&&&pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
&&&&&&&&&&&&&&&&&&&&pd.setIndeterminate(true);
&&&&&&&&&&&&&&&&&&&&pd.setCancelable(false);
&&&&&&&&&&&&&&&&&&&&pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
&&&&&&&&&&&&&&&&&&&&pd.show();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&sInstance.mHandler.postDelayed(mDelayDim,&screenTurnOffTime&);&
&&&&&&&&&&&&}
&&&&&&&&//&make&sure&we&never&fall&asleep&again
&&&&&&&&sInstance.mCpuWakeLock&=&null;
&&&&&&&&try&{
&&&&&&&&&&&&sInstance.mCpuWakeLock&=&sInstance.mPowerManager.newWakeLock(
&&&&&&&&&&&&&&&&&&&&。。。&。。。
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
Log.e(TAG, "ShutdownThread is already running, returning.");
sIsStarted =
// start the thread that initiates shutdown
sInstance.mContext =
sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
sInstance.mHandler = new Handler() {
bPlayaudio =
if (!bConfirmForAnimation) {
if (!sInstance.mPowerManager.isScreenOn()) {
bPlayaudio =
// throw up an indeterminate system dialog to indicate radio is
// shutting down.
beginAnimationTime = 0;
boolean mShutOffAnimation =
if (mIBootAnim == null) {
mIBootAnim = MediatekClassFactory.createInstance(IBootAnimExt.class);
} catch (Exception e) {
e.printStackTrace();
int screenTurnOffTime = mIBootAnim.getScreenTurnOffTime();
mShutOffAnimation = mIBootAnim.isCustBootAnim();
Log.e(TAG, "mIBootAnim get screenTurnOffTime : " + screenTurnOffTime);
String cust = SystemProperties.get("ro.operator.optr");
if (cust != null) {
if (cust.equals("CUST")) {
mShutOffAnimation =
synchronized (mEnableAnimatingSync) {
if(!mEnableAnimating) {
sInstance.mPowerManager.setBacklightBrightness(PowerManager.BRIGHTNESS_DIM);
if (mShutOffAnimation) {
Log.e(TAG, "mIBootAnim.isCustBootAnim() is true");
bootanimCust();
pd = new ProgressDialog(context);
pd.setTitle(context.getText(com.android.internal.R.string.power_off));
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
pd.show();
sInstance.mHandler.postDelayed(mDelayDim, screenTurnOffTime );
// make sure we never fall asleep again
sInstance.mCpuWakeLock =
sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(
。。。 。。。
这段代码有句话会影响关机动画播放不完
“sInstance.mHandler.postDelayed(mDelayDim,
screenTurnOffTime );&”
(1)“可以把这个screenTurnOffTime时间乘以2,这个时间看log是5000毫秒,就是5秒,乘以2就是10秒,大概就能播放完全关机动画了。”
(2)把这句话注释掉,但是有可能会引起问题,导致恢复出厂设置的时候没有进行恢复出厂的操作。目前正在追踪此问题;
这段代码中还有影响关机动画是否走客制化的关机动画,如果ro.operator.optr这个属性配置的是CUST,则会走客制化的关机动画,否则走系统默认的关机动画;
String&cust&=&SystemProperties.get("ro.operator.optr");
&&&&&&&&if&(cust&!=&null)&{
&&&&&&&&&&&&if&(cust.equals("CUST"))&{
&&&&&&&&&&&&&&&&mShutOffAnimation&=&true;
&&&&&&&&&&&&}
&&&&&&&&}&&
String cust = SystemProperties.get("ro.operator.optr");
if (cust != null) {
if (cust.equals("CUST")) {
mShutOffAnimation =
然后重点看&sInstance.start();这个方法,就走到了run()方法里满了;
6: 来看看ShutDownThread.java这个类的run()方法;
public&void&run()&{
&&&&&&&&checkShutdownFlow();
&&&&&&&&while&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&&stMgr.saveStates(mContext);
&&&&&&&&&&&&stMgr.enterShutdown(mContext);
&&&&&&&&&&&&running();
&&&&&&&&}&
&&&&&&&&if&(mShutdownFlow&!=&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&&stMgr.enterShutdown(mContext);
&&&&&&&&&&&&running();
public void run() {
checkShutdownFlow();
while (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
stMgr.saveStates(mContext);
stMgr.enterShutdown(mContext);
running();
if (mShutdownFlow != IPO_SHUTDOWN_FLOW) {
stMgr.enterShutdown(mContext);
running();
重点看running()这个方法:
下面这个方法比较长,来分析一下:
public&void&running()&{
&&&&&&&if(sPreShutdownApi&!=&null){
&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&sPreShutdownApi.onPowerOff();
&&&&&&&&&&&}&catch&(RemoteException&e)&{
&&&&&&&&&&&&&&&Log.e(TAG,&"onPowerOff&exception"&+&e.getMessage());
&&&&&&&&&&&}
&&&&&&&}else{
&&&&&&&&&&&Log.w(TAG,&"sPreShutdownApi&is&null");
&&&&&&&command&=&SystemProperties.get("sys.ipo.pwrdncap");
&&&&&&&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");
&&&&&&&Log.i(TAG,&"Sending&shutdown&broadcast...");
&&&&&&&//&First&send&the&high-level&shut&down&broadcast.
&&&&&&&mActionDone&=&false;
&&&&&&&///&M:&&ALPS&@{
&&&&&&&mContext.sendBroadcast(new&Intent("android.intent.action.ACTION_PRE_SHUTDOWN"));
&&&&&&&///&@}&
&&&&&&&mContext.sendOrderedBroadcastAsUser((new&Intent()).setAction(Intent.ACTION_SHUTDOWN).putExtra("_mode",&mShutdownFlow),
&&&&&&&&&&&&&&&UserHandle.ALL,&null,&br,&mHandler,&0,&null,&null);
&&&&&&&final&long&endTime&=&SystemClock.elapsedRealtime()&+&MAX_BROADCAST_TIME;
&&&&&&&synchronized&(mActionDoneSync)&{
&&&&&&&&&&&while&(!mActionDone)&{
&&&&&&&&&&&&&&&long&delay&=&endTime&-&SystemClock.elapsedRealtime();
&&&&&&&&&&&&&&&if&(delay&&=&0)&{
&&&&&&&&&&&&&&&&&&&Log.w(TAG,&"Shutdown&broadcast&ACTION_SHUTDOWN&timed&out");
&&&&&&&&&&&&&&&&&&&if&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&&&&&&&&&&&&&Log.d(TAG,&"change&shutdown&flow&from&ipo&to&normal:&ACTION_SHUTDOWN&timeout");
&&&&&&&&&&&&&&&&&&&&&&&mShutdownFlow&=&NORMAL_SHUTDOWN_FLOW;
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&mActionDoneSync.wait(delay);
&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&//&Also&send&ACTION_SHUTDOWN_IPO&in&IPO&shut&down&flow
&&&&&&&if&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&mActionDone&=&false;
&&&&&&&&&&&mContext.sendOrderedBroadcast(new&Intent("android.intent.action.ACTION_SHUTDOWN_IPO"),&null,
&&&&&&&&&&&&&&&&&&&br,&mHandler,&0,&null,&null);
&&&&&&&&&&&final&long&endTimeIPO&=&SystemClock.elapsedRealtime()&+&MAX_BROADCAST_TIME;
&&&&&&&&&&&synchronized&(mActionDoneSync)&{
&&&&&&&&&&&&&&&while&(!mActionDone)&{
&&&&&&&&&&&&&&&&&&&long&delay&=&endTimeIPO&-&SystemClock.elapsedRealtime();
&&&&&&&&&&&&&&&&&&&if&(delay&&=&0)&{
&&&&&&&&&&&&&&&&&&&&&&&Log.w(TAG,&"Shutdown&broadcast&ACTION_SHUTDOWN_IPO&timed&out");
&&&&&&&&&&&&&&&&&&&&&&&if&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&Log.d(TAG,&"change&shutdown&flow&from&ipo&to&normal:&ACTION_SHUTDOWN_IPO&timeout");
&&&&&&&&&&&&&&&&&&&&&&&&&&&mShutdownFlow&=&NORMAL_SHUTDOWN_FLOW;
&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&&&&&mActionDoneSync.wait(delay);
&&&&&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&if&(mShutdownFlow&!=&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&&&&&Log.i(TAG,&"Shutting&down&activity&manager...");
&&&&&&&&&&&final&IActivityManager&am&=
&&&&&&&&&&&&&&&ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
&&&&&&&&&&&if&(am&!=&null)&{
&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&am.shutdown(MAX_BROADCAST_TIME);
&&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&//&Shutdown&radios.
&&&&&&&Log.i(TAG,&"Shutting&down&radios...");
&&&&&&&shutdownRadios(MAX_RADIO_WAIT_TIME);
&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&Log.i(TAG,&"Shutting&down&MountService...");
&&&&&&&if&(&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&&&&(command.equals("1")||command.equals("3"))&)&{
&&&&&&&&&&&Log.i(TAG,&"bypass&MountService!");
&&&&&&&}&else&{
&&&&&&&&&&&//&Shutdown&MountService&to&ensure&media&is&in&a&safe&state
&&&&&&&&&&&IMountShutdownObserver&observer&=&new&IMountShutdownObserver.Stub()&{
&&&&&&&&&&&&&&&public&void&onShutDownComplete(int&statusCode)&throws&RemoteException&{
&&&&&&&&&&&&&&&&&&&Log.w(TAG,&"Result&code&"&+&statusCode&+&"&from&MountService.shutdown");
&&&&&&&&&&&&&&&&&&&if&(statusCode&&&0)&{
&&&&&&&&&&&&&&&&&&&&&&&mShutdownFlow&=&NORMAL_SHUTDOWN_FLOW;&
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&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");
&&&&&&&&&&&&&&&&&&&&&&&if&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&Log.d(TAG,&"change&shutdown&flow&from&ipo&to&normal:&MountService");
&&&&&&&&&&&&&&&&&&&&&&&&&&&mShutdownFlow&=&NORMAL_SHUTDOWN_FLOW;
&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&&&&&mActionDoneSync.wait(delay);
&&&&&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{
&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&//mountSerivce&���
&&&&&&&Log.i(TAG,&"MountService&shut&done...");
&&&&&&&//&[MTK]&fix&shutdown&animation&timing&issue
&&&&&&&//==================================================================
&&&&&&&try&{
&&&&&&&&&&&SystemProperties.set("service.shutanim.running","1");
&&&&&&&&&&&Log.i(TAG,&"set&service.shutanim.running&to&1");
&&&&&&&}&catch&(Exception&ex)&{
&&&&&&&&&&&Log.e(TAG,&"Failed&to&set&'service.shutanim.running'&=&1).");
&&&&&&&//==================================================================
&&&&&&&if&(mShutdownFlow&==&IPO_SHUTDOWN_FLOW)&{
&&&&&&&&&&&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.
&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&Thread.sleep(SHUTDOWN_VIBRATE_MS);
&&&&&&&&&&&&&&&}&catch&(InterruptedException&unused)&{
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&&&&&//&Shutdown&power
&&&&&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&&&&&Log.i(TAG,&"Performing&ipo&low-level&shutdown...");
&&&&&&&&&&&delayForPlayAnimation();
&&&&&&&&&&&if&(sInstance.mScreenWakeLock&!=&null&&&&sInstance.mScreenWakeLock.isHeld())&{
&&&&&&&&&&&&&&&sInstance.mScreenWakeLock.release();
&&&&&&&&&&&&&&&sInstance.mScreenWakeLock&=&null;
&&&&&&&&&&&}
&&&&&&&&&&&sInstance.mHandler.removeCallbacks(mDelayDim);&
&&&&&&&&&&&stMgr.shutdown(mContext);
&&&&&&&&&&&stMgr.finishShutdown(mContext);
&&&&&&&&&&&//To&void&previous&UI&flick&caused&by&shutdown&animation&stopping&before&BKL&turning&off&&&&&&&&&
&&&&&&&&&&&if&(pd&!=&null)&{
&&&&&&&&&&&&&&&pd.dismiss();
&&&&&&&&&&&&&&&pd&=&null;
&&&&&&&&&&&}&else&if&(beginAnimationTime&&&0)&{
&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&SystemProperties.set("service.bootanim.exit","1");
&&&&&&&&&&&&&&&&&&&Log.i(TAG,&"set&'service.bootanim.exit'&=&1).");
&&&&&&&&&&&&&&&}&catch&(Exception&ex)&{
&&&&&&&&&&&&&&&&&&&Log.e(TAG,&"Failed&to&set&'service.bootanim.exit'&=&1).");
&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&&&&//SystemProperties.set("ctl.stop","bootanim");
&&&&&&&&&&&}
&&&&&&&&&&&synchronized&(sIsStartedGuard)&{
&&&&&&&&&&&&&&&sIsStarted&=&false;
&&&&&&&&&&&}
&&&&&&&&&&&sInstance.mPowerManager.setBacklightBrightnessOff(false);&
&&&&&&&&&&&sInstance.mCpuWakeLock.acquire(<font COLOR="#C0);&
&&&&&&&&&&&synchronized&(mShutdownThreadSync)&{
&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&mShutdownThreadSync.wait();
&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{
&&&&&&&&&&&&&&&}
&&&&&&&&&&&}
&&&&&&&}&else&{
&&&&&&&&&&&rebootOrShutdown(mReboot,&mRebootReason);
public void running() {
if(sPreShutdownApi != null){
sPreShutdownApi.onPowerOff();
} catch (RemoteException e) {
Log.e(TAG, "onPowerOff exception" + e.getMessage());
Log.w(TAG, "sPreShutdownApi is null");
command = SystemProperties.get("sys.ipo.pwrdncap");
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");
Log.i(TAG, "Sending shutdown broadcast...");
// First send the high-level shut down broadcast.
mActionDone =
mContext.sendBroadcast(new Intent("android.intent.action.ACTION_PRE_SHUTDOWN"));
mContext.sendOrderedBroadcastAsUser((new Intent()).setAction(Intent.ACTION_SHUTDOWN).putExtra("_mode", mShutdownFlow),
UserHandle.ALL, null, br, mHandler, 0, null, null);
final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
synchronized (mActionDoneSync) {
while (!mActionDone) {
long delay = endTime - SystemClock.elapsedRealtime();
if (delay &= 0) {
Log.w(TAG, "Shutdown broadcast ACTION_SHUTDOWN timed out");
if (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
Log.d(TAG, "change shutdown flow from ipo to normal: ACTION_SHUTDOWN timeout");
mShutdownFlow = NORMAL_SHUTDOWN_FLOW;
mActionDoneSync.wait(delay);
} catch (InterruptedException e) {
// Also send ACTION_SHUTDOWN_IPO in IPO shut down flow
if (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
mActionDone =
mContext.sendOrderedBroadcast(new Intent("android.intent.action.ACTION_SHUTDOWN_IPO"), null,
br, mHandler, 0, null, null);
final long endTimeIPO = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
synchronized (mActionDoneSync) {
while (!mActionDone) {
long delay = endTimeIPO - SystemClock.elapsedRealtime();
if (delay &= 0) {
Log.w(TAG, "Shutdown broadcast ACTION_SHUTDOWN_IPO timed out");
if (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
Log.d(TAG, "change shutdown flow from ipo to normal: ACTION_SHUTDOWN_IPO timeout");
mShutdownFlow = NORMAL_SHUTDOWN_FLOW;
mActionDoneSync.wait(delay);
} catch (InterruptedException e) {
if (mShutdownFlow != IPO_SHUTDOWN_FLOW) {
// power off auto test, don't modify
Log.i(TAG, "Shutting down activity manager...");
final IActivityManager am =
ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
if (am != null) {
am.shutdown(MAX_BROADCAST_TIME);
} catch (RemoteException e) {
// power off auto test, don't modify
// Shutdown radios.
Log.i(TAG, "Shutting down radios...");
shutdownRadios(MAX_RADIO_WAIT_TIME);
// power off auto test, don't modify
Log.i(TAG, "Shutting down MountService...");
if ( (mShutdownFlow == IPO_SHUTDOWN_FLOW) && (command.equals("1")||command.equals("3")) ) {
Log.i(TAG, "bypass MountService!");
// Shutdown MountService to ensure media is in a safe state
IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
public void onShutDownComplete(int statusCode) throws RemoteException {
Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown");
if (statusCode & 0) {
mShutdownFlow = NORMAL_SHUTDOWN_FLOW;
actionDone();
// Set initial variables and time out time.
mActionDone =
final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
synchronized (mActionDoneSync) {
final IMountService mount = IMountService.Stub.asInterface(
ServiceManager.checkService("mount"));
if (mount != null) {
mount.shutdown(observer);
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");
if (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
Log.d(TAG, "change shutdown flow from ipo to normal: MountService");
mShutdownFlow = NORMAL_SHUTDOWN_FLOW;
mActionDoneSync.wait(delay);
} catch (InterruptedException e) {
// power off auto test, don't modify
//mountSerivce &#65533;&#65533;&#65533;
Log.i(TAG, "MountService shut done...");
// [MTK] fix shutdown animation timing issue
//==================================================================
SystemProperties.set("service.shutanim.running","1");
Log.i(TAG, "set service.shutanim.running to 1");
} catch (Exception ex) {
Log.e(TAG, "Failed to set 'service.shutanim.running' = 1).");
//==================================================================
if (mShutdownFlow == IPO_SHUTDOWN_FLOW) {
if (SHUTDOWN_VIBRATE_MS & 0) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator();
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.
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
// Shutdown power
// power off auto test, don't modify
Log.i(TAG, "Performing ipo low-level shutdown...");
delayForPlayAnimation();
if (sInstance.mScreenWakeLock != null && sInstance.mScreenWakeLock.isHeld()) {
sInstance.mScreenWakeLock.release();
sInstance.mScreenWakeLock =
sInstance.mHandler.removeCallbacks(mDelayDim);
stMgr.shutdown(mContext);
stMgr.finishShutdown(mContext);
//To void previous UI flick caused by shutdown animation stopping before BKL turning off
if (pd != null) {
pd.dismiss();
} else if (beginAnimationTime & 0) {
SystemProperties.set("service.bootanim.exit","1");
Log.i(TAG, "set 'service.bootanim.exit' = 1).");
} catch (Exception ex) {
Log.e(TAG, "Failed to set 'service.bootanim.exit' = 1).");
//SystemProperties.set("ctl.stop","bootanim");
synchronized (sIsStartedGuard) {
sIsStarted =
sInstance.mPowerManager.setBacklightBrightnessOff(false);
sInstance.mCpuWakeLock.acquire(2000);
synchronized (mShutdownThreadSync) {
mShutdownThreadSync.wait();
} catch (InterruptedException e) {
rebootOrShutdown(mReboot, mRebootReason);
这个方法做了一些列的操作,会关闭一些操作,如:
&shutdownRadios(MAX_RADIO_WAIT_TIME);
mount.shutdown(observer);
stMgr.shutdown(mContext);
重点看& rebootOrShutdown(mReboot,
mRebootReason);这个方法;准备重启的方法;
7:来看看rebootOrShutdown()这个方法:
public&static&void&rebootOrShutdown(boolean&reboot,&String&reason)&{
&&&&&&&&if&(reboot)&{
&&&&&&&&&&&&Log.i(TAG,&"Rebooting,&reason:&"&+&reason);
&&&&&&&&&&&&if&(&(reason&!=&null)&&&&reason.equals("recovery")&)&{
&&&&&&&&&&&&&&&&delayForPlayAnimation();
&&&&&&&&&&&&}
&&&&&&&&&&&&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.
&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&Thread.sleep(SHUTDOWN_VIBRATE_MS);
&&&&&&&&&&&&}&catch&(InterruptedException&unused)&{
&&&&&&&&&&&&}
&&&&&&&&delayForPlayAnimation();
&&&&&&&&//&Shutdown&power
&&&&&&&&//&power&off&auto&test,&don't&modify
&&&&&&&&Log.i(TAG,&"Performing&low-level&shutdown...");
&&&&&&&&//PowerManagerService.lowLevelShutdown();
&&&&&&&&//add&your&func:&HDMI&off
&&&&&&&&//add&for&MFR
&&&&&&&&try&{
&&&&&&&&&&&&if&(ImHDMI&==&null)
&&&&&&&&&&&&&&&&ImHDMI=MediatekClassFactory.createInstance(IHDMINative.class);
&&&&&&&&}&catch&(Exception&e)&{
&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&
&&&&&&&&ImHDMI.hdmiPowerEnable(false);
&&&&&&&&try&{
&&&&&&&&&&&&if&(mTvOut&==&null)
&&&&&&&&&&&&&&&&mTvOut&=MediatekClassFactory.createInstance(ITVOUTNative.class);
&&&&&&&&}&catch&(Exception&e)&{
&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&
&&&&&&&&mTvOut.tvoutPowerEnable(false);
&&&&&&&&//add&your&func:&HDMI&off
&&&&&&&&//unmout&data/cache&partitions&while&performing&shutdown
&&&&&&&&SystemProperties.set("ctl.start",&"shutdown");
&&&&&&&&&&
&&&&&&&&try&{
&&&&&&&&&&&&Thread.currentThread().sleep(Integer.MAX_VALUE);
&&&&&&&&}&catch&(&Exception&e)&{
&&&&&&&&&&&&Log.e(TAG,&"Shutdown&rebootOrShutdown&Thread.currentThread().sleep&exception!");&&
public static void rebootOrShutdown(boolean reboot, String reason) {
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
if ( (reason != null) && reason.equals("recovery") ) {
delayForPlayAnimation();
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();
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.
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
delayForPlayAnimation();
// Shutdown power
// power off auto test, don't modify
Log.i(TAG, "Performing low-level shutdown...");
//PowerManagerService.lowLevelShutdown();
//add your func: HDMI off
//add for MFR
if (ImHDMI == null)
ImHDMI=MediatekClassFactory.createInstance(IHDMINative.class);
} catch (Exception e) {
e.printStackTrace();
ImHDMI.hdmiPowerEnable(false);
if (mTvOut == null)
mTvOut =MediatekClassFactory.createInstance(ITVOUTNative.class);
} catch (Exception e) {
e.printStackTrace();
mTvOut.tvoutPowerEnable(false);
//add your func: HDMI off
//unmout data/cache partitions while performing shutdown
SystemProperties.set("ctl.start", "shutdown");
Thread.currentThread().sleep(Integer.MAX_VALUE);
} catch ( Exception e) {
Log.e(TAG, "Shutdown rebootOrShutdown Thread.currentThread().sleep exception!");
关机震动也在这个方法里面;这个方法重点看PowerManagerService.lowLevelReboot(reason);
& Log.i(TAG, "Rebooting, reason: " +
reason);这句log也很重要,可以有助于我们分析代码;
8:下面来看看PowerManagerServices.java这个类的lowLevelReboot()这个方法:
public&static&void&lowLevelReboot(String&reason)&throws&IOException&{
&&&&&&&&nativeReboot(reason);
public static void lowLevelReboot(String reason) throws IOException {
nativeReboot(reason);
这个方法调用到了native里面,后面的操作我就不分析了。。。
大致流程是:
&关机,然后开机,底层判断节点后进入恢复出厂模式,recevory.img释放完全后,进入开机的流程。。。
以后有进展再补充这部分的流程,整个过程大致就是这个样子了,里面的细节有好多没有分析,大家可以自行研究。。。,抛砖引玉的目的达到了。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 hoan down the road 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信