diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2015-04-14 21:39:44 -0700 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2015-04-14 21:39:47 -0700 |
| commit | d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363 (patch) | |
| tree | a40d6acf9315cb1656253c4af52357dfc259acf9 /core/java/android | |
| parent | 56bd3129138b525b0f2eba52bd4fa140f23e792c (diff) | |
Persist nickname and flags for volumes.
StorageManager now offers to persist a nickname and user flags for
active volumes. This metadata is kept around and spliced into
any future VolumeInfo when the same UUID is present. Current user
flags indicate "initialized" and "snoozed" states to control how
notifications are shown.
Notify listeners when metadata changes, and kick public notification
after a volume is initialized. Make unique PendingIntents when
multiple volumes are active.
Beginnings of plumbing to ask for missing volumes.
Offer explicit accessors for VolumeInfo and DiskInfo to give better
path to documentation and deprecation.
Bug: 19993667
Change-Id: I3d8b68be83f43ba992d21d51cad5b775776d681c
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/os/storage/DiskInfo.java | 5 | ||||
| -rw-r--r-- | core/java/android/os/storage/IMountService.java | 64 | ||||
| -rw-r--r-- | core/java/android/os/storage/IMountServiceListener.java | 26 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageEventListener.java | 3 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageManager.java | 51 | ||||
| -rw-r--r-- | core/java/android/os/storage/VolumeInfo.java | 51 |
6 files changed, 192 insertions, 8 deletions
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index e6160aac0d1d..dc96640f82ec 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -16,6 +16,7 @@ package android.os.storage; +import android.annotation.NonNull; import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; @@ -59,6 +60,10 @@ public class DiskInfo implements Parcelable { volumeIds = parcel.readStringArray(); } + public @NonNull String getId() { + return id; + } + public String getDescription() { // TODO: splice vendor label into these strings if ((flags & FLAG_SD) != 0) { diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 10ffd485dda9..0a8187e8772c 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -923,12 +923,13 @@ public interface IMountService extends IInterface { } @Override - public VolumeInfo[] getVolumes() throws RemoteException { + public VolumeInfo[] getVolumes(int _flags) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); VolumeInfo[] _result; try { _data.writeInterfaceToken(DESCRIPTOR); + _data.writeInt(_flags); mRemote.transact(Stub.TRANSACTION_getVolumes, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArray(VolumeInfo.CREATOR); @@ -1029,6 +1030,39 @@ public interface IMountService extends IInterface { _data.recycle(); } } + + @Override + public void setVolumeNickname(String volId, String nickname) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(volId); + _data.writeString(nickname); + mRemote.transact(Stub.TRANSACTION_setVolumeNickname, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } + + @Override + public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(volId); + _data.writeInt(flags); + _data.writeInt(mask); + mRemote.transact(Stub.TRANSACTION_setVolumeUserFlags, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } } private static final String DESCRIPTOR = "IMountService"; @@ -1132,6 +1166,9 @@ public interface IMountService extends IInterface { static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 50; static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 51; + static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 52; + static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 53; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1566,7 +1603,8 @@ public interface IMountService extends IInterface { } case TRANSACTION_getVolumes: { data.enforceInterface(DESCRIPTOR); - VolumeInfo[] volumes = getVolumes(); + int _flags = data.readInt(); + VolumeInfo[] volumes = getVolumes(_flags); reply.writeNoException(); reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; @@ -1614,6 +1652,23 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_setVolumeNickname: { + data.enforceInterface(DESCRIPTOR); + String volId = data.readString(); + String nickname = data.readString(); + setVolumeNickname(volId, nickname); + reply.writeNoException(); + return true; + } + case TRANSACTION_setVolumeUserFlags: { + data.enforceInterface(DESCRIPTOR); + String volId = data.readString(); + int _flags = data.readInt(); + int _mask = data.readInt(); + setVolumeUserFlags(volId, _flags, _mask); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1902,7 +1957,7 @@ public interface IMountService extends IInterface { public void waitForAsecScan() throws RemoteException; public DiskInfo[] getDisks() throws RemoteException; - public VolumeInfo[] getVolumes() throws RemoteException; + public VolumeInfo[] getVolumes(int flags) throws RemoteException; public void mount(String volId) throws RemoteException; public void unmount(String volId) throws RemoteException; @@ -1911,4 +1966,7 @@ public interface IMountService extends IInterface { public void partitionPublic(String diskId) throws RemoteException; public void partitionPrivate(String diskId) throws RemoteException; public void partitionMixed(String diskId, int ratio) throws RemoteException; + + public void setVolumeNickname(String volId, String nickname) throws RemoteException; + public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException; } diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java index 3965f9d34d51..fd914bc843ab 100644 --- a/core/java/android/os/storage/IMountServiceListener.java +++ b/core/java/android/os/storage/IMountServiceListener.java @@ -91,6 +91,13 @@ public interface IMountServiceListener extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_onVolumeMetadataChanged: { + data.enforceInterface(DESCRIPTOR); + final VolumeInfo vol = (VolumeInfo) data.readParcelable(null); + onVolumeMetadataChanged(vol); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -175,6 +182,22 @@ public interface IMountServiceListener extends IInterface { _data.recycle(); } } + + @Override + public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeParcelable(vol, 0); + mRemote.transact(Stub.TRANSACTION_onVolumeMetadataChanged, _data, _reply, + android.os.IBinder.FLAG_ONEWAY); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } } static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0); @@ -182,6 +205,7 @@ public interface IMountServiceListener extends IInterface { static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_onVolumeStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 2); + static final int TRANSACTION_onVolumeMetadataChanged = (IBinder.FIRST_CALL_TRANSACTION + 3); } /** @@ -204,4 +228,6 @@ public interface IMountServiceListener extends IInterface { public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) throws RemoteException; + + public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException; } diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java index 29d5494341a6..28a187d02911 100644 --- a/core/java/android/os/storage/StorageEventListener.java +++ b/core/java/android/os/storage/StorageEventListener.java @@ -40,4 +40,7 @@ public class StorageEventListener { public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { } + + public void onVolumeMetadataChanged(VolumeInfo vol) { + } } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index eb774778e0e7..0e977ff6f1b7 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -70,6 +70,9 @@ public class StorageManager { /** {@hide} */ public static final String PROP_PRIMARY_PHYSICAL = "ro.vold.primary_physical"; + /** {@hide} */ + public static final int FLAG_ALL_METADATA = 1 << 0; + private final Context mContext; private final ContentResolver mResolver; @@ -83,6 +86,7 @@ public class StorageManager { Handler.Callback { private static final int MSG_STORAGE_STATE_CHANGED = 1; private static final int MSG_VOLUME_STATE_CHANGED = 2; + private static final int MSG_VOLUME_METADATA_CHANGED = 3; final StorageEventListener mCallback; final Handler mHandler; @@ -105,6 +109,10 @@ public class StorageManager { mCallback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3); args.recycle(); return true; + case MSG_VOLUME_METADATA_CHANGED: + mCallback.onVolumeMetadataChanged((VolumeInfo) args.arg1); + args.recycle(); + return true; } args.recycle(); return false; @@ -132,6 +140,13 @@ public class StorageManager { args.argi3 = newState; mHandler.obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget(); } + + @Override + public void onVolumeMetadataChanged(VolumeInfo vol) { + final SomeArgs args = SomeArgs.obtain(); + args.arg1 = vol; + mHandler.obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget(); + } } /** @@ -480,8 +495,13 @@ public class StorageManager { /** {@hide} */ public @NonNull List<VolumeInfo> getVolumes() { + return getVolumes(0); + } + + /** {@hide} */ + public @NonNull List<VolumeInfo> getVolumes(int flags) { try { - return Arrays.asList(mMountService.getVolumes()); + return Arrays.asList(mMountService.getVolumes(flags)); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } @@ -556,6 +576,35 @@ public class StorageManager { } /** {@hide} */ + public void setVolumeNickname(String volId, String nickname) { + try { + mMountService.setVolumeNickname(volId, nickname); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** {@hide} */ + public void setVolumeInited(String volId, boolean inited) { + try { + mMountService.setVolumeUserFlags(volId, inited ? VolumeInfo.USER_FLAG_INITED : 0, + VolumeInfo.USER_FLAG_INITED); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** {@hide} */ + public void setVolumeSnoozed(String volId, boolean snoozed) { + try { + mMountService.setVolumeUserFlags(volId, snoozed ? VolumeInfo.USER_FLAG_SNOOZED : 0, + VolumeInfo.USER_FLAG_SNOOZED); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** {@hide} */ public @Nullable StorageVolume getStorageVolume(File file) { return getStorageVolume(getVolumeList(), file); } diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index fe1e206a650e..f06fc8c30b35 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -71,6 +71,9 @@ public class VolumeInfo implements Parcelable { public static final int FLAG_PRIMARY = 1 << 0; public static final int FLAG_VISIBLE = 1 << 1; + public static final int USER_FLAG_INITED = 1 << 0; + public static final int USER_FLAG_SNOOZED = 1 << 1; + private static SparseArray<String> sStateToEnvironment = new SparseArray<>(); private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>(); @@ -104,8 +107,9 @@ public class VolumeInfo implements Parcelable { /** Framework state */ public final int mtpIndex; - public String nickname; public String diskId; + public String nickname; + public int userFlags = 0; public VolumeInfo(String id, int type, int mtpIndex) { this.id = Preconditions.checkNotNull(id); @@ -124,8 +128,9 @@ public class VolumeInfo implements Parcelable { fsLabel = parcel.readString(); path = parcel.readString(); mtpIndex = parcel.readInt(); - nickname = parcel.readString(); diskId = parcel.readString(); + nickname = parcel.readString(); + userFlags = parcel.readInt(); } public static @NonNull String getEnvironmentForState(int state) { @@ -145,6 +150,30 @@ public class VolumeInfo implements Parcelable { return getBroadcastForEnvironment(getEnvironmentForState(state)); } + public @NonNull String getId() { + return id; + } + + public @Nullable String getDiskId() { + return diskId; + } + + public int getType() { + return type; + } + + public int getState() { + return state; + } + + public @Nullable String getFsUuid() { + return fsUuid; + } + + public @Nullable String getNickname() { + return nickname; + } + public @Nullable String getDescription() { if (ID_PRIVATE_INTERNAL.equals(id)) { return Resources.getSystem().getString(com.android.internal.R.string.storage_internal); @@ -165,6 +194,14 @@ public class VolumeInfo implements Parcelable { return (flags & FLAG_VISIBLE) != 0; } + public boolean isInited() { + return (userFlags & USER_FLAG_INITED) != 0; + } + + public boolean isSnoozed() { + return (userFlags & USER_FLAG_SNOOZED) != 0; + } + public boolean isVisibleToUser(int userId) { if (type == TYPE_PUBLIC && userId == this.userId) { return isVisible(); @@ -175,6 +212,10 @@ public class VolumeInfo implements Parcelable { } } + public File getPath() { + return new File(path); + } + public File getPathForUser(int userId) { if (path == null) { return null; @@ -284,8 +325,9 @@ public class VolumeInfo implements Parcelable { pw.println(); pw.printPair("path", path); pw.printPair("mtpIndex", mtpIndex); - pw.printPair("nickname", nickname); pw.printPair("diskId", diskId); + pw.printPair("nickname", nickname); + pw.printPair("userFlags", DebugUtils.flagsToString(getClass(), "USER_FLAG_", userFlags)); pw.decreaseIndent(); pw.println(); } @@ -331,7 +373,8 @@ public class VolumeInfo implements Parcelable { parcel.writeString(fsLabel); parcel.writeString(path); parcel.writeInt(mtpIndex); - parcel.writeString(nickname); parcel.writeString(diskId); + parcel.writeString(nickname); + parcel.writeInt(userFlags); } } |
