summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arnab Sen <arnabse@amazon.com> 2022-02-03 16:26:33 +0000
committer Arnab Sen <arnabse@amazon.com> 2023-07-01 07:46:42 +0530
commitdd16ab0ee6be9eb87945ad32548a0d5e74d0e5c3 (patch)
treebb7c41a37993c8522058c9ac4feeab0105b094b7
parent79572ee42e6a57b9e5deede5a3317d3244f866b6 (diff)
PackageManager: Create missing userdata directory
..when app is moved to Adopted storage. Whenever an user tries to move a package which is installed in more than one user to adopted storage, it fails with the error ‘Not enough space’ even if space is available on the adopted storage. To fix the issue check that if the user data directory is present or not. If the user data directory does not exist in the adopted storage, attempt to create user data directories. This ensures that user directories are created before the user data is copied from internal storage to adopted storage. This prevents the move from failing. Test: Perform the following steps: 1. Create multiple users apart from system user 2. Make ExternalLocTestApp and install for all the users. 3. Go to Settings > All Apps > ExternalLocTestApp > Storage & Cache 4. Tap on Change under Storage User and Select Adopted storage. 5. Check that the process is not failing Change-Id: I073f7f7686bd40ba1d126f04d125b0d2522190ee
-rw-r--r--services/core/java/com/android/server/pm/MovePackageHelper.java35
1 files changed, 35 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/pm/MovePackageHelper.java b/services/core/java/com/android/server/pm/MovePackageHelper.java
index c5ca06cc7b84..1f96205aa3cb 100644
--- a/services/core/java/com/android/server/pm/MovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/MovePackageHelper.java
@@ -34,6 +34,7 @@ import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
+import android.content.pm.UserInfo;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.result.ParseResult;
@@ -48,6 +49,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.text.TextUtils;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseIntArray;
@@ -220,6 +222,16 @@ public final class MovePackageHelper {
"Not enough free space to move");
}
+ try {
+ for (int index = 0; index < installedUserIds.length; index++) {
+ prepareUserDataForVolumeIfRequired(volumeUuid, installedUserIds[index], storage);
+ }
+ } catch (RuntimeException e) {
+ freezer.close();
+ throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+ "Failed to prepare user storage while moving app");
+ }
+
mPm.mMoveCallbacks.notifyStatusChanged(moveId, 10);
final CountDownLatch installedLatch = new CountDownLatch(1);
@@ -368,6 +380,29 @@ public final class MovePackageHelper {
return true;
}
+ private void prepareUserDataForVolumeIfRequired(String volumeUuid, int userId,
+ StorageManager storageManager) {
+ if (TextUtils.isEmpty(volumeUuid)
+ || doesDataDirectoryExistForUser(volumeUuid, userId)) {
+ return;
+ }
+ if (DEBUG_INSTALL) {
+ Slog.d(TAG, "Preparing user directories for user u" + userId + " for UUID "
+ + volumeUuid);
+ }
+ final UserInfo user = mPm.mUserManager.getUserInfo(userId);
+ if (user == null) return;
+ // This call is same as StorageEventHelper#loadPrivatePackagesInner which prepares
+ // the storage before reconciling apps
+ storageManager.prepareUserStorage(volumeUuid, user.id, user.serialNumber,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ }
+
+ private boolean doesDataDirectoryExistForUser(String uuid, int userId) {
+ final File userDirectoryFile = Environment.getDataUserCeDirectory(uuid, userId);
+ return userDirectoryFile != null && userDirectoryFile.exists();
+ }
+
public static class MoveCallbacks extends Handler {
private static final int MSG_CREATED = 1;
private static final int MSG_STATUS_CHANGED = 2;