Loading core/java/android/os/storage/StorageManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os.storage; import android.annotation.Nullable; import android.os.IVold; /** Loading Loading @@ -101,4 +102,11 @@ public abstract class StorageManagerInternal { * @param listener The listener that will be notified on reset events. */ public abstract void addResetListener(ResetListener listener); /** * Notified when any app op changes so that storage mount points can be updated if the app op * affects them. */ public abstract void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode); } services/core/java/com/android/server/StorageManagerService.java +61 −3 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.storage.DiskInfo; import android.os.storage.IObbActionListener; import android.os.storage.IStorageEventListener; Loading Loading @@ -3242,8 +3243,23 @@ class StorageManagerService extends IStorageManager.Stub public void opChanged(int op, int uid, String packageName) throws RemoteException { if (!ENABLE_ISOLATED_STORAGE) return; if (op == OP_REQUEST_INSTALL_PACKAGES) { // Only handling the case when the appop is denied. The other cases will be // handled in the synchronous callback from AppOpsService. if (packageName != null && mIAppOpsService.checkOperation( OP_REQUEST_INSTALL_PACKAGES, uid, packageName) != MODE_ALLOWED) { try { ActivityManager.getService().killUid( UserHandle.getAppId(uid), UserHandle.getUserId(uid), "OP_REQUEST_INSTALL_PACKAGES is denied"); } catch (RemoteException e) { // same process - should not happen } } } else { remountUidExternalStorage(uid, getMountMode(uid, packageName)); } } }; private void addObbStateLocked(ObbState obbState) throws RemoteException { Loading Loading @@ -3579,6 +3595,12 @@ class StorageManagerService extends IStorageManager.Stub if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } final String[] packagesForUid = mIPackageManager.getPackagesForUid(uid); if (packageName == null) { packageName = packagesForUid[0]; } if (mPmInternal.isInstantApp(packageName, UserHandle.getUserId(uid))) { return Zygote.MOUNT_EXTERNAL_NONE; } Loading @@ -3601,8 +3623,18 @@ class StorageManagerService extends IStorageManager.Stub // runtime permission; this is a firm CDD requirement final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES, uid) == PERMISSION_GRANTED; final boolean hasInstallOp = mIAppOpsService.checkOperation(OP_REQUEST_INSTALL_PACKAGES, uid, packageName) == MODE_ALLOWED; boolean hasInstallOp = false; // OP_REQUEST_INSTALL_PACKAGES is granted/denied per package but vold can't // update mountpoints of a specific package. So, check the appop for all packages // sharing the uid and allow same level of storage access for all packages even if // one of the packages has the appop granted. for (String uidPackageName : packagesForUid) { if (mIAppOpsService.checkOperation( OP_REQUEST_INSTALL_PACKAGES, uid, uidPackageName) == MODE_ALLOWED) { hasInstallOp = true; break; } } if ((hasInstall || hasInstallOp) && hasWrite) { return Zygote.MOUNT_EXTERNAL_WRITE; } Loading Loading @@ -3870,6 +3902,14 @@ class StorageManagerService extends IStorageManager.Stub if (ENABLE_ISOLATED_STORAGE) { return getMountMode(uid, packageName); } try { if (packageName == null) { final String[] packagesForUid = mIPackageManager.getPackagesForUid(uid); packageName = packagesForUid[0]; } } catch (RemoteException e) { // Should not happen - same process } // No locking - CopyOnWriteArrayList int mountMode = Integer.MAX_VALUE; for (ExternalStorageMountPolicy policy : mPolicies) { Loading Loading @@ -3918,5 +3958,23 @@ class StorageManagerService extends IStorageManager.Stub } return true; } public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) { if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE || code == OP_WRITE_EXTERNAL_STORAGE || code == OP_REQUEST_INSTALL_PACKAGES)) { final long token = Binder.clearCallingIdentity(); try { final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); if (userManagerInternal.isUserInitialized(UserHandle.getUserId(uid))) { onExternalStoragePolicyChanged(uid, packageName); } } finally { Binder.restoreCallingIdentity(token); } } } } } services/core/java/com/android/server/appop/AppOpsService.java +13 −0 Original line number Diff line number Diff line Loading @@ -1311,6 +1311,7 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { notifyOpChangedSync(code, uid, null, mode); return; } Loading @@ -1332,6 +1333,16 @@ public class AppOpsService extends IAppOpsService.Stub { } } } notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { final StorageManagerInternal storageManagerInternal = LocalServices.getService(StorageManagerInternal.class); if (storageManagerInternal != null) { storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode); } } /** Loading Loading @@ -1394,6 +1405,8 @@ public class AppOpsService extends IAppOpsService.Stub { AppOpsService::notifyOpChanged, this, repCbs, code, uid, packageName)); } notifyOpChangedSync(code, uid, packageName, mode); } private void notifyOpChanged(ArraySet<ModeCallback> callbacks, int code, Loading Loading
core/java/android/os/storage/StorageManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os.storage; import android.annotation.Nullable; import android.os.IVold; /** Loading Loading @@ -101,4 +102,11 @@ public abstract class StorageManagerInternal { * @param listener The listener that will be notified on reset events. */ public abstract void addResetListener(ResetListener listener); /** * Notified when any app op changes so that storage mount points can be updated if the app op * affects them. */ public abstract void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode); }
services/core/java/com/android/server/StorageManagerService.java +61 −3 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.storage.DiskInfo; import android.os.storage.IObbActionListener; import android.os.storage.IStorageEventListener; Loading Loading @@ -3242,8 +3243,23 @@ class StorageManagerService extends IStorageManager.Stub public void opChanged(int op, int uid, String packageName) throws RemoteException { if (!ENABLE_ISOLATED_STORAGE) return; if (op == OP_REQUEST_INSTALL_PACKAGES) { // Only handling the case when the appop is denied. The other cases will be // handled in the synchronous callback from AppOpsService. if (packageName != null && mIAppOpsService.checkOperation( OP_REQUEST_INSTALL_PACKAGES, uid, packageName) != MODE_ALLOWED) { try { ActivityManager.getService().killUid( UserHandle.getAppId(uid), UserHandle.getUserId(uid), "OP_REQUEST_INSTALL_PACKAGES is denied"); } catch (RemoteException e) { // same process - should not happen } } } else { remountUidExternalStorage(uid, getMountMode(uid, packageName)); } } }; private void addObbStateLocked(ObbState obbState) throws RemoteException { Loading Loading @@ -3579,6 +3595,12 @@ class StorageManagerService extends IStorageManager.Stub if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } final String[] packagesForUid = mIPackageManager.getPackagesForUid(uid); if (packageName == null) { packageName = packagesForUid[0]; } if (mPmInternal.isInstantApp(packageName, UserHandle.getUserId(uid))) { return Zygote.MOUNT_EXTERNAL_NONE; } Loading @@ -3601,8 +3623,18 @@ class StorageManagerService extends IStorageManager.Stub // runtime permission; this is a firm CDD requirement final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES, uid) == PERMISSION_GRANTED; final boolean hasInstallOp = mIAppOpsService.checkOperation(OP_REQUEST_INSTALL_PACKAGES, uid, packageName) == MODE_ALLOWED; boolean hasInstallOp = false; // OP_REQUEST_INSTALL_PACKAGES is granted/denied per package but vold can't // update mountpoints of a specific package. So, check the appop for all packages // sharing the uid and allow same level of storage access for all packages even if // one of the packages has the appop granted. for (String uidPackageName : packagesForUid) { if (mIAppOpsService.checkOperation( OP_REQUEST_INSTALL_PACKAGES, uid, uidPackageName) == MODE_ALLOWED) { hasInstallOp = true; break; } } if ((hasInstall || hasInstallOp) && hasWrite) { return Zygote.MOUNT_EXTERNAL_WRITE; } Loading Loading @@ -3870,6 +3902,14 @@ class StorageManagerService extends IStorageManager.Stub if (ENABLE_ISOLATED_STORAGE) { return getMountMode(uid, packageName); } try { if (packageName == null) { final String[] packagesForUid = mIPackageManager.getPackagesForUid(uid); packageName = packagesForUid[0]; } } catch (RemoteException e) { // Should not happen - same process } // No locking - CopyOnWriteArrayList int mountMode = Integer.MAX_VALUE; for (ExternalStorageMountPolicy policy : mPolicies) { Loading Loading @@ -3918,5 +3958,23 @@ class StorageManagerService extends IStorageManager.Stub } return true; } public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) { if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE || code == OP_WRITE_EXTERNAL_STORAGE || code == OP_REQUEST_INSTALL_PACKAGES)) { final long token = Binder.clearCallingIdentity(); try { final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); if (userManagerInternal.isUserInitialized(UserHandle.getUserId(uid))) { onExternalStoragePolicyChanged(uid, packageName); } } finally { Binder.restoreCallingIdentity(token); } } } } }
services/core/java/com/android/server/appop/AppOpsService.java +13 −0 Original line number Diff line number Diff line Loading @@ -1311,6 +1311,7 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { notifyOpChangedSync(code, uid, null, mode); return; } Loading @@ -1332,6 +1333,16 @@ public class AppOpsService extends IAppOpsService.Stub { } } } notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { final StorageManagerInternal storageManagerInternal = LocalServices.getService(StorageManagerInternal.class); if (storageManagerInternal != null) { storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode); } } /** Loading Loading @@ -1394,6 +1405,8 @@ public class AppOpsService extends IAppOpsService.Stub { AppOpsService::notifyOpChanged, this, repCbs, code, uid, packageName)); } notifyOpChangedSync(code, uid, packageName, mode); } private void notifyOpChanged(ArraySet<ModeCallback> callbacks, int code, Loading