diff options
9 files changed, 56 insertions, 25 deletions
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java index da8586c14256..e11d278399ce 100644 --- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java +++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java @@ -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."); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 2fe727cfaf72..cafccbf87265 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -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. @@ -3229,6 +3231,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 * of restarting the application. diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 16dac7d5ff27..4d6241b9ac06 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -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); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index d52dd3006a36..4b284ceeebf7 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -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) { } } diff --git a/core/java/com/android/internal/app/ShutdownActivity.java b/core/java/com/android/internal/app/ShutdownActivity.java index 97521cf68dd4..745d28f367a3 100644 --- a/core/java/com/android/internal/app/ShutdownActivity.java +++ b/core/java/com/android/internal/app/ShutdownActivity.java @@ -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) { } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 32c0fb82e9a3..01e36e1adcd2 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -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); } diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index 4c14c47c4eb8..8f041a5793ba 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -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() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 001a6f8011ed..85b2a41f6c5f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -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. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java index 39ebdfce2cf2..46aa117dc7cb 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java @@ -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. } |