Merge "Revert encryption mapping for device wipes."

This commit is contained in:
Ben Komalo
2011-09-11 16:48:32 -07:00
committed by Android (Google) Code Review
7 changed files with 43 additions and 23 deletions

View File

@@ -169,13 +169,15 @@ public interface IMountService extends IInterface {
* is an asynchronous operation. Applications should register * is an asynchronous operation. Applications should register
* StorageEventListener for storage related status changes. * 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 _data = Parcel.obtain();
Parcel _reply = Parcel.obtain(); Parcel _reply = Parcel.obtain();
try { try {
_data.writeInterfaceToken(DESCRIPTOR); _data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(mountPoint); _data.writeString(mountPoint);
_data.writeInt((force ? 1 : 0)); _data.writeInt((force ? 1 : 0));
_data.writeInt((removeEncryption ? 1 : 0));
mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0); mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0);
_reply.readException(); _reply.readException();
} finally { } finally {
@@ -842,9 +844,9 @@ public interface IMountService extends IInterface {
data.enforceInterface(DESCRIPTOR); data.enforceInterface(DESCRIPTOR);
String mountPoint; String mountPoint;
mountPoint = data.readString(); mountPoint = data.readString();
boolean force; boolean force = 0 != data.readInt();
force = 0 != data.readInt(); boolean removeEncrypt = 0 != data.readInt();
unmountVolume(mountPoint, force); unmountVolume(mountPoint, force, removeEncrypt);
reply.writeNoException(); reply.writeNoException();
return true; return true;
} }
@@ -1234,8 +1236,14 @@ public interface IMountService extends IInterface {
* Safely unmount external storage at given mount point. The unmount is an * Safely unmount external storage at given mount point. The unmount is an
* asynchronous operation. Applications should register StorageEventListener * asynchronous operation. Applications should register StorageEventListener
* for storage related status changes. * 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 * Unregisters an IMountServiceListener

View File

@@ -152,7 +152,8 @@ public class ExternalStorageFormatter extends Service
Environment.getExternalStorageDirectory().toString() : Environment.getExternalStorageDirectory().toString() :
mStorageVolume.getPath(); mStorageVolume.getPath();
try { 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) { } catch (RemoteException e) {
Log.w(TAG, "Failed talking with mount service", e); Log.w(TAG, "Failed talking with mount service", e);
} }

View File

@@ -1057,7 +1057,7 @@ public class PackageManagerTests extends AndroidTestCase {
try { try {
// Wait on observer // Wait on observer
synchronized(observer) { synchronized(observer) {
getMs().unmountVolume(path, true); getMs().unmountVolume(path, true, false);
long waitTime = 0; long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
observer.wait(WAIT_TIME_INCR); observer.wait(WAIT_TIME_INCR);

View File

@@ -421,7 +421,7 @@ public class AsecTests extends AndroidTestCase {
try { try {
// Wait on observer // Wait on observer
synchronized(observer) { synchronized(observer) {
getMs().unmountVolume(path, false); getMs().unmountVolume(path, false, false);
long waitTime = 0; long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
observer.wait(WAIT_TIME_INCR); observer.wait(WAIT_TIME_INCR);
@@ -486,7 +486,7 @@ public class AsecTests extends AndroidTestCase {
// Wait on observer // Wait on observer
synchronized(observer) { synchronized(observer) {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
getMs().unmountVolume(path, false); getMs().unmountVolume(path, false, false);
} }
long waitTime = 0; long waitTime = 0;
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {

View File

@@ -37,8 +37,8 @@ public:
virtual void setUsbMassStorageEnabled(const bool enable) = 0; virtual void setUsbMassStorageEnabled(const bool enable) = 0;
virtual bool isUsbMassStorageEnabled() = 0; virtual bool isUsbMassStorageEnabled() = 0;
virtual int32_t mountVolume(const String16& mountPoint) = 0; virtual int32_t mountVolume(const String16& mountPoint) = 0;
virtual int32_t virtual int32_t unmountVolume(
unmountVolume(const String16& mountPoint, const bool force) = 0; const String16& mountPoint, const bool force, const bool removeEncryption) = 0;
virtual int32_t formatVolume(const String16& mountPoint) = 0; virtual int32_t formatVolume(const String16& mountPoint) = 0;
virtual int32_t virtual int32_t
getStorageUsers(const String16& mountPoint, int32_t** users) = 0; getStorageUsers(const String16& mountPoint, int32_t** users) = 0;

View File

@@ -157,12 +157,13 @@ public:
return reply.readInt32(); 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; Parcel data, reply;
data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
data.writeString16(mountPoint); data.writeString16(mountPoint);
data.writeInt32(force ? 1 : 0); data.writeInt32(force ? 1 : 0);
data.writeInt32(removeEncryption ? 1 : 0);
if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) { if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
LOGD("unmountVolume could not contact remote\n"); LOGD("unmountVolume could not contact remote\n");
return -1; return -1;

View File

@@ -304,17 +304,19 @@ class MountService extends IMountService.Stub
class UnmountCallBack { class UnmountCallBack {
final String path; final String path;
final boolean force; final boolean force;
final boolean removeEncryption;
int retries; int retries;
UnmountCallBack(String path, boolean force) { UnmountCallBack(String path, boolean force, boolean removeEncryption) {
retries = 0; retries = 0;
this.path = path; this.path = path;
this.force = force; this.force = force;
this.removeEncryption = removeEncryption;
} }
void handleFinished() { void handleFinished() {
if (DEBUG_UNMOUNT) Slog.i(TAG, "Unmounting " + path); 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; final String method;
UmsEnableCallBack(String path, String method, boolean force) { UmsEnableCallBack(String path, String method, boolean force) {
super(path, force); super(path, force, false);
this.method = method; this.method = method;
} }
@@ -336,13 +338,13 @@ class MountService extends IMountService.Stub
class ShutdownCallBack extends UnmountCallBack { class ShutdownCallBack extends UnmountCallBack {
IMountShutdownObserver observer; IMountShutdownObserver observer;
ShutdownCallBack(String path, IMountShutdownObserver observer) { ShutdownCallBack(String path, IMountShutdownObserver observer) {
super(path, true); super(path, true, false);
this.observer = observer; this.observer = observer;
} }
@Override @Override
void handleFinished() { void handleFinished() {
int ret = doUnmountVolume(path, true); int ret = doUnmountVolume(path, true, removeEncryption);
if (observer != null) { if (observer != null) {
try { try {
observer.onShutDownComplete(ret); 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 * 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 * to make sure we dont end up in an instable state and kill some core
* processes. * 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)) { if (!getVolumeState(path).equals(Environment.MEDIA_MOUNTED)) {
return VoldResponseCode.OpFailedVolNotMounted; return VoldResponseCode.OpFailedVolNotMounted;
} }
@@ -905,8 +909,10 @@ class MountService extends IMountService.Stub
// Redundant probably. But no harm in updating state again. // Redundant probably. But no harm in updating state again.
mPms.updateExternalMediaStatus(false, false); mPms.updateExternalMediaStatus(false, false);
try { try {
mConnector.doCommand(String.format( String arg = removeEncryption
"volume unmount %s%s", path, (force ? " force" : ""))); ? " 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. // We unmounted the volume. None of the asec containers are available now.
synchronized (mAsecMountSet) { synchronized (mAsecMountSet) {
mAsecMountSet.clear(); mAsecMountSet.clear();
@@ -1371,12 +1377,16 @@ class MountService extends IMountService.Stub
return doMountVolume(path); 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); validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady(); waitForReady();
String volState = getVolumeState(path); 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) || if (Environment.MEDIA_UNMOUNTED.equals(volState) ||
Environment.MEDIA_REMOVED.equals(volState) || Environment.MEDIA_REMOVED.equals(volState) ||
Environment.MEDIA_SHARED.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. // TODO return valid return code when adding observer call back.
return; return;
} }
UnmountCallBack ucb = new UnmountCallBack(path, force); UnmountCallBack ucb = new UnmountCallBack(path, force, removeEncryption);
mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb)); mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
} }