am 158560ad
: Merge "Distinguish user-requested shutdown from power-related ones"
* commit '158560ad66f860ab9bb822f98a0ef9cf3afa922f': Distinguish user-requested shutdown from power-related ones
This commit is contained in:
@ -93,7 +93,7 @@ public class PowerCommand extends Svc.Command {
|
||||
} else if ("shutdown".equals(args[1])) {
|
||||
try {
|
||||
// no confirm, wait till device is off
|
||||
pm.shutdown(false, true);
|
||||
pm.shutdown(false, null, true);
|
||||
} catch (RemoteException e) {
|
||||
System.err.println("Failed to shutdown.");
|
||||
}
|
||||
|
@ -2018,7 +2018,9 @@ public class Intent implements Parcelable, Cloneable {
|
||||
/**
|
||||
* Activity Action: Start this activity to request system shutdown.
|
||||
* The optional boolean extra field {@link #EXTRA_KEY_CONFIRM} can be set to true
|
||||
* to request confirmation from the user before shutting down.
|
||||
* to request confirmation from the user before shutting down. The optional boolean
|
||||
* extra field {@link #EXTRA_USER_REQUESTED_SHUTDOWN} can be set to true to
|
||||
* indicate that the shutdown is requested by the user.
|
||||
*
|
||||
* <p class="note">This is a protected intent that can only be sent
|
||||
* by the system.
|
||||
@ -3228,6 +3230,15 @@ public class Intent implements Parcelable, Cloneable {
|
||||
*/
|
||||
public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
|
||||
|
||||
/**
|
||||
* Set to true in {@link #ACTION_REQUEST_SHUTDOWN} to indicate that the shutdown is
|
||||
* requested by the user.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public static final String EXTRA_USER_REQUESTED_SHUTDOWN =
|
||||
"android.intent.extra.USER_REQUESTED_SHUTDOWN";
|
||||
|
||||
/**
|
||||
* Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
|
||||
* {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
|
||||
|
@ -45,7 +45,7 @@ interface IPowerManager
|
||||
boolean setPowerSaveMode(boolean mode);
|
||||
|
||||
void reboot(boolean confirm, String reason, boolean wait);
|
||||
void shutdown(boolean confirm, boolean wait);
|
||||
void shutdown(boolean confirm, String reason, boolean wait);
|
||||
void crash(String message);
|
||||
|
||||
void setStayOnSetting(int val);
|
||||
|
@ -367,7 +367,13 @@ public final class PowerManager {
|
||||
* @hide
|
||||
*/
|
||||
public static final String REBOOT_RECOVERY = "recovery";
|
||||
|
||||
|
||||
/**
|
||||
* The value to pass as the 'reason' argument to android_reboot().
|
||||
* @hide
|
||||
*/
|
||||
public static final String SHUTDOWN_USER_REQUESTED = "userrequested";
|
||||
|
||||
final Context mContext;
|
||||
final IPowerManager mService;
|
||||
final Handler mHandler;
|
||||
@ -838,13 +844,14 @@ public final class PowerManager {
|
||||
* Turn off the device.
|
||||
*
|
||||
* @param confirm If true, shows a shutdown confirmation dialog.
|
||||
* @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
|
||||
* @param wait If true, this call waits for the shutdown to complete and does not return.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void shutdown(boolean confirm, boolean wait) {
|
||||
public void shutdown(boolean confirm, String reason, boolean wait) {
|
||||
try {
|
||||
mService.shutdown(confirm, wait);
|
||||
mService.shutdown(confirm, reason, wait);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IPowerManager;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Slog;
|
||||
@ -30,6 +31,7 @@ public class ShutdownActivity extends Activity {
|
||||
private static final String TAG = "ShutdownActivity";
|
||||
private boolean mReboot;
|
||||
private boolean mConfirm;
|
||||
private boolean mUserRequested;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -38,6 +40,7 @@ public class ShutdownActivity extends Activity {
|
||||
Intent intent = getIntent();
|
||||
mReboot = Intent.ACTION_REBOOT.equals(intent.getAction());
|
||||
mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
|
||||
mUserRequested = intent.getBooleanExtra(Intent.EXTRA_USER_REQUESTED_SHUTDOWN, false);
|
||||
Slog.i(TAG, "onCreate(): confirm=" + mConfirm);
|
||||
|
||||
Thread thr = new Thread("ShutdownActivity") {
|
||||
@ -49,7 +52,9 @@ public class ShutdownActivity extends Activity {
|
||||
if (mReboot) {
|
||||
pm.reboot(mConfirm, null, false);
|
||||
} else {
|
||||
pm.shutdown(mConfirm, false);
|
||||
pm.shutdown(mConfirm,
|
||||
mUserRequested ? PowerManager.SHUTDOWN_USER_REQUESTED : null,
|
||||
false);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
|
@ -2180,7 +2180,7 @@ public final class PowerManagerService extends SystemService
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
if (shutdown) {
|
||||
ShutdownThread.shutdown(mContext, confirm);
|
||||
ShutdownThread.shutdown(mContext, reason, confirm);
|
||||
} else {
|
||||
ShutdownThread.reboot(mContext, reason, confirm);
|
||||
}
|
||||
@ -2349,9 +2349,14 @@ public final class PowerManagerService extends SystemService
|
||||
/**
|
||||
* Low-level function turn the device off immediately, without trying
|
||||
* to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
|
||||
*
|
||||
* @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
|
||||
*/
|
||||
public static void lowLevelShutdown() {
|
||||
SystemProperties.set("sys.powerctl", "shutdown");
|
||||
public static void lowLevelShutdown(String reason) {
|
||||
if (reason == null) {
|
||||
reason = "";
|
||||
}
|
||||
SystemProperties.set("sys.powerctl", "shutdown," + reason);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3056,12 +3061,12 @@ public final class PowerManagerService extends SystemService
|
||||
* @param wait If true, this call waits for the shutdown to complete and does not return.
|
||||
*/
|
||||
@Override // Binder call
|
||||
public void shutdown(boolean confirm, boolean wait) {
|
||||
public void shutdown(boolean confirm, String reason, boolean wait) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
shutdownOrRebootInternal(true, confirm, null, wait);
|
||||
shutdownOrRebootInternal(true, confirm, reason, wait);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ public final class ShutdownThread extends Thread {
|
||||
private static boolean mReboot;
|
||||
private static boolean mRebootSafeMode;
|
||||
private static boolean mRebootUpdate;
|
||||
private static String mRebootReason;
|
||||
private static String mReason;
|
||||
|
||||
// Provides shutdown assurance in case the system_server is killed
|
||||
public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
|
||||
@ -123,11 +123,13 @@ public final class ShutdownThread extends Thread {
|
||||
* is shown.
|
||||
*
|
||||
* @param context Context used to display the shutdown progress dialog.
|
||||
* @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
|
||||
* @param confirm true if user confirmation is needed before shutting down.
|
||||
*/
|
||||
public static void shutdown(final Context context, boolean confirm) {
|
||||
public static void shutdown(final Context context, String reason, boolean confirm) {
|
||||
mReboot = false;
|
||||
mRebootSafeMode = false;
|
||||
mReason = reason;
|
||||
shutdownInner(context, confirm);
|
||||
}
|
||||
|
||||
@ -211,7 +213,7 @@ public final class ShutdownThread extends Thread {
|
||||
mReboot = true;
|
||||
mRebootSafeMode = false;
|
||||
mRebootUpdate = false;
|
||||
mRebootReason = reason;
|
||||
mReason = reason;
|
||||
shutdownInner(context, confirm);
|
||||
}
|
||||
|
||||
@ -226,7 +228,7 @@ public final class ShutdownThread extends Thread {
|
||||
mReboot = true;
|
||||
mRebootSafeMode = true;
|
||||
mRebootUpdate = false;
|
||||
mRebootReason = null;
|
||||
mReason = null;
|
||||
shutdownInner(context, confirm);
|
||||
}
|
||||
|
||||
@ -243,18 +245,18 @@ public final class ShutdownThread extends Thread {
|
||||
ProgressDialog pd = new ProgressDialog(context);
|
||||
|
||||
// Path 1: Reboot to recovery and install the update
|
||||
// Condition: mRebootReason == REBOOT_RECOVERY and mRebootUpdate == True
|
||||
// Condition: mReason == 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
|
||||
// Condition: mReason == 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)) {
|
||||
if (PowerManager.REBOOT_RECOVERY.equals(mReason)) {
|
||||
mRebootUpdate = new File(UNCRYPT_PACKAGE_FILE).exists();
|
||||
if (mRebootUpdate) {
|
||||
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_update_title));
|
||||
@ -343,7 +345,7 @@ public final class ShutdownThread extends Thread {
|
||||
* the beginning of the SystemServer startup.
|
||||
*/
|
||||
{
|
||||
String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
|
||||
String reason = (mReboot ? "1" : "0") + (mReason != null ? mReason : "");
|
||||
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
|
||||
}
|
||||
|
||||
@ -467,7 +469,7 @@ public final class ShutdownThread extends Thread {
|
||||
uncrypt();
|
||||
}
|
||||
|
||||
rebootOrShutdown(mContext, mReboot, mRebootReason);
|
||||
rebootOrShutdown(mContext, mReboot, mReason);
|
||||
}
|
||||
|
||||
private void setRebootProgress(final int progress, final CharSequence message) {
|
||||
@ -610,13 +612,14 @@ public final class ShutdownThread extends Thread {
|
||||
*
|
||||
* @param context Context used to vibrate or null without vibration
|
||||
* @param reboot true to reboot or false to shutdown
|
||||
* @param reason reason for reboot
|
||||
* @param reason reason for reboot/shutdown
|
||||
*/
|
||||
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
|
||||
if (reboot) {
|
||||
Log.i(TAG, "Rebooting, reason: " + reason);
|
||||
PowerManagerService.lowLevelReboot(reason);
|
||||
Log.e(TAG, "Reboot failed, will attempt shutdown instead");
|
||||
reason = null;
|
||||
} else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
|
||||
// vibrate before shutting down
|
||||
Vibrator vibrator = new SystemVibrator(context);
|
||||
@ -636,7 +639,7 @@ public final class ShutdownThread extends Thread {
|
||||
|
||||
// Shutdown power
|
||||
Log.i(TAG, "Performing low-level shutdown...");
|
||||
PowerManagerService.lowLevelShutdown();
|
||||
PowerManagerService.lowLevelShutdown(reason);
|
||||
}
|
||||
|
||||
private void uncrypt() {
|
||||
|
@ -5679,7 +5679,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
// Called by window manager policy. Not exposed externally.
|
||||
@Override
|
||||
public void shutdown(boolean confirm) {
|
||||
ShutdownThread.shutdown(mContext, confirm);
|
||||
ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
|
||||
}
|
||||
|
||||
// Called by window manager policy. Not exposed externally.
|
||||
|
@ -86,7 +86,7 @@ public class BridgePowerManager implements IPowerManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(boolean confirm, boolean wait) {
|
||||
public void shutdown(boolean confirm, String reason, boolean wait) {
|
||||
// pass for now.
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user