diff options
| author | 2016-03-28 05:18:38 +0000 | |
|---|---|---|
| committer | 2016-03-28 05:18:40 +0000 | |
| commit | 4d9b6e4f5724a4ef2340bc4725b824ca573f474c (patch) | |
| tree | d208b295e4c307b6cbc42623bf7436e93378401e | |
| parent | 1337deb6eac47b9eeef0999a928caba0cfca7126 (diff) | |
| parent | c02bfae73e139f2a1c56cc6b051bfc7877b8cf1d (diff) | |
Merge "Include "invisible" volumes in new storage API." into nyc-dev
| -rw-r--r-- | api/current.txt | 4 | ||||
| -rw-r--r-- | api/removed.txt | 9 | ||||
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | api/system-removed.txt | 9 | ||||
| -rw-r--r-- | api/test-current.txt | 4 | ||||
| -rw-r--r-- | api/test-removed.txt | 9 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageManager.java | 37 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageVolume.java | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/MountService.java | 61 |
9 files changed, 106 insertions, 35 deletions
diff --git a/api/current.txt b/api/current.txt index e672929ef321..f4a17655f480 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29569,8 +29569,8 @@ package android.os.storage { public class StorageManager { method public java.lang.String getMountedObbPath(java.lang.String); - method public android.os.storage.StorageVolume getPrimaryVolume(); - method public android.os.storage.StorageVolume[] getVolumeList(); + method public android.os.storage.StorageVolume getPrimaryStorageVolume(); + method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes(); method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); diff --git a/api/removed.txt b/api/removed.txt index 36c8ce5cdf50..86085c8ded67 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -136,6 +136,15 @@ package android.os { } +package android.os.storage { + + public class StorageManager { + method public android.os.storage.StorageVolume getPrimaryVolume(); + method public android.os.storage.StorageVolume[] getVolumeList(); + } + +} + package android.preference { public class PreferenceManager { diff --git a/api/system-current.txt b/api/system-current.txt index 13b6c2479001..8fe8c122a055 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -31881,8 +31881,8 @@ package android.os.storage { public class StorageManager { method public java.lang.String getMountedObbPath(java.lang.String); - method public android.os.storage.StorageVolume getPrimaryVolume(); - method public android.os.storage.StorageVolume[] getVolumeList(); + method public android.os.storage.StorageVolume getPrimaryStorageVolume(); + method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes(); method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); diff --git a/api/system-removed.txt b/api/system-removed.txt index d48b9b3cd403..bc1762722c18 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -134,6 +134,15 @@ package android.os { } +package android.os.storage { + + public class StorageManager { + method public android.os.storage.StorageVolume getPrimaryVolume(); + method public android.os.storage.StorageVolume[] getVolumeList(); + } + +} + package android.preference { public class PreferenceManager { diff --git a/api/test-current.txt b/api/test-current.txt index 15fb31dd5317..39b0dacefab8 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -29635,8 +29635,8 @@ package android.os.storage { public class StorageManager { method public java.lang.String getMountedObbPath(java.lang.String); - method public android.os.storage.StorageVolume getPrimaryVolume(); - method public android.os.storage.StorageVolume[] getVolumeList(); + method public android.os.storage.StorageVolume getPrimaryStorageVolume(); + method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes(); method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); diff --git a/api/test-removed.txt b/api/test-removed.txt index 36c8ce5cdf50..86085c8ded67 100644 --- a/api/test-removed.txt +++ b/api/test-removed.txt @@ -136,6 +136,15 @@ package android.os { } +package android.os.storage { + + public class StorageManager { + method public android.os.storage.StorageVolume getPrimaryVolume(); + method public android.os.storage.StorageVolume[] getVolumeList(); + } + +} + package android.preference { public class PreferenceManager { diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 22aec63a76a2..720d3f7b860a 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -34,8 +34,8 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings; -import android.security.KeyStore; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -49,6 +49,7 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -101,6 +102,10 @@ public class StorageManager { /** {@hide} */ public static final int FLAG_FOR_WRITE = 1 << 8; + /** {@hide} */ + public static final int FLAG_REAL_STATE = 1 << 9; + /** {@hide} */ + public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10; private final Context mContext; private final ContentResolver mResolver; @@ -859,11 +864,31 @@ public class StorageManager { } /** - * Gets the list of shared/external storage volumes available to the current user. + * Return the list of shared/external storage volumes available to the + * current user. This includes both the primary shared storage device and + * any attached external volumes including SD cards and USB drives. * - * <p>It always contains the primary storage volume, plus any additional external volume(s) - * available in the device, such as SD cards or attached USB drives. + * @see Environment#getExternalStorageDirectory() + * @see StorageVolume#createAccessIntent(String) + */ + public @NonNull List<StorageVolume> getStorageVolumes() { + final ArrayList<StorageVolume> res = new ArrayList<>(); + Collections.addAll(res, + getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE)); + return res; + } + + /** + * Return the primary shared/external storage volume available to the + * current user. This volume is the same storage device returned by + * {@link Environment#getExternalStorageDirectory()} and + * {@link Context#getExternalFilesDir(String)}. */ + public @NonNull StorageVolume getPrimaryStorageVolume() { + return getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE)[0]; + } + + /** @removed */ public @NonNull StorageVolume[] getVolumeList() { return getVolumeList(mContext.getUserId(), 0); } @@ -912,9 +937,7 @@ public class StorageManager { return paths; } - /** - * Gets the primary shared/external storage volume available to the current user. - */ + /** @removed */ public @NonNull StorageVolume getPrimaryVolume() { return getPrimaryVolume(getVolumeList()); } diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 34c0b145b047..c028e150b217 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -65,8 +65,8 @@ import java.io.File; * broad access to all files contained on a storage device. * </ul> * - * <p>It can be obtained through {@link StorageManager#getVolumeList()} and - * {@link StorageManager#getPrimaryVolume()} and also as an extra in some broadcasts + * <p>It can be obtained through {@link StorageManager#getStorageVolumes()} and + * {@link StorageManager#getPrimaryStorageVolume()} and also as an extra in some broadcasts * (see {@link #EXTRA_STORAGE_VOLUME}). * * <p> diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index ccca5baa798a..45008dcf72a1 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -2912,36 +2912,57 @@ class MountService extends IMountService.Stub @Override public StorageVolume[] getVolumeList(int uid, String packageName, int flags) { final int userId = UserHandle.getUserId(uid); - final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0; - boolean reportUnmounted = false; - boolean foundPrimary = false; + final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0; + final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0; + final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0; - final long identity = Binder.clearCallingIdentity(); + final boolean userKeyUnlocked; + final boolean storagePermission; + final long token = Binder.clearCallingIdentity(); try { - if (!mMountServiceInternal.hasExternalStorage(uid, packageName)) { - reportUnmounted = true; - } - if (!isUserKeyUnlocked(userId)) { - reportUnmounted = true; - } + userKeyUnlocked = isUserKeyUnlocked(userId); + storagePermission = mMountServiceInternal.hasExternalStorage(uid, packageName); } finally { - Binder.restoreCallingIdentity(identity); + Binder.restoreCallingIdentity(token); } + boolean foundPrimary = false; + final ArrayList<StorageVolume> res = new ArrayList<>(); synchronized (mLock) { for (int i = 0; i < mVolumes.size(); i++) { final VolumeInfo vol = mVolumes.valueAt(i); - if (forWrite ? vol.isVisibleForWrite(userId) : vol.isVisibleForRead(userId)) { - final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, - reportUnmounted); - if (vol.isPrimary()) { - res.add(0, userVol); - foundPrimary = true; - } else { - res.add(userVol); - } + switch (vol.getType()) { + case VolumeInfo.TYPE_PUBLIC: + case VolumeInfo.TYPE_EMULATED: + break; + default: + continue; + } + + boolean match = false; + if (forWrite) { + match = vol.isVisibleForWrite(userId); + } else { + match = vol.isVisibleForRead(userId) || includeInvisible; + } + if (!match) continue; + + boolean reportUnmounted = false; + if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) { + reportUnmounted = true; + } else if (!storagePermission && !realState) { + reportUnmounted = true; + } + + final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, + reportUnmounted); + if (vol.isPrimary()) { + res.add(0, userVol); + foundPrimary = true; + } else { + res.add(userVol); } } } |