Permalink
Browse files

Merge "Allow mounting of multiple volumes via mass storage (framework…

… part)" into jb
  • Loading branch information...
PierpaoloPernici authored and Gerrit Code Review committed Sep 30, 2012
2 parents 63aece2 + 096518a commit 438ef434cfb36753ec828888acd2cf6b45a35178
Showing with 83 additions and 39 deletions.
  1. +83 −39 services/java/com/android/server/MountService.java
@@ -374,6 +374,13 @@ public void handleMessage(Message msg) {
case H_UNMOUNT_PM_UPDATE: {
if (DEBUG_UNMOUNT) Slog.i(TAG, "H_UNMOUNT_PM_UPDATE");
UnmountCallBack ucb = (UnmountCallBack) msg.obj;
+ if (!mUpdatingStatus && !isExternalStorage(ucb.path)) {
+ // If PM isn't already updating, and this isn't an ASEC
+ // mount, then go ahead and do the unmount immediately.
+ if (DEBUG_UNMOUNT) Slog.i(TAG, " skipping PackageManager for " + ucb.path);
+ ucb.handleFinished();
+ break;
+ }
mForceUnmounts.add(ucb);
if (DEBUG_UNMOUNT) Slog.i(TAG, " registered = " + mUpdatingStatus);
// Register only if needed.
@@ -607,7 +614,9 @@ private void updatePublicVolumeState(String path, String state) {
// Update state on PackageManager, but only of real events
if (!mEmulateExternalStorage) {
if (Environment.MEDIA_UNMOUNTED.equals(state)) {
- mPms.updateExternalMediaStatus(false, false);
+ if (isExternalStorage(path)) {
+ mPms.updateExternalMediaStatus(false, false);
+ }
/*
* Some OBBs might have been unmounted when this volume was
@@ -617,7 +626,9 @@ private void updatePublicVolumeState(String path, String state) {
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
OBB_FLUSH_MOUNT_STATE, path));
} else if (Environment.MEDIA_MOUNTED.equals(state)) {
- mPms.updateExternalMediaStatus(true, false);
+ if (isExternalStorage(path)) {
+ mPms.updateExternalMediaStatus(true, false);
+ }
}
}
}
@@ -935,7 +946,9 @@ private int doUnmountVolume(String path, boolean force, boolean removeEncryption
Runtime.getRuntime().gc();
// Redundant probably. But no harm in updating state again.
- mPms.updateExternalMediaStatus(false, false);
+ if (isExternalStorage(path)) {
+ mPms.updateExternalMediaStatus(false, false);
+ }
try {
final Command cmd = new Command("volume", "unmount", path);
if (removeEncryption) {
@@ -1017,8 +1030,13 @@ private void notifyShareAvailabilityChange(final boolean avail) {
mSendUmsConnectedOnBoot = avail;
}
- final String path = Environment.getExternalStorageDirectory().getPath();
- if (avail == false && getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
+ final ArrayList<String> volumes = getShareableVolumes();
+ boolean mediaShared = false;
+ for (String path : volumes) {
+ if (getVolumeState(path).equals(Environment.MEDIA_SHARED))
+ mediaShared = true;
+ }
+ if (avail == false && mediaShared) {
/*
* USB mass storage disconnected while enabled
*/
@@ -1028,11 +1046,15 @@ public void run() {
try {
int rc;
Slog.w(TAG, "Disabling UMS after cable disconnect");
- doShareUnshareVolume(path, "ums", false);
- if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
- Slog.e(TAG, String.format(
- "Failed to remount {%s} on UMS enabled-disconnect (%d)",
- path, rc));
+ for (String path : volumes) {
+ if (getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
+ doShareUnshareVolume(path, "ums", false);
+ if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
+ Slog.e(TAG, String.format(
+ "Failed to remount {%s} on UMS enabled-disconnect (%d)",
+ path, rc));
+ }
+ }
}
} catch (Exception ex) {
Slog.w(TAG, "Failed to mount media on UMS enabled-disconnect", ex);
@@ -1308,46 +1330,68 @@ public boolean isUsbMassStorageConnected() {
}
}
+ private boolean isExternalStorage(String path) {
+ return Environment.getExternalStorageDirectory().getPath().equals(path);
+ }
+
+ private ArrayList<String> getShareableVolumes() {
+ // Sharable volumes have android:allowMassStorage="true" in storage_list.xml
+ ArrayList<String> volumesToMount = new ArrayList<String>();
+ synchronized (mVolumes) {
+ for (StorageVolume v : mVolumes) {
+ if (v.allowMassStorage()) {
+ volumesToMount.add(v.getPath());
+ }
+ }
+ }
+ return volumesToMount;
+ }
+
public void setUsbMassStorageEnabled(boolean enable) {
waitForReady();
validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
// TODO: Add support for multiple share methods
-
- /*
- * If the volume is mounted and we're enabling then unmount it
- */
- String path = Environment.getExternalStorageDirectory().getPath();
- String vs = getVolumeState(path);
- String method = "ums";
- if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
- // Override for isUsbMassStorageEnabled()
- setUmsEnabling(enable);
- UmsEnableCallBack umscb = new UmsEnableCallBack(path, method, true);
- mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, umscb));
- // Clear override
- setUmsEnabling(false);
- }
- /*
- * If we disabled UMS then mount the volume
- */
- if (!enable) {
- doShareUnshareVolume(path, method, enable);
- if (doMountVolume(path) != StorageResultCode.OperationSucceeded) {
- Slog.e(TAG, "Failed to remount " + path +
- " after disabling share method " + method);
- /*
- * Even though the mount failed, the unshare didn't so don't indicate an error.
- * The mountVolume() call will have set the storage state and sent the necessary
- * broadcasts.
- */
+ for (String path : getShareableVolumes()) {
+ /*
+ * If the volume is mounted and we're enabling then unmount it
+ */
+ String vs = getVolumeState(path);
+ String method = "ums";
+ if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
+ // Override for isUsbMassStorageEnabled()
+ setUmsEnabling(enable);
+ UmsEnableCallBack umscb = new UmsEnableCallBack(path, method, true);
+ mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, umscb));
+ // Clear override
+ setUmsEnabling(false);
+ }
+ /*
+ * If we disabled UMS then mount the volume
+ */
+ if (!enable) {
+ doShareUnshareVolume(path, method, enable);
+ if (doMountVolume(path) != StorageResultCode.OperationSucceeded) {
+ Slog.e(TAG, "Failed to remount " + path +
+ " after disabling share method " + method);
+ /*
+ * Even though the mount failed, the unshare didn't so don't indicate an error.
+ * The mountVolume() call will have set the storage state and sent the necessary
+ * broadcasts.
+ */
+ }
}
}
}
public boolean isUsbMassStorageEnabled() {
waitForReady();
- return doGetVolumeShared(Environment.getExternalStorageDirectory().getPath(), "ums");
+ for (String path : getShareableVolumes()) {
+ if (doGetVolumeShared(path, "ums"))
+ return true;
+ }
+ // no volume is shared
+ return false;
}
/**

0 comments on commit 438ef43

Please sign in to comment.