From 449490c4a7b64801097c3a1121c11785138204aa Mon Sep 17 00:00:00 2001 From: MingWei Date: Wed, 7 Feb 2024 17:30:13 +0000 Subject: Restrict RecognitionService process capabilities Only provides certain privileged recognition service the privilege process capabilities from system server. For recognition service provided by client apps, it needs to stay in foreground in order to keep the while-in-use permission. Test: Cts Bug: 307947153 Change-Id: Idd702017c4a4f7cc63b591660b599eccfa61b956 --- .../speech/RemoteSpeechRecognitionService.java | 18 ++++-- .../SpeechRecognitionManagerServiceImpl.java | 64 +++++++++++++++++++++- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java index bb5a697114d3..7ddb61e5ca52 100644 --- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java +++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java @@ -68,12 +68,14 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl valuesByCaller = mRemoteServicesByUid.computeIfAbsent(callingUid, key -> new HashSet<>()); @@ -328,6 +343,53 @@ final class SpeechRecognitionManagerServiceImpl extends } } + /** + * Checks if the given service component should have privileged binding flags when created. Only + * a service component that matches with any of the following condition would be granted: + * + * + */ + @GuardedBy("mLock") + private boolean checkPrivilege(@NonNull ComponentName serviceComponent) { + final ComponentName defaultComponent = getDefaultRecognitionServiceComponent(); + final ComponentName onDeviceComponent = getOnDeviceComponentNameLocked(); + final boolean preinstalled = isPreinstalledApp(serviceComponent); + return serviceComponent.equals(defaultComponent) + || serviceComponent.equals(onDeviceComponent) + || preinstalled; + } + + private boolean isPreinstalledApp(@NonNull ComponentName serviceComponent) { + PackageManager pm = getContext().getPackageManager(); + if (pm == null) { + return false; + } + + try { + ApplicationInfo info = pm.getApplicationInfoAsUser(serviceComponent.getPackageName(), + PackageManager.MATCH_SYSTEM_ONLY, getUserId()); + return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + @Nullable + private ComponentName getDefaultRecognitionServiceComponent() { + String componentName = Settings.Secure.getStringForUser( + getContext().getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE, + getUserId()); + if (componentName == null) { + return null; + } + return ComponentName.unflattenFromString(componentName); + } + private boolean componentMapsToRecognitionService(@NonNull ComponentName serviceComponent) { List resolveInfos; -- cgit v1.2.3-59-g8ed1b