diff --git a/api/current.txt b/api/current.txt index 3fb05450c16c8..d24e350e0f99b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator 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 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 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 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 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 diff --git a/api/system-current.txt b/api/system-current.txt index 64589093654eb..eb9f82af93123 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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 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 onGetAppPermissions(@NonNull String); method @NonNull public abstract java.util.List 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 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 diff --git a/api/test-current.txt b/api/test-current.txt index 99cdfb012155c..973e70067c37d 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -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 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"; } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 8986c6fd02c21..146cf0cd2da95 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -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; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 4b0b8cb12d5e7..15982a796a7e1 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -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. * diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index a906790c45abc..82a34ceea8b95 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -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 { @@ -717,6 +719,43 @@ public class ApplicationPackageManager extends PackageManager { } } + @Override + public @NonNull Set getWhitelistedRestrictedPermissions( + @NonNull String packageName, @PermissionWhitelistFlags int whitelistFlags) { + try { + final List 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) { @@ -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(); } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index d67bfb6c9c84f..8749b108c1687 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -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() { @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() { @Override public PermissionControllerManager createService(ContextImpl ctx) { - return new PermissionControllerManager(ctx.getOuterContext()); + return new PermissionControllerManager(ctx.getOuterContext(), + ctx.getMainThreadHandler()); }}); registerService(Context.ROLE_SERVICE, RoleManager.class, diff --git a/core/java/android/app/role/IRoleController.aidl b/core/java/android/app/role/IRoleController.aidl index a472eacb28a18..19762e0841b1f 100644 --- a/core/java/android/app/role/IRoleController.aidl +++ b/core/java/android/app/role/IRoleController.aidl @@ -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); diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java index bd981179e2ff3..027e152ee95ff 100644 --- a/core/java/android/app/role/RoleControllerManager.java +++ b/core/java/android/app/role/RoleControllerManager.java @@ -120,13 +120,6 @@ public class RoleControllerManager { flags, callback)); } - /** - * @see RoleControllerService#onSmsKillSwitchToggled(boolean) - */ - public void onSmsKillSwitchToggled(boolean enabled) { - mRemoteService.scheduleAsyncRequest(new OnSmsKillSwitchToggledRequest(enabled)); - } - /** * @see RoleControllerService#onIsApplicationQualifiedForRole(String, String) */ @@ -415,28 +408,6 @@ public class RoleControllerManager { } } - /** - * Request for {@link #onSmsKillSwitchToggled(boolean)} - */ - private static final class OnSmsKillSwitchToggledRequest - implements AbstractRemoteService.AsyncRequest { - - 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)} */ diff --git a/core/java/android/app/role/RoleControllerService.java b/core/java/android/app/role/RoleControllerService.java index 312761d43afd6..2bc94560edd77 100644 --- a/core/java/android/app/role/RoleControllerService.java +++ b/core/java/android/app/role/RoleControllerService.java @@ -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 @@ -258,17 +249,6 @@ public abstract class RoleControllerService extends Service { public abstract boolean onClearRoleHolders(@NonNull String roleName, @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. * diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index ddfe75568eee1..71242fbac9a5e 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -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 { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index fb2218778c9b3..cf704d52cba05 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -130,6 +130,15 @@ interface IPackageManager { void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId); + List 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 getInstalledModules(int flags); ModuleInfo getModuleInfo(String packageName, int flags); + + int getRuntimePermissionsVersion(int userId); + + void setRuntimePermissionsVersion(int version, int userId); } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index ec2e8ca260606..90fb20bb0163b 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -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 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 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) { @@ -1481,6 +1495,43 @@ public class PackageInstaller { this.grantedRuntimePermissions = permissions; } + /** + * 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. + * + *

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. + * + *

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 + * null 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 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. * @@ -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 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(); @@ -2048,6 +2105,25 @@ public class PackageInstaller { return grantedRuntimePermissions; } + /** + * 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 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)}. * @@ -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); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 025d8f9507f9a..83e15e8daa39a 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -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 - * - * @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. + * 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. + * + * @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. @@ -3101,6 +3190,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, @@ -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 {} @@ -3924,6 +4046,163 @@ public abstract class PackageManager { @NonNull String packageName, @PermissionFlags int flagMask, @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. + * + *

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. + * + *

    There are three whitelists: + * + *
  1. 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. + * + *
  2. 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. + * + *
  3. 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 getWhitelistedRestrictedPermissions( + @NonNull String packageName, @PermissionWhitelistFlags int whitelistFlag) { + return Collections.emptySet(); + } + + /** + * Adds a whitelisted restricted permission for an app. + * + *

    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. + * + *

      There are three whitelists: + * + *
    1. 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. + * + *
    2. 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. + * + *
    3. 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. + * + *

      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. + * + *

      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. + * + *

        There are three whitelists: + * + *
      1. 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. + * + *
      2. 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. + * + *
      3. 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. + * + *

        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 @@ -6514,6 +6793,13 @@ public abstract class PackageManager { @UnsupportedAppUsage 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); } } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index cd324afb04797..5f54735839072 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -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); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 8981000714dd7..2b23e7a2a6338 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -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) { diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 6a41f334827dd..f838900d43d7a 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -319,6 +319,27 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @SystemApi public static final int FLAG_REMOVED = 1<<1; + /** + * Flag for {@link #flags}, corresponding to hardRestricted + * value of {@link android.R.attr#permissionFlags}. + * + *

        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 softRestricted + * value of {@link android.R.attr#permissionFlags}. + * + *

        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. @@ -574,11 +595,31 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { return size; } + /** @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 CREATOR = new Creator() { @Override diff --git a/core/java/android/os/RemoteCallback.java b/core/java/android/os/RemoteCallback.java index 22cf404c4f570..047ba1d20056e 100644 --- a/core/java/android/os/RemoteCallback.java +++ b/core/java/android/os/RemoteCallback.java @@ -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; diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl index 4f65d244d3c1f..45c01bcf255b6 100644 --- a/core/java/android/permission/IPermissionController.aidl +++ b/core/java/android/permission/IPermissionController.aidl @@ -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); } diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java index 55fae3014666f..be8973751bf8d 100644 --- a/core/java/android/permission/PermissionControllerManager.java +++ b/core/java/android/permission/PermissionControllerManager.java @@ -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 sRemoteServices = new SparseArray<>(1); + private static ArrayMap, 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 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; @@ -453,6 +458,23 @@ public final class PermissionControllerManager { countSystem, numMillis, executor, callback)); } + /** + * 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 callback) { + mRemoteService.scheduleRequest(new PendingGrantOrUpgradeDefaultRuntimePermissionsRequest( + mRemoteService, executor, callback)); + } + /** * A connection to the remote service */ @@ -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 { + private final @NonNull Consumer mCallback; + + private final @NonNull RemoteCallback mRemoteCallback; + + private PendingGrantOrUpgradeDefaultRuntimePermissionsRequest( + @NonNull RemoteService service, @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer 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); + } + } + } } diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java index 2313d5972cbd8..ed44367e28c67 100644 --- a/core/java/android/permission/PermissionControllerService.java +++ b/core/java/android/permission/PermissionControllerService.java @@ -177,6 +177,17 @@ public abstract class PermissionControllerService extends Service { public abstract @NonNull List onGetPermissionUsages( 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. * @@ -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); + } } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 2ea706613ef84..1aa5b06569355 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -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(); + } } /** diff --git a/core/java/android/permission/PermissionManagerInternal.java b/core/java/android/permission/PermissionManagerInternal.java index 92dbab33a2f09..71674311965ce 100644 --- a/core/java/android/permission/PermissionManagerInternal.java +++ b/core/java/android/permission/PermissionManagerInternal.java @@ -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); } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 9ec77232ec28b..166de3fde7413 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -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") diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ee0c83ea72f8b..2e1ef38048b2f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -13390,18 +13390,6 @@ public final class Settings { public static final String LOCATION_GLOBAL_KILL_SWITCH = "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. diff --git a/core/java/android/util/StatsLogAtoms.java b/core/java/android/util/StatsLogAtoms.java index bbede5394ede0..4780cb58ca063 100644 --- a/core/java/android/util/StatsLogAtoms.java +++ b/core/java/android/util/StatsLogAtoms.java @@ -76,6 +76,13 @@ public class StatsLogAtoms { public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED; + /** + * 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 diff --git a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java index 206efa94b7f69..c3aa847acae17 100644 --- a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java @@ -32,7 +32,6 @@ import java.util.ArrayList; * * @param the concrete remote service class * @param the interface of the binder service - * @hide */ public abstract class AbstractMultiplePendingRequestsRemoteService, I extends IInterface> diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index de526eff275e0..b94eb1626e37e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -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" /> @@ -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" /> @@ -3427,6 +3435,12 @@ + + + diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 8f3f25aad1822..47c243ca1e041 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -310,13 +310,24 @@ - + + + + +