Loading services/core/java/com/android/server/policy/AppOpsPolicy.java +2 −3 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +26 −10 Original line number Diff line number Diff line Loading @@ -125,16 +125,27 @@ 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. // TODO(b/212458940): Find a better approach for checking the permission that doesn't // require the client to know such details about the permissions logic. 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); } Loading Loading @@ -163,20 +174,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 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: 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, Loading services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +6 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -933,11 +930,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); }); Loading Loading
services/core/java/com/android/server/policy/AppOpsPolicy.java +2 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +26 −10 Original line number Diff line number Diff line Loading @@ -125,16 +125,27 @@ 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. // TODO(b/212458940): Find a better approach for checking the permission that doesn't // require the client to know such details about the permissions logic. 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); } Loading Loading @@ -163,20 +174,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 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: 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, Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +6 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -933,11 +930,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); }); Loading