From 13c7197da8a16f77f6398708a6314c80cb01e0d1 Mon Sep 17 00:00:00 2001 From: Ben Komalo Date: Wed, 7 Sep 2011 16:35:56 -0700 Subject: [PATCH] Revert encryption mapping for device wipes. External storage volumes that were emulated+encrypted needed to have their encryption mapping removed so that it doesn't try to encrypt the volume after formatting them. This just wires through an argument through vold, and assumes that vold will do the right thing even if there is no encryption mapping set. Bug: 5017638 Change-Id: I858fae3d12cb415bc34637f520f71220ad9daaad --- .../android/os/storage/IMountService.java | 18 ++++++++--- .../os/storage/ExternalStorageFormatter.java | 3 +- .../content/pm/PackageManagerTests.java | 2 +- .../src/android/os/storage/AsecTests.java | 4 +-- include/storage/IMountService.h | 4 +-- libs/storage/IMountService.cpp | 3 +- .../java/com/android/server/MountService.java | 32 ++++++++++++------- 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index e0130b5cd0694..d1dc6e578b82b 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -169,13 +169,15 @@ public interface IMountService extends IInterface { * 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 @@ public interface IMountService extends IInterface { 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 @@ public interface IMountService extends IInterface { * 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 4773ce4b6add3..3905c88ac2825 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 @@ public class ExternalStorageFormatter extends Service 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 6c87c3b7c47a2..68ddcc4b7af8d 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 @@ public class PackageManagerTests extends AndroidTestCase { 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 dda301090c91c..5efbd88530609 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 @@ public class AsecTests extends AndroidTestCase { 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 @@ public class AsecTests extends AndroidTestCase { // 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 472d8e502f73b..43df7f06f4d44 100644 --- a/include/storage/IMountService.h +++ b/include/storage/IMountService.h @@ -37,8 +37,8 @@ public: 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 7fbf67a02764d..8ddbeaedcfb41 100644 --- a/libs/storage/IMountService.cpp +++ b/libs/storage/IMountService.cpp @@ -157,12 +157,13 @@ public: 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 d806309cd34f0..582f0ede6c63b 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -304,17 +304,19 @@ class MountService extends IMountService.Stub 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 @@ class MountService extends IMountService.Stub 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 MountService extends IMountService.Stub 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 @@ class MountService extends IMountService.Stub * 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 @@ class MountService extends IMountService.Stub // 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 @@ class MountService extends IMountService.Stub 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 @@ class MountService extends IMountService.Stub // 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)); }