Merge "Fixup OBB directories correctly after package install."
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index e78aef5..4bd31f8 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -16,6 +16,7 @@
package android.os.storage;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IVold;
@@ -124,4 +125,14 @@
* legacy storage, {@code false} otherwise.
*/
public abstract boolean hasLegacyExternalStorage(int uid);
+
+ /**
+ * Makes sure app-private data directories on external storage are setup correctly
+ * after an application is installed or upgraded. The main use for this is OBB dirs,
+ * which can be created/modified by the installer.
+ *
+ * @param packageName the package name of the package
+ * @param uid the uid of the package
+ */
+ public abstract void prepareAppDataAfterInstall(@NonNull String packageName, int uid);
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 53dbb93..3b0a1a3 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4409,6 +4409,25 @@
}
}
+ @Override
+ public void prepareAppDataAfterInstall(String packageName, int uid) {
+ int userId = UserHandle.getUserId(uid);
+ final Environment.UserEnvironment userEnv = new Environment.UserEnvironment(userId);
+
+ // The installer may have downloaded OBBs for this newly installed application;
+ // make sure the OBB dir for the application is setup correctly, if it exists.
+ File[] packageObbDirs = userEnv.buildExternalStorageAppObbDirs(packageName);
+ for (File packageObbDir : packageObbDirs) {
+ try {
+ mVold.fixupAppDir(packageObbDir.getCanonicalPath() + "/", uid);
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to get canonical path for " + packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to fixup app dir for " + packageName);
+ }
+ }
+ }
+
public boolean hasExternalStorage(int uid, String packageName) {
// No need to check for system uid. This avoids a deadlock between
// PackageManagerService and AppOpsService.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e96f85b..2a3f7ed 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21736,6 +21736,7 @@
}
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
+ StorageManagerInternal smInternal = mInjector.getStorageManagerInternal();
for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
final int flags;
if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
@@ -21749,6 +21750,13 @@
if (ps.getInstalled(user.id)) {
// TODO: when user data is locked, mark that we're still dirty
prepareAppDataLIF(pkg, user.id, flags);
+
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
+ // Prepare app data on external storage; currently this is used to
+ // setup any OBB dirs that were created by the installer correctly.
+ int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
+ smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
+ }
}
}
}