summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/policy/AppOpsPolicy.java33
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