diff options
author | Nate Myren <ntmyren@google.com> | 2019-06-07 13:11:58 -0700 |
---|---|---|
committer | Nate Myren <ntmyren@google.com> | 2019-06-28 16:56:26 +0000 |
commit | d3a63856866a417d3a2cd870b1cf9083f6ae278f (patch) | |
tree | 82a6b9c315b6597de1f8cbb442a68786fd4445ab | |
parent | 9562bc95cbb80686b92e62a814f84d00c464b909 (diff) |
Permission flag updates now notify listeners
Added a version of the onPermissionUpdated and
onInstallPermissionUpdated methods which will notify
OnPermissionChangedListeners, and added this to the
PermissionManagerService "updatePermissionFlags" and
"updatePermissionFlagsForAllApps" methods. Also adds
OnPermissionsChangedListener to @TestApi
Fixes: 135937566
Test: atest PermissionUpdateListenerTest
Change-Id: I906598c366234c3daaa202261678bca04837cb13
8 files changed, 54 insertions, 10 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 0127dfe19253..bc98bbcfc928 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -694,6 +694,7 @@ package android.content.pm { } public abstract class PackageManager { + method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable public String getIncidentReportApproverPackageName(); @@ -707,6 +708,7 @@ package android.content.pm { method @NonNull public abstract String getSharedSystemSharedLibraryPackageName(); method @Nullable public String getWellbeingPackageName(); method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle); field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage"; @@ -729,6 +731,10 @@ package android.content.pm { field public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared"; } + public static interface PackageManager.OnPermissionsChangedListener { + method public void onPermissionsChanged(int); + } + public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int FLAG_REMOVED = 2; // 0x2 field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000 diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index e08f4a28e77c..b845a37b0342 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -105,6 +105,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @TestApi public interface OnPermissionsChangedListener { /** @@ -6413,6 +6414,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) public abstract void addOnPermissionsChangeListener( @NonNull OnPermissionsChangedListener listener); @@ -6425,6 +6427,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) public abstract void removeOnPermissionsChangeListener( @NonNull OnPermissionsChangedListener listener); diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index ff4e1005c9d9..dfff67f3a5fa 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -268,6 +268,8 @@ applications that come with the platform <permission name="android.permission.INSTALL_PACKAGES"/> <!-- Needed for test only --> <permission name="android.permission.INTERACT_ACROSS_PROFILES"/> + <!-- Permission required to test onPermissionsChangedListener --> + <permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/> <permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.LOCAL_MAC_ADDRESS"/> <permission name="android.permission.MANAGE_ACCESSIBILITY"/> diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 98c6702f899d..8689eef79583 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -101,6 +101,8 @@ <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" /> + <!-- Permission required to test onPermissionsChangedListener --> + <uses-permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" /> <uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" /> <uses-permission android:name="android.permission.GET_DETAILED_TASKS" /> <uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" /> diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 62dd3fbe6d1d..86b10442a357 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1765,11 +1765,12 @@ public class PackageManagerService extends IPackageManager.Stub private PermissionCallback mPermissionCallback = new PermissionCallback() { @Override - public void onGidsChanged(int appId, int userId) { + public void onGidsChanged(int appId, @UserIdInt int userId) { mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED)); } + @Override - public void onPermissionGranted(int uid, int userId) { + public void onPermissionGranted(int uid, @UserIdInt int userId) { mOnPermissionChangeListeners.onPermissionsChanged(uid); // Not critical; if this is lost, the application has to request again. @@ -1777,14 +1778,16 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeRuntimePermissionsForUserLPr(userId, false); } } + @Override public void onInstallPermissionGranted() { synchronized (mPackages) { scheduleWriteSettingsLocked(); } } + @Override - public void onPermissionRevoked(int uid, int userId) { + public void onPermissionRevoked(int uid, @UserIdInt int userId) { mOnPermissionChangeListeners.onPermissionsChanged(uid); synchronized (mPackages) { @@ -1795,26 +1798,43 @@ public class PackageManagerService extends IPackageManager.Stub final int appId = UserHandle.getAppId(uid); killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); } + @Override public void onInstallPermissionRevoked() { synchronized (mPackages) { scheduleWriteSettingsLocked(); } } + @Override - public void onPermissionUpdated(int[] updatedUserIds, boolean sync) { + public void onPermissionUpdated(@UserIdInt int[] updatedUserIds, boolean sync) { synchronized (mPackages) { for (int userId : updatedUserIds) { mSettings.writeRuntimePermissionsForUserLPr(userId, sync); } } } + + @Override + public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync, + int uid) { + onPermissionUpdated(updatedUserIds, sync); + mOnPermissionChangeListeners.onPermissionsChanged(uid); + } + @Override public void onInstallPermissionUpdated() { synchronized (mPackages) { scheduleWriteSettingsLocked(); } } + + @Override + public void onInstallPermissionUpdatedNotifyListener(int uid) { + onInstallPermissionUpdated(); + mOnPermissionChangeListeners.onPermissionsChanged(uid); + } + @Override public void onPermissionRemoved() { synchronized (mPackages) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 890a3c3ab7ff..6a8f1ed18c85 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -2926,10 +2926,11 @@ public class PermissionManagerService { // Install and runtime permissions are stored in different places, // so figure out what permission changed and persist the change. if (permissionsState.getInstallPermissionState(permName) != null) { - callback.onInstallPermissionUpdated(); + callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid); } else if (permissionsState.getRuntimePermissionState(permName, userId) != null || hadState) { - callback.onPermissionUpdated(new int[] { userId }, false); + callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false, + pkg.applicationInfo.uid); } } } @@ -2963,6 +2964,8 @@ public class PermissionManagerService { PermissionsState permissionsState = ps.getPermissionsState(); changed |= permissionsState.updatePermissionFlagsForAllPermissions( userId, flagMask, flagValues); + callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false, + pkg.applicationInfo.uid); } return changed; } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index 98781e86805d..8428477733cd 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -16,6 +16,7 @@ package com.android.server.pm.permission; +import android.annotation.AppIdInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -44,24 +45,29 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager * callback methods. */ public static class PermissionCallback { - public void onGidsChanged(int appId, int userId) { + public void onGidsChanged(@AppIdInt int appId, @UserIdInt int userId) { } public void onPermissionChanged() { } - public void onPermissionGranted(int uid, int userId) { + public void onPermissionGranted(int uid, @UserIdInt int userId) { } public void onInstallPermissionGranted() { } - public void onPermissionRevoked(int uid, int userId) { + public void onPermissionRevoked(int uid, @UserIdInt int userId) { } public void onInstallPermissionRevoked() { } - public void onPermissionUpdated(int[] updatedUserIds, boolean sync) { + public void onPermissionUpdated(@UserIdInt int[] updatedUserIds, boolean sync) { + } + public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync, + int uid) { } public void onPermissionRemoved() { } public void onInstallPermissionUpdated() { } + public void onInstallPermissionUpdatedNotifyListener(int uid) { + } } public abstract void systemReady(); diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt index a87e2f57bb5f..cc260ac14147 100644 --- a/test-mock/api/test-current.txt +++ b/test-mock/api/test-current.txt @@ -7,6 +7,7 @@ package android.test.mock { } @Deprecated public class MockPackageManager extends android.content.pm.PackageManager { + method public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public boolean arePermissionsIndividuallyControlled(); method public String getDefaultBrowserPackageNameAsUser(int); method public int getInstallReason(String, android.os.UserHandle); @@ -18,6 +19,7 @@ package android.test.mock { method @NonNull public String getServicesSystemSharedLibraryPackageName(); method @NonNull public String getSharedSystemSharedLibraryPackageName(); method public void grantRuntimePermission(String, String, android.os.UserHandle); + method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public void revokeRuntimePermission(String, String, android.os.UserHandle); method public void updatePermissionFlags(String, String, int, int, android.os.UserHandle); } |