use of android.os.storage.StorageManager in project platform_frameworks_base by android.
the class PackageHelper method resolveInstallVolume.
/**
* Given a requested {@link PackageInfo#installLocation} and calculated
* install size, pick the actual volume to install the app. Only considers
* internal and private volumes, and prefers to keep an existing package on
* its current volume.
*
* @return the {@link VolumeInfo#fsUuid} to install onto, or {@code null}
* for internal storage.
*/
public static String resolveInstallVolume(Context context, String packageName, int installLocation, long sizeBytes) throws IOException {
final boolean forceAllowOnExternal = Settings.Global.getInt(context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
// TODO: handle existing apps installed in ASEC; currently assumes
// they'll end up back on internal storage
ApplicationInfo existingInfo = null;
try {
existingInfo = context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException ignored) {
}
final StorageManager storageManager = context.getSystemService(StorageManager.class);
final boolean fitsOnInternal = fitsOnInternal(context, sizeBytes);
final ArraySet<String> allCandidates = new ArraySet<>();
VolumeInfo bestCandidate = null;
long bestCandidateAvailBytes = Long.MIN_VALUE;
for (VolumeInfo vol : storageManager.getVolumes()) {
if (vol.type == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) {
final long availBytes = storageManager.getStorageBytesUntilLow(new File(vol.path));
if (availBytes >= sizeBytes) {
allCandidates.add(vol.fsUuid);
}
if (availBytes >= bestCandidateAvailBytes) {
bestCandidate = vol;
bestCandidateAvailBytes = availBytes;
}
}
}
// System apps always forced to internal storage
if (existingInfo != null && existingInfo.isSystemApp()) {
installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
}
// If app expresses strong desire for internal storage, honor it
if (!forceAllowOnExternal && installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
if (existingInfo != null && !Objects.equals(existingInfo.volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
throw new IOException("Cannot automatically move " + packageName + " from " + existingInfo.volumeUuid + " to internal storage");
}
if (fitsOnInternal) {
return StorageManager.UUID_PRIVATE_INTERNAL;
} else {
throw new IOException("Requested internal only, but not enough space");
}
}
// If app already exists somewhere, we must stay on that volume
if (existingInfo != null) {
if (Objects.equals(existingInfo.volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL) && fitsOnInternal) {
return StorageManager.UUID_PRIVATE_INTERNAL;
} else if (allCandidates.contains(existingInfo.volumeUuid)) {
return existingInfo.volumeUuid;
} else {
throw new IOException("Not enough space on existing volume " + existingInfo.volumeUuid + " for " + packageName + " upgrade");
}
}
// volume with most space
if (bestCandidate != null) {
return bestCandidate.fsUuid;
} else if (fitsOnInternal) {
return StorageManager.UUID_PRIVATE_INTERNAL;
} else {
throw new IOException("No special requests, but no room anywhere");
}
}
use of android.os.storage.StorageManager in project android_frameworks_base by ParanoidAndroid.
the class UsbDeviceManager method systemReady.
public void systemReady() {
if (DEBUG)
Slog.d(TAG, "systemReady");
mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
// We do not show the USB notification if the primary volume supports mass storage.
// The legacy mass storage UI will be used instead.
boolean massStorageSupported = false;
final StorageManager storageManager = StorageManager.from(mContext);
final StorageVolume primary = storageManager.getPrimaryVolume();
massStorageSupported = primary != null && primary.allowMassStorage();
mUseUsbNotification = !massStorageSupported;
// make sure the ADB_ENABLED setting value matches the current state
Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}
use of android.os.storage.StorageManager in project android_frameworks_base by ParanoidAndroid.
the class MountServiceTests method testAttemptMountNonObb.
@LargeTest
public void testAttemptMountNonObb() {
StorageManager sm = getStorageManager();
final File outFile = getFilePath("test1_nosig.obb");
mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
assertFalse("OBB should not be mounted", sm.isObbMounted(outFile.getPath()));
assertNull("OBB's mounted path should be null", sm.getMountedObbPath(outFile.getPath()));
}
use of android.os.storage.StorageManager in project android_frameworks_base by ParanoidAndroid.
the class MountServiceTests method testAttemptMountObbWrongPackage.
@LargeTest
public void testAttemptMountObbWrongPackage() {
StorageManager sm = getStorageManager();
final File outFile = getFilePath("test1_wrongpackage.obb");
mountObb(sm, R.raw.test1_wrongpackage, outFile, OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
assertFalse("OBB should not be mounted", sm.isObbMounted(outFile.getPath()));
assertNull("OBB's mounted path should be null", sm.getMountedObbPath(outFile.getPath()));
}
use of android.os.storage.StorageManager in project android_frameworks_base by ParanoidAndroid.
the class MountServiceTests method testMountAndUnmountTwoObbs.
@LargeTest
public void testMountAndUnmountTwoObbs() {
StorageManager sm = getStorageManager();
final File file1 = getFilePath("test1.obb");
final File file2 = getFilePath("test2.obb");
ObbObserver oo1 = mountObbWithoutWait(sm, R.raw.test1, file1);
ObbObserver oo2 = mountObbWithoutWait(sm, R.raw.test1, file2);
Log.d(TAG, "Waiting for OBB #1 to complete mount");
waitForObbActionCompletion(sm, file1, oo1, OnObbStateChangeListener.MOUNTED, false);
Log.d(TAG, "Waiting for OBB #2 to complete mount");
waitForObbActionCompletion(sm, file2, oo2, OnObbStateChangeListener.MOUNTED, false);
final String mountPath1 = checkMountedPath(sm, file1);
final File mountDir1 = new File(mountPath1);
assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
final String mountPath2 = checkMountedPath(sm, file2);
final File mountDir2 = new File(mountPath2);
assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
unmountObb(sm, file1, OnObbStateChangeListener.UNMOUNTED);
unmountObb(sm, file2, OnObbStateChangeListener.UNMOUNTED);
}
Aggregations