diff options
| -rwxr-xr-x | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/content/pm/PermissionInfo.java | 15 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 4 | ||||
| -rw-r--r-- | core/res/res/values/attrs_manifest.xml | 3 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 14 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 2 | ||||
| -rw-r--r-- | services/core/java/android/content/pm/PackageManagerInternal.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 41 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/permission/BasePermission.java | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/permission/PermissionManagerService.java | 19 |
11 files changed, 103 insertions, 3 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index daad70339866..87f8760ab61f 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2303,6 +2303,7 @@ package android.content.pm { field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 + field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000 field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000 diff --git a/api/test-current.txt b/api/test-current.txt index e604806278a9..9139285f8721 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -878,6 +878,7 @@ package android.content.pm { field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 + field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000 field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000 diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index a0f089b2df41..3aa1a6d3f8ff 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -259,6 +259,17 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @TestApi public static final int PROTECTION_FLAG_COMPANION = 0x800000; + /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>retailDemo</code> value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000; + /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { PROTECTION_FLAG_PRIVILEGED, @@ -282,6 +293,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_APP_PREDICTOR, PROTECTION_FLAG_TELEPHONY, PROTECTION_FLAG_COMPANION, + PROTECTION_FLAG_RETAIL_DEMO, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} @@ -528,6 +540,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0) { protLevel += "|telephony"; } + if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) { + protLevel += "|retailDemo"; + } return protLevel; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 3a1b63d56b5f..816a85f9ec98 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4014,9 +4014,9 @@ statistics <p>Declaring the permission implies intention to use the API and the user of the device can grant permission through the Settings application. - <p>Protection level: signature|privileged|development|appop --> + <p>Protection level: signature|privileged|development|appop|retailDemo --> <permission android:name="android.permission.PACKAGE_USAGE_STATS" - android:protectionLevel="signature|privileged|development|appop" /> + android:protectionLevel="signature|privileged|development|appop|retailDemo" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @hide @SystemApi Allows an application to observe usage time of apps. The app can register diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index cfed805d5d88..124765c877ae 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -301,6 +301,9 @@ <!-- Additional flag from base permission type: this permission can be automatically granted to the system companion device manager service --> <flag name="companion" value="0x800000" /> + <!-- Additional flag from base permission type: this permission will be granted to the + retail demo app, as defined by the OEM. --> + <flag name="retailDemo" value="0x1000000" /> </attr> <!-- Flags indicating more context for a permission group. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 52b92d2660da..612fc928dae0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3590,7 +3590,6 @@ --> <string name="config_defaultWellbeingPackage" translatable="false"></string> - <!-- The package name for the system telephony apps. This package must be trusted, as it will be granted with permissions with special telephony protection level. Note, framework by default support multiple telephony apps, each package @@ -3658,6 +3657,19 @@ --> <string name="config_defaultContentSuggestionsService" translatable="false"></string> + <!-- The package name for the default retail demo app. + This package must be trusted, as it has the permissions to query the usage stats on the + device. + Example: "com.google.android.retaildemo" + --> + <string name="config_retailDemoPackage" translatable="false"></string> + + <!-- The package signature hash for the default retail demo app. + This package must be trusted, as it has the permissions to query the usage stats on the + device. + --> + <string name="config_retailDemoPackageSignature" translatable="false"></string> + <!-- Whether the device uses the default focus highlight when focus state isn't specified. --> <bool name="config_useDefaultFocusHighlight">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 21128e33b6e5..b6db3897b14d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3395,6 +3395,8 @@ <java-symbol type="string" name="config_defaultAttentionService" /> <java-symbol type="string" name="config_defaultSystemCaptionsService" /> <java-symbol type="string" name="config_defaultSystemCaptionsManagerService" /> + <java-symbol type="string" name="config_retailDemoPackage" /> + <java-symbol type="string" name="config_retailDemoPackageSignature" /> <java-symbol type="string" name="notification_channel_foreground_service" /> <java-symbol type="string" name="foreground_service_app_in_background" /> diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 27b6bfb8f5fd..bdcd832e4f4a 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -67,6 +67,7 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_TELEPHONY = 12; public static final int PACKAGE_WIFI = 13; public static final int PACKAGE_COMPANION = 14; + public static final int PACKAGE_RETAIL_DEMO = 15; @IntDef(value = { INTEGRITY_VERIFICATION_ALLOW, @@ -105,6 +106,7 @@ public abstract class PackageManagerInternal { PACKAGE_TELEPHONY, PACKAGE_WIFI, PACKAGE_COMPANION, + PACKAGE_RETAIL_DEMO, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 93a0506f673d..394b0ad7b0e8 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1542,6 +1542,7 @@ public class PackageManagerService extends IPackageManager.Stub final @Nullable String[] mTelephonyPackages; final @NonNull String mServicesExtensionPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; + final @Nullable String mRetailDemoPackage; private final PackageUsage mPackageUsage = new PackageUsage(); private final CompilerStats mCompilerStats = new CompilerStats(); @@ -3161,6 +3162,7 @@ public class PackageManagerService extends IPackageManager.Stub mAppPredictionServicePackage = getAppPredictionServicePackageName(); mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); mTelephonyPackages = getTelephonyPackageNames(); + mRetailDemoPackage = getRetailDemoPackageName(); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. @@ -19703,6 +19705,41 @@ public class PackageManagerService extends IPackageManager.Stub } @Nullable + private String getRetailDemoPackageName() { + final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage); + final String predefinedSignature = mContext.getString( + R.string.config_retailDemoPackageSignature); + + if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) { + return null; + } + + final AndroidPackage androidPkg = mPackages.get(predefinedPkgName); + if (androidPkg != null) { + final SigningDetails signingDetail = androidPkg.getSigningDetails(); + if (signingDetail != null && signingDetail.signatures != null) { + try { + final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256"); + for (Signature signature : signingDetail.signatures) { + if (TextUtils.equals(predefinedSignature, + HexEncoding.encodeToString(msgDigest.digest( + signature.toByteArray()), false))) { + return predefinedPkgName; + } + } + } catch (NoSuchAlgorithmException e) { + Slog.e( + TAG, + "Unable to verify signatures as getting the retail demo package name", + e); + } + } + } + + return null; + } + + @Nullable private String ensureSystemPackageName(@Nullable String packageName) { if (packageName == null) { return null; @@ -22990,6 +23027,10 @@ public class PackageManagerService extends IPackageManager.Stub return filterOnlySystemPackages(mTelephonyPackages); case PackageManagerInternal.PACKAGE_COMPANION: return filterOnlySystemPackages("com.android.companiondevicemanager"); + case PackageManagerInternal.PACKAGE_RETAIL_DEMO: + return TextUtils.isEmpty(mRetailDemoPackage) + ? ArrayUtils.emptyArray(String.class) + : new String[] {mRetailDemoPackage}; default: return ArrayUtils.emptyArray(String.class); } diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 565a85fd1ac1..e323c9869afb 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -284,6 +284,10 @@ public final class BasePermission { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0; } + public boolean isRetailDemo() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0; + } + public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { return; diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 6167a509b85f..1fc2dd5193e1 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -55,6 +55,8 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ApplicationPackageManager; import android.app.IActivityManager; +import android.app.admin.DeviceAdminInfo; +import android.app.admin.DevicePolicyManagerInternal; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.Context; @@ -3355,10 +3357,27 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Special permissions for the system companion device manager. allowed = true; } + if (!allowed && bp.isRetailDemo() + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM), + pkg.getPackageName()) && isProfileOwner(pkg.getUid())) { + // Special permission granted only to the OEM specified retail demo app + allowed = true; + } } return allowed; } + private static boolean isProfileOwner(int uid) { + DevicePolicyManagerInternal dpmInternal = + LocalServices.getService(DevicePolicyManagerInternal.class); + if (dpmInternal != null) { + return dpmInternal + .isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + } + return false; + } + private static boolean canGrantOemPermission(PackageSetting ps, String permission) { if (!ps.isOem()) { return false; |