Merge "New sm command to unmount app data and obb app visibility mount" am: 3299d00b87 am: 40c7e3d17d am: 05af40c490

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1552534

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ie35b99efa56faaf4339a7c344743092a5b5d540b
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index ef1e413..9088db8 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -105,6 +105,8 @@
             runStartCheckpoint();
         } else if ("supports-checkpoint".equals(op)) {
             runSupportsCheckpoint();
+        } else if ("unmount-app-data-dirs".equals(op)) {
+            runDisableAppDataIsolation();
         } else {
             throw new IllegalArgumentException();
         }
@@ -251,6 +253,13 @@
         System.out.println(result.get());
     }
 
+    public void runDisableAppDataIsolation() throws RemoteException {
+        final String pkgName = nextArg();
+        final int pid = Integer.parseInt(nextArg());
+        final int userId = Integer.parseInt(nextArg());
+        mSm.disableAppDataIsolation(pkgName, pid, userId);
+    }
+
     public void runForget() throws RemoteException {
         final String fsUuid = nextArg();
         if ("all".equals(fsUuid)) {
@@ -347,6 +356,8 @@
         System.err.println("");
         System.err.println("       sm supports-checkpoint");
         System.err.println("");
+        System.err.println("       sm unmount-app-data-dirs PACKAGE_NAME PID USER_ID");
+        System.err.println("");
         return 1;
     }
 }
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 99bdfd1..4669b20 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -195,4 +195,5 @@
     void abortChanges(in String message, boolean retry) = 87;
     void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88;
     void fixupAppDir(in String path) = 89;
+    void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90;
 }
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d21182b..cd6a9fb 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1526,7 +1526,6 @@
         }
     }
 
-
     private void onVolumeStateChangedAsync(VolumeInfo vol, int oldState, int newState) {
         synchronized (mLock) {
             // Remember that we saw this volume so we're ready to accept user
@@ -3275,6 +3274,27 @@
         }
     }
 
+    /*
+     * Disable storage's app data isolation for testing.
+     */
+    @Override
+    public void disableAppDataIsolation(String pkgName, int pid, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) {
+            throw new SecurityException("no permission to enable app visibility");
+        }
+        final String[] sharedPackages =
+                mPmInternal.getSharedUserPackagesForPackage(pkgName, userId);
+        final int uid = mPmInternal.getPackageUid(pkgName, 0, userId);
+        final String[] packages =
+                sharedPackages.length != 0 ? sharedPackages : new String[]{pkgName};
+        try {
+            mVold.unmountAppStorageDirs(uid, pid, packages);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
     /** Not thread safe */
     class AppFuseMountScope extends AppFuseBridge.MountScope {
         private boolean mMounted = false;