use of android.os.storage.VolumeInfo in project android_frameworks_base by AOSPA.
the class MountService method setPrimaryStorageUuid.
@Override
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
final VolumeInfo from;
final VolumeInfo to;
synchronized (mLock) {
if (Objects.equals(mPrimaryStorageUuid, volumeUuid)) {
throw new IllegalArgumentException("Primary storage already at " + volumeUuid);
}
if (mMoveCallback != null) {
throw new IllegalStateException("Move already in progress");
}
mMoveCallback = callback;
mMoveTargetUuid = volumeUuid;
// the current storage location, so we have nothing to move.
if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid) || Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
Slog.d(TAG, "Skipping move to/from primary physical");
onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
mHandler.obtainMessage(H_RESET).sendToTarget();
return;
} else {
from = findStorageForUuid(mPrimaryStorageUuid);
to = findStorageForUuid(volumeUuid);
if (from == null) {
Slog.w(TAG, "Failing move due to missing from volume " + mPrimaryStorageUuid);
onMoveStatusLocked(PackageManager.MOVE_FAILED_INTERNAL_ERROR);
return;
} else if (to == null) {
Slog.w(TAG, "Failing move due to missing to volume " + volumeUuid);
onMoveStatusLocked(PackageManager.MOVE_FAILED_INTERNAL_ERROR);
return;
}
}
}
try {
mConnector.execute("volume", "move_storage", from.id, to.id);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
use of android.os.storage.VolumeInfo in project android_frameworks_base by AOSPA.
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.VolumeInfo in project android_frameworks_base by AOSPA.
the class Sm method runListVolumes.
public void runListVolumes() throws RemoteException {
final String filter = nextArg();
final int filterType;
if ("public".equals(filter)) {
filterType = VolumeInfo.TYPE_PUBLIC;
} else if ("private".equals(filter)) {
filterType = VolumeInfo.TYPE_PRIVATE;
} else if ("emulated".equals(filter)) {
filterType = VolumeInfo.TYPE_EMULATED;
} else {
filterType = -1;
}
final VolumeInfo[] vols = mSm.getVolumes(0);
for (VolumeInfo vol : vols) {
if (filterType == -1 || filterType == vol.getType()) {
final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid());
}
}
}
use of android.os.storage.VolumeInfo in project android_frameworks_base by AOSPA.
the class ApplicationPackageManager method getPackageCandidateVolumes.
@Override
@NonNull
public 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 (Objects.equals(vol, currentVol) || isPackageCandidateVolume(mContext, app, vol)) {
candidates.add(vol);
}
}
return candidates;
}
use of android.os.storage.VolumeInfo in project android_frameworks_base by AOSPA.
the class ApplicationPackageManager method getPrimaryStorageCandidateVolumes.
@Override
@NonNull
public 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<>();
if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, storage.getPrimaryStorageUuid()) && currentVol != null) {
// TODO: support moving primary physical to emulated volume
candidates.add(currentVol);
} else {
for (VolumeInfo vol : vols) {
if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
candidates.add(vol);
}
}
}
return candidates;
}
Aggregations