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