Browse Source

Restricted permission mechanism - framework

This change adds a mechanism for restricting permissions (only runtime
for now), so that an app cannot hold the permission if it is not white
listed. The whitelisting can happen at install or at any later point.

There are three whitelists: system: OS managed with default grants
and role holders being on it; upgrade: only OS puts on this list
apps when upgrading from a pre to post restriction permission database
version and OS and installer on record can remove; installer: only
the installer on record can add and remove (and the system of course).

Added a permission policy service that sits on top of permissions
and app ops and is responsible to sync between permissions and app
ops when there is an interdependecy in any direction.

Added versioning to the runtime permissions database to allow operations
that need to be done once on upgrade such as adding all permissions held
by apps pre upgrade to the upgrade whitelist if the new permisison version
inctroduces a new restricted permission. The upgrade logic is in the
permission controller and we will eventually put the default grants there.

NOTE: This change is reacting to a VP feedback for how we would handle
SMS/CallLog restriction as we pivoted from role based approach to roles
for things the user would understand plus whitelist for everything else.
This would also help us roll out softly the storage permisison as there
is too much churm coming from developer feedback.

Exempt-From-Owner-Approval: trivial change due to APi adjustment

Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.PermissionsHostTest
Test: atest CtsPermissionTestCases
Test: atest CtsPermission2TestCases
Test: atest RoleManagerTestCases

bug:124769181

Change-Id: Ic48e3c728387ecf02f89d517ba1fe785ab9c75fd
ten
Svet Ganov 2 years ago
parent
commit
d8eb8b2690
56 changed files with 2021 additions and 312 deletions
  1. 11
    0
      api/current.txt
  2. 14
    9
      api/system-current.txt
  3. 12
    7
      api/test-current.txt
  4. 2
    0
      cmds/statsd/src/atoms.proto
  5. 9
    55
      core/java/android/app/AppOpsManager.java
  6. 45
    4
      core/java/android/app/ApplicationPackageManager.java
  7. 5
    2
      core/java/android/app/SystemServiceRegistry.java
  8. 0
    2
      core/java/android/app/role/IRoleController.aidl
  9. 0
    29
      core/java/android/app/role/RoleControllerManager.java
  10. 0
    20
      core/java/android/app/role/RoleControllerService.java
  11. 1
    17
      core/java/android/content/ContentProvider.java
  12. 14
    1
      core/java/android/content/pm/IPackageManager.aidl
  13. 77
    0
      core/java/android/content/pm/PackageInstaller.java
  14. 295
    5
      core/java/android/content/pm/PackageManager.java
  15. 11
    0
      core/java/android/content/pm/PackageManagerInternal.java
  16. 13
    0
      core/java/android/content/pm/PackageParser.java
  17. 41
    0
      core/java/android/content/pm/PermissionInfo.java
  18. 1
    1
      core/java/android/os/RemoteCallback.java
  19. 1
    0
      core/java/android/permission/IPermissionController.aidl
  20. 77
    8
      core/java/android/permission/PermissionControllerManager.java
  21. 28
    0
      core/java/android/permission/PermissionControllerService.java
  22. 49
    1
      core/java/android/permission/PermissionManager.java
  23. 34
    0
      core/java/android/permission/PermissionManagerInternal.java
  24. 1
    24
      core/java/android/provider/DeviceConfig.java
  25. 0
    12
      core/java/android/provider/Settings.java
  26. 7
    0
      core/java/android/util/StatsLogAtoms.java
  27. 0
    1
      core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
  28. 15
    1
      core/res/AndroidManifest.xml
  29. 12
    1
      core/res/res/values/attrs_manifest.xml
  30. 0
    1
      core/tests/coretests/src/android/provider/SettingsBackupTest.java
  31. 3
    0
      packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
  32. 0
    5
      packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
  33. 1
    1
      packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
  34. 1
    0
      packages/Shell/AndroidManifest.xml
  35. 0
    1
      services/core/java/com/android/server/am/CoreSettingsObserver.java
  36. 1
    1
      services/core/java/com/android/server/am/UserController.java
  37. 1
    1
      services/core/java/com/android/server/pm/OtaDexoptService.java
  38. 10
    0
      services/core/java/com/android/server/pm/PackageInstallerService.java
  39. 32
    4
      services/core/java/com/android/server/pm/PackageInstallerSession.java
  40. 286
    19
      services/core/java/com/android/server/pm/PackageManagerService.java
  41. 5
    1
      services/core/java/com/android/server/pm/PackageManagerShellCommand.java
  42. 45
    4
      services/core/java/com/android/server/pm/Settings.java
  43. 16
    0
      services/core/java/com/android/server/pm/permission/BasePermission.java
  44. 68
    26
      services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
  45. 398
    20
      services/core/java/com/android/server/pm/permission/PermissionManagerService.java
  46. 10
    1
      services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
  47. 2
    2
      services/core/java/com/android/server/pm/permission/PermissionsState.java
  48. 281
    0
      services/core/java/com/android/server/policy/PermissionPolicyService.java
  49. 1
    1
      services/core/java/com/android/server/policy/PhoneWindowManager.java
  50. 0
    20
      services/core/java/com/android/server/role/RoleManagerService.java
  51. 8
    1
      services/java/com/android/server/SystemServer.java
  52. 29
    1
      services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
  53. 5
    0
      services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
  54. 5
    0
      services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
  55. 8
    2
      telephony/java/com/android/internal/telephony/TelephonyPermissions.java
  56. 30
    0
      test-mock/src/android/test/mock/MockPackageManager.java

+ 11
- 0
api/current.txt View File

@@ -11483,10 +11483,12 @@ package android.content.pm {
method public void setOriginatingUri(@Nullable android.net.Uri);
method public void setReferrerUri(@Nullable android.net.Uri);
method public void setSize(long);
method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionParams> CREATOR;
field public static final int MODE_FULL_INSTALL = 1; // 0x1
field public static final int MODE_INHERIT_EXISTING = 2; // 0x2
field @NonNull public static final java.util.Set<java.lang.String> RESTRICTED_PERMISSIONS_ALL;
}

public class PackageItemInfo {
@@ -11523,6 +11525,7 @@ package android.content.pm {
method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo);
method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo);
method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName);
method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean addWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int);
method public abstract boolean canRequestPackageInstalls();
method public abstract String[] canonicalToCurrentPackageNames(@NonNull String[]);
method @CheckResult public abstract int checkPermission(@NonNull String, @NonNull String);
@@ -11592,11 +11595,13 @@ package android.content.pm {
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
method public boolean hasSigningCertificate(int, @NonNull byte[], int);
method public abstract boolean hasSystemFeature(@NonNull String);
method public abstract boolean hasSystemFeature(@NonNull String, int);
method public boolean isDeviceUpgrading();
method public abstract boolean isInstantApp();
method public abstract boolean isInstantApp(@NonNull String);
method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -11613,6 +11618,7 @@ package android.content.pm {
method @NonNull public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @Deprecated public abstract void removePackageFromPreferred(@NonNull String);
method public abstract void removePermission(@NonNull String);
method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean removeWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int);
method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int);
method @Nullable public abstract android.content.pm.ProviderInfo resolveContentProvider(@NonNull String, int);
method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int);
@@ -11740,6 +11746,9 @@ package android.content.pm {
field public static final String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct";
field public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint";
field public static final String FEATURE_WIFI_RTT = "android.hardware.wifi.rtt";
field public static final int FLAG_PERMISSION_WHITELIST_INSTALLER = 2; // 0x2
field public static final int FLAG_PERMISSION_WHITELIST_SYSTEM = 1; // 0x1
field public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 4; // 0x4
field public static final int GET_ACTIVITIES = 1; // 0x1
field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
field @Deprecated public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
@@ -11840,7 +11849,9 @@ package android.content.pm {
method @Nullable public CharSequence loadDescription(@NonNull android.content.pm.PackageManager);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR;
field public static final int FLAG_COSTS_MONEY = 1; // 0x1
field public static final int FLAG_HARD_RESTRICTED = 4; // 0x4
field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000
field public static final int FLAG_SOFT_RESTRICTED = 8; // 0x8
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20

+ 14
- 9
api/system-current.txt View File

@@ -201,6 +201,7 @@ package android {
field public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS";
field public static final String WRITE_DEVICE_CONFIG = "android.permission.WRITE_DEVICE_CONFIG";
field public static final String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE";
field public static final String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS";
@@ -1581,6 +1582,7 @@ package android.content.pm {
method public boolean getInstallAsInstantApp(boolean);
method public boolean getInstallAsVirtualPreload();
method public boolean getRequestDowngrade();
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
}

public static class PackageInstaller.SessionParams implements android.os.Parcelable {
@@ -1651,8 +1653,12 @@ package android.content.pm {
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock";
field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000
field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20
field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800
field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000
field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000
field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
@@ -1708,6 +1714,7 @@ package android.content.pm {
field public static final int MATCH_ANY_USER = 4194304; // 0x400000
field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_INSTANT = 8388608; // 0x800000
field public static boolean RESTRICTED_PERMISSIONS_ENABLED;
field public static final int RESTRICTION_HIDE_FROM_SUGGESTIONS = 1; // 0x1
field public static final int RESTRICTION_HIDE_NOTIFICATIONS = 2; // 0x2
field public static final int RESTRICTION_NONE = 0; // 0x0
@@ -1722,7 +1729,7 @@ package android.content.pm {
method public void onPermissionsChanged(int);
}

@IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
@IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
}

public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -5451,7 +5458,7 @@ package android.os {
}

public static interface RemoteCallback.OnResultListener {
method public void onResult(android.os.Bundle);
method public void onResult(@Nullable android.os.Bundle);
}

public class ServiceSpecificException extends java.lang.RuntimeException {
@@ -5694,6 +5701,7 @@ package android.permission {
method @NonNull public abstract java.util.List<android.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(@NonNull String);
method @NonNull public abstract java.util.List<android.permission.RuntimePermissionUsageInfo> onGetPermissionUsages(boolean, long);
method public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream);
method public abstract void onGrantOrUpgradeDefaultRuntimePermissions();
method @BinderThread public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle);
method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream);
method public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String);
@@ -5703,7 +5711,9 @@ package android.permission {
}

public final class PermissionManager {
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public int getRuntimePermissionsVersion();
method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
method @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public void setRuntimePermissionsVersion(@IntRange(from=0) int);
}

public static final class PermissionManager.SplitPermissionInfo {
@@ -5871,6 +5881,7 @@ package android.provider {
field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";
field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
field public static final String NAMESPACE_PRIVACY = "privacy";
field public static final String NAMESPACE_ROLLBACK = "rollback";
field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
field public static final String NAMESPACE_RUNTIME = "runtime";
@@ -5891,12 +5902,6 @@ package android.provider {
method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
}

public static interface DeviceConfig.Privacy {
field public static final String NAMESPACE = "privacy";
field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
}

public static class DeviceConfig.Properties {
method public boolean getBoolean(@NonNull String, boolean);
method public float getFloat(@NonNull String, float);
@@ -6075,7 +6080,6 @@ package android.provider {
field public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis";
field public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
field public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
field public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled";
field public static final String THEATER_MODE_ON = "theater_mode_on";
field public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
field public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
@@ -9521,6 +9525,7 @@ package android.util {
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED = 5; // 0x5
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED = 1; // 0x1
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = 3; // 0x3
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION = 9; // 0x9
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED = 2; // 0x2
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED = 6; // 0x6
field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE = 7; // 0x7

+ 12
- 7
api/test-current.txt View File

@@ -655,8 +655,13 @@ package android.content.pm {
ctor public LauncherApps(android.content.Context);
}

public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
}

public static class PackageInstaller.SessionParams implements android.os.Parcelable {
method public void setEnableRollback(boolean);
method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
}
@@ -679,7 +684,11 @@ package android.content.pm {
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";
field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000
field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800
field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000
field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000
field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80
@@ -688,6 +697,7 @@ package android.content.pm {
field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_KNOWN_PACKAGES = 4202496; // 0x402000
field public static boolean RESTRICTED_PERMISSIONS_ENABLED;
field public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
field public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
}
@@ -1820,7 +1830,7 @@ package android.os {
}

public static interface RemoteCallback.OnResultListener {
method public void onResult(android.os.Bundle);
method public void onResult(@Nullable android.os.Bundle);
}

public final class StrictMode {
@@ -2101,6 +2111,7 @@ package android.provider {
method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
field public static final String NAMESPACE_AUTOFILL = "autofill";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
field public static final String NAMESPACE_PRIVACY = "privacy";
field public static final String NAMESPACE_ROLLBACK = "rollback";
field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
}
@@ -2113,11 +2124,6 @@ package android.provider {
method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
}

public static interface DeviceConfig.Privacy {
field public static final String NAMESPACE = "privacy";
field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
}

public static class DeviceConfig.Properties {
method public boolean getBoolean(@NonNull String, boolean);
method public float getFloat(@NonNull String, float);
@@ -2172,7 +2178,6 @@ package android.provider {
field public static final String LOW_POWER_MODE = "low_power";
field public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
field public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled";
field public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
}


+ 2
- 0
cmds/statsd/src/atoms.proto View File

@@ -5453,6 +5453,8 @@ message PermissionGrantRequestResultReported {
USER_DENIED_WITH_PREJUDICE = 7;
// permission was automatically denied
AUTO_DENIED = 8;
// permission request was ignored because permission is restricted
IGNORED_RESTRICTED_PERMISSION = 9;
}
// The result of the permission grant
optional Result result = 6;

+ 9
- 55
core/java/android/app/AppOpsManager.java View File

@@ -30,9 +30,7 @@ import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
import android.media.AudioAttributes.AttributeUsage;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
@@ -42,7 +40,6 @@ import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
@@ -70,7 +67,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;

@@ -1757,21 +1753,21 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED, // VIBRATE
AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
AppOpsManager.MODE_DEFAULT, // READ_CALL_LOG
AppOpsManager.MODE_DEFAULT, // WRITE_CALL_LOG
AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
AppOpsManager.MODE_ALLOWED, // CALL_PHONE
AppOpsManager.MODE_ALLOWED, // READ_SMS
AppOpsManager.MODE_DEFAULT, // READ_SMS
AppOpsManager.MODE_IGNORED, // WRITE_SMS
AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
AppOpsManager.MODE_DEFAULT, // RECEIVE_SMS
AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
AppOpsManager.MODE_ALLOWED, // SEND_SMS
AppOpsManager.MODE_DEFAULT, // RECEIVE_MMS
AppOpsManager.MODE_DEFAULT, // RECEIVE_WAP_PUSH
AppOpsManager.MODE_DEFAULT, // SEND_SMS
AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
@@ -1805,10 +1801,10 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
AppOpsManager.MODE_ALLOWED, // USE_SIP
AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
AppOpsManager.MODE_DEFAULT, // PROCESS_OUTGOING_CALLS
AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
AppOpsManager.MODE_DEFAULT, // READ_CELL_BROADCASTS
AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
@@ -2101,51 +2097,9 @@ public class AppOpsManager {
* @hide
*/
public static @Mode int opToDefaultMode(int op) {
// STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
switch (op) {
// SMS permissions
case AppOpsManager.OP_SEND_SMS:
case AppOpsManager.OP_RECEIVE_SMS:
case AppOpsManager.OP_READ_SMS:
case AppOpsManager.OP_RECEIVE_WAP_PUSH:
case AppOpsManager.OP_RECEIVE_MMS:
case AppOpsManager.OP_READ_CELL_BROADCASTS:
// CallLog permissions
case AppOpsManager.OP_READ_CALL_LOG:
case AppOpsManager.OP_WRITE_CALL_LOG:
case AppOpsManager.OP_PROCESS_OUTGOING_CALLS: {
if (sSmsAndCallLogRestrictionEnabled.get() == 1) {
return AppOpsManager.MODE_DEFAULT;
}
}
}
return sOpDefaultMode[op];
}

// STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
private static final AtomicInteger sSmsAndCallLogRestrictionEnabled = new AtomicInteger(-1);

// STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
static {
final Context context = ActivityThread.currentApplication();
if (context != null) {
sSmsAndCallLogRestrictionEnabled.set(ActivityThread.currentActivityThread()
.getIntCoreSetting(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));

final Uri uri =
Settings.Global.getUriFor(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED);
context.getContentResolver().registerContentObserver(uri, false, new ContentObserver(
context.getMainThreadHandler()) {
@Override
public void onChange(boolean selfChange) {
sSmsAndCallLogRestrictionEnabled.set(Settings.Global.getInt(
context.getContentResolver(),
Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));
}
});
}
}

/**
* Retrieve the default mode for the app op.
*

+ 45
- 4
core/java/android/app/ApplicationPackageManager.java View File

@@ -89,6 +89,7 @@ import android.system.OsConstants;
import android.system.StructStat;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.LauncherIcons;
import android.util.Log;
@@ -111,6 +112,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/** @hide */
public class ApplicationPackageManager extends PackageManager {
@@ -718,6 +720,43 @@ public class ApplicationPackageManager extends PackageManager {
}

@Override
public @NonNull Set<String> getWhitelistedRestrictedPermissions(
@NonNull String packageName, @PermissionWhitelistFlags int whitelistFlags) {
try {
final List<String> whitelist = mPM.getWhitelistedRestrictedPermissions(
packageName, whitelistFlags, getUserId());
if (whitelist != null) {
return new ArraySet<>(whitelist);
}
return Collections.emptySet();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

@Override
public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
try {
return mPM.addWhitelistedRestrictedPermission(packageName, permission,
whitelistFlags, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

@Override
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
try {
return mPM.removeWhitelistedRestrictedPermission(packageName, permission,
whitelistFlags, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

@Override
@UnsupportedAppUsage
public boolean shouldShowRequestPermissionRationale(String permission) {
try {
@@ -2634,13 +2673,15 @@ public class ApplicationPackageManager extends PackageManager {
}
}

/**
* @hide
*/
@Override
public boolean isUpgrade() {
return isDeviceUpgrading();
}

@Override
public boolean isDeviceUpgrading() {
try {
return mPM.isUpgrade();
return mPM.isDeviceUpgrading();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

+ 5
- 2
core/java/android/app/SystemServiceRegistry.java View File

@@ -50,6 +50,7 @@ import android.content.om.IOverlayManager;
import android.content.om.OverlayManager;
import android.content.pm.CrossProfileApps;
import android.content.pm.ICrossProfileApps;
import android.content.pm.IPackageManager;
import android.content.pm.IShortcutService;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -1239,14 +1240,16 @@ final class SystemServiceRegistry {
new CachedServiceFetcher<PermissionManager>() {
@Override
public PermissionManager createService(ContextImpl ctx) {
return new PermissionManager(ctx.getOuterContext());
IPackageManager packageManager = AppGlobals.getPackageManager();
return new PermissionManager(ctx.getOuterContext(), packageManager);
}});

registerService(Context.PERMISSION_CONTROLLER_SERVICE, PermissionControllerManager.class,
new CachedServiceFetcher<PermissionControllerManager>() {
@Override
public PermissionControllerManager createService(ContextImpl ctx) {
return new PermissionControllerManager(ctx.getOuterContext());
return new PermissionControllerManager(ctx.getOuterContext(),
ctx.getMainThreadHandler());
}});

registerService(Context.ROLE_SERVICE, RoleManager.class,

+ 0
- 2
core/java/android/app/role/IRoleController.aidl View File

@@ -33,8 +33,6 @@ oneway interface IRoleController {

void onClearRoleHolders(in String roleName, int flags, in RemoteCallback callback);

void onSmsKillSwitchToggled(boolean enabled);

void isApplicationQualifiedForRole(in String roleName, in String packageName,
in RemoteCallback callback);


+ 0
- 29
core/java/android/app/role/RoleControllerManager.java View File

@@ -121,13 +121,6 @@ public class RoleControllerManager {
}

/**
* @see RoleControllerService#onSmsKillSwitchToggled(boolean)
*/
public void onSmsKillSwitchToggled(boolean enabled) {
mRemoteService.scheduleAsyncRequest(new OnSmsKillSwitchToggledRequest(enabled));
}

/**
* @see RoleControllerService#onIsApplicationQualifiedForRole(String, String)
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@@ -416,28 +409,6 @@ public class RoleControllerManager {
}

/**
* Request for {@link #onSmsKillSwitchToggled(boolean)}
*/
private static final class OnSmsKillSwitchToggledRequest
implements AbstractRemoteService.AsyncRequest<IRoleController> {

private final boolean mEnabled;

private OnSmsKillSwitchToggledRequest(boolean enabled) {
mEnabled = enabled;
}

@Override
public void run(@NonNull IRoleController service) {
try {
service.onSmsKillSwitchToggled(mEnabled);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Error calling onSmsKillSwitchToggled()", e);
}
}
}

/**
* Request for {@link #isApplicationQualifiedForRole(String, String, Executor, Consumer)}
*/
private static final class IsApplicationQualifiedForRoleRequest extends

+ 0
- 20
core/java/android/app/role/RoleControllerService.java View File

@@ -131,15 +131,6 @@ public abstract class RoleControllerService extends Service {
roleName, flags, callback));
}

@Override
public void onSmsKillSwitchToggled(boolean enabled) {
enforceCallerSystemUid("onSmsKillSwitchToggled");

mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
RoleControllerService::onSmsKillSwitchToggled, RoleControllerService.this,
enabled));
}

private void enforceCallerSystemUid(@NonNull String methodName) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Only the system process can call " + methodName
@@ -259,17 +250,6 @@ public abstract class RoleControllerService extends Service {
@RoleManager.ManageHoldersFlags int flags);

/**
* Cleanup appop/permissions state in response to sms kill switch toggle
*
* @param enabled whether kill switch was turned on
*
* @hide
*/
//STOPSHIP: remove this api before shipping a final version
@WorkerThread
public abstract void onSmsKillSwitchToggled(boolean enabled);

/**
* Check whether an application is qualified for a role.
*
* @param roleName name of the role to check for

+ 1
- 17
core/java/android/content/ContentProvider.java View File

@@ -620,13 +620,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
private int noteProxyOp(String callingPkg, int op) {
if (op != AppOpsManager.OP_NONE) {
int mode = mAppOpsManager.noteProxyOp(op, callingPkg);
int nonDefaultMode = mode == MODE_DEFAULT ? interpretDefaultAppOpMode(op) : mode;
if (mode == MODE_DEFAULT && nonDefaultMode == MODE_IGNORED) {
Log.w(TAG, "Denying access for " + callingPkg + " to " + getClass().getName()
+ " (" + AppOpsManager.opToName(op)
+ " = " + AppOpsManager.opToName(mode) + ")");
}
return mode == MODE_DEFAULT ? nonDefaultMode : mode;
return mode == MODE_DEFAULT ? MODE_IGNORED : mode;
}

return AppOpsManager.MODE_ALLOWED;
@@ -654,16 +648,6 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
return mTransport.noteProxyOp(callingPkg, AppOpsManager.permissionToOpCode(permission));
}

/**
* Allows for custom interpretations of {@link AppOpsManager#MODE_DEFAULT} by individual
* content providers
*
* @hide
*/
protected int interpretDefaultAppOpMode(int op) {
return MODE_IGNORED;
}

/** {@hide} */
protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken)
throws SecurityException {

+ 14
- 1
core/java/android/content/pm/IPackageManager.aidl View File

@@ -130,6 +130,15 @@ interface IPackageManager {

void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);

List<String> getWhitelistedRestrictedPermissions(String packageName, int flags,
int userId);

boolean addWhitelistedRestrictedPermission(String packageName, String permission,
int whitelistFlags, int userId);

boolean removeWhitelistedRestrictedPermission(String packageName, String permission,
int whitelistFlags, int userId);

boolean shouldShowRequestPermissionRationale(String permissionName,
String packageName, int userId);

@@ -643,7 +652,7 @@ interface IPackageManager {

boolean isFirstBoot();
boolean isOnlyCoreApps();
boolean isUpgrade();
boolean isDeviceUpgrading();

void setPermissionEnforced(String permission, boolean enforced);
boolean isPermissionEnforced(String permission);
@@ -757,4 +766,8 @@ interface IPackageManager {
List<ModuleInfo> getInstalledModules(int flags);

ModuleInfo getModuleInfo(String packageName, int flags);

int getRuntimePermissionsVersion(int userId);

void setRuntimePermissionsVersion(int version, int userId);
}

+ 77
- 0
core/java/android/content/pm/PackageInstaller.java View File

@@ -30,6 +30,7 @@ import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageManager.DeleteFlags;
import android.content.pm.PackageManager.InstallReason;
@@ -48,6 +49,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArraySet;
import android.util.ExceptionUtils;

import com.android.internal.util.IndentingPrintWriter;
@@ -62,8 +64,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;

/**
@@ -1265,6 +1269,11 @@ public class PackageInstaller {
*/
public static final int MODE_INHERIT_EXISTING = 2;

/**
* Special constant to refer to all restricted permissions.
*/
public static final @NonNull Set<String> RESTRICTED_PERMISSIONS_ALL = new ArraySet<>();

/** {@hide} */
public static final int UID_UNKNOWN = -1;

@@ -1306,6 +1315,8 @@ public class PackageInstaller {
/** {@hide} */
public String[] grantedRuntimePermissions;
/** {@hide} */
public List<String> whitelistedRestrictedPermissions;
/** {@hide} */
public String installerPackageName;
/** {@hide} */
public boolean isMultiPackage;
@@ -1339,6 +1350,7 @@ public class PackageInstaller {
abiOverride = source.readString();
volumeUuid = source.readString();
grantedRuntimePermissions = source.readStringArray();
whitelistedRestrictedPermissions = source.createStringArrayList();
installerPackageName = source.readString();
isMultiPackage = source.readBoolean();
isStaged = source.readBoolean();
@@ -1360,6 +1372,7 @@ public class PackageInstaller {
ret.abiOverride = abiOverride;
ret.volumeUuid = volumeUuid;
ret.grantedRuntimePermissions = grantedRuntimePermissions;
ret.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
ret.installerPackageName = installerPackageName;
ret.isMultiPackage = isMultiPackage;
ret.isStaged = isStaged;
@@ -1474,6 +1487,7 @@ public class PackageInstaller {
*
* @hide
*/
@TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
public void setGrantedRuntimePermissions(String[] permissions) {
@@ -1482,6 +1496,43 @@ public class PackageInstaller {
}

/**
* Sets which restricted permissions to be whitelisted for the app. Whitelisting
* is not granting the permissions, rather it allows the app to hold permissions
* which are otherwise restricted. Whitelisting a non restricted permission has
* no effect.
*
* <p> Permissions can be hard restricted which means that the app cannot hold
* them or soft restricted where the app can hold the permission but in a weaker
* form. Whether a permission is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard
* restricted} or {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted}
* depends on the permission declaration. Whitelisting a hard restricted permission
* allows the app to hold that permission and whitelisting a soft restricted
* permission allows the app to hold the permission in its full, unrestricted form.
*
* <p>The whitelisted permissions would be applied as the {@link
* PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER installer whitelist}.
*
* @param permissions The restricted permissions to whitelist. Pass
* {@link #RESTRICTED_PERMISSIONS_ALL} to whitelist all permissions and
* <code>null</code> to clear. If you want to whitelist some permissions
* (not all) the list must contain at least one permission.
*
* @see PackageManager#addWhitelistedRestrictedPermission(String, String, int)
* @see PackageManager#removeWhitelistedRestrictedPermission(String, String, int)
*/
public void setWhitelistedRestrictedPermissions(@Nullable Set<String> permissions) {
if (permissions == RESTRICTED_PERMISSIONS_ALL) {
installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
}
if (permissions != null) {
this.whitelistedRestrictedPermissions = new ArrayList<>(permissions);
} else {
installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
this.whitelistedRestrictedPermissions = null;
}
}

/**
* Request that rollbacks be enabled or disabled for the given upgrade.
*
* <p>If the parent session is staged or has rollback enabled, all children sessions
@@ -1656,6 +1707,7 @@ public class PackageInstaller {
pw.printPair("abiOverride", abiOverride);
pw.printPair("volumeUuid", volumeUuid);
pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
pw.printPair("whitelistedRestrictedPermissions", whitelistedRestrictedPermissions);
pw.printPair("installerPackageName", installerPackageName);
pw.printPair("isMultiPackage", isMultiPackage);
pw.printPair("isStaged", isStaged);
@@ -1683,6 +1735,7 @@ public class PackageInstaller {
dest.writeString(abiOverride);
dest.writeString(volumeUuid);
dest.writeStringArray(grantedRuntimePermissions);
dest.writeStringList(whitelistedRestrictedPermissions);
dest.writeString(installerPackageName);
dest.writeBoolean(isMultiPackage);
dest.writeBoolean(isStaged);
@@ -1794,6 +1847,8 @@ public class PackageInstaller {
public Uri referrerUri;
/** {@hide} */
public String[] grantedRuntimePermissions;
/** {@hide}*/
public List<String> whitelistedRestrictedPermissions;
/** {@hide} */
public int installFlags;
/** {@hide} */
@@ -1847,6 +1902,8 @@ public class PackageInstaller {
originatingUid = source.readInt();
referrerUri = source.readParcelable(null);
grantedRuntimePermissions = source.readStringArray();
whitelistedRestrictedPermissions = source.createStringArrayList();

installFlags = source.readInt();
isMultiPackage = source.readBoolean();
isStaged = source.readBoolean();
@@ -2049,6 +2106,25 @@ public class PackageInstaller {
}

/**
* Get the value set in {@link SessionParams#setWhitelistedRestrictedPermissions(Set)}.
* Note that if all permissions are whitelisted this method returns {@link
* SessionParams#RESTRICTED_PERMISSIONS_ALL}.
*
* @hide
*/
@TestApi
@SystemApi
public @NonNull Set<String> getWhitelistedRestrictedPermissions() {
if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0) {
return SessionParams.RESTRICTED_PERMISSIONS_ALL;
}
if (whitelistedRestrictedPermissions != null) {
return new ArraySet<>(whitelistedRestrictedPermissions);
}
return Collections.emptySet();
}

/**
* Get the value set in {@link SessionParams#setAllowDowngrade(boolean)}.
*
* @deprecated use {@link #getRequestDowngrade()}.
@@ -2277,6 +2353,7 @@ public class PackageInstaller {
dest.writeInt(originatingUid);
dest.writeParcelable(referrerUri, flags);
dest.writeStringArray(grantedRuntimePermissions);
dest.writeStringList(whitelistedRestrictedPermissions);
dest.writeInt(installFlags);
dest.writeBoolean(isMultiPackage);
dest.writeBoolean(isStaged);

+ 295
- 5
core/java/android/content/pm/PackageManager.java View File

@@ -69,8 +69,10 @@ import dalvik.system.VMRuntime;
import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
* Class for retrieving various kinds of information related to the application
@@ -84,6 +86,11 @@ public abstract class PackageManager {
/** {@hide} */
public static final boolean APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE = true;

/** {@hide} */
@SystemApi
@TestApi
public static boolean RESTRICTED_PERMISSIONS_ENABLED = false;

/**
* This exception is thrown when a given package, application, or component
* name cannot be found.
@@ -712,6 +719,7 @@ public abstract class PackageManager {
INSTALL_ALL_USERS,
INSTALL_REQUEST_DOWNGRADE,
INSTALL_GRANT_RUNTIME_PERMISSIONS,
INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
INSTALL_FORCE_VOLUME_UUID,
INSTALL_FORCE_PERMISSION_PROMPT,
INSTALL_INSTANT_APP,
@@ -794,6 +802,16 @@ public abstract class PackageManager {
*/
public static final int INSTALL_GRANT_RUNTIME_PERMISSIONS = 0x00000100;

/**
* Flag parameter for {@link #installPackage} to indicate that all restricted
* permissions should be whitelisted. If {@link #INSTALL_ALL_USERS}
* is set the restricted permissions will be whitelisted for all users, otherwise
* only to the owner.
*
* @hide
*/
public static final int INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00000200;

/** {@hide} */
public static final int INSTALL_FORCE_VOLUME_UUID = 0x00000200;

@@ -3075,14 +3093,72 @@ public abstract class PackageManager {
public static final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED = 1 << 9;

/**
* Mask for all permission flags present in Android P
* Permission flag: The permission is restricted but the app is exempt
* from the restriction and is allowed to hold this permission in its
* full form and the exemption is provided by the installer on record.
*
* @hide
*/
@TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 1 << 11;

/**
* Permission flag: The permission is restricted but the app is exempt
* from the restriction and is allowed to hold this permission in its
* full form and the exemption is provided by the system due to its
* permission policy.
*
* @deprecated This constant does not contain useful information and should never have been
* exposed. When checking permission flags always flag each flag explicitly and ignore all
* flags that do not matter for this particular code.
* @hide
*/
@TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 1 << 12;

/**
* Permission flag: The permission is restricted but the app is exempt
* from the restriction and is allowed to hold this permission and the
* exemption is provided by the system when upgrading from an OS version
* where the permission was not restricted to an OS version where the
* permission is restricted.
*
* @hide
*/
@TestApi
@SystemApi
public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 1 << 13;


/**
* Permission flag: The permission is disabled but may be granted. If
* disabled the data protected by the permission should be protected
* by a no-op (empty list, default error, etc) instead of crashing the
* client.
*
* @hide
*/
@TestApi
@SystemApi
public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 1 << 14;


/**
* Permission flags: Bitwise or of all permission flags allowing an
* exemption for a restricted permission.
* @hide
*/
public static final int FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT =
FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
| FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
| FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;

/**
* Mask for all permission flags.
*
* @hide
*
* @deprecated Don't use - does not capture all flags.
*/
@Deprecated
@SystemApi
public static final int MASK_PERMISSION_FLAGS = 0xFF;
@@ -3092,7 +3168,20 @@ public abstract class PackageManager {
*
* @hide
*/
public static final int MASK_PERMISSION_FLAGS_ALL = 0x3FF;
public static final int MASK_PERMISSION_FLAGS_ALL = FLAG_PERMISSION_USER_SET
| FLAG_PERMISSION_USER_FIXED
| FLAG_PERMISSION_POLICY_FIXED
| FLAG_PERMISSION_REVOKE_ON_UPGRADE
| FLAG_PERMISSION_SYSTEM_FIXED
| FLAG_PERMISSION_GRANTED_BY_DEFAULT
| FLAG_PERMISSION_REVIEW_REQUIRED
| FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
| FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED
| FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED
| FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
| FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
| FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
| FLAG_PERMISSION_APPLY_RESTRICTION;

/**
* Injected activity in app that forwards user to setting activity of that app.
@@ -3102,6 +3191,35 @@ public abstract class PackageManager {
public static final String APP_DETAILS_ACTIVITY_CLASS_NAME = AppDetailsActivity.class.getName();

/**
* Permission whitelist flag: permissions whitelisted by the system.
* Permissions can also be whitelisted by the installer or on upgrade.
*/
public static final int FLAG_PERMISSION_WHITELIST_SYSTEM = 1 << 0;

/**
* Permission whitelist flag: permissions whitelisted by the installer.
* Permissions can also be whitelisted by the system or on upgrade.
*/
public static final int FLAG_PERMISSION_WHITELIST_INSTALLER = 1 << 1;

/**
* Permission whitelist flag: permissions whitelisted by the system
* when upgrading from an OS version where the permission was not
* restricted to an OS version where the permission is restricted.
* Permissions can also be whitelisted by the installer or the system.
*/
public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 1 << 2;

/** @hide */
@IntDef(flag = true, prefix = {"FLAG_PERMISSION_WHITELIST_"}, value = {
FLAG_PERMISSION_WHITELIST_SYSTEM,
FLAG_PERMISSION_WHITELIST_INSTALLER,
FLAG_PERMISSION_WHITELIST_UPGRADE
})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionWhitelistFlags {}

/**
* This is a library that contains components apps can invoke. For
* example, a services for apps to bind to, or standard chooser UI,
* etc. This library is versioned and backwards compatible. Clients
@@ -3824,6 +3942,10 @@ public abstract class PackageManager {
/*
FLAG_PERMISSION_REVOKE_WHEN_REQUESED
*/
FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT,
FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT,
FLAG_PERMISSION_APPLY_RESTRICTION
})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionFlags {}
@@ -3925,6 +4047,163 @@ public abstract class PackageManager {
@PermissionFlags int flagValues, @NonNull UserHandle user);

/**
* Gets the restricted permissions that have been whitelisted and the app
* is allowed to have them granted in their full form.
*
* <p> Permissions can be hard restricted which means that the app cannot hold
* them or soft restricted where the app can hold the permission but in a weaker
* form. Whether a permission is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard
* restricted} or {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted}
* depends on the permission declaration. Whitelisting a hard restricted permission
* allows for the to hold that permission and whitelisting a soft restricted
* permission allows the app to hold the permission in its full, unrestricted form.
*
* <p><ol>There are three whitelists:
*
* <li>one for cases where the system permission policy whitelists a permission
* This list corresponds to the{@link #FLAG_PERMISSION_WHITELIST_SYSTEM} flag.
* Can only be accessed by pre-installed holders of a dedicated permission.
*
* <li>one for cases where the system whitelists the permission when upgrading
* from an OS version in which the permission was not restricted to an OS version
* in which the permission is restricted. This list corresponds to the {@link
* #FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by pre-installed
* holders of a dedicated permission or the installer on record.
*
* <li>one for cases where the installer of the package whitelists a permission.
* This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_INSTALLER} flag.
* Can be accessed by pre-installed holders of a dedicated permission or the
* installer on record.
*
* @param packageName The app for which to get whitelisted permissions.
* @param whitelistFlag The flag to determine which whitelist to query. Only one flag
* can be passed.s
* @return The whitelisted permissions that are on any of the whitelists you query for.
*
* @see #addWhitelistedRestrictedPermission(String, String, int)
* @see #removeWhitelistedRestrictedPermission(String, String, int)
* @see #FLAG_PERMISSION_WHITELIST_SYSTEM
* @see #FLAG_PERMISSION_WHITELIST_UPGRADE
* @see #FLAG_PERMISSION_WHITELIST_INSTALLER
*
* @throws SecurityException if you try to access a whitelist that you have no access to.
*/
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public @NonNull Set<String> getWhitelistedRestrictedPermissions(
@NonNull String packageName, @PermissionWhitelistFlags int whitelistFlag) {
return Collections.emptySet();
}

/**
* Adds a whitelisted restricted permission for an app.
*
* <p> Permissions can be hard restricted which means that the app cannot hold
* them or soft restricted where the app can hold the permission but in a weaker
* form. Whether a permission is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard
* restricted} or {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted}
* depends on the permission declaration. Whitelisting a hard restricted permission
* allows for the to hold that permission and whitelisting a soft restricted
* permission allows the app to hold the permission in its full, unrestricted form.
*
* <p><ol>There are three whitelists:
*
* <li>one for cases where the system permission policy whitelists a permission
* This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_SYSTEM} flag.
* Can only be modified by pre-installed holders of a dedicated permission.
*
* <li>one for cases where the system whitelists the permission when upgrading
* from an OS version in which the permission was not restricted to an OS version
* in which the permission is restricted. This list corresponds to the {@link
* #FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be modified by pre-installed
* holders of a dedicated permission. The installer on record can only remove
* permissions from this whitelist.
*
* <li>one for cases where the installer of the package whitelists a permission.
* This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_INSTALLER} flag.
* Can be modified by pre-installed holders of a dedicated permission or the installer
* on record.
*
* <p>You need to specify the whitelists for which to set the whitelisted permissions
* which will clear the previous whitelisted permissions and replace them with the
* provided ones.
*
* @param packageName The app for which to get whitelisted permissions.
* @param permission The whitelisted permission to add.
* @param whitelistFlags The whitelists to which to add. Passing multiple flags
* updates all specified whitelists.
* @return Whether the permission was added to the whitelist.
*
* @see #getWhitelistedRestrictedPermissions(String, int)
* @see #removeWhitelistedRestrictedPermission(String, String, int)
* @see #FLAG_PERMISSION_WHITELIST_SYSTEM
* @see #FLAG_PERMISSION_WHITELIST_UPGRADE
* @see #FLAG_PERMISSION_WHITELIST_INSTALLER
*
* @throws SecurityException if you try to modify a whitelist that you have no access to.
*/
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
return false;
}

/**
* Removes a whitelisted restricted permission for an app.
*
* <p> Permissions can be hard restricted which means that the app cannot hold
* them or soft restricted where the app can hold the permission but in a weaker
* form. Whether a permission is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard
* restricted} or {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted}
* depends on the permission declaration. Whitelisting a hard restricted permission
* allows for the to hold that permission and whitelisting a soft restricted
* permission allows the app to hold the permission in its full, unrestricted form.
*
* <p><ol>There are three whitelists:
*
* <li>one for cases where the system permission policy whitelists a permission
* This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_SYSTEM} flag.
* Can only be modified by pre-installed holders of a dedicated permission.
*
* <li>one for cases where the system whitelists the permission when upgrading
* from an OS version in which the permission was not restricted to an OS version
* in which the permission is restricted. This list corresponds to the {@link
* #FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be modified by pre-installed
* holders of a dedicated permission. The installer on record can only remove
* permissions from this whitelist.
*
* <li>one for cases where the installer of the package whitelists a permission.
* This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_INSTALLER} flag.
* Can be modified by pre-installed holders of a dedicated permission or the installer
* on record.
*
* <p>You need to specify the whitelists for which to set the whitelisted permissions
* which will clear the previous whitelisted permissions and replace them with the
* provided ones.
*
* @param packageName The app for which to get whitelisted permissions.
* @param permission The whitelisted permission to remove.
* @param whitelistFlags The whitelists from which to remove. Passing multiple flags
* updates all specified whitelists.
* @return Whether the permission was removed from the whitelist.
*
* @see #getWhitelistedRestrictedPermissions(String, int)
* @see #addWhitelistedRestrictedPermission(String, String, int)
* @see #FLAG_PERMISSION_WHITELIST_SYSTEM
* @see #FLAG_PERMISSION_WHITELIST_UPGRADE
* @see #FLAG_PERMISSION_WHITELIST_INSTALLER
*
* @throws SecurityException if you try to modify a whitelist that you have no access to.
*/
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
return false;
}

/**
* Gets whether you should show UI with rationale for requesting a permission.
* You should do this only if you do not have the permission and the context in
* which the permission is requested does not clearly communicate to the user
@@ -6515,6 +6794,13 @@ public abstract class PackageManager {
public abstract boolean isUpgrade();

/**
* Returns true if the device is upgrading, such as first boot after OTA.
*/
public boolean isDeviceUpgrading() {
return false;
}

/**
* Return interface that offers the ability to install, upgrade, and remove
* applications on the device.
*/
@@ -6739,6 +7025,10 @@ public abstract class PackageManager {
case FLAG_PERMISSION_REVOKE_WHEN_REQUESTED: return "REVOKE_WHEN_REQUESTED";
case FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED: return "USER_SENSITIVE_WHEN_GRANTED";
case FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED: return "USER_SENSITIVE_WHEN_DENIED";
case FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT: return "RESTRICTION_INSTALLER_EXEMPT";
case FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT: return "RESTRICTION_SYSTEM_EXEMPT";
case FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT: return "RESTRICTION_UPGRADE_EXEMPT";
case FLAG_PERMISSION_APPLY_RESTRICTION: return "FLAG_PERMISSION_APPLY_RESTRICTION";
default: return Integer.toString(flag);
}
}

+ 11
- 0
core/java/android/content/pm/PackageManagerInternal.java View File

@@ -80,6 +80,8 @@ public abstract class PackageManagerInternal {
public interface PackageListObserver {
/** A package was added to the system. */
void onPackageAdded(@NonNull String packageName, int uid);
/** A package was changed - either installed for a specific user or updated. */
default void onPackageChanged(@NonNull String packageName, int uid) {}
/** A package was removed from the system. */
void onPackageRemoved(@NonNull String packageName, int uid);
}
@@ -950,4 +952,13 @@ public abstract class PackageManagerInternal {
*/
public abstract void uninstallApex(String packageName, long versionCode, int userId,
IntentSender intentSender);

/**
* Whether default permission grants have been performed for a user
* since the device booted.
*
* @param userId The user id.
* @return true if default permissions
*/
public abstract boolean wereDefaultPermissionsGrantedSinceBoot(int userId);
}

+ 13
- 0
core/java/android/content/pm/PackageParser.java View File

@@ -3279,6 +3279,19 @@ public class PackageParser {
perm.info.flags = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermission_permissionFlags, 0);

// For now only platform runtime permissions can be restricted
if (!perm.info.isRuntime() || !"android".equals(perm.info.packageName)) {
perm.info.flags &= ~PermissionInfo.FLAG_HARD_RESTRICTED;
perm.info.flags &= ~PermissionInfo.FLAG_SOFT_RESTRICTED;
} else {
// The platform does not get to specify conflicting permissions
if ((perm.info.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0
&& (perm.info.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0) {
throw new IllegalStateException("Permission cannot be both soft and hard"
+ " restricted: " + perm.info.name);
}
}

sa.recycle();

if (perm.info.protectionLevel == -1) {

+ 41
- 0
core/java/android/content/pm/PermissionInfo.java View File

@@ -320,6 +320,27 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_REMOVED = 1<<1;

/**
* Flag for {@link #flags}, corresponding to <code>hardRestricted</code>
* value of {@link android.R.attr#permissionFlags}.
*
* <p> This permission is restricted by the platform and it would be
* grantable only to apps that meet special criteria per platform
* policy.
*/
public static final int FLAG_HARD_RESTRICTED = 1<<2;

/**
* Flag for {@link #flags}, corresponding to <code>softRestricted</code>
* value of {@link android.R.attr#permissionFlags}.
*
* <p>This permission is restricted by the platform and it would be
* grantable in its full form to apps that meet special criteria
* per platform policy. Otherwise, a weaker form of the permission
* would be granted. The weak grant depends on the permission.
*/
public static final int FLAG_SOFT_RESTRICTED = 1<<3;

/**
* Flag for {@link #flags}, indicating that this permission has been
* installed into the system's globally defined permissions.
*/
@@ -575,10 +596,30 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
}

/** @hide */
public boolean isHardRestricted() {
return (flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
}

/** @hide */
public boolean isSoftRestricted() {
return (flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0;
}

/** @hide */
public boolean isRestricted() {
return isHardRestricted() || isSoftRestricted();
}

/** @hide */
public boolean isAppOp() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
}

/** @hide */
public boolean isRuntime() {
return getProtection() == PROTECTION_DANGEROUS;
}

public static final @NonNull Creator<PermissionInfo> CREATOR =
new Creator<PermissionInfo>() {
@Override

+ 1
- 1
core/java/android/os/RemoteCallback.java View File

@@ -29,7 +29,7 @@ import android.annotation.TestApi;
public final class RemoteCallback implements Parcelable {

public interface OnResultListener {
public void onResult(Bundle result);
void onResult(@Nullable Bundle result);
}

private final OnResultListener mListener;

+ 1
- 0
core/java/android/permission/IPermissionController.aidl View File

@@ -40,4 +40,5 @@ oneway interface IPermissionController {
void getPermissionUsages(boolean countSystem, long numMillis, in RemoteCallback callback);
void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName,
String permission, int grantState, in RemoteCallback callback);
void grantOrUpgradeDefaultRuntimePermissions(in RemoteCallback callback);
}

+ 77
- 8
core/java/android/permission/PermissionControllerManager.java View File

@@ -56,7 +56,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import android.util.Pair;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
@@ -95,7 +95,8 @@ public final class PermissionControllerManager {
* Global remote services (per user) used by all {@link PermissionControllerManager managers}
*/
@GuardedBy("sLock")
private static SparseArray<RemoteService> sRemoteServices = new SparseArray<>(1);
private static ArrayMap<Pair<Integer, Thread>, RemoteService> sRemoteServices
= new ArrayMap<>(1);

/**
* The key for retrieving the result from the returned bundle.
@@ -217,20 +218,24 @@ public final class PermissionControllerManager {
* Create a new {@link PermissionControllerManager}.
*
* @param context to create the manager for
* @param handler handler to schedule work
*
* @hide
*/
public PermissionControllerManager(@NonNull Context context) {
public PermissionControllerManager(@NonNull Context context, @NonNull Handler handler) {
synchronized (sLock) {
RemoteService remoteService = sRemoteServices.get(context.getUserId(), null);
Pair<Integer, Thread> key = new Pair<>(context.getUserId(),
handler.getLooper().getThread());
RemoteService remoteService = sRemoteServices.get(key);
if (remoteService == null) {
Intent intent = new Intent(SERVICE_INTERFACE);
intent.setPackage(context.getPackageManager().getPermissionControllerPackageName());
ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0);

remoteService = new RemoteService(context.getApplicationContext(),
serviceInfo.getComponentInfo().getComponentName(), context.getUser());
sRemoteServices.put(context.getUserId(), remoteService);
serviceInfo.getComponentInfo().getComponentName(), handler,
context.getUser());
sRemoteServices.put(key, remoteService);
}

mRemoteService = remoteService;
@@ -454,6 +459,23 @@ public final class PermissionControllerManager {
}

/**
* Grant or upgrade runtime permissions. The upgrade could be performed
* based on whether the device upgraded, whether the permission database
* version is old, or because the permission policy changed.
*
* @param executor Executor on which to invoke the callback
* @param callback Callback to receive the result
*
* @hide
*/
@RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
public void grantOrUpgradeDefaultRuntimePermissions(
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
mRemoteService.scheduleRequest(new PendingGrantOrUpgradeDefaultRuntimePermissionsRequest(
mRemoteService, executor, callback));
}

/**
* A connection to the remote service
*/
static final class RemoteService extends
@@ -469,10 +491,10 @@ public final class PermissionControllerManager {
* @param user User the remote service should be connected as
*/
RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
@NonNull UserHandle user) {
@NonNull Handler handler, @NonNull UserHandle user) {
super(context, SERVICE_INTERFACE, componentName, user.getIdentifier(),
service -> Log.e(TAG, "RemoteService " + service + " died"),
context.getMainThreadHandler(), 0, false, 1);
handler, 0, false, 1);
}

/**
@@ -1147,4 +1169,51 @@ public final class PermissionControllerManager {
}
}
}

/**
* Request for {@link #grantOrUpgradeDefaultRuntimePermissions(Executor, Consumer)}
*/
private static final class PendingGrantOrUpgradeDefaultRuntimePermissionsRequest extends
AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> {
private final @NonNull Consumer<Boolean> mCallback;

private final @NonNull RemoteCallback mRemoteCallback;

private PendingGrantOrUpgradeDefaultRuntimePermissionsRequest(
@NonNull RemoteService service, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<Boolean> callback) {
super(service);
mCallback = callback;

mRemoteCallback = new RemoteCallback(result -> executor.execute(() -> {
long token = Binder.clearCallingIdentity();
try {
callback.accept(result != null);
} finally {
Binder.restoreCallingIdentity(token);
finish();
}
}), null);
}

@Override
protected void onTimeout(RemoteService remoteService) {
long token = Binder.clearCallingIdentity();
try {
mCallback.accept(false);
} finally {
Binder.restoreCallingIdentity(token);
}
}

@Override
public void run() {
try {
getService().getServiceInterface().grantOrUpgradeDefaultRuntimePermissions(
mRemoteCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error granting or upgrading runtime permissions", e);
}
}
}
}

+ 28
- 0
core/java/android/permission/PermissionControllerService.java View File

@@ -178,6 +178,17 @@ public abstract class PermissionControllerService extends Service {
boolean countSystem, long numMillis);

/**
* Grant or upgrade runtime permissions. The upgrade could be performed
* based on whether the device upgraded, whether the permission database
* version is old, or because the permission policy changed.
*
* @see PackageManager#isDeviceUpgrading()
* @see PermissionManager#getRuntimePermissionsVersion()
* @see PermissionManager#setRuntimePermissionsVersion(int)
*/
public abstract void onGrantOrUpgradeDefaultRuntimePermissions();

/**
* Set the runtime permission state from a device admin.
*
* @param callerPackageName The package name of the admin requesting the change
@@ -350,6 +361,18 @@ public abstract class PermissionControllerService extends Service {
PermissionControllerService.this, callerPackageName, packageName,
permission, grantState, callback));
}

@Override
public void grantOrUpgradeDefaultRuntimePermissions(@NonNull RemoteCallback callback) {
checkNotNull(callback, "callback");

enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
null);

mHandler.sendMessage(obtainMessage(
PermissionControllerService::grantOrUpgradeDefaultRuntimePermissions,
PermissionControllerService.this, callback));
}
};
}

@@ -426,4 +449,9 @@ public abstract class PermissionControllerService extends Service {
result.putBoolean(PermissionControllerManager.KEY_RESULT, wasSet);
callback.sendResult(result);
}

private void grantOrUpgradeDefaultRuntimePermissions(@NonNull RemoteCallback callback) {
onGrantOrUpgradeDefaultRuntimePermissions();
callback.sendResult(Bundle.EMPTY);
}
}

+ 49
- 1
core/java/android/permission/PermissionManager.java View File

@@ -16,10 +16,19 @@

package android.permission;

import android.Manifest;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.RemoteException;

import com.android.internal.annotations.Immutable;
import com.android.server.SystemConfig;
@@ -46,14 +55,53 @@ public final class PermissionManager {

private final @NonNull Context mContext;

private final IPackageManager mPackageManager;

/**
* Creates a new instance.
*
* @param context The current context in which to operate.
* @hide
*/
public PermissionManager(@NonNull Context context) {
public PermissionManager(@NonNull Context context, IPackageManager packageManager) {
mContext = context;
mPackageManager = packageManager;
}

/**
* Gets the version of the runtime permission database.
*
* @return The database version.
*
* @hide
*/
@TestApi
@SystemApi
@RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
public @IntRange(from = 0) int getRuntimePermissionsVersion() {
try {
return mPackageManager.getRuntimePermissionsVersion(mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

/**
* Sets the version of the runtime permission database.
*
* @param version The new version.
*
* @hide
*/
@TestApi
@SystemApi
@RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
public void setRuntimePermissionsVersion(@IntRange(from = 0) int version) {
try {
mPackageManager.setRuntimePermissionsVersion(version, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

/**

+ 34
- 0
core/java/android/permission/PermissionManagerInternal.java View File

@@ -18,6 +18,7 @@ package android.permission;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.UserHandle;

/**
@@ -28,6 +29,23 @@ import android.os.UserHandle;
* @hide
*/
public abstract class PermissionManagerInternal {

/**
* Listener for package permission state (permissions or flags) changes.
*/
public interface OnRuntimePermissionStateChangedListener {

/**
* Called when the runtime permission state (permissions or flags) changed.
*
* @param packageName The package for which the change happened.
* @param userId the user id for which the change happened.
*/
@Nullable
void onRuntimePermissionStateChanged(@NonNull String packageName,
@UserIdInt int userId);
}

/**
* Get the state of the runtime permissions as xml file.
*
@@ -59,4 +77,20 @@ public abstract class PermissionManagerInternal {
*/
public abstract void restoreDelayedRuntimePermissions(@NonNull String packageName,
@NonNull UserHandle user);

/**
* Adds a listener for runtime permission state (permissions or flags) changes.
*
* @param listener The listener.
*/
public abstract void addOnRuntimePermissionStateChangedListener(
@NonNull OnRuntimePermissionStateChangedListener listener);

/**
* Removes a listener for runtime permission state (permissions or flags) changes.
*
* @param listener The listener.
*/
public abstract void removeOnRuntimePermissionStateChangedListener(
@NonNull OnRuntimePermissionStateChangedListener listener);
}

+ 1
- 24
core/java/android/provider/DeviceConfig.java View File

@@ -281,30 +281,7 @@ public final class DeviceConfig {
*/
@SystemApi
@TestApi
public interface Privacy {
String NAMESPACE = "privacy";

/**
* Whether to show the Permissions Hub.
*
* @hide
*/
@SystemApi
String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";

/**
* Whether to show location access check notifications.
*/
String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";

/**
* Whether to disable the new device identifier access restrictions.
*
* @hide
*/
String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
"device_identifier_access_restrictions_disabled";
}
public static final String NAMESPACE_PRIVACY = "privacy";

private static final Object sLock = new Object();
@GuardedBy("sLock")

+ 0
- 12
core/java/android/provider/Settings.java View File

@@ -13391,18 +13391,6 @@ public final class Settings {
"location_global_kill_switch";

/**
* If set to 1, app cannot request read sms permission unless it's the default sms handler.
*
* STOPSHIP: Remove this once we ship with the restriction enabled.
*
* @hide
*/
@SystemApi
@TestApi
public static final String SMS_ACCESS_RESTRICTION_ENABLED =
"sms_access_restriction_enabled";

/**
* If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
* permission check for 3P apps.
*

+ 7
- 0
core/java/android/util/StatsLogAtoms.java View File

@@ -78,6 +78,13 @@ public class StatsLogAtoms {

/**
* Possible value of {@link PermissionGrantRequestResultReported_Result}:
* permission request was ignored because it was restricted
*/
public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION =
StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION;

/**
* Possible value of {@link PermissionGrantRequestResultReported_Result}:
* permission was granted by user action
*/
public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED =

+ 0
- 1
core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java View File

@@ -32,7 +32,6 @@ import java.util.ArrayList;
*
* @param <S> the concrete remote service class
* @param <I> the interface of the binder service
* @hide
*/
public abstract class AbstractMultiplePendingRequestsRemoteService<S
extends AbstractMultiplePendingRequestsRemoteService<S, I>, I extends IInterface>

+ 15
- 1
core/res/AndroidManifest.xml View File

@@ -728,7 +728,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_sendSms"
android:description="@string/permdesc_sendSms"
android:permissionFlags="costsMoney"
android:permissionFlags="costsMoney|hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to receive SMS messages.
@@ -738,6 +738,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveSms"
android:description="@string/permdesc_receiveSms"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to read SMS messages.
@@ -747,6 +748,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readSms"
android:description="@string/permdesc_readSms"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to receive WAP push messages.
@@ -756,6 +758,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveWapPush"
android:description="@string/permdesc_receiveWapPush"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to monitor incoming MMS messages.
@@ -765,6 +768,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveMms"
android:description="@string/permdesc_receiveMms"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
@@ -783,6 +787,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readCellBroadcasts"
android:description="@string/permdesc_readCellBroadcasts"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- ====================================================================== -->
@@ -947,6 +952,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readCallLog"
android:description="@string/permdesc_readCallLog"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to write (but not read) the user's
@@ -966,6 +972,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_writeCallLog"
android:description="@string/permdesc_writeCallLog"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- Allows an application to see the number being dialed during an outgoing
@@ -980,6 +987,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_processOutgoingCalls"
android:description="@string/permdesc_processOutgoingCalls"
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />

<!-- ====================================================================== -->
@@ -3427,6 +3435,12 @@
<permission android:name="android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY"
android:protectionLevel="signature|installer" />

<!-- @SystemApi Allows an application to whitelist restricted permissions
on any of the whitelists.
@hide -->
<permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS"
android:protectionLevel="signature|installer" />

<!-- @hide Allows an application to observe permission changes. -->
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
android:protectionLevel="signature|privileged" />

+ 12
- 1
core/res/res/values/attrs_manifest.xml View File

@@ -310,13 +310,24 @@
<!-- Set to indicate that this permission allows an operation that
may cost the user money. Such permissions may be highlighted
when shown to the user with this additional information. -->
<flag name="costsMoney" value="0x0001" />
<flag name="costsMoney" value="0x1" />
<!-- Additional flag from base permission type: this permission has been
removed and it is no longer enforced. It shouldn't be shown in the
UI. Removed permissions are kept as normal permissions for backwards
compatibility as apps may be checking them before calling an API.
-->
<flag name="removed" value="0x2" />
<!-- This permission is restricted by the platform and it would be
grantable only to apps that meet special criteria per platform
policy.
-->
<flag name="hardRestricted" value="0x4" />
<!-- This permission is restricted by the platform and it would be
grantable in its full form to apps that meet special criteria
per platform policy. Otherwise, a weaker form of the permission
would be granted. The weak grant depends on the permission.
-->
<flag name="softRestricted" value="0x8" />
</attr>

<!-- Specified the name of a group that this permission is associated

+ 0
- 1
core/tests/coretests/src/android/provider/SettingsBackupTest.java View File

@@ -433,7 +433,6 @@ public class SettingsBackupTest {
Settings.Global.SIGNED_CONFIG_VERSION,
Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
Settings.Global.SMS_SHORT_CODE_CONFIRMATION,

+ 3
- 0
packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java View File

@@ -139,6 +139,9 @@ public class InstallInstalling extends AlertActivity {
getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
params.installReason = PackageManager.INSTALL_REASON_USER;

// Whitelist all restricted permissions.
params.setWhitelistedRestrictedPermissions(null /*permissions*/);

File file = new File(mPackageURI.getPath());
try {
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);

+ 0
- 5
packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java View File

@@ -1236,11 +1236,6 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL,
GlobalSettingsProto.Sms.SHORT_CODES_UPDATE_METADATA_URL);
dumpSetting(s, p,
Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
GlobalSettingsProto.Sms.ACCESS_RESTRICTION_ENABLED);
p.end(smsToken);

final long soundsToken = p.start(GlobalSettingsProto.SOUNDS);
dumpSetting(s, p,
Settings.Global.CAR_DOCK_SOUND,

+ 1
- 1
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java View File

@@ -3610,7 +3610,7 @@ public class SettingsProvider extends ContentProvider {

final boolean isUpgrade;
try {
isUpgrade = mPackageManager.isUpgrade();
isUpgrade = mPackageManager.isDeviceUpgrading();
} catch (RemoteException e) {
throw new IllegalStateException("Package manager not available");
}

+ 1
- 0
packages/Shell/AndroidManifest.xml View File

@@ -99,6 +99,7 @@
<uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" />
<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" />
<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" />

+ 0
- 1
services/core/java/com/android/server/am/CoreSettingsObserver.java View File

@@ -74,7 +74,6 @@ final class CoreSettingsObserver extends ContentObserver {
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS_GLES, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, int.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);

+ 1
- 1
services/core/java/com/android/server/am/UserController.java View File

@@ -2269,7 +2269,7 @@ class UserController implements Handler.Callback {
boolean isFirstBootOrUpgrade() {
IPackageManager pm = AppGlobals.getPackageManager();
try {
return pm.isFirstBoot() || pm.isUpgrade();
return pm.isFirstBoot() || pm.isDeviceUpgrading();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

+ 1
- 1
services/core/java/com/android/server/pm/OtaDexoptService.java View File

@@ -353,7 +353,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
throw new IllegalStateException("Should not be ota-dexopting when trying to move.");
}

if (!mPackageManagerService.isUpgrade()) {
if (!mPackageManagerService.isDeviceUpgrading()) {
Slog.d(TAG, "No upgrade, skipping A/B artifacts check.");
return;
}

+ 10
- 0
services/core/java/com/android/server/pm/PackageInstallerService.java View File

@@ -531,6 +531,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
+ "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
}

// Only system components can circumvent restricted whitelisting when installing.
if ((params.installFlags
& PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
&& mContext.checkCallingOrSelfPermission(Manifest.permission
.WHITELIST_RESTRICTED_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
throw new SecurityException("You need the "
+ "android.permission.WHITELIST_RESTRICTED_PERMISSIONS permission to"
+ " use the PackageManager.INSTALL_WHITELIST_RESTRICTED_PERMISSIONS flag");
}

// Defensively resize giant app icons
if (params.appIcon != null) {
final ActivityManager am = (ActivityManager) mContext.getSystemService(

+ 32
- 4
services/core/java/com/android/server/pm/PackageInstallerSession.java View File

@@ -139,6 +139,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
static final String TAG_SESSION = "session";
static final String TAG_CHILD_SESSION = "childSession";
private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION =
"whitelisted-restricted-permission";
private static final String ATTR_SESSION_ID = "sessionId";
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
@@ -486,6 +488,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
info.originatingUid = params.originatingUid;
info.referrerUri = params.referrerUri;
info.grantedRuntimePermissions = params.grantedRuntimePermissions;
info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions;
info.installFlags = params.installFlags;
info.isMultiPackage = params.isMultiPackage;