From 71938e18ca4ad77519da70565710ef37e79443f8 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Thu, 10 May 2018 18:28:29 -0700 Subject: [PATCH] Access removable volumes through /mnt/media_rw Due to permissions changes, we now need to access the underlying filesystem of removable devices in order to get write access. Add internalPath to StorageVolume, and have VolumeInfo set the field on creation. Bug: 77849654 Test: Can write to emulated sdcard through MTP Change-Id: I63302ecf2dd2600a1c9f3f6ab106c3695654cbaa --- .../android/os/storage/StorageVolume.java | 19 +++++++++++++++++-- core/java/android/os/storage/VolumeInfo.java | 6 +++++- media/java/android/mtp/MtpStorage.java | 3 +-- media/java/android/mtp/MtpStorageManager.java | 2 +- .../android/server/StorageManagerService.java | 2 +- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 839a8bf42b109..fd5a22a9c551c 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -78,6 +78,7 @@ public final class StorageVolume implements Parcelable { private final String mId; private final File mPath; + private final File mInternalPath; private final String mDescription; private final boolean mPrimary; private final boolean mRemovable; @@ -118,11 +119,12 @@ public final class StorageVolume implements Parcelable { public static final int STORAGE_ID_PRIMARY = 0x00010001; /** {@hide} */ - public StorageVolume(String id, File path, String description, boolean primary, - boolean removable, boolean emulated, boolean allowMassStorage, + public StorageVolume(String id, File path, File internalPath, String description, + boolean primary, boolean removable, boolean emulated, boolean allowMassStorage, long maxFileSize, UserHandle owner, String fsUuid, String state) { mId = Preconditions.checkNotNull(id); mPath = Preconditions.checkNotNull(path); + mInternalPath = Preconditions.checkNotNull(internalPath); mDescription = Preconditions.checkNotNull(description); mPrimary = primary; mRemovable = removable; @@ -137,6 +139,7 @@ public final class StorageVolume implements Parcelable { private StorageVolume(Parcel in) { mId = in.readString(); mPath = new File(in.readString()); + mInternalPath = new File(in.readString()); mDescription = in.readString(); mPrimary = in.readInt() != 0; mRemovable = in.readInt() != 0; @@ -163,6 +166,16 @@ public final class StorageVolume implements Parcelable { return mPath.toString(); } + /** + * Returns the path of the underlying filesystem. + * + * @return the internal path + * @hide + */ + public String getInternalPath() { + return mInternalPath.toString(); + } + /** {@hide} */ public File getPathFile() { return mPath; @@ -351,6 +364,7 @@ public final class StorageVolume implements Parcelable { pw.increaseIndent(); pw.printPair("mId", mId); pw.printPair("mPath", mPath); + pw.printPair("mInternalPath", mInternalPath); pw.printPair("mDescription", mDescription); pw.printPair("mPrimary", mPrimary); pw.printPair("mRemovable", mRemovable); @@ -384,6 +398,7 @@ public final class StorageVolume implements Parcelable { public void writeToParcel(Parcel parcel, int flags) { parcel.writeString(mId); parcel.writeString(mPath.toString()); + parcel.writeString(mInternalPath.toString()); parcel.writeString(mDescription); parcel.writeInt(mPrimary ? 1 : 0); parcel.writeInt(mRemovable ? 1 : 0); diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 9e3e386eedb25..a2a8d7fff37c5 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -333,6 +333,10 @@ public class VolumeInfo implements Parcelable { if (userPath == null) { userPath = new File("/dev/null"); } + File internalPath = getInternalPathForUser(userId); + if (internalPath == null) { + internalPath = new File("/dev/null"); + } String description = null; String derivedFsUuid = fsUuid; @@ -371,7 +375,7 @@ public class VolumeInfo implements Parcelable { description = context.getString(android.R.string.unknownName); } - return new StorageVolume(id, userPath, description, isPrimary(), removable, + return new StorageVolume(id, userPath, internalPath, description, isPrimary(), removable, emulated, allowMassStorage, maxFileSize, new UserHandle(userId), derivedFsUuid, envState); } diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java index c72b827d8a2de..2625e0cc932c5 100644 --- a/media/java/android/mtp/MtpStorage.java +++ b/media/java/android/mtp/MtpStorage.java @@ -16,7 +16,6 @@ package android.mtp; -import android.content.Context; import android.os.storage.StorageVolume; /** @@ -36,7 +35,7 @@ public class MtpStorage { public MtpStorage(StorageVolume volume, int storageId) { mStorageId = storageId; - mPath = volume.getPath(); + mPath = volume.getInternalPath(); mDescription = volume.getDescription(null); mRemovable = volume.isRemovable(); mMaxFileSize = volume.getMaxFileSize(); diff --git a/media/java/android/mtp/MtpStorageManager.java b/media/java/android/mtp/MtpStorageManager.java index bdc87413288ab..a36d88d735e3e 100644 --- a/media/java/android/mtp/MtpStorageManager.java +++ b/media/java/android/mtp/MtpStorageManager.java @@ -399,8 +399,8 @@ public class MtpStorageManager { */ public synchronized MtpStorage addMtpStorage(StorageVolume volume) { int storageId = ((getNextStorageId() & 0x0000FFFF) << 16) + 1; - MtpObject root = new MtpObject(volume.getPath(), storageId, null, true); MtpStorage storage = new MtpStorage(volume, storageId); + MtpObject root = new MtpObject(storage.getPath(), storageId, null, true); mRoots.put(storageId, root); return storage; } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 6c35bdae5a3e7..2dc8818951b52 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -2799,7 +2799,7 @@ class StorageManagerService extends IStorageManager.Stub final String uuid = null; final String state = Environment.MEDIA_REMOVED; - res.add(0, new StorageVolume(id, path, + res.add(0, new StorageVolume(id, path, path, description, primary, removable, emulated, allowMassStorage, maxFileSize, owner, uuid, state)); }