diff options
| -rw-r--r-- | services/core/java/com/android/server/policy/AppOpsPolicy.java | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index a389f40e772b..7689f5f5fd65 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -81,6 +81,12 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat private final VoiceInteractionManagerInternal mVoiceInteractionManagerInternal; /** + * Whether this device allows only the HotwordDetectionService to use OP_RECORD_AUDIO_HOTWORD + * which doesn't incur the privacy indicator. + */ + private final boolean mIsHotwordDetectionServiceRequired; + + /** * The locking policy around the location tags is a bit special. Since we want to * avoid grabbing the lock on every op note we are taking the approach where the * read and write are being done via a thread-safe data structure such that the @@ -114,6 +120,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat mRoleManager = mContext.getSystemService(RoleManager.class); mVoiceInteractionManagerInternal = LocalServices.getService( VoiceInteractionManagerInternal.class); + mIsHotwordDetectionServiceRequired = isHotwordDetectionServiceRequired( + mContext.getPackageManager()); final LocationManagerInternal locationManagerInternal = LocalServices.getService( LocationManagerInternal.class); @@ -174,6 +182,12 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat initializeActivityRecognizersTags(); } + private static boolean isHotwordDetectionServiceRequired(PackageManager pm) { + // The HotwordDetectionService APIs aren't ready yet for Auto or TV. + return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)); + } + @Override public int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag, boolean raw, @@ -257,6 +271,7 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat private int resolveDatasourceOp(int code, int uid, @NonNull String packageName, @Nullable String attributionTag) { + code = resolveRecordAudioOp(code, uid); if (attributionTag == null) { return code; } @@ -359,6 +374,24 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat return code; } + private int resolveRecordAudioOp(int code, int uid) { + if (code == AppOpsManager.OP_RECORD_AUDIO_HOTWORD) { + if (!mIsHotwordDetectionServiceRequired) { + return code; + } + // Only the HotwordDetectionService can use the HOTWORD op which doesn't incur the + // privacy indicator. Downgrade to standard RECORD_AUDIO for other processes. + final HotwordDetectionServiceIdentity hotwordDetectionServiceIdentity = + mVoiceInteractionManagerInternal.getHotwordDetectionServiceIdentity(); + if (hotwordDetectionServiceIdentity != null + && uid == hotwordDetectionServiceIdentity.getIsolatedUid()) { + return code; + } + return AppOpsManager.OP_RECORD_AUDIO; + } + return code; + } + private int resolveUid(int code, int uid) { // The HotwordDetectionService is an isolated service, which ordinarily cannot hold // permissions. So we allow it to assume the owning package identity for certain |