Merge "add audioCapabilities to SoundTrigger properties"

This commit is contained in:
Nicholas Ambur
2020-01-11 16:39:55 +00:00
committed by Android (Google) Code Review
15 changed files with 476 additions and 99 deletions

View File

@@ -42770,14 +42770,19 @@ package android.service.voice {
method public android.content.Intent createReEnrollIntent();
method public android.content.Intent createUnEnrollIntent();
method public int getParameter(int);
method public int getSupportedAudioCapabilities();
method public int getSupportedRecognitionModes();
method @Nullable public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
method public int setParameter(int, int);
method public boolean startRecognition(int);
method public boolean stopRecognition();
field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 4; // 0x4
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 8; // 0x8
field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
field public static final int STATE_HARDWARE_UNAVAILABLE = -2; // 0xfffffffe

View File

@@ -3567,7 +3567,10 @@ package android.hardware.soundtrigger {
public static final class SoundTrigger.ModuleProperties implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
field public static final int CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> CREATOR;
field public final int audioCapabilities;
field @NonNull public final String description;
field public final int id;
field @NonNull public final String implementor;
@@ -4363,6 +4366,8 @@ package android.media.soundtrigger {
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public boolean stopRecognition();
field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 4; // 0x4
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 8; // 0x8
}
public abstract static class SoundTriggerDetector.Callback {

View File

@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.hardware.soundtrigger.ModelParams;
import android.media.AudioFormat;
import android.media.audio.common.AudioConfig;
import android.media.soundtrigger_middleware.AudioCapabilities;
import android.media.soundtrigger_middleware.ConfidenceLevel;
import android.media.soundtrigger_middleware.ModelParameterRange;
import android.media.soundtrigger_middleware.Phrase;
@@ -56,7 +57,8 @@ class ConversionUtil {
properties.maxBufferMs,
properties.concurrentCapture,
properties.powerConsumptionMw,
properties.triggerInEvent
properties.triggerInEvent,
aidl2apiAudioCapabilities(properties.audioCapabilities)
);
}
@@ -145,6 +147,7 @@ class ConversionUtil {
apiConfig.keyphrases[i]);
}
aidlConfig.data = Arrays.copyOf(apiConfig.data, apiConfig.data.length);
aidlConfig.audioCapabilities = api2aidlAudioCapabilities(apiConfig.audioCapabilities);
return aidlConfig;
}
@@ -326,4 +329,26 @@ class ConversionUtil {
}
return new SoundTrigger.ModelParamRange(aidlRange.minInclusive, aidlRange.maxInclusive);
}
public static int aidl2apiAudioCapabilities(int aidlCapabilities) {
int result = 0;
if ((aidlCapabilities & AudioCapabilities.ECHO_CANCELLATION) != 0) {
result |= SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION;
}
if ((aidlCapabilities & AudioCapabilities.NOISE_SUPPRESSION) != 0) {
result |= SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION;
}
return result;
}
public static int api2aidlAudioCapabilities(int apiCapabilities) {
int result = 0;
if ((apiCapabilities & SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION) != 0) {
result |= AudioCapabilities.ECHO_CANCELLATION;
}
if ((apiCapabilities & SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION) != 0) {
result |= AudioCapabilities.NOISE_SUPPRESSION;
}
return result;
}
}

View File

@@ -24,6 +24,7 @@ import static android.system.OsConstants.EPIPE;
import static java.util.Objects.requireNonNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -42,6 +43,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
@@ -83,6 +86,30 @@ public class SoundTrigger {
*
****************************************************************************/
public static final class ModuleProperties implements Parcelable {
/**
* Bit field values of AudioCapabilities supported by the implemented HAL
* driver.
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "AUDIO_CAPABILITY_" }, value = {
CAPABILITY_ECHO_CANCELLATION,
CAPABILITY_NOISE_SUPPRESSION
})
public @interface AudioCapabilities {}
/**
* If set the underlying module supports AEC.
* Describes bit field {@link ModuleProperties#audioCapabilities}
*/
public static final int CAPABILITY_ECHO_CANCELLATION = 0x1;
/**
* If set, the underlying module supports noise suppression.
* Describes bit field {@link ModuleProperties#audioCapabilities}
*/
public static final int CAPABILITY_NOISE_SUPPRESSION = 0x2;
/** Unique module ID provided by the native service */
public final int id;
@@ -137,12 +164,19 @@ public class SoundTrigger {
* recognition callback event */
public final boolean returnsTriggerInEvent;
/**
* Bit field encoding of the AudioCapabilities
* supported by the firmware.
*/
@AudioCapabilities
public final int audioCapabilities;
ModuleProperties(int id, @NonNull String implementor, @NonNull String description,
@NonNull String uuid, int version, @NonNull String supportedModelArch,
int maxSoundModels, int maxKeyphrases, int maxUsers, int recognitionModes,
boolean supportsCaptureTransition, int maxBufferMs,
boolean supportsConcurrentCapture, int powerConsumptionMw,
boolean returnsTriggerInEvent) {
boolean returnsTriggerInEvent, int audioCapabilities) {
this.id = id;
this.implementor = requireNonNull(implementor);
this.description = requireNonNull(description);
@@ -158,6 +192,7 @@ public class SoundTrigger {
this.supportsConcurrentCapture = supportsConcurrentCapture;
this.powerConsumptionMw = powerConsumptionMw;
this.returnsTriggerInEvent = returnsTriggerInEvent;
this.audioCapabilities = audioCapabilities;
}
public static final @android.annotation.NonNull Parcelable.Creator<ModuleProperties> CREATOR
@@ -187,10 +222,11 @@ public class SoundTrigger {
boolean supportsConcurrentCapture = in.readByte() == 1;
int powerConsumptionMw = in.readInt();
boolean returnsTriggerInEvent = in.readByte() == 1;
int audioCapabilities = in.readInt();
return new ModuleProperties(id, implementor, description, uuid, version,
supportedModelArch, maxSoundModels, maxKeyphrases, maxUsers, recognitionModes,
supportsCaptureTransition, maxBufferMs, supportsConcurrentCapture,
powerConsumptionMw, returnsTriggerInEvent);
powerConsumptionMw, returnsTriggerInEvent, audioCapabilities);
}
@Override
@@ -210,6 +246,7 @@ public class SoundTrigger {
dest.writeByte((byte) (supportsConcurrentCapture ? 1 : 0));
dest.writeInt(powerConsumptionMw);
dest.writeByte((byte) (returnsTriggerInEvent ? 1 : 0));
dest.writeInt(audioCapabilities);
}
@Override
@@ -227,7 +264,8 @@ public class SoundTrigger {
+ ", supportsCaptureTransition=" + supportsCaptureTransition + ", maxBufferMs="
+ maxBufferMs + ", supportsConcurrentCapture=" + supportsConcurrentCapture
+ ", powerConsumptionMw=" + powerConsumptionMw
+ ", returnsTriggerInEvent=" + returnsTriggerInEvent + "]";
+ ", returnsTriggerInEvent=" + returnsTriggerInEvent
+ ", audioCapabilities=" + audioCapabilities + "]";
}
}
@@ -1049,13 +1087,27 @@ public class SoundTrigger {
@NonNull
public final byte[] data;
@UnsupportedAppUsage
/**
* Bit field encoding of the AudioCapabilities
* supported by the firmware.
*/
@ModuleProperties.AudioCapabilities
public final int audioCapabilities;
public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data) {
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data,
int audioCapabilities) {
this.captureRequested = captureRequested;
this.allowMultipleTriggers = allowMultipleTriggers;
this.keyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
this.data = data != null ? data : new byte[0];
this.audioCapabilities = audioCapabilities;
}
@UnsupportedAppUsage
public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data) {
this(captureRequested, allowMultipleTriggers, keyphrases, data, 0);
}
public static final @android.annotation.NonNull Parcelable.Creator<RecognitionConfig> CREATOR
@@ -1075,7 +1127,9 @@ public class SoundTrigger {
KeyphraseRecognitionExtra[] keyphrases =
in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
byte[] data = in.readBlob();
return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data);
int audioCapabilities = in.readInt();
return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data,
audioCapabilities);
}
@Override
@@ -1084,6 +1138,7 @@ public class SoundTrigger {
dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
dest.writeTypedArray(keyphrases, flags);
dest.writeBlob(data);
dest.writeInt(audioCapabilities);
}
@Override
@@ -1095,7 +1150,8 @@ public class SoundTrigger {
public String toString() {
return "RecognitionConfig [captureRequested=" + captureRequested
+ ", allowMultipleTriggers=" + allowMultipleTriggers + ", keyphrases="
+ Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data) + "]";
+ Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data)
+ ", audioCapabilities=" + Integer.toHexString(audioCapabilities) + "]";
}
}

View File

@@ -119,7 +119,9 @@ public class AlwaysOnHotwordDetector {
@IntDef(flag = true, prefix = { "RECOGNITION_FLAG_" }, value = {
RECOGNITION_FLAG_NONE,
RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
})
public @interface RecognitionFlags {}
@@ -144,6 +146,26 @@ public class AlwaysOnHotwordDetector {
*/
public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
/**
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
* if the underlying recognition should use AEC.
* This capability may or may not be supported by the system, and support can be queried
* by calling {@link #getSupportedAudioCapabilities()}. The corresponding capabilities field for
* this flag is {@link #AUDIO_CAPABILITY_ECHO_CANCELLATION}. If this flag is passed without the
* audio capability supported, there will be no audio effect applied.
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 0x4;
/**
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
* if the underlying recognition should use noise suppression.
* This capability may or may not be supported by the system, and support can be queried
* by calling {@link #getSupportedAudioCapabilities()}. The corresponding capabilities field for
* this flag is {@link #AUDIO_CAPABILITY_NOISE_SUPPRESSION}. If this flag is passed without the
* audio capability supported, there will be no audio effect applied.
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
//---- Recognition mode flags. Return codes for getSupportedRecognitionModes() ----//
// Must be kept in sync with the related attribute defined as searchKeyphraseRecognitionFlags.
@@ -168,6 +190,30 @@ public class AlwaysOnHotwordDetector {
public static final int RECOGNITION_MODE_USER_IDENTIFICATION
= SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
//-- Audio capabilities. Values in returned bit field for getSupportedAudioCapabilities() --//
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "AUDIO_CAPABILITY_" }, value = {
AUDIO_CAPABILITY_ECHO_CANCELLATION,
AUDIO_CAPABILITY_NOISE_SUPPRESSION,
})
public @interface AudioCapabilities {}
/**
* If set the underlying module supports AEC.
* Returned by {@link #getSupportedAudioCapabilities()}
*/
public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION =
SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION;
/**
* If set, the underlying module supports noise suppression.
* Returned by {@link #getSupportedAudioCapabilities()}
*/
public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION =
SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "MODEL_PARAM_" }, value = {
@@ -447,6 +493,37 @@ public class AlwaysOnHotwordDetector {
return mKeyphraseMetadata.recognitionModeFlags;
}
/**
* Get the audio capabilities supported by the platform which can be enabled when
* starting a recognition.
*
* @see #AUDIO_CAPABILITY_ECHO_CANCELLATION
* @see #AUDIO_CAPABILITY_NOISE_SUPPRESSION
*
* @return Bit field encoding of the AudioCapabilities supported.
*/
@AudioCapabilities
public int getSupportedAudioCapabilities() {
if (DBG) Slog.d(TAG, "getSupportedAudioCapabilities()");
synchronized (mLock) {
return getSupportedAudioCapabilitiesLocked();
}
}
private int getSupportedAudioCapabilitiesLocked() {
try {
ModuleProperties properties =
mModelManagementService.getDspModuleProperties(mVoiceInteractionService);
if (properties != null) {
return properties.audioCapabilities;
}
return 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Starts recognition for the associated keyphrase.
*
@@ -711,12 +788,21 @@ public class AlwaysOnHotwordDetector {
(recognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
boolean allowMultipleTriggers =
(recognitionFlags&RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
int audioCapabilities = 0;
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
audioCapabilities |= AUDIO_CAPABILITY_ECHO_CANCELLATION;
}
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION) != 0) {
audioCapabilities |= AUDIO_CAPABILITY_NOISE_SUPPRESSION;
}
int code = STATUS_ERROR;
try {
code = mModelManagementService.startRecognition(mVoiceInteractionService,
mKeyphraseMetadata.id, mLocale.toLanguageTag(), mInternalCallback,
new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
recognitionExtra, null /* additional data */));
recognitionExtra, null /* additional data */, audioCapabilities));
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in startRecognition!", e);
}

View File

@@ -25,6 +25,7 @@ import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.media.AudioFormat;
import android.os.Handler;
@@ -75,7 +76,9 @@ public final class SoundTriggerDetector {
value = {
RECOGNITION_FLAG_NONE,
RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
})
public @interface RecognitionFlags {}
@@ -100,10 +103,33 @@ public final class SoundTriggerDetector {
* triggers after a call to {@link #startRecognition(int)}, if the model
* triggers multiple times.
* When this isn't specified, the default behavior is to stop recognition once the
* trigger happenss, till the caller starts recognition again.
* trigger happens, till the caller starts recognition again.
*/
public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
/**
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
* if the underlying recognition should use AEC.
* This capability may or may not be supported by the system, and support can be queried
* by calling {@link SoundTriggerManager#getModuleProperties()} and checking
* {@link ModuleProperties#audioCapabilities}. The corresponding capabilities field for
* this flag is {@link SoundTrigger.ModuleProperties#CAPABILITY_ECHO_CANCELLATION}.
* If this flag is passed without the audio capability supported, there will be no audio effect
* applied.
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 0x4;
/**
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
* if the underlying recognition should use noise suppression.
* This capability may or may not be supported by the system, and support can be queried
* by calling {@link SoundTriggerManager#getModuleProperties()} and checking
* {@link ModuleProperties#audioCapabilities}. The corresponding capabilities field for
* this flag is {@link SoundTrigger.ModuleProperties#CAPABILITY_NOISE_SUPPRESSION}. If this flag
* is passed without the audio capability supported, there will be no audio effect applied.
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
/**
* Additional payload for {@link Callback#onDetected}.
*/
@@ -267,11 +293,20 @@ public final class SoundTriggerDetector {
boolean allowMultipleTriggers =
(recognitionFlags & RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
int status = STATUS_OK;
int audioCapabilities = 0;
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
audioCapabilities |= SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION;
}
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION) != 0) {
audioCapabilities |= SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION;
}
int status;
try {
status = mSoundTriggerService.startRecognition(new ParcelUuid(mSoundModelId),
mRecognitionCallback, new RecognitionConfig(captureTriggerAudio,
allowMultipleTriggers, null, null));
allowMultipleTriggers, null, null, audioCapabilities));
} catch (RemoteException e) {
return false;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media.soundtrigger_middleware;
/**
* AudioCapabilities supported by the implemented HAL driver.
* @hide
*/
@Backing(type="int")
enum AudioCapabilities {
/**
* If set the underlying module supports AEC.
*/
ECHO_CANCELLATION = 1 << 0,
/**
* If set, the underlying module supports noise suppression.
*/
NOISE_SUPPRESSION = 1 << 1,
}

View File

@@ -28,6 +28,12 @@ parcelable RecognitionConfig {
/* Configuration for each key phrase. */
PhraseRecognitionExtra[] phraseRecognitionExtras;
/**
* Bit field encoding of the AudioCapabilities
* supported by the firmware.
*/
int audioCapabilities;
/** Opaque capture configuration data. */
byte[] data;
}

View File

@@ -58,4 +58,11 @@ parcelable SoundTriggerModuleProperties {
* Rated power consumption when detection is active with TDB
* silence/sound/speech ratio */
int powerConsumptionMw;
/**
* Bit field encoding of the AudioCapabilities
* supported by the firmware.
* This property is supported for soundtrigger HAL v2.3 and above.
* If running a previous version, this value will be 0.
*/
int audioCapabilities;
}

View File

@@ -24,6 +24,7 @@ import android.hardware.soundtrigger.V2_3.ISoundTriggerHw;
import android.hardware.soundtrigger.V2_3.Properties;
import android.media.audio.common.AudioConfig;
import android.media.audio.common.AudioOffloadInfo;
import android.media.soundtrigger_middleware.AudioCapabilities;
import android.media.soundtrigger_middleware.ConfidenceLevel;
import android.media.soundtrigger_middleware.ModelParameter;
import android.media.soundtrigger_middleware.ModelParameterRange;
@@ -74,6 +75,8 @@ class ConversionUtil {
@NonNull Properties hidlProperties) {
SoundTriggerModuleProperties aidlProperties = hidl2aidlProperties(hidlProperties.base);
aidlProperties.supportedModelArch = hidlProperties.supportedModelArch;
aidlProperties.audioCapabilities =
hidl2aidlAudioCapabilities(hidlProperties.audioCapabilities);
return aidlProperties;
}
@@ -209,16 +212,17 @@ class ConversionUtil {
return hidlModel;
}
static @NonNull
ISoundTriggerHw.RecognitionConfig aidl2hidlRecognitionConfig(
static @NonNull android.hardware.soundtrigger.V2_3.RecognitionConfig aidl2hidlRecognitionConfig(
@NonNull RecognitionConfig aidlConfig) {
ISoundTriggerHw.RecognitionConfig hidlConfig = new ISoundTriggerHw.RecognitionConfig();
hidlConfig.header.captureRequested = aidlConfig.captureRequested;
android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
new android.hardware.soundtrigger.V2_3.RecognitionConfig();
hidlConfig.base.header.captureRequested = aidlConfig.captureRequested;
for (PhraseRecognitionExtra aidlPhraseExtra : aidlConfig.phraseRecognitionExtras) {
hidlConfig.header.phrases.add(aidl2hidlPhraseRecognitionExtra(aidlPhraseExtra));
hidlConfig.base.header.phrases.add(aidl2hidlPhraseRecognitionExtra(aidlPhraseExtra));
}
hidlConfig.data = HidlMemoryUtil.byteArrayToHidlMemory(aidlConfig.data,
hidlConfig.base.data = HidlMemoryUtil.byteArrayToHidlMemory(aidlConfig.data,
"SoundTrigger RecognitionConfig");
hidlConfig.audioCapabilities = aidlConfig.audioCapabilities;
return hidlConfig;
}
@@ -395,4 +399,17 @@ class ConversionUtil {
return android.hardware.soundtrigger.V2_3.ModelParameter.INVALID;
}
}
static int hidl2aidlAudioCapabilities(int hidlCapabilities) {
int aidlCapabilities = 0;
if ((hidlCapabilities
& android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION) != 0) {
aidlCapabilities |= AudioCapabilities.ECHO_CANCELLATION;
}
if ((hidlCapabilities
& android.hardware.soundtrigger.V2_3.AudioCapabilities.NOISE_SUPPRESSION) != 0) {
aidlCapabilities |= AudioCapabilities.NOISE_SUPPRESSION;
}
return aidlCapabilities;
}
}

View File

@@ -66,12 +66,17 @@ class Hw2CompatUtil {
return model_2_0;
}
static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig convertRecognitionConfig_2_1_to_2_0(
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config) {
static android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig convertRecognitionConfig_2_3_to_2_1(
android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
return config.base;
}
static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig convertRecognitionConfig_2_3_to_2_0(
android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config_2_0 =
config.header;
config.base.header;
// Note: this mutates the input!
config_2_0.data = HidlMemoryUtil.hidlMemoryToByteList(config.data);
config_2_0.data = HidlMemoryUtil.hidlMemoryToByteList(config.base.data);
return config_2_0;
}

View File

@@ -92,12 +92,12 @@ public interface ISoundTriggerHw2 {
void stopAllRecognitions();
/**
* @see android.hardware.soundtrigger.V2_2.ISoundTriggerHw#startRecognition_2_1(int,
* android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig,
* @see android.hardware.soundtrigger.V2_3.ISoundTriggerHw#startRecognition_2_3(int,
* android.hardware.soundtrigger.V2_3.RecognitionConfig,
* android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback, int)
*/
void startRecognition(int modelHandle,
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config,
android.hardware.soundtrigger.V2_3.RecognitionConfig config,
SoundTriggerHw2Compat.Callback callback, int cookie);
/**

View File

@@ -217,16 +217,15 @@ final class SoundTriggerHw2Compat implements ISoundTriggerHw2 {
@Override
public void startRecognition(int modelHandle,
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config,
android.hardware.soundtrigger.V2_3.RecognitionConfig config,
Callback callback, int cookie) {
try {
try {
int retval = as2_1().startRecognition_2_1(modelHandle, config,
new SoundTriggerCallback(callback), cookie);
handleHalStatus(retval, "startRecognition_2_1");
int retval = as2_3().startRecognition_2_3(modelHandle, config);
handleHalStatus(retval, "startRecognition_2_3");
} catch (NotSupported e) {
// Fall-back to the 2.0 version:
startRecognition_2_0(modelHandle, config, callback, cookie);
startRecognition_2_1(modelHandle, config, callback, cookie);
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
@@ -369,13 +368,31 @@ final class SoundTriggerHw2Compat implements ISoundTriggerHw2 {
return handle.get();
}
private void startRecognition_2_1(int modelHandle,
android.hardware.soundtrigger.V2_3.RecognitionConfig config,
Callback callback, int cookie) {
try {
try {
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config_2_1 =
Hw2CompatUtil.convertRecognitionConfig_2_3_to_2_1(config);
int retval = as2_1().startRecognition_2_1(modelHandle, config_2_1,
new SoundTriggerCallback(callback), cookie);
handleHalStatus(retval, "startRecognition_2_1");
} catch (NotSupported e) {
// Fall-back to the 2.0 version:
startRecognition_2_0(modelHandle, config, callback, cookie);
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
private void startRecognition_2_0(int modelHandle,
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config,
android.hardware.soundtrigger.V2_3.RecognitionConfig config,
Callback callback, int cookie)
throws RemoteException {
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config_2_0 =
Hw2CompatUtil.convertRecognitionConfig_2_1_to_2_0(config);
Hw2CompatUtil.convertRecognitionConfig_2_3_to_2_0(config);
int retval = as2_0().startRecognition(modelHandle, config_2_0,
new SoundTriggerCallback(callback), cookie);
handleHalStatus(retval, "startRecognition");

View File

@@ -401,10 +401,10 @@ class SoundTriggerModule {
notifyAbort();
return;
}
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig hidlConfig =
android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
ConversionUtil.aidl2hidlRecognitionConfig(config);
hidlConfig.header.captureDevice = mSession.mDeviceHandle;
hidlConfig.header.captureHandle = mSession.mIoHandle;
hidlConfig.base.header.captureDevice = mSession.mDeviceHandle;
hidlConfig.base.header.captureHandle = mSession.mIoHandle;
mHalService.startRecognition(mHandle, hidlConfig, this, 0);
setState(ModelState.ACTIVE);
}

View File

@@ -37,6 +37,7 @@ import android.hardware.audio.common.V2_0.Uuid;
import android.hardware.soundtrigger.V2_3.OptionalModelParameterRange;
import android.media.audio.common.AudioChannelMask;
import android.media.audio.common.AudioFormat;
import android.media.soundtrigger_middleware.AudioCapabilities;
import android.media.soundtrigger_middleware.ConfidenceLevel;
import android.media.soundtrigger_middleware.ISoundTriggerCallback;
import android.media.soundtrigger_middleware.ISoundTriggerModule;
@@ -59,6 +60,7 @@ import android.os.HwParcel;
import android.os.IHwBinder;
import android.os.IHwInterface;
import android.os.RemoteException;
import android.util.Pair;
import org.junit.Before;
import org.junit.Test;
@@ -161,6 +163,9 @@ public class SoundTriggerMiddlewareImplTest {
new android.hardware.soundtrigger.V2_3.Properties();
properties.base = createDefaultProperties(supportConcurrentCapture);
properties.supportedModelArch = "supportedModelArch";
properties.audioCapabilities =
android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION
| android.hardware.soundtrigger.V2_3.AudioCapabilities.NOISE_SUPPRESSION;
return properties;
}
@@ -185,8 +190,11 @@ public class SoundTriggerMiddlewareImplTest {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_3.ISoundTriggerHw) {
assertEquals("supportedModelArch", properties.supportedModelArch);
assertEquals(AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
properties.audioCapabilities);
} else {
assertEquals("", properties.supportedModelArch);
assertEquals(0, properties.audioCapabilities);
}
}
@@ -330,12 +338,17 @@ public class SoundTriggerMiddlewareImplTest {
mService = new SoundTriggerMiddlewareImpl(mHalDriver, mAudioSessionProvider);
}
private int loadGenericModel_2_0(ISoundTriggerModule module, int hwHandle)
throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadGenericModel_2_0(ISoundTriggerModule module,
int hwHandle) throws RemoteException {
SoundModel model = createGenericSoundModel();
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel> modelCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback =
invocation.getArgument(1);
@@ -354,7 +367,8 @@ public class SoundTriggerMiddlewareImplTest {
modelEvent.model = hwHandle;
callback.soundModelCallback(modelEvent, callbackCookie);
return null;
}).when(mHalDriver).loadSoundModel(modelCaptor.capture(), any(), anyInt(), any());
}).when(mHalDriver).loadSoundModel(modelCaptor.capture(), callbackCaptor.capture(),
cookieCaptor.capture(), any());
when(mAudioSessionProvider.acquireSession()).thenReturn(
new SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession(101, 102, 103));
@@ -371,17 +385,23 @@ public class SoundTriggerMiddlewareImplTest {
assertEquals(model.vendorUuid, ConversionUtil.hidl2aidlUuid(hidlModel.vendorUuid));
assertArrayEquals(new Byte[]{91, 92, 93, 94, 95}, hidlModel.data.toArray());
return handle;
return new Pair<>(handle,
new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue()));
}
private int loadGenericModel_2_1(ISoundTriggerModule module, int hwHandle)
throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadGenericModel_2_1(ISoundTriggerModule module,
int hwHandle) throws RemoteException {
android.hardware.soundtrigger.V2_1.ISoundTriggerHw driver =
(android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
SoundModel model = createGenericSoundModel();
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> modelCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback =
invocation.getArgument(1);
@@ -400,7 +420,8 @@ public class SoundTriggerMiddlewareImplTest {
modelEvent.header.model = hwHandle;
callback.soundModelCallback_2_1(modelEvent, callbackCookie);
return null;
}).when(driver).loadSoundModel_2_1(modelCaptor.capture(), any(), anyInt(), any());
}).when(driver).loadSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
cookieCaptor.capture(), any());
when(mAudioSessionProvider.acquireSession()).thenReturn(
new SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession(101, 102, 103));
@@ -418,10 +439,12 @@ public class SoundTriggerMiddlewareImplTest {
assertArrayEquals(new byte[]{91, 92, 93, 94, 95},
HidlMemoryUtil.hidlMemoryToByteArray(hidlModel.data));
return handle;
return new Pair<>(handle,
new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue()));
}
private int loadGenericModel(ISoundTriggerModule module, int hwHandle) throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadGenericModel(ISoundTriggerModule module,
int hwHandle) throws RemoteException {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
return loadGenericModel_2_1(module, hwHandle);
} else {
@@ -429,12 +452,17 @@ public class SoundTriggerMiddlewareImplTest {
}
}
private int loadPhraseModel_2_0(ISoundTriggerModule module, int hwHandle)
throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadPhraseModel_2_0(ISoundTriggerModule module,
int hwHandle) throws RemoteException {
PhraseSoundModel model = createPhraseSoundModel();
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel>
modelCaptor = ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback =
invocation.getArgument(
@@ -456,7 +484,8 @@ public class SoundTriggerMiddlewareImplTest {
modelEvent.model = hwHandle;
callback.soundModelCallback(modelEvent, callbackCookie);
return null;
}).when(mHalDriver).loadPhraseSoundModel(modelCaptor.capture(), any(), anyInt(), any());
}).when(mHalDriver).loadPhraseSoundModel(modelCaptor.capture(), callbackCaptor.capture(),
cookieCaptor.capture(), any());
when(mAudioSessionProvider.acquireSession()).thenReturn(
new SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession(101, 102, 103));
@@ -488,11 +517,12 @@ public class SoundTriggerMiddlewareImplTest {
| android.hardware.soundtrigger.V2_0.RecognitionMode.USER_IDENTIFICATION,
hidlPhrase.recognitionModes);
return handle;
return new Pair<>(handle,
new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue()));
}
private int loadPhraseModel_2_1(ISoundTriggerModule module, int hwHandle)
throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadPhraseModel_2_1(ISoundTriggerModule module,
int hwHandle) throws RemoteException {
android.hardware.soundtrigger.V2_1.ISoundTriggerHw driver =
(android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
@@ -500,6 +530,11 @@ public class SoundTriggerMiddlewareImplTest {
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel>
modelCaptor = ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback =
invocation.getArgument(
@@ -521,7 +556,8 @@ public class SoundTriggerMiddlewareImplTest {
modelEvent.header.model = hwHandle;
callback.soundModelCallback_2_1(modelEvent, callbackCookie);
return null;
}).when(driver).loadPhraseSoundModel_2_1(modelCaptor.capture(), any(), anyInt(), any());
}).when(driver).loadPhraseSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
cookieCaptor.capture(), any());
when(mAudioSessionProvider.acquireSession()).thenReturn(
new SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession(101, 102, 103));
@@ -554,10 +590,12 @@ public class SoundTriggerMiddlewareImplTest {
| android.hardware.soundtrigger.V2_0.RecognitionMode.USER_IDENTIFICATION,
hidlPhrase.recognitionModes);
return handle;
return new Pair<>(handle,
new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue()));
}
private int loadPhraseModel(ISoundTriggerModule module, int hwHandle) throws RemoteException {
private Pair<Integer, SoundTriggerHwCallback> loadPhraseModel(
ISoundTriggerModule module, int hwHandle) throws RemoteException {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
return loadPhraseModel_2_1(module, hwHandle);
} else {
@@ -572,18 +610,14 @@ public class SoundTriggerMiddlewareImplTest {
verify(mAudioSessionProvider).releaseSession(101);
}
private SoundTriggerHwCallback startRecognition_2_0(ISoundTriggerModule module, int handle,
private void startRecognition_2_0(ISoundTriggerModule module, int handle,
int hwHandle) throws RemoteException {
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig>
configCaptor = ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
when(mHalDriver.startRecognition(eq(hwHandle), configCaptor.capture(),
callbackCaptor.capture(), cookieCaptor.capture())).thenReturn(0);
when(mHalDriver.startRecognition(eq(hwHandle), configCaptor.capture(), any(), anyInt()))
.thenReturn(0);
RecognitionConfig config = createRecognitionConfig();
@@ -606,11 +640,9 @@ public class SoundTriggerMiddlewareImplTest {
assertEquals(234, halLevel.userId);
assertEquals(34, halLevel.levelPercent);
assertArrayEquals(new Byte[]{5, 4, 3, 2, 1}, halConfig.data.toArray());
return new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue());
}
private SoundTriggerHwCallback startRecognition_2_1(ISoundTriggerModule module, int handle,
private void startRecognition_2_1(ISoundTriggerModule module, int handle,
int hwHandle) throws RemoteException {
android.hardware.soundtrigger.V2_1.ISoundTriggerHw driver =
(android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
@@ -618,13 +650,9 @@ public class SoundTriggerMiddlewareImplTest {
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig>
configCaptor = ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig.class);
ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
when(driver.startRecognition_2_1(eq(hwHandle), configCaptor.capture(),
callbackCaptor.capture(), cookieCaptor.capture())).thenReturn(0);
when(driver.startRecognition_2_1(eq(hwHandle), configCaptor.capture(), any(), anyInt()))
.thenReturn(0);
RecognitionConfig config = createRecognitionConfig();
@@ -648,16 +676,56 @@ public class SoundTriggerMiddlewareImplTest {
assertEquals(34, halLevel.levelPercent);
assertArrayEquals(new byte[]{5, 4, 3, 2, 1},
HidlMemoryUtil.hidlMemoryToByteArray(halConfig.data));
return new SoundTriggerHwCallback(callbackCaptor.getValue(), cookieCaptor.getValue());
}
private SoundTriggerHwCallback startRecognition(ISoundTriggerModule module, int handle,
private void startRecognition_2_3(ISoundTriggerModule module, int handle,
int hwHandle) throws RemoteException {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
return startRecognition_2_1(module, handle, hwHandle);
android.hardware.soundtrigger.V2_3.ISoundTriggerHw driver =
(android.hardware.soundtrigger.V2_3.ISoundTriggerHw) mHalDriver;
ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig>
configCaptor = ArgumentCaptor.forClass(
android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
when(driver.startRecognition_2_3(eq(hwHandle), configCaptor.capture())).thenReturn(0);
RecognitionConfig config = createRecognitionConfig();
module.startRecognition(handle, config);
verify(driver).startRecognition_2_3(eq(hwHandle), any());
android.hardware.soundtrigger.V2_3.RecognitionConfig halConfigExtended =
configCaptor.getValue();
android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig halConfig_2_1 =
halConfigExtended.base;
assertTrue(halConfig_2_1.header.captureRequested);
assertEquals(102, halConfig_2_1.header.captureHandle);
assertEquals(103, halConfig_2_1.header.captureDevice);
assertEquals(1, halConfig_2_1.header.phrases.size());
android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra halPhraseExtra =
halConfig_2_1.header.phrases.get(0);
assertEquals(123, halPhraseExtra.id);
assertEquals(4, halPhraseExtra.confidenceLevel);
assertEquals(5, halPhraseExtra.recognitionModes);
assertEquals(1, halPhraseExtra.levels.size());
android.hardware.soundtrigger.V2_0.ConfidenceLevel halLevel = halPhraseExtra.levels.get(0);
assertEquals(234, halLevel.userId);
assertEquals(34, halLevel.levelPercent);
assertArrayEquals(new byte[]{5, 4, 3, 2, 1},
HidlMemoryUtil.hidlMemoryToByteArray(halConfig_2_1.data));
assertEquals(AudioCapabilities.ECHO_CANCELLATION
| AudioCapabilities.NOISE_SUPPRESSION, halConfigExtended.audioCapabilities);
}
private void startRecognition(ISoundTriggerModule module, int handle,
int hwHandle) throws RemoteException {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_3.ISoundTriggerHw) {
startRecognition_2_3(module, handle, hwHandle);
} else if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
startRecognition_2_1(module, handle, hwHandle);
} else {
return startRecognition_2_0(module, handle, hwHandle);
startRecognition_2_0(module, handle, hwHandle);
}
}
@@ -672,6 +740,8 @@ public class SoundTriggerMiddlewareImplTest {
config.phraseRecognitionExtras[0].levels[0].userId = 234;
config.phraseRecognitionExtras[0].levels[0].levelPercent = 34;
config.data = new byte[]{5, 4, 3, 2, 1};
config.audioCapabilities = AudioCapabilities.ECHO_CANCELLATION
| AudioCapabilities.NOISE_SUPPRESSION;
return config;
}
@@ -687,6 +757,9 @@ public class SoundTriggerMiddlewareImplTest {
if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) {
verify((android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver,
never()).startRecognition_2_1(anyInt(), any(), any(), anyInt());
} else if (mHalDriver instanceof android.hardware.soundtrigger.V2_3.ISoundTriggerHw) {
verify((android.hardware.soundtrigger.V2_3.ISoundTriggerHw) mHalDriver,
never()).startRecognition_2_3(anyInt(), any());
}
}
@@ -798,7 +871,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 7;
int handle = loadGenericModel(module, hwHandle);
int handle = loadGenericModel(module, hwHandle).first;
unloadModel(module, handle, hwHandle);
module.detach();
}
@@ -810,7 +883,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 73;
int handle = loadPhraseModel(module, hwHandle);
int handle = loadPhraseModel(module, hwHandle).first;
unloadModel(module, handle, hwHandle);
module.detach();
}
@@ -823,7 +896,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 7;
int handle = loadGenericModel(module, hwHandle);
int handle = loadGenericModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -844,7 +917,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 67;
int handle = loadPhraseModel(module, hwHandle);
int handle = loadPhraseModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -865,10 +938,12 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 7;
int handle = loadGenericModel(module, hwHandle);
Pair<Integer, SoundTriggerHwCallback> modelHandles = loadGenericModel(module, hwHandle);
int handle = modelHandles.first;
SoundTriggerHwCallback hwCallback = modelHandles.second;
// Initiate a recognition.
SoundTriggerHwCallback hwCallback = startRecognition(module, handle, hwHandle);
startRecognition(module, handle, hwHandle);
// Signal a capture from the driver.
hwCallback.sendRecognitionEvent(hwHandle,
@@ -894,10 +969,12 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 7;
int handle = loadPhraseModel(module, hwHandle);
Pair<Integer, SoundTriggerHwCallback> modelHandles = loadPhraseModel(module, hwHandle);
int handle = modelHandles.first;
SoundTriggerHwCallback hwCallback = modelHandles.second;
// Initiate a recognition.
SoundTriggerHwCallback hwCallback = startRecognition(module, handle, hwHandle);
startRecognition(module, handle, hwHandle);
// Signal a capture from the driver.
hwCallback.sendPhraseRecognitionEvent(hwHandle,
@@ -930,10 +1007,12 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 17;
int handle = loadGenericModel(module, hwHandle);
Pair<Integer, SoundTriggerHwCallback> modelHandles = loadGenericModel(module, hwHandle);
int handle = modelHandles.first;
SoundTriggerHwCallback hwCallback = modelHandles.second;
// Initiate a recognition.
SoundTriggerHwCallback hwCallback = startRecognition(module, handle, hwHandle);
startRecognition(module, handle, hwHandle);
// Force a trigger.
module.forceRecognitionEvent(handle);
@@ -973,10 +1052,12 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 17;
int handle = loadPhraseModel(module, hwHandle);
Pair<Integer, SoundTriggerHwCallback> modelHandles = loadPhraseModel(module, hwHandle);
int handle = modelHandles.first;
SoundTriggerHwCallback hwCallback = modelHandles.second;
// Initiate a recognition.
SoundTriggerHwCallback hwCallback = startRecognition(module, handle, hwHandle);
startRecognition(module, handle, hwHandle);
// Force a trigger.
module.forceRecognitionEvent(handle);
@@ -1013,7 +1094,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 11;
int handle = loadGenericModel(module, hwHandle);
int handle = loadGenericModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -1061,7 +1142,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 11;
int handle = loadPhraseModel(module, hwHandle);
int handle = loadPhraseModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -1109,7 +1190,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 13;
int handle = loadGenericModel(module, hwHandle);
int handle = loadGenericModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -1145,7 +1226,7 @@ public class SoundTriggerMiddlewareImplTest {
// Load the model.
final int hwHandle = 13;
int handle = loadPhraseModel(module, hwHandle);
int handle = loadPhraseModel(module, hwHandle).first;
// Initiate a recognition.
startRecognition(module, handle, hwHandle);
@@ -1182,7 +1263,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 12;
int modelHandle = loadGenericModel(module, hwHandle);
int modelHandle = loadGenericModel(module, hwHandle).first;
doAnswer((Answer<Void>) invocation -> {
android.hardware.soundtrigger.V2_3.ISoundTriggerHw.queryParameterCallback
@@ -1218,7 +1299,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 13;
int modelHandle = loadGenericModel(module, hwHandle);
int modelHandle = loadGenericModel(module, hwHandle).first;
ModelParameterRange range = module.queryModelParameterSupport(modelHandle,
ModelParameter.THRESHOLD_FACTOR);
@@ -1239,7 +1320,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 13;
int modelHandle = loadGenericModel(module, hwHandle);
int modelHandle = loadGenericModel(module, hwHandle).first;
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_3.ISoundTriggerHw.queryParameterCallback
@@ -1272,7 +1353,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 14;
int modelHandle = loadGenericModel(module, hwHandle);
int modelHandle = loadGenericModel(module, hwHandle).first;
doAnswer(invocation -> {
android.hardware.soundtrigger.V2_3.ISoundTriggerHw.getParameterCallback
@@ -1304,7 +1385,7 @@ public class SoundTriggerMiddlewareImplTest {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
final int hwHandle = 17;
int modelHandle = loadGenericModel(module, hwHandle);
int modelHandle = loadGenericModel(module, hwHandle).first;
when(driver.setParameter(hwHandle,
android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR,