From a3f9ee62e5b6991310519e0d2a58cbd6f57a2053 Mon Sep 17 00:00:00 2001 From: Sergey Volnov Date: Mon, 22 Mar 2021 19:51:58 +0000 Subject: [PATCH] Enhance AlwaysOnHotwordDetector.EventPayload with more fields. This will eventually support a more flexible information handling: passing HotwordDetectedResult and audio stream directly from the server. Bug: 182788844 Bug: 168305377 CTS-Coverage-Bug: 183425641 Test: N/A committing data class, will test e2e Change-Id: Ie97723c113bced3046a1d2a652a95f94399399be --- core/api/system-current.txt | 2 + .../voice/AlwaysOnHotwordDetector.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index d54526d1c52b2..45119030442df 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10368,7 +10368,9 @@ package android.service.voice { } public static class AlwaysOnHotwordDetector.EventPayload { + method @Nullable public android.os.ParcelFileDescriptor getAudioStream(); method @Nullable public android.media.AudioFormat getCaptureAudioFormat(); + method @Nullable public android.service.voice.HotwordDetectedResult getHotwordDetectedResult(); method @Nullable public byte[] getTriggerAudio(); } diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 1ea40bea8e576..fc22b3233b80d 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -44,6 +44,7 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; @@ -342,14 +343,35 @@ public class AlwaysOnHotwordDetector { // Raw data associated with the event. // This is the audio that triggered the keyphrase if {@code isTriggerAudio} is true. private final byte[] mData; + private final HotwordDetectedResult mHotwordDetectedResult; + private final ParcelFileDescriptor mAudioStream; private EventPayload(boolean triggerAvailable, boolean captureAvailable, AudioFormat audioFormat, int captureSession, byte[] data) { + this(triggerAvailable, captureAvailable, audioFormat, captureSession, data, null, + null); + } + + EventPayload(AudioFormat audioFormat, HotwordDetectedResult hotwordDetectedResult) { + this(false, false, audioFormat, -1, null, hotwordDetectedResult, null); + } + + EventPayload(AudioFormat audioFormat, + HotwordDetectedResult hotwordDetectedResult, + ParcelFileDescriptor audioStream) { + this(false, false, audioFormat, -1, null, hotwordDetectedResult, audioStream); + } + + private EventPayload(boolean triggerAvailable, boolean captureAvailable, + AudioFormat audioFormat, int captureSession, byte[] data, + HotwordDetectedResult hotwordDetectedResult, ParcelFileDescriptor audioStream) { mTriggerAvailable = triggerAvailable; mCaptureAvailable = captureAvailable; mCaptureSession = captureSession; mAudioFormat = audioFormat; mData = data; + mHotwordDetectedResult = hotwordDetectedResult; + mAudioStream = audioStream; } /** @@ -405,6 +427,33 @@ public class AlwaysOnHotwordDetector { return null; } } + + /** + * Returns {@link HotwordDetectedResult} associated with the hotword event, passed from + * {@link HotwordDetectionService}. + */ + @Nullable + public HotwordDetectedResult getHotwordDetectedResult() { + return mHotwordDetectedResult; + } + + /** + * Returns a stream with bytes corresponding to the open audio stream with hotword data. + * + *

This data represents an audio stream in the format returned by + * {@link #getCaptureAudioFormat}. + * + *

Clients are expected to start consuming the stream within 1 second of receiving the + * event. + * + *

When this method returns a non-null, clients must close this stream when it's no + * longer needed. Failing to do so will result in microphone being open for longer periods + * of time, and app being attributed for microphone usage. + */ + @Nullable + public ParcelFileDescriptor getAudioStream() { + return mAudioStream; + } } /**