diff options
| -rw-r--r-- | core/api/system-current.txt | 1 | ||||
| -rw-r--r-- | core/api/test-current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/service/voice/AlwaysOnHotwordDetector.java | 47 |
3 files changed, 46 insertions, 5 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 5a8ee9456f87..99688c78d7ec 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13042,6 +13042,7 @@ package android.service.voice { method @Nullable public android.media.AudioFormat getCaptureAudioFormat(); method @Nullable public byte[] getData(); method public int getDataFormat(); + method public long getHalEventReceivedMillis(); method @Nullable public android.service.voice.HotwordDetectedResult getHotwordDetectedResult(); method @NonNull public java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra> getKeyphraseRecognitionExtras(); method @Deprecated @Nullable public byte[] getTriggerAudio(); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 5a84b9782ee6..ceb883b0340c 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2875,7 +2875,7 @@ package android.service.voice { public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector { method public void overrideAvailability(int); method public void resetAvailability(); - method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], @NonNull java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>); + method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int, int, long, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], @NonNull java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>); } public static final class AlwaysOnHotwordDetector.EventPayload.Builder { @@ -2887,6 +2887,7 @@ package android.service.voice { method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setCaptureSession(int); method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setData(@NonNull byte[]); method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setDataFormat(int); + method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setHalEventReceivedMillis(long); method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setHotwordDetectedResult(@NonNull android.service.voice.HotwordDetectedResult); method @NonNull public android.service.voice.AlwaysOnHotwordDetector.EventPayload.Builder setKeyphraseRecognitionExtras(@NonNull java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>); } diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index ffa15f065a02..65f32e2cf442 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; import static android.Manifest.permission.RECORD_AUDIO; import static android.service.voice.VoiceInteractionService.MULTIPLE_ACTIVE_HOTWORD_DETECTORS; +import android.annotation.ElapsedRealtimeLong; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -54,6 +55,7 @@ import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; +import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -401,6 +403,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { private final ParcelFileDescriptor mAudioStream; private final List<KeyphraseRecognitionExtra> mKephraseExtras; + @ElapsedRealtimeLong + private final long mHalEventReceivedMillis; + private EventPayload(boolean captureAvailable, @Nullable AudioFormat audioFormat, int captureSession, @@ -408,7 +413,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { @Nullable byte[] data, @Nullable HotwordDetectedResult hotwordDetectedResult, @Nullable ParcelFileDescriptor audioStream, - @NonNull List<KeyphraseRecognitionExtra> keyphraseExtras) { + @NonNull List<KeyphraseRecognitionExtra> keyphraseExtras, + @ElapsedRealtimeLong long halEventReceivedMillis) { mCaptureAvailable = captureAvailable; mCaptureSession = captureSession; mAudioFormat = audioFormat; @@ -417,6 +423,7 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { mHotwordDetectedResult = hotwordDetectedResult; mAudioStream = audioStream; mKephraseExtras = keyphraseExtras; + mHalEventReceivedMillis = halEventReceivedMillis; } /** @@ -546,6 +553,21 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { } /** + * Timestamp of when the trigger event from SoundTriggerHal was received by the system + * server. + * + * Clock monotonic including suspend time or its equivalent on the system, + * in the same units and timebase as {@link SystemClock#elapsedRealtime()}. + * + * @return Elapsed realtime in milliseconds when the event was received from the HAL. + * Returns -1 if the event was not generated from the HAL. + */ + @ElapsedRealtimeLong + public long getHalEventReceivedMillis() { + return mHalEventReceivedMillis; + } + + /** * Builder class for {@link EventPayload} objects * * @hide @@ -561,6 +583,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { private HotwordDetectedResult mHotwordDetectedResult = null; private ParcelFileDescriptor mAudioStream = null; private List<KeyphraseRecognitionExtra> mKeyphraseExtras = Collections.emptyList(); + @ElapsedRealtimeLong + private long mHalEventReceivedMillis = -1; public Builder() {} @@ -682,13 +706,27 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { } /** + * Timestamp of when the trigger event from SoundTriggerHal was received by the + * framework. + * + * Clock monotonic including suspend time or its equivalent on the system, + * in the same units and timebase as {@link SystemClock#elapsedRealtime()}. + */ + @NonNull + public Builder setHalEventReceivedMillis( + @ElapsedRealtimeLong long halEventReceivedMillis) { + mHalEventReceivedMillis = halEventReceivedMillis; + return this; + } + + /** * Builds an {@link EventPayload} instance */ @NonNull public EventPayload build() { return new EventPayload(mCaptureAvailable, mAudioFormat, mCaptureSession, mDataFormat, mData, mHotwordDetectedResult, mAudioStream, - mKeyphraseExtras); + mKeyphraseExtras, mHalEventReceivedMillis); } } } @@ -897,8 +935,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { @TestApi @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int status, int soundModelHandle, - boolean captureAvailable, int captureSession, int captureDelayMs, int capturePreambleMs, - boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data, + @ElapsedRealtimeLong long halEventReceivedMillis, boolean captureAvailable, + int captureSession, int captureDelayMs, int capturePreambleMs, boolean triggerInData, + @NonNull AudioFormat captureFormat, @Nullable byte[] data, @NonNull List<KeyphraseRecognitionExtra> keyphraseRecognitionExtras) { Log.d(TAG, "triggerHardwareRecognitionEventForTest()"); synchronized (mLock) { |