diff options
| author | 2020-02-04 06:56:48 +0000 | |
|---|---|---|
| committer | 2020-02-04 06:56:48 +0000 | |
| commit | 6bfbee076b8e211e337a785286fed77aa9fd54f5 (patch) | |
| tree | b30119f6dc01e130edb4919542572d8061d9961f | |
| parent | fb740d58fe731175859d6609b4f295df516cd3c1 (diff) | |
| parent | 8126b1fe0f09f359f3ec3b80bc5717e101e295b8 (diff) | |
Merge "Added a new "retailDemo" protection level."
| -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 78dc577b38de..89811ada123a 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2304,6 +2304,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 c8d746b44a15..cee560b00abe 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -933,6 +933,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 6df0161c3ca6..0e7214a4f3d3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4018,9 +4018,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 059bc443a609..b22e1867f257 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 21d1d3cf9c89..d676150a4ba3 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3396,6 +3396,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 c09fb38c4d8a..db8d490d53b9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1544,6 +1544,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(); @@ -3160,6 +3161,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. @@ -19723,6 +19725,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; @@ -23010,6 +23047,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; |