diff options
3 files changed, 32 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index 18c45e494c9b..8b4690629ec5 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -196,9 +196,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat } 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)); + // Usage of the HotwordDetectionService won't be enforced until a later release. + return false; } @Override diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java index 9999aff3aa91..2b03fe88a1ec 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java @@ -125,16 +125,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware * originator temporarily doesn't have the right permissions to use this service. */ private void enforcePermissionsForPreflight(@NonNull Identity identity) { - enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO); - enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD); + enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, + /* allowSoftDenial= */ true); + enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD, + /* allowSoftDenial= */ true); } /** * Throws a {@link SecurityException} iff the originator has permission to receive data. */ void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) { - enforcePermissionForDataDelivery(mContext, identity, RECORD_AUDIO, - reason); + // SoundTrigger data is treated the same as Hotword-source audio. This should incur the + // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required, + // and since this is a data delivery check, soft denials aren't accepted. + enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, + /* allowSoftDenial= */ false); + int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); + mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid, + identity.packageName, identity.attributionTag, reason); + enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, reason); } @@ -163,20 +172,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware /** * Throws a {@link SecurityException} if originator permanently doesn't have the given * permission. - * Soft (temporary) denials are considered OK for preflight purposes. * - * @param context A {@link Context}, used for permission checks. - * @param identity The identity to check. - * @param permission The identifier of the permission we want to check. + * @param context A {@link Context}, used for permission checks. + * @param identity The identity to check. + * @param permission The identifier of the permission we want to check. + * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials. */ + // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it + // clearer when soft denials are not allowed. private static void enforcePermissionForPreflight(@NonNull Context context, - @NonNull Identity identity, @NonNull String permission) { + @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) { final int status = PermissionUtil.checkPermissionForPreflight(context, identity, permission); switch (status) { case PermissionChecker.PERMISSION_GRANTED: - case PermissionChecker.PERMISSION_SOFT_DENIED: return; + case PermissionChecker.PERMISSION_SOFT_DENIED: + if (allowSoftDenial) { + return; + } // else fall through case PermissionChecker.PERMISSION_HARD_DENIED: throw new SecurityException( String.format("Failed to obtain permission %s for identity %s", permission, diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 734172fc1549..a9aeb985d115 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -23,11 +23,8 @@ import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPH import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN; import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS; -import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.AppOpsManager; import android.content.ComponentName; import android.content.ContentCaptureOptions; import android.content.Context; @@ -935,11 +932,12 @@ final class HotwordDetectionConnection { // TODO: Share this code with SoundTriggerMiddlewarePermission. private void enforcePermissionsForDataDelivery() { Binder.withCleanCallingIdentity(() -> { - enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO); - int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); - mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, - mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName, - mVoiceInteractorIdentity.attributionTag, OP_MESSAGE); + // Hack to make sure we show the mic privacy-indicator since the Trusted Hotword + // requirement isn't being enforced for now. Normally, we would note the HOTWORD op here + // instead. + enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity, + RECORD_AUDIO, OP_MESSAGE); + enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity, CAPTURE_AUDIO_HOTWORD, OP_MESSAGE); }); |