GP37W2怎么恢复出厂设置会怎么样

12459人阅读
& & & 最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程;& & & 在setting--&备份与重置---&恢复出厂设置---&重置手机---&清除全部内容---&手机关机---&开机---&进行恢复出厂的操作---&开机流程;& & & Step 1:前面找settings中的布局我就省略了,这部分相对简单一些,直接到清除全部内容这个按钮的操作,& & 对应的java类是setting中的MasterClearConfirm.java这个类,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.PONENT_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”& & & & Step 2:这个广播接受的地方,参见AndroidManifest.xml中的代码,如下:&receiver android:name=&com.android.server.MasterClearReceiver&
android:permission=&android.permission.MASTER_CLEAR&
android:priority=&100& &
&intent-filter&
&!-- For Checkin, Settings, etc.: action=MASTER_CLEAR --&
&action android:name=&android.intent.action.MASTER_CLEAR& /&
&!-- MCS always uses REMOTE_INTENT: category=MASTER_CLEAR --&
&action android:name=&com.google.android.c2dm.intent.RECEIVE& /&
&category android:name=&android.intent.category.MASTER_CLEAR& /&
&/intent-filter&
&/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.&);
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的数据;& & & Step 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() {
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);
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();& & Step 4:接着我们来看看PowerManager的reboot方法做了哪些操作:
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();
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() {
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& & Step 5:这个追踪ShutdownThread.reboot()这个方法,这就有点像破案电影,一点一点查找罪犯的难点;来窥视一下这个类: 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.&);
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);
/*if (!context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_slowBlur)) {
sConfirmDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
/* To fix video+UI+blur flick issue */
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.&);
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);
/* To fix video+UI+blur flick issue */
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 =
}然后重点看&sInstance.start();这个方法,就走到了run()方法里满了;& & Step 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();
}重点看running()这个方法:下面这个方法比较长,来分析一下: 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();
* Write a system property in case the system_server reboots before we
* get to the actual hardware restart. If that happens, we'll retry at
* the beginning of the SystemServer startup.
String reason = (mReboot ? &1& : &0&) + (mRebootReason != null ? mRebootReason : &&);
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
* If we are rebooting into safe mode, write a system property
* indicating so.
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 ???
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);这个方法;准备重启的方法;& &Step 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();
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&);
/* sleep for a long time, prevent start another service */
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也很重要,可以有助于我们分析代码;& & Step 8:下面来看看PowerManagerServices.java这个类的lowLevelReboot()这个方法:public static void lowLevelReboot(String reason) throws IOException {
nativeReboot(reason);
}这个方法调用到了native里面,后面的操作我就不分析了。。。大致流程是:& &关机,然后开机,底层判断节点后进入恢复出厂模式,recevory.img释放完全后,进入开机的流程。。。以后有进展再补充这部分的流程,整个过程大致就是这个样子了,里面的细节有好多没有分析,大家可以自行研究。。。,抛砖引玉的目的达到了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
AndroidQQ群一:; AndroidQQ群二:; AndroidQQ群三:;

我要回帖

更多关于 恢复出厂设置会怎么样 的文章

 

随机推荐