framework: storage: Add 'force' option to unmount/destroy storage apis, and update callsites.
Also adds additional storage unit tests
Signed-off-by: San Mehat <san@google.com>
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 4e2ffa4..ad377e3 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -97,7 +97,7 @@
public static final int OpFailedMediaBlank = 402;
public static final int OpFailedMediaCorrupt = 403;
public static final int OpFailedVolNotMounted = 404;
- public static final int OpFailedVolBusy = 405;
+ public static final int OpFailedStorageBusy = 405;
/*
* 600 series - Unsolicited broadcasts.
@@ -184,7 +184,7 @@
String vs = getVolumeState(path);
if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
mUmsEnabling = enable; // Override for isUsbMassStorageEnabled()
- int rc = doUnmountVolume(path);
+ int rc = doUnmountVolume(path, false);
mUmsEnabling = false; // Clear override
if (rc != StorageResultCode.OperationSucceeded) {
Log.e(TAG, String.format("Failed to unmount before enabling UMS (%d)", rc));
@@ -527,7 +527,7 @@
return rc;
}
- private int doUnmountVolume(String path) {
+ private int doUnmountVolume(String path, boolean force) {
if (!getVolumeState(path).equals(Environment.MEDIA_MOUNTED)) {
return VoldResponseCode.OpFailedVolNotMounted;
}
@@ -537,7 +537,8 @@
// notified that the applications installed on the media will be killed.
mPms.updateExternalMediaStatus(false);
try {
- mConnector.doCommand(String.format("volume unmount %s", path));
+ mConnector.doCommand(String.format(
+ "volume unmount %s%s", path, (force ? " force" : "")));
return StorageResultCode.OperationSucceeded;
} catch (NativeDaemonConnectorException e) {
// Don't worry about mismatch in PackageManager since the
@@ -545,6 +546,8 @@
int code = e.getCode();
if (code == VoldResponseCode.OpFailedVolNotMounted) {
return StorageResultCode.OperationFailedStorageNotMounted;
+ } else if (code == VoldResponseCode.OpFailedStorageBusy) {
+ return StorageResultCode.OperationFailedStorageBusy;
} else {
return StorageResultCode.OperationFailedInternalError;
}
@@ -733,7 +736,7 @@
/*
* If the media is mounted, then gracefully unmount it.
*/
- if (doUnmountVolume(path) != StorageResultCode.OperationSucceeded) {
+ if (doUnmountVolume(path, true) != StorageResultCode.OperationSucceeded) {
Log.e(TAG, "Failed to unmount media for shutdown");
}
}
@@ -782,11 +785,11 @@
return doMountVolume(path);
}
- public int unmountVolume(String path) {
+ public int unmountVolume(String path, boolean force) {
validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
- return doUnmountVolume(path);
+ return doUnmountVolume(path, force);
}
public int formatVolume(String path) {
@@ -878,16 +881,21 @@
return rc;
}
- public int destroySecureContainer(String id) {
+ public int destroySecureContainer(String id, boolean force) {
validatePermission(android.Manifest.permission.ASEC_DESTROY);
waitForReady();
warnOnNotMounted();
int rc = StorageResultCode.OperationSucceeded;
try {
- mConnector.doCommand(String.format("asec destroy %s", id));
+ mConnector.doCommand(String.format("asec destroy %s%s", id, (force ? " force" : "")));
} catch (NativeDaemonConnectorException e) {
- rc = StorageResultCode.OperationFailedInternalError;
+ int code = e.getCode();
+ if (code == VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedStorageBusy;
+ } else {
+ rc = StorageResultCode.OperationFailedInternalError;
+ }
}
if (rc == StorageResultCode.OperationSucceeded) {
@@ -928,7 +936,7 @@
return rc;
}
- public int unmountSecureContainer(String id) {
+ public int unmountSecureContainer(String id, boolean force) {
validatePermission(android.Manifest.permission.ASEC_MOUNT_UNMOUNT);
waitForReady();
warnOnNotMounted();
@@ -940,11 +948,16 @@
}
int rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("asec unmount %s", id);
+ String cmd = String.format("asec unmount %s%s", id, (force ? " force" : ""));
try {
mConnector.doCommand(cmd);
} catch (NativeDaemonConnectorException e) {
- rc = StorageResultCode.OperationFailedInternalError;
+ int code = e.getCode();
+ if (code == VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedStorageBusy;
+ } else {
+ rc = StorageResultCode.OperationFailedInternalError;
+ }
}
if (rc == StorageResultCode.OperationSucceeded) {