Loading core/java/android/content/Intent.java +6 −0 Original line number Diff line number Diff line Loading @@ -2723,6 +2723,9 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; /** {@hide} */ public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). Loading Loading @@ -3425,6 +3428,9 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT = "android.intent.extra.TIME_PREF_24_HOUR_FORMAT"; /** {@hide} */ public static final String EXTRA_REASON = "android.intent.extra.REASON"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Intent flags (see mFlags variable). Loading core/java/android/os/RecoverySystem.java +58 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import java.io.ByteArrayInputStream; Loading Loading @@ -333,9 +334,10 @@ public class RecoverySystem { throws IOException { String filename = packageFile.getCanonicalPath(); Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!"); String arg = "--update_package=" + filename + "\n--locale=" + Locale.getDefault().toString(); bootCommand(context, arg); final String filenameArg = "--update_package=" + filename; final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, filenameArg, localeArg); } /** Loading @@ -352,7 +354,18 @@ public class RecoverySystem { * @throws SecurityException if the current user is not allowed to wipe data. */ public static void rebootWipeUserData(Context context) throws IOException { rebootWipeUserData(context, false); rebootWipeUserData(context, false, context.getPackageName()); } /** {@hide} */ public static void rebootWipeUserData(Context context, String reason) throws IOException { rebootWipeUserData(context, false, reason); } /** {@hide} */ public static void rebootWipeUserData(Context context, boolean shutdown) throws IOException { rebootWipeUserData(context, shutdown, context.getPackageName()); } /** Loading @@ -373,7 +386,7 @@ public class RecoverySystem { * * @hide */ public static void rebootWipeUserData(Context context, boolean shutdown) public static void rebootWipeUserData(Context context, boolean shutdown, String reason) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { Loading @@ -395,13 +408,18 @@ public class RecoverySystem { // Block until the ordered broadcast has completed. condition.block(); String shutdownArg = ""; String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after\n"; shutdownArg = "--shutdown_after"; } String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } bootCommand(context, shutdownArg + "--wipe_data\n--locale=" + Locale.getDefault().toString()); final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } /** Loading @@ -409,23 +427,38 @@ public class RecoverySystem { * @throws IOException if something goes wrong. */ public static void rebootWipeCache(Context context) throws IOException { bootCommand(context, "--wipe_cache\n--locale=" + Locale.getDefault().toString()); rebootWipeCache(context, context.getPackageName()); } /** {@hide} */ public static void rebootWipeCache(Context context, String reason) throws IOException { String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, "--wipe_cache", reasonArg, localeArg); } /** * Reboot into the recovery system with the supplied argument. * @param arg to pass to the recovery utility. * @param args to pass to the recovery utility. * @throws IOException if something goes wrong. */ private static void bootCommand(Context context, String arg) throws IOException { private static void bootCommand(Context context, String... args) throws IOException { RECOVERY_DIR.mkdirs(); // In case we need it COMMAND_FILE.delete(); // In case it's not writable LOG_FILE.delete(); FileWriter command = new FileWriter(COMMAND_FILE); try { for (String arg : args) { if (!TextUtils.isEmpty(arg)) { command.write(arg); command.write("\n"); } } } finally { command.close(); } Loading Loading @@ -470,5 +503,15 @@ public class RecoverySystem { return log; } /** * Internally, recovery treats each line of the command file as a separate * argv, so we only need to protect against newlines and nulls. */ private static String sanitizeArg(String arg) { arg = arg.replace('\0', '?'); arg = arg.replace('\n', '?'); return arg; } private void RecoverySystem() { } // Do not instantiate } core/java/com/android/internal/os/storage/ExternalStorageFormatter.java +14 −3 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ public class ExternalStorageFormatter extends Service private boolean mFactoryReset = false; private boolean mAlwaysReset = false; private String mReason = null; StorageEventListener mStorageListener = new StorageEventListener() { @Override Loading Loading @@ -84,6 +85,7 @@ public class ExternalStorageFormatter extends Service mAlwaysReset = true; } mReason = intent.getStringExtra(Intent.EXTRA_REASON); mStorageVolume = intent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME); if (mProgressDialog == null) { Loading Loading @@ -135,7 +137,10 @@ public class ExternalStorageFormatter extends Service void fail(int msg) { Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); if (mAlwaysReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); } stopSelf(); } Loading Loading @@ -179,7 +184,10 @@ public class ExternalStorageFormatter extends Service } if (success) { if (mFactoryReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); // Intent handling is asynchronous -- assume it will happen soon. stopSelf(); return; Loading @@ -188,7 +196,10 @@ public class ExternalStorageFormatter extends Service // If we didn't succeed, or aren't doing a full factory // reset, then it is time to remount the storage. if (!success && mAlwaysReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); } else { try { mountService.mountVolume(extStoragePath); Loading services/core/java/com/android/server/MasterClearReceiver.java +2 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class MasterClearReceiver extends BroadcastReceiver { } final boolean shutdown = intent.getBooleanExtra("shutdown", false); final String reason = intent.getStringExtra(Intent.EXTRA_REASON); Slog.w(TAG, "!!! FACTORY RESET !!!"); // The reboot call is blocking, so we need to do it on another thread. Loading @@ -45,7 +46,7 @@ public class MasterClearReceiver extends BroadcastReceiver { @Override public void run() { try { RecoverySystem.rebootWipeUserData(context, shutdown); RecoverySystem.rebootWipeUserData(context, shutdown, reason); Log.wtf(TAG, "Still running after master clear?!"); } catch (IOException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +23 −7 Original line number Diff line number Diff line Loading @@ -2862,7 +2862,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } void wipeDataLocked(int flags) { void wipeDataLocked(int flags, String reason) { // If the SD card is encrypted and non-removable, we have to force a wipe. boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted(); boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0; Loading @@ -2871,12 +2871,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) { Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET); intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true); intent.putExtra(Intent.EXTRA_REASON, reason); intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); mWakeLock.acquire(10000); mContext.startService(intent); } else { try { RecoverySystem.rebootWipeUserData(mContext); RecoverySystem.rebootWipeUserData(mContext, reason); } catch (IOException e) { Slog.w(LOG_TAG, "Failed requesting data wipe", e); } catch (SecurityException e) { Loading @@ -2885,6 +2886,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public void wipeData(int flags, final int userHandle) { if (!mHasFeature) { return; Loading @@ -2896,20 +2898,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(null, final ActiveAdmin admin = getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_WIPE_DATA); final String source; if (admin != null && admin.info != null) { final ComponentName cname = admin.info.getComponent(); if (cname != null) { source = cname.flattenToShortString(); } else { source = admin.info.getPackageName(); } } else { source = "?"; } long ident = Binder.clearCallingIdentity(); try { wipeDeviceOrUserLocked(flags, userHandle); wipeDeviceOrUserLocked(flags, userHandle, "DevicePolicyManager.wipeData() from " + source); } finally { Binder.restoreCallingIdentity(ident); } } } private void wipeDeviceOrUserLocked(int flags, final int userHandle) { private void wipeDeviceOrUserLocked(int flags, final int userHandle, String reason) { if (userHandle == UserHandle.USER_OWNER) { wipeDataLocked(flags); wipeDataLocked(flags, reason); } else { mHandler.post(new Runnable() { public void run() { Loading Loading @@ -3061,7 +3077,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (wipeData) { // Call without holding lock. wipeDeviceOrUserLocked(0, identifier); wipeDeviceOrUserLocked(0, identifier, "reportFailedPasswordAttempt()"); } } finally { Binder.restoreCallingIdentity(ident); Loading Loading
core/java/android/content/Intent.java +6 −0 Original line number Diff line number Diff line Loading @@ -2723,6 +2723,9 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; /** {@hide} */ public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). Loading Loading @@ -3425,6 +3428,9 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT = "android.intent.extra.TIME_PREF_24_HOUR_FORMAT"; /** {@hide} */ public static final String EXTRA_REASON = "android.intent.extra.REASON"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Intent flags (see mFlags variable). Loading
core/java/android/os/RecoverySystem.java +58 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import java.io.ByteArrayInputStream; Loading Loading @@ -333,9 +334,10 @@ public class RecoverySystem { throws IOException { String filename = packageFile.getCanonicalPath(); Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!"); String arg = "--update_package=" + filename + "\n--locale=" + Locale.getDefault().toString(); bootCommand(context, arg); final String filenameArg = "--update_package=" + filename; final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, filenameArg, localeArg); } /** Loading @@ -352,7 +354,18 @@ public class RecoverySystem { * @throws SecurityException if the current user is not allowed to wipe data. */ public static void rebootWipeUserData(Context context) throws IOException { rebootWipeUserData(context, false); rebootWipeUserData(context, false, context.getPackageName()); } /** {@hide} */ public static void rebootWipeUserData(Context context, String reason) throws IOException { rebootWipeUserData(context, false, reason); } /** {@hide} */ public static void rebootWipeUserData(Context context, boolean shutdown) throws IOException { rebootWipeUserData(context, shutdown, context.getPackageName()); } /** Loading @@ -373,7 +386,7 @@ public class RecoverySystem { * * @hide */ public static void rebootWipeUserData(Context context, boolean shutdown) public static void rebootWipeUserData(Context context, boolean shutdown, String reason) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { Loading @@ -395,13 +408,18 @@ public class RecoverySystem { // Block until the ordered broadcast has completed. condition.block(); String shutdownArg = ""; String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after\n"; shutdownArg = "--shutdown_after"; } String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } bootCommand(context, shutdownArg + "--wipe_data\n--locale=" + Locale.getDefault().toString()); final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } /** Loading @@ -409,23 +427,38 @@ public class RecoverySystem { * @throws IOException if something goes wrong. */ public static void rebootWipeCache(Context context) throws IOException { bootCommand(context, "--wipe_cache\n--locale=" + Locale.getDefault().toString()); rebootWipeCache(context, context.getPackageName()); } /** {@hide} */ public static void rebootWipeCache(Context context, String reason) throws IOException { String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, "--wipe_cache", reasonArg, localeArg); } /** * Reboot into the recovery system with the supplied argument. * @param arg to pass to the recovery utility. * @param args to pass to the recovery utility. * @throws IOException if something goes wrong. */ private static void bootCommand(Context context, String arg) throws IOException { private static void bootCommand(Context context, String... args) throws IOException { RECOVERY_DIR.mkdirs(); // In case we need it COMMAND_FILE.delete(); // In case it's not writable LOG_FILE.delete(); FileWriter command = new FileWriter(COMMAND_FILE); try { for (String arg : args) { if (!TextUtils.isEmpty(arg)) { command.write(arg); command.write("\n"); } } } finally { command.close(); } Loading Loading @@ -470,5 +503,15 @@ public class RecoverySystem { return log; } /** * Internally, recovery treats each line of the command file as a separate * argv, so we only need to protect against newlines and nulls. */ private static String sanitizeArg(String arg) { arg = arg.replace('\0', '?'); arg = arg.replace('\n', '?'); return arg; } private void RecoverySystem() { } // Do not instantiate }
core/java/com/android/internal/os/storage/ExternalStorageFormatter.java +14 −3 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ public class ExternalStorageFormatter extends Service private boolean mFactoryReset = false; private boolean mAlwaysReset = false; private String mReason = null; StorageEventListener mStorageListener = new StorageEventListener() { @Override Loading Loading @@ -84,6 +85,7 @@ public class ExternalStorageFormatter extends Service mAlwaysReset = true; } mReason = intent.getStringExtra(Intent.EXTRA_REASON); mStorageVolume = intent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME); if (mProgressDialog == null) { Loading Loading @@ -135,7 +137,10 @@ public class ExternalStorageFormatter extends Service void fail(int msg) { Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); if (mAlwaysReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); } stopSelf(); } Loading Loading @@ -179,7 +184,10 @@ public class ExternalStorageFormatter extends Service } if (success) { if (mFactoryReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); // Intent handling is asynchronous -- assume it will happen soon. stopSelf(); return; Loading @@ -188,7 +196,10 @@ public class ExternalStorageFormatter extends Service // If we didn't succeed, or aren't doing a full factory // reset, then it is time to remount the storage. if (!success && mAlwaysReset) { sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_REASON, mReason); sendBroadcast(intent); } else { try { mountService.mountVolume(extStoragePath); Loading
services/core/java/com/android/server/MasterClearReceiver.java +2 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class MasterClearReceiver extends BroadcastReceiver { } final boolean shutdown = intent.getBooleanExtra("shutdown", false); final String reason = intent.getStringExtra(Intent.EXTRA_REASON); Slog.w(TAG, "!!! FACTORY RESET !!!"); // The reboot call is blocking, so we need to do it on another thread. Loading @@ -45,7 +46,7 @@ public class MasterClearReceiver extends BroadcastReceiver { @Override public void run() { try { RecoverySystem.rebootWipeUserData(context, shutdown); RecoverySystem.rebootWipeUserData(context, shutdown, reason); Log.wtf(TAG, "Still running after master clear?!"); } catch (IOException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +23 −7 Original line number Diff line number Diff line Loading @@ -2862,7 +2862,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } void wipeDataLocked(int flags) { void wipeDataLocked(int flags, String reason) { // If the SD card is encrypted and non-removable, we have to force a wipe. boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted(); boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0; Loading @@ -2871,12 +2871,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) { Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET); intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true); intent.putExtra(Intent.EXTRA_REASON, reason); intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); mWakeLock.acquire(10000); mContext.startService(intent); } else { try { RecoverySystem.rebootWipeUserData(mContext); RecoverySystem.rebootWipeUserData(mContext, reason); } catch (IOException e) { Slog.w(LOG_TAG, "Failed requesting data wipe", e); } catch (SecurityException e) { Loading @@ -2885,6 +2886,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public void wipeData(int flags, final int userHandle) { if (!mHasFeature) { return; Loading @@ -2896,20 +2898,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(null, final ActiveAdmin admin = getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_WIPE_DATA); final String source; if (admin != null && admin.info != null) { final ComponentName cname = admin.info.getComponent(); if (cname != null) { source = cname.flattenToShortString(); } else { source = admin.info.getPackageName(); } } else { source = "?"; } long ident = Binder.clearCallingIdentity(); try { wipeDeviceOrUserLocked(flags, userHandle); wipeDeviceOrUserLocked(flags, userHandle, "DevicePolicyManager.wipeData() from " + source); } finally { Binder.restoreCallingIdentity(ident); } } } private void wipeDeviceOrUserLocked(int flags, final int userHandle) { private void wipeDeviceOrUserLocked(int flags, final int userHandle, String reason) { if (userHandle == UserHandle.USER_OWNER) { wipeDataLocked(flags); wipeDataLocked(flags, reason); } else { mHandler.post(new Runnable() { public void run() { Loading Loading @@ -3061,7 +3077,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (wipeData) { // Call without holding lock. wipeDeviceOrUserLocked(0, identifier); wipeDeviceOrUserLocked(0, identifier, "reportFailedPasswordAttempt()"); } } finally { Binder.restoreCallingIdentity(ident); Loading