AOHD.EventPayload.getHalEventTimestampMillis API

AlwaysOnHotwordDetector.EventPayload API for exposing the timestamp
which represents the time the SoundTrigger HAL emitted a
RecognitionEvent

Test: atest CtsVoiceInteractionHostTestCases
Bug: 265852186
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:51d3a40d4bee1fa4f8f44ec4e59380911ffa0684)
Merged-In: I0f8d37e19002910bbfbf3bfd77cdecbf7c588e81
Change-Id: I0f8d37e19002910bbfbf3bfd77cdecbf7c588e81
This commit is contained in:
Nicholas Ambur
2023-02-14 09:27:33 +00:00
committed by Cherrypicker Worker
parent aa23a487f5
commit 3467c24496
3 changed files with 46 additions and 5 deletions

View File

@@ -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();

View File

@@ -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>);
}

View File

@@ -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;
}
/**
@@ -545,6 +552,21 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
return mKephraseExtras;
}
/**
* 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
*
@@ -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() {}
@@ -681,6 +705,20 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
return this;
}
/**
* 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
*/
@@ -688,7 +726,7 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
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) {