diff options
author | Makoto Onuki <omakoto@google.com> | 2018-02-15 10:59:41 -0800 |
---|---|---|
committer | Makoto Onuki <omakoto@google.com> | 2018-02-20 12:14:18 -0800 |
commit | 700feef8a60e06784d28d1db9502e650df854cad (patch) | |
tree | eb635270a03ffb5a2722a2fe85a90e3609e8c434 | |
parent | f9a02975eaa5a36584eb1f214193d24053af73f1 (diff) |
Shortcut permissions for default text classifier
- Add two shortcut related permissions as SystemAPI for the default
text classifier.
- The default text classifier package name still comes from the
system resource.
Bug: 73083596
Bug: 71555985
Test: atest CtsPermission2TestCases
Test: Manual test with a test package, with the following in config.xml
<string name="config_defaultTextClassifierPackage" translatable="false">com.example.android.pm.shortcutlauncherdemo</string>
Change-Id: I19081d9d6ba0b33eb25d19aa55b4fe2f26a75897
18 files changed, 183 insertions, 37 deletions
diff --git a/api/current.txt b/api/current.txt index df18f10243e0..3456ad9b7644 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11388,6 +11388,8 @@ package android.content.pm { ctor public PermissionInfo(); ctor public PermissionInfo(android.content.pm.PermissionInfo); method public int describeContents(); + method public int getProtection(); + method public int getProtectionFlags(); method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager); field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 @@ -11404,8 +11406,8 @@ package android.content.pm { field public static final int PROTECTION_FLAG_SETUP = 2048; // 0x800 field public static final deprecated int PROTECTION_FLAG_SYSTEM = 16; // 0x10 field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200 - field public static final int PROTECTION_MASK_BASE = 15; // 0xf - field public static final int PROTECTION_MASK_FLAGS = 65520; // 0xfff0 + field public static final deprecated int PROTECTION_MASK_BASE = 15; // 0xf + field public static final deprecated int PROTECTION_MASK_FLAGS = 65520; // 0xfff0 field public static final int PROTECTION_NORMAL = 0; // 0x0 field public static final int PROTECTION_SIGNATURE = 2; // 0x2 field public static final deprecated int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3 @@ -11413,7 +11415,7 @@ package android.content.pm { field public int flags; field public java.lang.String group; field public java.lang.CharSequence nonLocalizedDescription; - field public int protectionLevel; + field public deprecated int protectionLevel; } public final class ProviderInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable { diff --git a/api/system-current.txt b/api/system-current.txt index 44349dc1a47e..bbeafe0d34ff 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10,6 +10,7 @@ package android { field public static final java.lang.String ACCESS_MTP = "android.permission.ACCESS_MTP"; field public static final java.lang.String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS"; field public static final java.lang.String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; + field public static final java.lang.String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS"; field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER"; field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER"; field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; @@ -179,6 +180,7 @@ package android { field public static final java.lang.String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED"; field public static final java.lang.String TV_INPUT_HARDWARE = "android.permission.TV_INPUT_HARDWARE"; field public static final java.lang.String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER"; + field public static final java.lang.String UNLIMITED_SHORTCUTS_API_CALLS = "android.permission.UNLIMITED_SHORTCUTS_API_CALLS"; field public static final java.lang.String UPDATE_APP_OPS_STATS = "android.permission.UPDATE_APP_OPS_STATS"; field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK"; @@ -1085,6 +1087,7 @@ package android.content.pm { public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int FLAG_REMOVED = 2; // 0x2 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 + field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public int requestRes; } diff --git a/api/test-current.txt b/api/test-current.txt index 9bfc105efa8f..710df970314d 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -215,6 +215,7 @@ package android.content.pm { } public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { + field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000 } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 13117bcbc929..f8f50a278511 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2802,4 +2802,13 @@ public class ApplicationPackageManager extends PackageManager { return mArtManager; } } + + @Override + public String getSystemTextClassifierPackageName() { + try { + return mPM.getSystemTextClassifierPackageName(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 379bff49c911..36a74a489890 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -660,4 +660,6 @@ interface IPackageManager { boolean hasSigningCertificate(String packageName, in byte[] signingCertificate, int flags); boolean hasUidSigningCertificate(int uid, in byte[] signingCertificate, int flags); + + String getSystemTextClassifierPackageName(); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 07a991188a49..bd7961fffca8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -6022,4 +6022,14 @@ public abstract class PackageManager { throw new UnsupportedOperationException( "hasSigningCertificate not implemented in subclass"); } + + /** + * @return the system defined text classifier package name, or null if there's none. + * + * @hide + */ + public String getSystemTextClassifierPackageName() { + throw new UnsupportedOperationException( + "getSystemTextClassifierPackageName not implemented in subclass"); + } } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 6f093ba8d005..41aa9c374978 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -43,12 +43,14 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_INSTALLER = 2; public static final int PACKAGE_VERIFIER = 3; public static final int PACKAGE_BROWSER = 4; + public static final int PACKAGE_SYSTEM_TEXT_CLASSIFIER = 5; @IntDef(value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, PACKAGE_INSTALLER, PACKAGE_VERIFIER, PACKAGE_BROWSER, + PACKAGE_SYSTEM_TEXT_CLASSIFIER, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index dda4167d3c3b..7490d0255786 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3182,7 +3182,7 @@ public class PackageParser { perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel); - if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_FLAGS) != 0) { + if (perm.info.getProtectionFlags() != 0) { if ( (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_INSTANT) == 0 && (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) == 0 && (perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) != diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 21bd7f0ce763..938409af90e9 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -16,12 +16,16 @@ package android.content.pm; +import android.annotation.IntDef; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Information you can retrieve about a particular security permission * known to the system. This corresponds to information collected from the @@ -56,6 +60,16 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @Deprecated public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; + /** @hide */ + @IntDef(flag = false, prefix = { "PROTECTION_" }, value = { + PROTECTION_NORMAL, + PROTECTION_DANGEROUS, + PROTECTION_SIGNATURE, + PROTECTION_SIGNATURE_OR_SYSTEM, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Protection {} + /** * Additional flag for {@link #protectionLevel}, corresponding * to the <code>privileged</code> value of @@ -155,30 +169,71 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000; /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>text_classifier</code> value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 0x10000; + + /** @hide */ + @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { + PROTECTION_FLAG_PRIVILEGED, + PROTECTION_FLAG_SYSTEM, + PROTECTION_FLAG_DEVELOPMENT, + PROTECTION_FLAG_APPOP, + PROTECTION_FLAG_PRE23, + PROTECTION_FLAG_INSTALLER, + PROTECTION_FLAG_VERIFIER, + PROTECTION_FLAG_PREINSTALLED, + PROTECTION_FLAG_SETUP, + PROTECTION_FLAG_INSTANT, + PROTECTION_FLAG_RUNTIME_ONLY, + PROTECTION_FLAG_OEM, + PROTECTION_FLAG_VENDOR_PRIVILEGED, + PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ProtectionFlags {} + + /** * Mask for {@link #protectionLevel}: the basic protection type. + * + * @deprecated Use #getProtection() instead. */ + @Deprecated public static final int PROTECTION_MASK_BASE = 0xf; /** * Mask for {@link #protectionLevel}: additional flag bits. + * + * @deprecated Use #getProtectionFlags() instead. */ + @Deprecated public static final int PROTECTION_MASK_FLAGS = 0xfff0; /** * The level of access this permission is protecting, as per * {@link android.R.attr#protectionLevel}. Consists of - * a base permission type and zero or more flags: + * a base permission type and zero or more flags. Use the following functions + * to extract them. * * <pre> - * int basePermissionType = protectionLevel & {@link #PROTECTION_MASK_BASE}; - * int permissionFlags = protectionLevel & {@link #PROTECTION_MASK_FLAGS}; + * int basePermissionType = permissionInfo.getProtection(); + * int permissionFlags = permissionInfo.getProtectionFlags(); * </pre> * * <p></p>Base permission types are {@link #PROTECTION_NORMAL}, * {@link #PROTECTION_DANGEROUS}, {@link #PROTECTION_SIGNATURE} * and the deprecated {@link #PROTECTION_SIGNATURE_OR_SYSTEM}. * Flags are listed under {@link android.R.attr#protectionLevel}. + * + * @deprecated Use #getProtection() and #getProtectionFlags() instead. */ + @Deprecated public int protectionLevel; /** @@ -304,6 +359,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0) { protLevel += "|vendorPrivileged"; } + if ((level & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0) { + protLevel += "|textClassifier"; + } return protLevel; } @@ -344,6 +402,22 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { return null; } + /** + * Return the base permission type. + */ + @Protection + public int getProtection() { + return protectionLevel & PROTECTION_MASK_BASE; + } + + /** + * Return the additional flags in {@link #protectionLevel}. + */ + @ProtectionFlags + public int getProtectionFlags() { + return protectionLevel & ~PROTECTION_MASK_BASE; + } + @Override public String toString() { return "PermissionInfo{" diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java index 6c8c8bc36127..2c8c4ecaa610 100644 --- a/core/java/android/service/textclassifier/TextClassifierService.java +++ b/core/java/android/service/textclassifier/TextClassifierService.java @@ -26,6 +26,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.CancellationSignal; import android.os.IBinder; @@ -37,8 +38,6 @@ import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; import android.view.textclassifier.TextSelection; -import com.android.internal.R; - /** * Abstract base class for the TextClassifier service. * @@ -263,28 +262,33 @@ public abstract class TextClassifierService extends Service { */ @Nullable public static ComponentName getServiceComponentName(Context context) { - final String str = context.getString(R.string.config_defaultTextClassifierService); - if (!TextUtils.isEmpty(str)) { - try { - final ComponentName componentName = ComponentName.unflattenFromString(str); - final Intent intent = new Intent(SERVICE_INTERFACE).setComponent(componentName); - final ServiceInfo si = context.getPackageManager() - .getServiceInfo(intent.getComponent(), 0); - final String permission = si == null ? null : si.permission; - if (Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE.equals(permission)) { - return componentName; - } - Slog.w(LOG_TAG, String.format( - "Service %s should require %s permission. Found %s permission", - intent.getComponent().flattenToString(), - Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE, - si.permission)); - } catch (PackageManager.NameNotFoundException e) { - Slog.w(LOG_TAG, String.format("Service %s not found", str)); - } - } else { + final String packageName = context.getPackageManager().getSystemTextClassifierPackageName(); + if (TextUtils.isEmpty(packageName)) { Slog.d(LOG_TAG, "No configured system TextClassifierService"); + return null; + } + + final Intent intent = new Intent(SERVICE_INTERFACE).setPackage(packageName); + + final ResolveInfo ri = context.getPackageManager().resolveService(intent, + PackageManager.MATCH_SYSTEM_ONLY); + + if ((ri == null) || (ri.serviceInfo == null)) { + Slog.w(LOG_TAG, String.format("Package or service not found in package %s", + packageName)); + return null; + } + final ServiceInfo si = ri.serviceInfo; + + final String permission = si.permission; + if (Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE.equals(permission)) { + return si.getComponentName(); } + Slog.w(LOG_TAG, String.format( + "Service %s should require %s permission. Found %s permission", + si.getComponentName(), + Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE, + si.permission)); return null; } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 3a527b59d074..7cf997196706 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3810,9 +3810,15 @@ <permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE" android:protectionLevel="signature|development|instant|appop" /> - <!-- @hide Allows system components to access all app shortcuts. --> + <!-- @SystemApi Allows to access all app shortcuts. + @hide --> <permission android:name="android.permission.ACCESS_SHORTCUTS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|textClassifier" /> + + <!-- @SystemApi Allows unlimited calls to shortcut mutation APIs. + @hide --> + <permission android:name="android.permission.UNLIMITED_SHORTCUTS_API_CALLS" + android:protectionLevel="signature|textClassifier" /> <!-- @SystemApi Allows an application to read the runtime profiles of other apps. @hide <p>Not for use by third-party applications. --> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 287f29615e2b..97f678466c8e 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -173,10 +173,10 @@ values listed below. If no protectionLevel is defined for a custom permission, the system assigns the default ("normal"). <p>Each protection level consists of a base permission type and zero or - more flags: + more flags. Use the following functions to extract those. <pre> - int basePermissionType = protectionLevel & {@link android.content.pm.PermissionInfo#PROTECTION_MASK_BASE}; - int permissionFlags = protectionLevel & {@link android.content.pm.PermissionInfo#PROTECTION_MASK_FLAGS}; + int basePermissionType = permissionInfo.getProtection(); + int permissionFlags = permissionInfo.getProtectionFlags(); </pre> --> <attr name="protectionLevel"> @@ -265,6 +265,9 @@ <!-- Additional flag from base permission type: this permission can be granted to privileged apps in vendor partition. --> <flag name="vendorPrivileged" value="0x8000" /> + <!-- Additional flag from base permission type: this permission can be automatically + granted to the system default text classifier --> + <flag name="textClassifier" value="0x10000" /> </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 1f4425fef271..d0c07dcfc878 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3150,14 +3150,14 @@ --> <string name="config_defaultAutofillService" translatable="false"></string> - <!-- The component name, flattened to a string, for the default system textclassifier service. + <!-- The package name for the default system textclassifier service. This service must be trusted, as it can be activated without explicit consent of the user. (e.g. com.android.textclassifier/.TextClassifierServiceImpl). If no textclassifier service with the specified name exists on the device (or if this is set to empty string), a default textclassifier will be loaded in the calling app's process. See android.view.textclassifier.TextClassificationManager. --> - <string name="config_defaultTextClassifierService" translatable="false"></string> + <string name="config_defaultTextClassifierPackage" 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 b69ded80009c..150354be6e48 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3105,7 +3105,7 @@ <java-symbol type="string" name="notification_channel_heavy_weight_app" /> <java-symbol type="string" name="notification_channel_system_changes" /> <java-symbol type="string" name="config_defaultAutofillService" /> - <java-symbol type="string" name="config_defaultTextClassifierService" /> + <java-symbol type="string" name="config_defaultTextClassifierPackage" /> <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/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b9f6d211c7f7..f49ada931888 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -237,6 +237,7 @@ import android.provider.Settings.Secure; import android.security.KeyStore; import android.security.SystemKeyStore; import android.service.pm.PackageServiceDumpProto; +import android.service.textclassifier.TextClassifierService; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; @@ -1391,6 +1392,7 @@ public class PackageManagerService extends IPackageManager.Stub final @NonNull String mRequiredUninstallerPackage; final @Nullable String mSetupWizardPackage; final @Nullable String mStorageManagerPackage; + final @Nullable String mSystemTextClassifierPackage; final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; @@ -2951,6 +2953,9 @@ public class PackageManagerService extends IPackageManager.Stub filter.setPriority(0); } } + + mSystemTextClassifierPackage = getSystemTextClassifierPackageName(); + mDeferProtectedFilters = false; mProtectedFilters.clear(); @@ -20247,6 +20252,11 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } @Override + public String getSystemTextClassifierPackageName() { + return mContext.getString(R.string.config_defaultTextClassifierPackage); + } + + @Override public void setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage) { if (!sUserManager.exists(userId)) return; @@ -23374,6 +23384,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); return "android"; case PackageManagerInternal.PACKAGE_VERIFIER: return mRequiredVerifierPackage; + case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER: + return mSystemTextClassifierPackage; } return null; } 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 75a61064c1c9..bcf4b07d4d26 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -228,6 +228,10 @@ public final class BasePermission { public boolean isVendorPrivileged() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0; } + public boolean isSystemTextClassifier() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) + != 0; + } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { 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 afaafbc68b22..afa9dd0a911f 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1148,6 +1148,13 @@ public class PermissionManagerService { // this app is a setup wizard, then it gets the permission. allowed = true; } + if (!allowed && bp.isSystemTextClassifier() + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER, + UserHandle.USER_SYSTEM))) { + // Special permissions for the system default text classifier. + allowed = true; + } } return allowed; } diff --git a/test-mock/src/android/test/mock/MockPackageManager.java b/test-mock/src/android/test/mock/MockPackageManager.java index 1ddc52c9f7b4..1af7c3a479b6 100644 --- a/test-mock/src/android/test/mock/MockPackageManager.java +++ b/test-mock/src/android/test/mock/MockPackageManager.java @@ -1209,4 +1209,11 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** + * @hide + */ + @Override + public String getSystemTextClassifierPackageName() { + throw new UnsupportedOperationException(); + } } |