Fix devices with primary physical storage.
Always assume the factory-reset default primary storage before parsing storage settings. Without this, we'd always default to picking internal emulated storage during first boot or upgrade. Bump version code to re-evaluate this for devices that default to physical storage as primary. Also restrict available move targets when storage is physical, since we can't really translate between multi-user and non-multi-user aware storage. Bug: 20836019 Change-Id: I186ded1aa3dd9cea67497a4f53b0973031174ccd
This commit is contained in:
@@ -1571,9 +1571,15 @@ final class ApplicationPackageManager extends PackageManager {
|
|||||||
final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
|
final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
|
||||||
final List<VolumeInfo> vols = storage.getVolumes();
|
final List<VolumeInfo> vols = storage.getVolumes();
|
||||||
final List<VolumeInfo> candidates = new ArrayList<>();
|
final List<VolumeInfo> candidates = new ArrayList<>();
|
||||||
for (VolumeInfo vol : vols) {
|
if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
|
||||||
if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
|
storage.getPrimaryStorageUuid()) && currentVol != null) {
|
||||||
candidates.add(vol);
|
// 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;
|
return candidates;
|
||||||
@@ -1590,12 +1596,7 @@ final class ApplicationPackageManager extends PackageManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can move to public volumes on legacy devices
|
// We can move to any private volume
|
||||||
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);
|
return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ class MountService extends IMountService.Stub
|
|||||||
|
|
||||||
private static final int VERSION_INIT = 1;
|
private static final int VERSION_INIT = 1;
|
||||||
private static final int VERSION_ADD_PRIMARY = 2;
|
private static final int VERSION_ADD_PRIMARY = 2;
|
||||||
|
private static final int VERSION_FIX_PRIMARY = 3;
|
||||||
|
|
||||||
private static final String TAG_VOLUMES = "volumes";
|
private static final String TAG_VOLUMES = "volumes";
|
||||||
private static final String ATTR_VERSION = "version";
|
private static final String ATTR_VERSION = "version";
|
||||||
@@ -1187,8 +1188,17 @@ class MountService extends IMountService.Stub
|
|||||||
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
|
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDefaultPrimaryStorageUuid() {
|
||||||
|
if (SystemProperties.getBoolean(StorageManager.PROP_PRIMARY_PHYSICAL, false)) {
|
||||||
|
return StorageManager.UUID_PRIMARY_PHYSICAL;
|
||||||
|
} else {
|
||||||
|
return StorageManager.UUID_PRIVATE_INTERNAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readSettingsLocked() {
|
private void readSettingsLocked() {
|
||||||
mRecords.clear();
|
mRecords.clear();
|
||||||
|
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
|
||||||
|
|
||||||
FileInputStream fis = null;
|
FileInputStream fis = null;
|
||||||
try {
|
try {
|
||||||
@@ -1202,16 +1212,13 @@ class MountService extends IMountService.Stub
|
|||||||
final String tag = in.getName();
|
final String tag = in.getName();
|
||||||
if (TAG_VOLUMES.equals(tag)) {
|
if (TAG_VOLUMES.equals(tag)) {
|
||||||
final int version = readIntAttribute(in, ATTR_VERSION, VERSION_INIT);
|
final int version = readIntAttribute(in, ATTR_VERSION, VERSION_INIT);
|
||||||
if (version >= VERSION_ADD_PRIMARY) {
|
final boolean primaryPhysical = SystemProperties.getBoolean(
|
||||||
|
StorageManager.PROP_PRIMARY_PHYSICAL, false);
|
||||||
|
final boolean validAttr = (version >= VERSION_FIX_PRIMARY)
|
||||||
|
|| (version >= VERSION_ADD_PRIMARY && !primaryPhysical);
|
||||||
|
if (validAttr) {
|
||||||
mPrimaryStorageUuid = readStringAttribute(in,
|
mPrimaryStorageUuid = readStringAttribute(in,
|
||||||
ATTR_PRIMARY_STORAGE_UUID);
|
ATTR_PRIMARY_STORAGE_UUID);
|
||||||
} else {
|
|
||||||
if (SystemProperties.getBoolean(StorageManager.PROP_PRIMARY_PHYSICAL,
|
|
||||||
false)) {
|
|
||||||
mPrimaryStorageUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
|
|
||||||
} else {
|
|
||||||
mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (TAG_VOLUME.equals(tag)) {
|
} else if (TAG_VOLUME.equals(tag)) {
|
||||||
@@ -1240,7 +1247,7 @@ class MountService extends IMountService.Stub
|
|||||||
out.setOutput(fos, "utf-8");
|
out.setOutput(fos, "utf-8");
|
||||||
out.startDocument(null, true);
|
out.startDocument(null, true);
|
||||||
out.startTag(null, TAG_VOLUMES);
|
out.startTag(null, TAG_VOLUMES);
|
||||||
writeIntAttribute(out, ATTR_VERSION, VERSION_ADD_PRIMARY);
|
writeIntAttribute(out, ATTR_VERSION, VERSION_FIX_PRIMARY);
|
||||||
writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid);
|
writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid);
|
||||||
final int size = mRecords.size();
|
final int size = mRecords.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
@@ -1482,7 +1489,7 @@ class MountService extends IMountService.Stub
|
|||||||
// If this had been primary storage, revert back to internal and
|
// If this had been primary storage, revert back to internal and
|
||||||
// reset vold so we bind into new volume into place.
|
// reset vold so we bind into new volume into place.
|
||||||
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
|
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
|
||||||
mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
|
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,11 +1504,13 @@ class MountService extends IMountService.Stub
|
|||||||
final String fsUuid = mRecords.keyAt(i);
|
final String fsUuid = mRecords.keyAt(i);
|
||||||
mCallbacks.notifyVolumeForgotten(fsUuid);
|
mCallbacks.notifyVolumeForgotten(fsUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
mRecords.clear();
|
mRecords.clear();
|
||||||
writeSettingsLocked();
|
|
||||||
|
|
||||||
mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
|
if (!Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, mPrimaryStorageUuid)) {
|
||||||
|
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeSettingsLocked();
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1522,13 +1531,8 @@ class MountService extends IMountService.Stub
|
|||||||
waitForReady();
|
waitForReady();
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final VolumeInfo from = Preconditions.checkNotNull(
|
if (Objects.equals(mPrimaryStorageUuid, volumeUuid)) {
|
||||||
findStorageForUuid(mPrimaryStorageUuid));
|
throw new IllegalArgumentException("Primary storage already at " + volumeUuid);
|
||||||
final VolumeInfo to = Preconditions.checkNotNull(
|
|
||||||
findStorageForUuid(volumeUuid));
|
|
||||||
|
|
||||||
if (Objects.equals(from, to)) {
|
|
||||||
throw new IllegalArgumentException("Primary storage already at " + from);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMoveCallback != null) {
|
if (mMoveCallback != null) {
|
||||||
@@ -1537,10 +1541,26 @@ class MountService extends IMountService.Stub
|
|||||||
mMoveCallback = callback;
|
mMoveCallback = callback;
|
||||||
mMoveTargetUuid = volumeUuid;
|
mMoveTargetUuid = volumeUuid;
|
||||||
|
|
||||||
try {
|
// When moving to/from primary physical volume, we probably just nuked
|
||||||
mConnector.execute("volume", "move_storage", from.id, to.id);
|
// the current storage location, so we have nothing to move.
|
||||||
} catch (NativeDaemonConnectorException e) {
|
if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid)
|
||||||
throw e.rethrowAsParcelableException();
|
|| 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);
|
||||||
|
resetIfReadyAndConnected();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
final VolumeInfo from = Preconditions.checkNotNull(
|
||||||
|
findStorageForUuid(mPrimaryStorageUuid));
|
||||||
|
final VolumeInfo to = Preconditions.checkNotNull(
|
||||||
|
findStorageForUuid(volumeUuid));
|
||||||
|
|
||||||
|
try {
|
||||||
|
mConnector.execute("volume", "move_storage", from.id, to.id);
|
||||||
|
} catch (NativeDaemonConnectorException e) {
|
||||||
|
throw e.rethrowAsParcelableException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user