diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 201 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 10 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageMoveObserver.aidl | 4 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 44 | ||||
-rw-r--r-- | core/java/android/os/storage/DiskInfo.java | 17 | ||||
-rw-r--r-- | core/java/android/os/storage/IMountService.java | 52 | ||||
-rw-r--r-- | core/java/android/os/storage/IMountServiceListener.java | 16 | ||||
-rw-r--r-- | core/java/android/os/storage/StorageEventListener.java | 2 | ||||
-rw-r--r-- | core/java/android/os/storage/StorageManager.java | 47 | ||||
-rw-r--r-- | core/java/android/os/storage/VolumeInfo.java | 4 | ||||
-rw-r--r-- | core/java/com/android/internal/util/Preconditions.java | 6 |
11 files changed, 344 insertions, 59 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index dfe7e18..10f5960 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -62,6 +62,9 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; @@ -81,7 +84,9 @@ import com.android.internal.util.UserIcons; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Objects; /*package*/ final class ApplicationPackageManager extends PackageManager { @@ -98,6 +103,9 @@ final class ApplicationPackageManager extends PackageManager { @GuardedBy("mLock") private PackageInstaller mInstaller; + @GuardedBy("mDelegates") + private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>(); + UserManager getUserManager() { synchronized (mLock) { if (mUserManager == null) { @@ -1410,57 +1418,100 @@ final class ApplicationPackageManager extends PackageManager { } @Override - public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { + public String getInstallerPackageName(String packageName) { + try { + return mPM.getInstallerPackageName(packageName); + } catch (RemoteException e) { + // Should never happen! + } + return null; + } + + @Override + public int getMoveStatus(int moveId) { try { - mPM.movePackage(packageName, observer, flags); + return mPM.getMoveStatus(moveId); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } @Override - public void movePackageAndData(String packageName, String volumeUuid, - IPackageMoveObserver observer) { + public void registerMoveCallback(MoveCallback callback, Handler handler) { + synchronized (mDelegates) { + final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback, + handler.getLooper()); + try { + mPM.registerMoveCallback(delegate); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + mDelegates.add(delegate); + } + } + + @Override + public void unregisterMoveCallback(MoveCallback callback) { + synchronized (mDelegates) { + for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) { + final MoveCallbackDelegate delegate = i.next(); + if (delegate.mCallback == callback) { + try { + mPM.unregisterMoveCallback(delegate); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + i.remove(); + } + } + } + } + + @Override + public int movePackage(String packageName, VolumeInfo vol) { try { - mPM.movePackageAndData(packageName, volumeUuid, observer); + final String volumeUuid; + if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { + volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; + } else if (vol.isPrimaryPhysical()) { + volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; + } else { + volumeUuid = Preconditions.checkNotNull(vol.fsUuid); + } + + return mPM.movePackage(packageName, volumeUuid); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } @Override - public @NonNull VolumeInfo getApplicationCurrentVolume(ApplicationInfo app) { + public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) { final StorageManager storage = mContext.getSystemService(StorageManager.class); if (app.isInternal()) { - return Preconditions.checkNotNull( - storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL)); + return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); } else if (app.isExternalAsec()) { - final List<VolumeInfo> vols = storage.getVolumes(); - for (VolumeInfo vol : vols) { - if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isPrimary()) { - return vol; - } - } - throw new IllegalStateException("Failed to find primary public volume"); + return storage.getPrimaryPhysicalVolume(); } else { - return Preconditions.checkNotNull(storage.findVolumeByUuid(app.volumeUuid)); + return storage.findVolumeByUuid(app.volumeUuid); } } @Override - public @NonNull List<VolumeInfo> getApplicationCandidateVolumes(ApplicationInfo app) { + public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) { final StorageManager storage = mContext.getSystemService(StorageManager.class); + final VolumeInfo currentVol = getPackageCurrentVolume(app); final List<VolumeInfo> vols = storage.getVolumes(); final List<VolumeInfo> candidates = new ArrayList<>(); for (VolumeInfo vol : vols) { - if (isCandidateVolume(app, vol)) { + if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(app, vol)) { candidates.add(vol); } } return candidates; } - private static boolean isCandidateVolume(ApplicationInfo app, VolumeInfo vol) { + private static boolean isPackageCandidateVolume(ApplicationInfo app, VolumeInfo vol) { // Private internal is always an option if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { return true; @@ -1473,10 +1524,14 @@ final class ApplicationPackageManager extends PackageManager { return false; } - // Moving into an ASEC on public primary is only an option when app is - // internal, or already in ASEC - if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isPrimary()) { - return app.isInternal() || app.isExternalAsec(); + // Gotta be able to write there + if (!vol.isMountedWritable()) { + return false; + } + + // Moving into an ASEC on public primary is only option internal + if (vol.isPrimaryPhysical()) { + return app.isInternal(); } // Otherwise we can move to any private volume @@ -1484,13 +1539,66 @@ final class ApplicationPackageManager extends PackageManager { } @Override - public String getInstallerPackageName(String packageName) { + public int movePrimaryStorage(VolumeInfo vol) { try { - return mPM.getInstallerPackageName(packageName); + final String volumeUuid; + if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { + volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; + } else if (vol.isPrimaryPhysical()) { + volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; + } else { + volumeUuid = Preconditions.checkNotNull(vol.fsUuid); + } + + return mPM.movePrimaryStorage(volumeUuid); } catch (RemoteException e) { - // Should never happen! + throw e.rethrowAsRuntimeException(); } - return null; + } + + public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() { + final StorageManager storage = mContext.getSystemService(StorageManager.class); + final String volumeUuid = storage.getPrimaryStorageUuid(); + if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { + return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); + } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { + return storage.getPrimaryPhysicalVolume(); + } else { + return storage.findVolumeByUuid(volumeUuid); + } + } + + public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() { + final StorageManager storage = mContext.getSystemService(StorageManager.class); + final VolumeInfo currentVol = getPrimaryStorageCurrentVolume(); + final List<VolumeInfo> vols = storage.getVolumes(); + final List<VolumeInfo> candidates = new ArrayList<>(); + for (VolumeInfo vol : vols) { + if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) { + candidates.add(vol); + } + } + return candidates; + } + + private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) { + // Private internal is always an option + if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { + return true; + } + + // Gotta be able to write there + if (!vol.isMountedWritable()) { + return false; + } + + // We can move to public volumes on legacy devices + if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) { + return true; + } + + // Otherwise we can move to any private volume + return (vol.getType() == VolumeInfo.TYPE_PRIVATE); } @Override @@ -1941,6 +2049,45 @@ final class ApplicationPackageManager extends PackageManager { return null; } + /** {@hide} */ + private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements + Handler.Callback { + private static final int MSG_STARTED = 1; + private static final int MSG_STATUS_CHANGED = 2; + + final MoveCallback mCallback; + final Handler mHandler; + + public MoveCallbackDelegate(MoveCallback callback, Looper looper) { + mCallback = callback; + mHandler = new Handler(looper, this); + } + + @Override + public boolean handleMessage(Message msg) { + final int moveId = msg.arg1; + switch (msg.what) { + case MSG_STARTED: + mCallback.onStarted(moveId, (String) msg.obj); + return true; + case MSG_STATUS_CHANGED: + mCallback.onStatusChanged(moveId, msg.arg2, (long) msg.obj); + return true; + } + return false; + } + + @Override + public void onStarted(int moveId, String title) { + mHandler.obtainMessage(MSG_STARTED, moveId, 0, title).sendToTarget(); + } + + @Override + public void onStatusChanged(int moveId, int status, long estMillis) { + mHandler.obtainMessage(MSG_STATUS_CHANGED, moveId, status, estMillis).sendToTarget(); + } + } + private final ContextImpl mContext; private final IPackageManager mPM; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 447c668..ae59bfc 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -50,7 +50,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.content.IntentSender; -import com.android.internal.os.IResultReceiver; /** * See {@link PackageManager} for documentation on most of the APIs @@ -431,8 +430,13 @@ interface IPackageManager { PackageCleanItem nextPackageToClean(in PackageCleanItem lastPackage); - void movePackage(String packageName, IPackageMoveObserver observer, int flags); - void movePackageAndData(String packageName, String volumeUuid, IPackageMoveObserver observer); + int getMoveStatus(int moveId); + + void registerMoveCallback(in IPackageMoveObserver callback); + void unregisterMoveCallback(in IPackageMoveObserver callback); + + int movePackage(in String packageName, in String volumeUuid); + int movePrimaryStorage(in String volumeUuid); boolean addPermissionAsync(in PermissionInfo info); diff --git a/core/java/android/content/pm/IPackageMoveObserver.aidl b/core/java/android/content/pm/IPackageMoveObserver.aidl index baa1595..50ab3b5 100644 --- a/core/java/android/content/pm/IPackageMoveObserver.aidl +++ b/core/java/android/content/pm/IPackageMoveObserver.aidl @@ -22,6 +22,6 @@ package android.content.pm; * @hide */ oneway interface IPackageMoveObserver { - void packageMoved(in String packageName, int returnCode); + void onStarted(int moveId, String title); + void onStatusChanged(int moveId, int status, long estMillis); } - diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index e4108b1..e1c271d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -42,6 +42,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; +import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.storage.VolumeInfo; @@ -875,7 +876,8 @@ public abstract class PackageManager { * * @hide */ - public static final int MOVE_SUCCEEDED = 1; + public static final int MOVE_SUCCEEDED = -100; + /** * Error code that is passed to the {@link IPackageMoveObserver} by * {@link #movePackage(android.net.Uri, IPackageMoveObserver)} @@ -941,6 +943,7 @@ public abstract class PackageManager { * been installed on external media. * @hide */ + @Deprecated public static final int MOVE_INTERNAL = 0x00000001; /** @@ -948,8 +951,12 @@ public abstract class PackageManager { * the package should be moved to external media. * @hide */ + @Deprecated public static final int MOVE_EXTERNAL_MEDIA = 0x00000002; + /** {@hide} */ + public static final String EXTRA_MOVE_ID = "android.content.pm.extra.MOVE_ID"; + /** * Usable by the required verifier as the {@code verificationCode} argument * for {@link PackageManager#verifyPendingInstall} to indicate that it will @@ -4183,17 +4190,42 @@ public abstract class PackageManager { * @hide */ @Deprecated - public abstract void movePackage(String packageName, IPackageMoveObserver observer, int flags); + public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { + throw new UnsupportedOperationException(); + } /** {@hide} */ - public abstract void movePackageAndData(String packageName, String volumeUuid, - IPackageMoveObserver observer); + public static boolean isMoveStatusFinished(int status) { + return (status < 0 || status > 100); + } + + /** {@hide} */ + public static abstract class MoveCallback { + public abstract void onStarted(int moveId, String title); + public abstract void onStatusChanged(int moveId, int status, long estMillis); + } /** {@hide} */ - public abstract @Nullable VolumeInfo getApplicationCurrentVolume(ApplicationInfo app); + public abstract int getMoveStatus(int moveId); /** {@hide} */ - public abstract @NonNull List<VolumeInfo> getApplicationCandidateVolumes(ApplicationInfo app); + public abstract void registerMoveCallback(MoveCallback callback, Handler handler); + /** {@hide} */ + public abstract void unregisterMoveCallback(MoveCallback callback); + + /** {@hide} */ + public abstract int movePackage(String packageName, VolumeInfo vol); + /** {@hide} */ + public abstract @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app); + /** {@hide} */ + public abstract @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app); + + /** {@hide} */ + public abstract int movePrimaryStorage(VolumeInfo vol); + /** {@hide} */ + public abstract @Nullable VolumeInfo getPrimaryStorageCurrentVolume(); + /** {@hide} */ + public abstract @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes(); /** * Returns the device identity that verifiers can use to associate their scheme to a particular diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index 64f2a05..9623695 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -36,7 +36,10 @@ import java.util.Objects; * @hide */ public class DiskInfo implements Parcelable { - public static final String EXTRA_DISK_ID = "android.os.storage.extra.DISK_ID"; + public static final String ACTION_DISK_SCANNED = + "android.os.storage.action.DISK_SCANNED"; + public static final String EXTRA_DISK_ID = + "android.os.storage.extra.DISK_ID"; public static final int FLAG_ADOPTABLE = 1 << 0; public static final int FLAG_DEFAULT_PRIMARY = 1 << 1; @@ -96,6 +99,14 @@ public class DiskInfo implements Parcelable { } } + public boolean isAdoptable() { + return (flags & FLAG_ADOPTABLE) != 0; + } + + public boolean isDefaultPrimary() { + return (flags & FLAG_DEFAULT_PRIMARY) != 0; + } + public boolean isSd() { return (flags & FLAG_SD) != 0; } @@ -104,10 +115,6 @@ public class DiskInfo implements Parcelable { return (flags & FLAG_USB) != 0; } - public boolean isAdoptable() { - return (flags & FLAG_ADOPTABLE) != 0; - } - @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 0a8187e..0b1031c 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -1063,6 +1063,38 @@ public interface IMountService extends IInterface { _data.recycle(); } } + + @Override + public String getPrimaryStorageUuid() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + String _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_getPrimaryStorageUuid, _data, _reply, 0); + _reply.readException(); + _result = _reply.readString(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } + + @Override + public void setPrimaryStorageUuid(String volumeUuid) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(volumeUuid); + mRemote.transact(Stub.TRANSACTION_setPrimaryStorageUuid, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } } private static final String DESCRIPTOR = "IMountService"; @@ -1169,6 +1201,9 @@ public interface IMountService extends IInterface { static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 52; static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 53; + static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 54; + static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 55; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1669,6 +1704,20 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_getPrimaryStorageUuid: { + data.enforceInterface(DESCRIPTOR); + String volumeUuid = getPrimaryStorageUuid(); + reply.writeNoException(); + reply.writeString(volumeUuid); + return true; + } + case TRANSACTION_setPrimaryStorageUuid: { + data.enforceInterface(DESCRIPTOR); + String volumeUuid = data.readString(); + setPrimaryStorageUuid(volumeUuid); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1969,4 +2018,7 @@ public interface IMountService extends IInterface { public void setVolumeNickname(String volId, String nickname) throws RemoteException; public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException; + + public String getPrimaryStorageUuid() throws RemoteException; + public void setPrimaryStorageUuid(String volumeUuid) throws RemoteException; } diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java index 8e878a4..fcb4779 100644 --- a/core/java/android/os/storage/IMountServiceListener.java +++ b/core/java/android/os/storage/IMountServiceListener.java @@ -98,10 +98,11 @@ public interface IMountServiceListener extends IInterface { reply.writeNoException(); return true; } - case TRANSACTION_onDiskUnsupported: { + case TRANSACTION_onDiskScanned: { data.enforceInterface(DESCRIPTOR); final DiskInfo disk = (DiskInfo) data.readParcelable(null); - onDiskUnsupported(disk); + final int volumeCount = data.readInt(); + onDiskScanned(disk, volumeCount); reply.writeNoException(); return true; } @@ -207,13 +208,14 @@ public interface IMountServiceListener extends IInterface { } @Override - public void onDiskUnsupported(DiskInfo disk) throws RemoteException { + public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeParcelable(disk, 0); - mRemote.transact(Stub.TRANSACTION_onDiskUnsupported, _data, _reply, + _data.writeInt(volumeCount); + mRemote.transact(Stub.TRANSACTION_onDiskScanned, _data, _reply, android.os.IBinder.FLAG_ONEWAY); _reply.readException(); } finally { @@ -224,12 +226,10 @@ public interface IMountServiceListener extends IInterface { } static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0); - 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); - static final int TRANSACTION_onDiskUnsupported = (IBinder.FIRST_CALL_TRANSACTION + 4); + static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 4); } /** @@ -255,5 +255,5 @@ public interface IMountServiceListener extends IInterface { public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException; - public void onDiskUnsupported(DiskInfo disk) throws RemoteException; + public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException; } diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java index ad2fae0..6a0140e 100644 --- a/core/java/android/os/storage/StorageEventListener.java +++ b/core/java/android/os/storage/StorageEventListener.java @@ -44,6 +44,6 @@ public class StorageEventListener { public void onVolumeMetadataChanged(VolumeInfo vol) { } - public void onDiskUnsupported(DiskInfo disk) { + public void onDiskScanned(DiskInfo disk, int volumeCount) { } } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index f101352..747fb40 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -73,6 +73,11 @@ public class StorageManager { public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable"; /** {@hide} */ + public static final String UUID_PRIVATE_INTERNAL = null; + /** {@hide} */ + public static final String UUID_PRIMARY_PHYSICAL = "primary_physical"; + + /** {@hide} */ public static final int FLAG_ALL_METADATA = 1 << 0; private final Context mContext; @@ -89,7 +94,7 @@ public class StorageManager { 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; - private static final int MSG_DISK_UNSUPPORTED = 4; + private static final int MSG_DISK_SCANNED = 4; final StorageEventListener mCallback; final Handler mHandler; @@ -116,8 +121,8 @@ public class StorageManager { mCallback.onVolumeMetadataChanged((VolumeInfo) args.arg1); args.recycle(); return true; - case MSG_DISK_UNSUPPORTED: - mCallback.onDiskUnsupported((DiskInfo) args.arg1); + case MSG_DISK_SCANNED: + mCallback.onDiskScanned((DiskInfo) args.arg1, args.argi2); args.recycle(); return true; } @@ -156,10 +161,11 @@ public class StorageManager { } @Override - public void onDiskUnsupported(DiskInfo disk) { + public void onDiskScanned(DiskInfo disk, int volumeCount) { final SomeArgs args = SomeArgs.obtain(); args.arg1 = disk; - mHandler.obtainMessage(MSG_DISK_UNSUPPORTED, args).sendToTarget(); + args.argi2 = volumeCount; + mHandler.obtainMessage(MSG_DISK_SCANNED, args).sendToTarget(); } } @@ -534,17 +540,26 @@ public class StorageManager { /** {@hide} */ public @Nullable String getBestVolumeDescription(VolumeInfo vol) { String descrip = vol.getDescription(); - if (vol.disk != null) { if (TextUtils.isEmpty(descrip)) { descrip = vol.disk.getDescription(); } } - return descrip; } /** {@hide} */ + public @Nullable VolumeInfo getPrimaryPhysicalVolume() { + final List<VolumeInfo> vols = getVolumes(); + for (VolumeInfo vol : vols) { + if (vol.isPrimaryPhysical()) { + return vol; + } + } + return null; + } + + /** {@hide} */ public void mount(String volId) { try { mMountService.mount(volId); @@ -628,6 +643,24 @@ public class StorageManager { } /** {@hide} */ + public String getPrimaryStorageUuid() { + try { + return mMountService.getPrimaryStorageUuid(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** {@hide} */ + public void setPrimaryStorageUuid(String volumeUuid) { + try { + mMountService.setPrimaryStorageUuid(volumeUuid); + } 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 f3498d5..4e9cfc7 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -242,6 +242,10 @@ public class VolumeInfo implements Parcelable { return (mountFlags & MOUNT_FLAG_PRIMARY) != 0; } + public boolean isPrimaryPhysical() { + return isPrimary() && (getType() == TYPE_PUBLIC); + } + public boolean isVisible() { return (mountFlags & MOUNT_FLAG_VISIBLE) != 0; } diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 414b7bc..b692a18 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -24,6 +24,12 @@ import java.util.Collection; */ public class Preconditions { + public static void checkArgument(boolean expression) { + if (!expression) { + throw new IllegalArgumentException(); + } + } + /** * Ensures that an object reference passed as a parameter to the calling * method is not null. |