Merge "Improve the reboot-to-recovery dialogs" into mnc-dev
This commit is contained in:
@@ -414,8 +414,14 @@
|
||||
<string name="silent_mode_ring">Ringer on</string>
|
||||
|
||||
<!-- Reboot to Recovery Progress Dialog. This is shown before it reboots to recovery. -->
|
||||
<string name="reboot_to_recovery_title">Prepare for update</string>
|
||||
<string name="reboot_to_recovery_progress">Processing the update package\u2026</string>
|
||||
<string name="reboot_to_update_title">Android system update</string>
|
||||
<string name="reboot_to_update_prepare">Preparing to update\u2026</string>
|
||||
<string name="reboot_to_update_package">Processing the update package\u2026</string>
|
||||
<string name="reboot_to_update_reboot">Restarting\u2026</string>
|
||||
|
||||
<!-- Reboot to Recovery for factory reset. -->
|
||||
<string name="reboot_to_reset_title">Factory data reset</string>
|
||||
<string name="reboot_to_reset_message">Restarting\u2026</string>
|
||||
|
||||
<!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. -->
|
||||
<string name="shutdown_progress">Shutting down\u2026</string>
|
||||
|
||||
@@ -820,8 +820,12 @@
|
||||
<java-symbol type="string" name="mobile_provisioning_url" />
|
||||
<java-symbol type="string" name="mobile_redirected_provisioning_url" />
|
||||
<java-symbol type="string" name="quick_contacts_not_available" />
|
||||
<java-symbol type="string" name="reboot_to_recovery_progress" />
|
||||
<java-symbol type="string" name="reboot_to_recovery_title" />
|
||||
<java-symbol type="string" name="reboot_to_update_package" />
|
||||
<java-symbol type="string" name="reboot_to_update_prepare" />
|
||||
<java-symbol type="string" name="reboot_to_update_title" />
|
||||
<java-symbol type="string" name="reboot_to_update_reboot" />
|
||||
<java-symbol type="string" name="reboot_to_reset_title" />
|
||||
<java-symbol type="string" name="reboot_to_reset_message" />
|
||||
<java-symbol type="string" name="reboot_safemode_confirm" />
|
||||
<java-symbol type="string" name="reboot_safemode_title" />
|
||||
<java-symbol type="string" name="relationTypeAssistant" />
|
||||
|
||||
@@ -67,6 +67,12 @@ public final class ShutdownThread extends Thread {
|
||||
private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
|
||||
private static final int MAX_RADIO_WAIT_TIME = 12*1000;
|
||||
private static final int MAX_UNCRYPT_WAIT_TIME = 15*60*1000;
|
||||
// constants for progress bar. the values are roughly estimated based on timeout.
|
||||
private static final int BROADCAST_STOP_PERCENT = 2;
|
||||
private static final int ACTIVITY_MANAGER_STOP_PERCENT = 4;
|
||||
private static final int PACKAGE_MANAGER_STOP_PERCENT = 6;
|
||||
private static final int RADIO_STOP_PERCENT = 18;
|
||||
private static final int MOUNT_SERVICE_STOP_PERCENT = 20;
|
||||
|
||||
// length of vibration before shutting down
|
||||
private static final int SHUTDOWN_VIBRATE_MS = 500;
|
||||
@@ -75,11 +81,13 @@ public final class ShutdownThread extends Thread {
|
||||
private static Object sIsStartedGuard = new Object();
|
||||
private static boolean sIsStarted = false;
|
||||
|
||||
// uncrypt status file
|
||||
// uncrypt status files
|
||||
private static final String UNCRYPT_STATUS_FILE = "/cache/recovery/uncrypt_status";
|
||||
private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
|
||||
|
||||
private static boolean mReboot;
|
||||
private static boolean mRebootSafeMode;
|
||||
private static boolean mRebootUpdate;
|
||||
private static String mRebootReason;
|
||||
|
||||
// Provides shutdown assurance in case the system_server is killed
|
||||
@@ -203,6 +211,7 @@ public final class ShutdownThread extends Thread {
|
||||
public static void reboot(final Context context, String reason, boolean confirm) {
|
||||
mReboot = true;
|
||||
mRebootSafeMode = false;
|
||||
mRebootUpdate = false;
|
||||
mRebootReason = reason;
|
||||
shutdownInner(context, confirm);
|
||||
}
|
||||
@@ -222,6 +231,7 @@ public final class ShutdownThread extends Thread {
|
||||
|
||||
mReboot = true;
|
||||
mRebootSafeMode = true;
|
||||
mRebootUpdate = false;
|
||||
mRebootReason = null;
|
||||
shutdownInner(context, confirm);
|
||||
}
|
||||
@@ -235,16 +245,44 @@ public final class ShutdownThread extends Thread {
|
||||
sIsStarted = true;
|
||||
}
|
||||
|
||||
// throw up an indeterminate system dialog to indicate radio is
|
||||
// shutting down.
|
||||
// Throw up a system dialog to indicate the device is rebooting / shutting down.
|
||||
ProgressDialog pd = new ProgressDialog(context);
|
||||
|
||||
// Path 1: Reboot to recovery and install the update
|
||||
// Condition: mRebootReason == REBOOT_RECOVERY and mRebootUpdate == True
|
||||
// (mRebootUpdate is set by checking if /cache/recovery/uncrypt_file exists.)
|
||||
// UI: progress bar
|
||||
//
|
||||
// Path 2: Reboot to recovery for factory reset
|
||||
// Condition: mRebootReason == REBOOT_RECOVERY
|
||||
// UI: spinning circle only (no progress bar)
|
||||
//
|
||||
// Path 3: Regular reboot / shutdown
|
||||
// Condition: Otherwise
|
||||
// UI: spinning circle only (no progress bar)
|
||||
if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
|
||||
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_recovery_title));
|
||||
mRebootUpdate = new File(UNCRYPT_PACKAGE_FILE).exists();
|
||||
if (mRebootUpdate) {
|
||||
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_update_title));
|
||||
pd.setMessage(context.getText(
|
||||
com.android.internal.R.string.reboot_to_update_prepare));
|
||||
pd.setMax(100);
|
||||
pd.setProgressNumberFormat(null);
|
||||
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
pd.setProgress(0);
|
||||
pd.setIndeterminate(false);
|
||||
} else {
|
||||
// Factory reset path. Set the dialog message accordingly.
|
||||
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
|
||||
pd.setMessage(context.getText(
|
||||
com.android.internal.R.string.reboot_to_reset_message));
|
||||
pd.setIndeterminate(true);
|
||||
}
|
||||
} else {
|
||||
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.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
|
||||
pd.setIndeterminate(true);
|
||||
pd.setCancelable(false);
|
||||
pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
||||
|
||||
@@ -339,13 +377,20 @@ public final class ShutdownThread extends Thread {
|
||||
if (delay <= 0) {
|
||||
Log.w(TAG, "Shutdown broadcast timed out");
|
||||
break;
|
||||
} else if (mRebootUpdate) {
|
||||
int status = (int)((MAX_BROADCAST_TIME - delay) * 1.0 *
|
||||
BROADCAST_STOP_PERCENT / MAX_BROADCAST_TIME);
|
||||
sInstance.setRebootProgress(status, null);
|
||||
}
|
||||
try {
|
||||
mActionDoneSync.wait(delay);
|
||||
mActionDoneSync.wait(Math.min(delay, PHONE_STATE_POLL_SLEEP_MSEC));
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mRebootUpdate) {
|
||||
sInstance.setRebootProgress(BROADCAST_STOP_PERCENT, null);
|
||||
}
|
||||
|
||||
Log.i(TAG, "Shutting down activity manager...");
|
||||
|
||||
@@ -357,6 +402,9 @@ public final class ShutdownThread extends Thread {
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
if (mRebootUpdate) {
|
||||
sInstance.setRebootProgress(ACTIVITY_MANAGER_STOP_PERCENT, null);
|
||||
}
|
||||
|
||||
Log.i(TAG, "Shutting down package manager...");
|
||||
|
||||
@@ -365,9 +413,15 @@ public final class ShutdownThread extends Thread {
|
||||
if (pm != null) {
|
||||
pm.shutdown();
|
||||
}
|
||||
if (mRebootUpdate) {
|
||||
sInstance.setRebootProgress(PACKAGE_MANAGER_STOP_PERCENT, null);
|
||||
}
|
||||
|
||||
// Shutdown radios.
|
||||
shutdownRadios(MAX_RADIO_WAIT_TIME);
|
||||
if (mRebootUpdate) {
|
||||
sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);
|
||||
}
|
||||
|
||||
// Shutdown MountService to ensure media is in a safe state
|
||||
IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
|
||||
@@ -399,64 +453,44 @@ public final class ShutdownThread extends Thread {
|
||||
if (delay <= 0) {
|
||||
Log.w(TAG, "Shutdown wait timed out");
|
||||
break;
|
||||
} else if (mRebootUpdate) {
|
||||
int status = (int)((MAX_SHUTDOWN_WAIT_TIME - delay) * 1.0 *
|
||||
(MOUNT_SERVICE_STOP_PERCENT - RADIO_STOP_PERCENT) /
|
||||
MAX_SHUTDOWN_WAIT_TIME);
|
||||
status += RADIO_STOP_PERCENT;
|
||||
sInstance.setRebootProgress(status, null);
|
||||
}
|
||||
try {
|
||||
mActionDoneSync.wait(delay);
|
||||
mActionDoneSync.wait(Math.min(delay, PHONE_STATE_POLL_SLEEP_MSEC));
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mRebootUpdate) {
|
||||
sInstance.setRebootProgress(MOUNT_SERVICE_STOP_PERCENT, null);
|
||||
|
||||
// If it's to reboot into recovery, invoke uncrypt via init service.
|
||||
if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
|
||||
// If it's to reboot to install update, invoke uncrypt via init service.
|
||||
uncrypt();
|
||||
}
|
||||
|
||||
rebootOrShutdown(mContext, mReboot, mRebootReason);
|
||||
}
|
||||
|
||||
private void prepareUncryptProgress() {
|
||||
// Reset the dialog message to show the decrypt process.
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mProgressDialog != null) {
|
||||
mProgressDialog.dismiss();
|
||||
}
|
||||
// It doesn't work to change the style of the existing
|
||||
// one. Have to create a new one.
|
||||
ProgressDialog pd = new ProgressDialog(mContext);
|
||||
|
||||
pd.setTitle(mContext.getText(
|
||||
com.android.internal.R.string.reboot_to_recovery_title));
|
||||
pd.setMessage(mContext.getText(
|
||||
com.android.internal.R.string.reboot_to_recovery_progress));
|
||||
pd.setIndeterminate(false);
|
||||
pd.setMax(100);
|
||||
pd.setCancelable(false);
|
||||
pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
||||
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
pd.setProgressNumberFormat(null);
|
||||
pd.setProgress(0);
|
||||
|
||||
mProgressDialog = pd;
|
||||
mProgressDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUncryptProgress(final int progress) {
|
||||
private void setRebootProgress(final int progress, final CharSequence message) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mProgressDialog != null) {
|
||||
mProgressDialog.setProgress(progress);
|
||||
if (message != null) {
|
||||
mProgressDialog.setMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void shutdownRadios(int timeout) {
|
||||
private void shutdownRadios(final int timeout) {
|
||||
// If a radio is wedged, disabling it may hang so we do this work in another thread,
|
||||
// just in case.
|
||||
final long endTime = SystemClock.elapsedRealtime() + timeout;
|
||||
@@ -511,7 +545,15 @@ public final class ShutdownThread extends Thread {
|
||||
|
||||
Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
|
||||
|
||||
while (SystemClock.elapsedRealtime() < endTime) {
|
||||
long delay = endTime - SystemClock.elapsedRealtime();
|
||||
while (delay > 0) {
|
||||
if (mRebootUpdate) {
|
||||
int status = (int)((timeout - delay) * 1.0 *
|
||||
(RADIO_STOP_PERCENT - PACKAGE_MANAGER_STOP_PERCENT) / timeout);
|
||||
status += PACKAGE_MANAGER_STOP_PERCENT;
|
||||
sInstance.setRebootProgress(status, null);
|
||||
}
|
||||
|
||||
if (!bluetoothOff) {
|
||||
try {
|
||||
bluetoothOff = !bluetooth.isEnabled();
|
||||
@@ -552,6 +594,8 @@ public final class ShutdownThread extends Thread {
|
||||
break;
|
||||
}
|
||||
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
|
||||
|
||||
delay = endTime - SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -604,9 +648,6 @@ public final class ShutdownThread extends Thread {
|
||||
private void uncrypt() {
|
||||
Log.i(TAG, "Calling uncrypt and monitoring the progress...");
|
||||
|
||||
// Update the ProcessDialog message and style.
|
||||
sInstance.prepareUncryptProgress();
|
||||
|
||||
final boolean[] done = new boolean[1];
|
||||
done[0] = false;
|
||||
Thread t = new Thread() {
|
||||
@@ -627,25 +668,32 @@ public final class ShutdownThread extends Thread {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new FileReader(UNCRYPT_STATUS_FILE))) {
|
||||
|
||||
int last_status = Integer.MIN_VALUE;
|
||||
int lastStatus = Integer.MIN_VALUE;
|
||||
while (true) {
|
||||
String str = reader.readLine();
|
||||
try {
|
||||
int status = Integer.parseInt(str);
|
||||
|
||||
// Avoid flooding the log with the same message.
|
||||
if (status == last_status && last_status != Integer.MIN_VALUE) {
|
||||
if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
|
||||
continue;
|
||||
}
|
||||
last_status = status;
|
||||
lastStatus = status;
|
||||
|
||||
if (status >= 0 && status < 100) {
|
||||
// Update status
|
||||
Log.d(TAG, "uncrypt read status: " + status);
|
||||
sInstance.setUncryptProgress(status);
|
||||
// Scale down to [MOUNT_SERVICE_STOP_PERCENT, 100).
|
||||
status = (int)(status * (100.0 - MOUNT_SERVICE_STOP_PERCENT) / 100);
|
||||
status += MOUNT_SERVICE_STOP_PERCENT;
|
||||
CharSequence msg = mContext.getText(
|
||||
com.android.internal.R.string.reboot_to_update_package);
|
||||
sInstance.setRebootProgress(status, msg);
|
||||
} else if (status == 100) {
|
||||
Log.d(TAG, "uncrypt successfully finished.");
|
||||
sInstance.setUncryptProgress(status);
|
||||
CharSequence msg = mContext.getText(
|
||||
com.android.internal.R.string.reboot_to_update_reboot);
|
||||
sInstance.setRebootProgress(status, msg);
|
||||
break;
|
||||
} else {
|
||||
// Error in /system/bin/uncrypt. Or it's rebooting to recovery
|
||||
|
||||
Reference in New Issue
Block a user