Merge "Revert encryption mapping for device wipes."
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index e0130b5..d1dc6e5 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -169,13 +169,15 @@
* is an asynchronous operation. Applications should register
* StorageEventListener for storage related status changes.
*/
- public void unmountVolume(String mountPoint, boolean force) throws RemoteException {
+ public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
+ throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(mountPoint);
_data.writeInt((force ? 1 : 0));
+ _data.writeInt((removeEncryption ? 1 : 0));
mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0);
_reply.readException();
} finally {
@@ -842,9 +844,9 @@
data.enforceInterface(DESCRIPTOR);
String mountPoint;
mountPoint = data.readString();
- boolean force;
- force = 0 != data.readInt();
- unmountVolume(mountPoint, force);
+ boolean force = 0 != data.readInt();
+ boolean removeEncrypt = 0 != data.readInt();
+ unmountVolume(mountPoint, force, removeEncrypt);
reply.writeNoException();
return true;
}
@@ -1234,8 +1236,14 @@
* Safely unmount external storage at given mount point. The unmount is an
* asynchronous operation. Applications should register StorageEventListener
* for storage related status changes.
+ * @param mountPoint the mount point
+ * @param force whether or not to forcefully unmount it (e.g. even if programs are using this
+ * data currently)
+ * @param removeEncryption whether or not encryption mapping should be removed from the volume.
+ * This value implies {@code force}.
*/
- public void unmountVolume(String mountPoint, boolean force) throws RemoteException;
+ public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
+ throws RemoteException;
/**
* Unregisters an IMountServiceListener
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
index 4773ce4..3905c88 100644
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
@@ -152,7 +152,8 @@
Environment.getExternalStorageDirectory().toString() :
mStorageVolume.getPath();
try {
- mountService.unmountVolume(extStoragePath, true);
+ // Remove encryption mapping if this is an unmount for a factory reset.
+ mountService.unmountVolume(extStoragePath, true, mFactoryReset);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with mount service", e);
}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 6c87c3b..68ddcc4 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -1057,7 +1057,7 @@
try {
// Wait on observer
synchronized(observer) {
- getMs().unmountVolume(path, true);
+ getMs().unmountVolume(path, true, false);
long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
observer.wait(WAIT_TIME_INCR);
diff --git a/core/tests/coretests/src/android/os/storage/AsecTests.java b/core/tests/coretests/src/android/os/storage/AsecTests.java
index dda3010..5efbd88 100755
--- a/core/tests/coretests/src/android/os/storage/AsecTests.java
+++ b/core/tests/coretests/src/android/os/storage/AsecTests.java
@@ -421,7 +421,7 @@
try {
// Wait on observer
synchronized(observer) {
- getMs().unmountVolume(path, false);
+ getMs().unmountVolume(path, false, false);
long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
observer.wait(WAIT_TIME_INCR);
@@ -486,7 +486,7 @@
// Wait on observer
synchronized(observer) {
for (int i = 0; i < 5; i++) {
- getMs().unmountVolume(path, false);
+ getMs().unmountVolume(path, false, false);
}
long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h
index 472d8e5..43df7f0 100644
--- a/include/storage/IMountService.h
+++ b/include/storage/IMountService.h
@@ -37,8 +37,8 @@
virtual void setUsbMassStorageEnabled(const bool enable) = 0;
virtual bool isUsbMassStorageEnabled() = 0;
virtual int32_t mountVolume(const String16& mountPoint) = 0;
- virtual int32_t
- unmountVolume(const String16& mountPoint, const bool force) = 0;
+ virtual int32_t unmountVolume(
+ const String16& mountPoint, const bool force, const bool removeEncryption) = 0;
virtual int32_t formatVolume(const String16& mountPoint) = 0;
virtual int32_t
getStorageUsers(const String16& mountPoint, int32_t** users) = 0;
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index 7fbf67a..8ddbeae 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -157,12 +157,13 @@
return reply.readInt32();
}
- int32_t unmountVolume(const String16& mountPoint, const bool force)
+ int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption)
{
Parcel data, reply;
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
data.writeString16(mountPoint);
data.writeInt32(force ? 1 : 0);
+ data.writeInt32(removeEncryption ? 1 : 0);
if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
LOGD("unmountVolume could not contact remote\n");
return -1;
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d806309..582f0ed 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -304,17 +304,19 @@
class UnmountCallBack {
final String path;
final boolean force;
+ final boolean removeEncryption;
int retries;
- UnmountCallBack(String path, boolean force) {
+ UnmountCallBack(String path, boolean force, boolean removeEncryption) {
retries = 0;
this.path = path;
this.force = force;
+ this.removeEncryption = removeEncryption;
}
void handleFinished() {
if (DEBUG_UNMOUNT) Slog.i(TAG, "Unmounting " + path);
- doUnmountVolume(path, true);
+ doUnmountVolume(path, true, removeEncryption);
}
}
@@ -322,7 +324,7 @@
final String method;
UmsEnableCallBack(String path, String method, boolean force) {
- super(path, force);
+ super(path, force, false);
this.method = method;
}
@@ -336,13 +338,13 @@
class ShutdownCallBack extends UnmountCallBack {
IMountShutdownObserver observer;
ShutdownCallBack(String path, IMountShutdownObserver observer) {
- super(path, true);
+ super(path, true, false);
this.observer = observer;
}
@Override
void handleFinished() {
- int ret = doUnmountVolume(path, true);
+ int ret = doUnmountVolume(path, true, removeEncryption);
if (observer != null) {
try {
observer.onShutDownComplete(ret);
@@ -888,8 +890,10 @@
* This might even take a while and might be retried after timed delays
* to make sure we dont end up in an instable state and kill some core
* processes.
+ * If removeEncryption is set, force is implied, and the system will remove any encryption
+ * mapping set on the volume when unmounting.
*/
- private int doUnmountVolume(String path, boolean force) {
+ private int doUnmountVolume(String path, boolean force, boolean removeEncryption) {
if (!getVolumeState(path).equals(Environment.MEDIA_MOUNTED)) {
return VoldResponseCode.OpFailedVolNotMounted;
}
@@ -905,8 +909,10 @@
// Redundant probably. But no harm in updating state again.
mPms.updateExternalMediaStatus(false, false);
try {
- mConnector.doCommand(String.format(
- "volume unmount %s%s", path, (force ? " force" : "")));
+ String arg = removeEncryption
+ ? " force_and_revert"
+ : (force ? " force" : "");
+ mConnector.doCommand(String.format("volume unmount %s%s", path, arg));
// We unmounted the volume. None of the asec containers are available now.
synchronized (mAsecMountSet) {
mAsecMountSet.clear();
@@ -1371,12 +1377,16 @@
return doMountVolume(path);
}
- public void unmountVolume(String path, boolean force) {
+ public void unmountVolume(String path, boolean force, boolean removeEncryption) {
validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
String volState = getVolumeState(path);
- if (DEBUG_UNMOUNT) Slog.i(TAG, "Unmounting " + path + " force = " + force);
+ if (DEBUG_UNMOUNT) {
+ Slog.i(TAG, "Unmounting " + path
+ + " force = " + force
+ + " removeEncryption = " + removeEncryption);
+ }
if (Environment.MEDIA_UNMOUNTED.equals(volState) ||
Environment.MEDIA_REMOVED.equals(volState) ||
Environment.MEDIA_SHARED.equals(volState) ||
@@ -1385,7 +1395,7 @@
// TODO return valid return code when adding observer call back.
return;
}
- UnmountCallBack ucb = new UnmountCallBack(path, force);
+ UnmountCallBack ucb = new UnmountCallBack(path, force, removeEncryption);
mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
}