Skip to content

Commit 8ff0c92

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "You can now long press on the power off menu to reboot to safe mode."
2 parents 7dc3d82 + 19caadc commit 8ff0c92

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

core/java/com/android/internal/app/ShutdownThread.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,15 @@ public final class ShutdownThread extends Thread {
6464
private static boolean sIsStarted = false;
6565

6666
private static boolean mReboot;
67+
private static boolean mRebootSafeMode;
6768
private static String mRebootReason;
6869

6970
// Provides shutdown assurance in case the system_server is killed
7071
public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
7172

73+
// Indicates whether we are rebooting into safe mode
74+
public static final String REBOOT_SAFEMODE_PROPERTY = "persist.sys.safemode";
75+
7276
// static instance of this thread
7377
private static final ShutdownThread sInstance = new ShutdownThread();
7478

@@ -92,6 +96,12 @@ private ShutdownThread() {
9296
* @param confirm true if user confirmation is needed before shutting down.
9397
*/
9498
public static void shutdown(final Context context, boolean confirm) {
99+
mReboot = false;
100+
mRebootSafeMode = false;
101+
shutdownInner(context, confirm);
102+
}
103+
104+
static void shutdownInner(final Context context, boolean confirm) {
95105
// ensure that only one thread is trying to power down.
96106
// any additional calls are just returned
97107
synchronized (sIsStartedGuard) {
@@ -103,16 +113,20 @@ public static void shutdown(final Context context, boolean confirm) {
103113

104114
final int longPressBehavior = context.getResources().getInteger(
105115
com.android.internal.R.integer.config_longPressOnPowerBehavior);
106-
final int resourceId = longPressBehavior == 2
107-
? com.android.internal.R.string.shutdown_confirm_question
108-
: com.android.internal.R.string.shutdown_confirm;
116+
final int resourceId = mRebootSafeMode
117+
? com.android.internal.R.string.reboot_safemode_confirm
118+
: (longPressBehavior == 2
119+
? com.android.internal.R.string.shutdown_confirm_question
120+
: com.android.internal.R.string.shutdown_confirm);
109121

110122
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
111123

112124
if (confirm) {
113125
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
114126
final AlertDialog dialog = new AlertDialog.Builder(context)
115-
.setTitle(com.android.internal.R.string.power_off)
127+
.setTitle(mRebootSafeMode
128+
? com.android.internal.R.string.reboot_safemode_title
129+
: com.android.internal.R.string.power_off)
116130
.setMessage(resourceId)
117131
.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
118132
public void onClick(DialogInterface dialog, int which) {
@@ -162,8 +176,23 @@ public void onDismiss(DialogInterface unused) {
162176
*/
163177
public static void reboot(final Context context, String reason, boolean confirm) {
164178
mReboot = true;
179+
mRebootSafeMode = false;
165180
mRebootReason = reason;
166-
shutdown(context, confirm);
181+
shutdownInner(context, confirm);
182+
}
183+
184+
/**
185+
* Request a reboot into safe mode. Must be called from a Looper thread in which its UI
186+
* is shown.
187+
*
188+
* @param context Context used to display the shutdown progress dialog.
189+
* @param confirm true if user confirmation is needed before shutting down.
190+
*/
191+
public static void rebootSafeMode(final Context context, boolean confirm) {
192+
mReboot = true;
193+
mRebootSafeMode = true;
194+
mRebootReason = null;
195+
shutdownInner(context, confirm);
167196
}
168197

169198
private static void beginShutdownSequence(Context context) {
@@ -254,6 +283,14 @@ public void run() {
254283
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
255284
}
256285

286+
/*
287+
* If we are rebooting into safe mode, write a system property
288+
* indicating so.
289+
*/
290+
if (mRebootSafeMode) {
291+
SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
292+
}
293+
257294
Log.i(TAG, "Sending shutdown broadcast...");
258295

259296
// First send the high-level shut down broadcast.

core/res/res/values/public.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,8 @@
708708
<java-symbol type="string" name="preposition_for_time" />
709709
<java-symbol type="string" name="progress_erasing" />
710710
<java-symbol type="string" name="progress_unmounting" />
711+
<java-symbol type="string" name="reboot_safemode_confirm" />
712+
<java-symbol type="string" name="reboot_safemode_title" />
711713
<java-symbol type="string" name="relationTypeAssistant" />
712714
<java-symbol type="string" name="relationTypeBrother" />
713715
<java-symbol type="string" name="relationTypeChild" />

core/res/res/values/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,15 @@
315315
power off dialog instead of the global actions menu. -->
316316
<string name="shutdown_confirm_question">Do you want to shut down?</string>
317317

318+
<!-- Title of dialog to confirm rebooting into safe mode. [CHAR LIMIT=50] -->
319+
<string name="reboot_safemode_title">Reboot to safe mode</string>
320+
321+
<!-- Shutdown Confirmation Dialog. Message in the confirmation dialog
322+
when the user asks to reboot into safe mode. [CHAR LIMIT=NONE] -->
323+
<string name="reboot_safemode_confirm">Do you want to reboot into safe mode?
324+
This will disable all third party applications you have installed.
325+
They will be restored when you reboot again.</string>
326+
318327
<!-- Recent Tasks dialog: title
319328
TODO: this should move to SystemUI.apk, but the code for the old
320329
recent dialog is still in the framework

policy/src/com/android/internal/policy/impl/GlobalActions.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import android.view.View;
4949
import android.view.ViewGroup;
5050
import android.view.WindowManager;
51+
import android.widget.AdapterView;
5152
import android.widget.BaseAdapter;
5253
import android.widget.ImageView;
5354
import android.widget.TextView;
@@ -181,6 +182,11 @@ public void onPress() {
181182
ShutdownThread.shutdown(mContext, true);
182183
}
183184

185+
public boolean onLongPress() {
186+
ShutdownThread.rebootSafeMode(mContext, true);
187+
return true;
188+
}
189+
184190
public boolean showDuringKeyguard() {
185191
return true;
186192
}
@@ -242,6 +248,15 @@ public boolean showBeforeProvisioning() {
242248

243249
final AlertDialog dialog = ab.create();
244250
dialog.getListView().setItemsCanFocus(true);
251+
dialog.getListView().setLongClickable(true);
252+
dialog.getListView().setOnItemLongClickListener(
253+
new AdapterView.OnItemLongClickListener() {
254+
@Override
255+
public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
256+
long id) {
257+
return mAdapter.getItem(position).onLongPress();
258+
}
259+
});
245260
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
246261

247262
dialog.setOnDismissListener(this);
@@ -365,6 +380,8 @@ private interface Action {
365380

366381
void onPress();
367382

383+
public boolean onLongPress();
384+
368385
/**
369386
* @return whether this action should appear in the dialog when the keygaurd
370387
* is showing.
@@ -406,6 +423,10 @@ public boolean isEnabled() {
406423

407424
abstract public void onPress();
408425

426+
public boolean onLongPress() {
427+
return false;
428+
}
429+
409430
public View create(
410431
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
411432
View v = inflater.inflate(R.layout.global_actions_item, parent, false);
@@ -530,6 +551,10 @@ public final void onPress() {
530551
changeStateFromPress(nowOn);
531552
}
532553

554+
public boolean onLongPress() {
555+
return false;
556+
}
557+
533558
public boolean isEnabled() {
534559
return !mState.inTransition();
535560
}
@@ -599,6 +624,10 @@ public View create(Context context, View convertView, ViewGroup parent,
599624
public void onPress() {
600625
}
601626

627+
public boolean onLongPress() {
628+
return false;
629+
}
630+
602631
public boolean showDuringKeyguard() {
603632
return true;
604633
}

services/java/com/android/server/wm/WindowManagerService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
3535

3636
import com.android.internal.app.IBatteryStats;
37+
import com.android.internal.app.ShutdownThread;
3738
import com.android.internal.policy.PolicyManager;
3839
import com.android.internal.policy.impl.PhoneWindowManager;
3940
import com.android.internal.view.IInputContext;
@@ -6505,6 +6506,13 @@ public boolean detectSafeMode() {
65056506
KeyEvent.KEYCODE_VOLUME_DOWN);
65066507
mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
65076508
|| volumeDownState > 0;
6509+
try {
6510+
if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6511+
mSafeMode = true;
6512+
SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6513+
}
6514+
} catch (IllegalArgumentException e) {
6515+
}
65086516
if (mSafeMode) {
65096517
Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
65106518
+ " dpad=" + dpadState + " trackball=" + trackballState + ")");

0 commit comments

Comments
 (0)