diff options
Diffstat (limited to 'core/java/android/app/ApplicationPackageManager.java')
-rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 907ae26..e71713a 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -67,6 +67,8 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.StorageManager; +import android.os.storage.VolumeInfo; import android.util.ArrayMap; import android.util.Log; import android.view.Display; @@ -1425,6 +1427,61 @@ final class ApplicationPackageManager extends PackageManager { } @Override + public @NonNull VolumeInfo getApplicationCurrentVolume(ApplicationInfo app) { + final StorageManager storage = mContext.getSystemService(StorageManager.class); + if (app.isInternal()) { + return Preconditions.checkNotNull( + 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"); + } else { + return Preconditions.checkNotNull(storage.findVolumeByUuid(app.volumeUuid)); + } + } + + @Override + public @NonNull List<VolumeInfo> getApplicationCandidateVolumes(ApplicationInfo app) { + final StorageManager storage = mContext.getSystemService(StorageManager.class); + final List<VolumeInfo> vols = storage.getVolumes(); + final List<VolumeInfo> candidates = new ArrayList<>(); + for (VolumeInfo vol : vols) { + if (isCandidateVolume(app, vol)) { + candidates.add(vol); + } + } + return candidates; + } + + private static boolean isCandidateVolume(ApplicationInfo app, VolumeInfo vol) { + // Private internal is always an option + if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { + return true; + } + + // System apps and apps demanding internal storage can't be moved + // anywhere else + if (app.isSystemApp() + || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { + 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(); + } + + // Otherwise we can move to any private volume + return (vol.getType() == VolumeInfo.TYPE_PRIVATE); + } + + @Override public String getInstallerPackageName(String packageName) { try { return mPM.getInstallerPackageName(packageName); |