Loading services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java +11 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.voiceinteraction; import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; import static android.Manifest.permission.LOG_COMPAT_CHANGE; import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG; import static android.Manifest.permission.RECORD_AUDIO; import static android.service.attention.AttentionService.PROXIMITY_UNKNOWN; import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_EXTERNAL; Loading @@ -43,11 +45,14 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENT import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_SECURITY_EXCEPTION; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_UNEXPECTED_CALLBACK; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK; import static com.android.server.voiceinteraction.HotwordDetectionConnection.ENFORCE_HOTWORD_PHRASE_ID; import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.attention.AttentionManagerInternal; import android.content.Context; import android.content.PermissionChecker; Loading Loading @@ -692,8 +697,13 @@ abstract class DetectorSession { } } static void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result, @RequiresPermission(allOf = {READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE}) void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result, SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) { if (!CompatChanges.isChangeEnabled(ENFORCE_HOTWORD_PHRASE_ID, mVoiceInteractionServiceUid)) { return; } // verify the phrase ID in HotwordDetectedResult is not exposing extra phrases // the DSP did not detect for (SoundTrigger.KeyphraseRecognitionExtra keyphrase : recognitionEvent.keyphraseExtras) { Loading services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +24 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.ComponentName; import android.content.ContentCaptureOptions; import android.content.Context; Loading @@ -39,6 +41,7 @@ import android.media.AudioFormat; import android.media.AudioManagerInternal; import android.media.permission.Identity; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.IRemoteCallback; Loading @@ -48,6 +51,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SharedMemory; import android.provider.DeviceConfig; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetector; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; Loading Loading @@ -83,6 +87,26 @@ final class HotwordDetectionConnection { private static final String TAG = "HotwordDetectionConnection"; static final boolean DEBUG = false; /** * For apps targeting Android API {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, * implementors of the {@link HotwordDetectionService} must not augment the phrase IDs which are * supplied via {@link HotwordDetectionService * #onDetect(AlwaysOnHotwordDetector.EventPayload, long, HotwordDetectionService.Callback)}. * * <p>The {@link HotwordDetectedResult#getHotwordPhraseId()} must match one of the phrase IDs * from the {@link android.service.voice.AlwaysOnHotwordDetector * .EventPayload#getKeyphraseRecognitionExtras()} list. * </p> * * <p>This behavior change is made to ensure the {@link HotwordDetectionService} honors what * it receives from the {@link android.hardware.soundtrigger.SoundTriggerModule}, and it * cannot signal to the client application a phrase which was not origially detected. * </p> */ @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final long ENFORCE_HOTWORD_PHRASE_ID = 215066299L; private static final String KEY_RESTART_PERIOD_IN_SECONDS = "restart_period_in_seconds"; private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; Loading Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java +11 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.voiceinteraction; import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; import static android.Manifest.permission.LOG_COMPAT_CHANGE; import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG; import static android.Manifest.permission.RECORD_AUDIO; import static android.service.attention.AttentionService.PROXIMITY_UNKNOWN; import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_EXTERNAL; Loading @@ -43,11 +45,14 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENT import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_SECURITY_EXCEPTION; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_UNEXPECTED_CALLBACK; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK; import static com.android.server.voiceinteraction.HotwordDetectionConnection.ENFORCE_HOTWORD_PHRASE_ID; import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.attention.AttentionManagerInternal; import android.content.Context; import android.content.PermissionChecker; Loading Loading @@ -692,8 +697,13 @@ abstract class DetectorSession { } } static void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result, @RequiresPermission(allOf = {READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE}) void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result, SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) { if (!CompatChanges.isChangeEnabled(ENFORCE_HOTWORD_PHRASE_ID, mVoiceInteractionServiceUid)) { return; } // verify the phrase ID in HotwordDetectedResult is not exposing extra phrases // the DSP did not detect for (SoundTrigger.KeyphraseRecognitionExtra keyphrase : recognitionEvent.keyphraseExtras) { Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +24 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.ComponentName; import android.content.ContentCaptureOptions; import android.content.Context; Loading @@ -39,6 +41,7 @@ import android.media.AudioFormat; import android.media.AudioManagerInternal; import android.media.permission.Identity; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.IRemoteCallback; Loading @@ -48,6 +51,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SharedMemory; import android.provider.DeviceConfig; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetector; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; Loading Loading @@ -83,6 +87,26 @@ final class HotwordDetectionConnection { private static final String TAG = "HotwordDetectionConnection"; static final boolean DEBUG = false; /** * For apps targeting Android API {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, * implementors of the {@link HotwordDetectionService} must not augment the phrase IDs which are * supplied via {@link HotwordDetectionService * #onDetect(AlwaysOnHotwordDetector.EventPayload, long, HotwordDetectionService.Callback)}. * * <p>The {@link HotwordDetectedResult#getHotwordPhraseId()} must match one of the phrase IDs * from the {@link android.service.voice.AlwaysOnHotwordDetector * .EventPayload#getKeyphraseRecognitionExtras()} list. * </p> * * <p>This behavior change is made to ensure the {@link HotwordDetectionService} honors what * it receives from the {@link android.hardware.soundtrigger.SoundTriggerModule}, and it * cannot signal to the client application a phrase which was not origially detected. * </p> */ @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final long ENFORCE_HOTWORD_PHRASE_ID = 215066299L; private static final String KEY_RESTART_PERIOD_IN_SECONDS = "restart_period_in_seconds"; private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; Loading