diff options
Diffstat (limited to 'core/java')
5 files changed, 277 insertions, 23 deletions
diff --git a/core/java/android/hardware/soundtrigger/ConversionUtil.java b/core/java/android/hardware/soundtrigger/ConversionUtil.java index 8231c58a105e..d2721018ef52 100644 --- a/core/java/android/hardware/soundtrigger/ConversionUtil.java +++ b/core/java/android/hardware/soundtrigger/ConversionUtil.java @@ -16,6 +16,7 @@ package android.hardware.soundtrigger; +import android.annotation.Nullable; import android.hardware.soundtrigger.ModelParams; import android.media.AudioFormat; import android.media.audio.common.AudioConfig; @@ -32,8 +33,6 @@ import android.media.soundtrigger_middleware.SoundModel; import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor; import android.media.soundtrigger_middleware.SoundTriggerModuleProperties; -import android.annotation.Nullable; - import java.util.Arrays; import java.util.UUID; diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index 55505ba2e278..2f0752b7c209 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -588,19 +588,19 @@ public class SoundTrigger { } } - /***************************************************************************** + /** * A ModelParamRange is a representation of supported parameter range for a * given loaded model. - ****************************************************************************/ + */ public static final class ModelParamRange implements Parcelable { /** - * start of supported range inclusive + * The inclusive start of supported range. */ public final int start; /** - * end of supported range inclusive + * The inclusive end of supported range. */ public final int end; @@ -609,31 +609,65 @@ public class SoundTrigger { this.end = end; } + /** @hide */ private ModelParamRange(@NonNull Parcel in) { this.start = in.readInt(); this.end = in.readInt(); } @NonNull - public static final Creator<ModelParamRange> CREATOR = new Creator<ModelParamRange>() { - @Override - @NonNull - public ModelParamRange createFromParcel(@NonNull Parcel in) { - return new ModelParamRange(in); - } - - @Override - @NonNull - public ModelParamRange[] newArray(int size) { - return new ModelParamRange[size]; - } - }; + public static final Creator<ModelParamRange> CREATOR = + new Creator<ModelParamRange>() { + @Override + @NonNull + public ModelParamRange createFromParcel(@NonNull Parcel in) { + return new ModelParamRange(in); + } + + @Override + @NonNull + public ModelParamRange[] newArray(int size) { + return new ModelParamRange[size]; + } + }; + /** @hide */ @Override public int describeContents() { return 0; } + /** @hide */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (start); + result = prime * result + (end); + return result; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ModelParamRange other = (ModelParamRange) obj; + if (start != other.start) { + return false; + } + if (end != other.end) { + return false; + } + return true; + } + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(start); diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 67925bfea2c2..d7c6d0f265c6 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -168,6 +168,22 @@ public class AlwaysOnHotwordDetector { public static final int RECOGNITION_MODE_USER_IDENTIFICATION = SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = { "MODEL_PARAM_" }, value = { + MODEL_PARAM_THRESHOLD_FACTOR, + }) + public @interface ModelParams {} + + /** + * Controls the sensitivity threshold adjustment factor for a given model. + * Negative value corresponds to less sensitive model (high threshold) and + * a positive value corresponds to a more sensitive model (low threshold). + * Default value is 0. + */ + public static final int MODEL_PARAM_THRESHOLD_FACTOR = + android.hardware.soundtrigger.ModelParams.THRESHOLD_FACTOR; + static final String TAG = "AlwaysOnHotwordDetector"; static final boolean DBG = false; @@ -198,6 +214,53 @@ public class AlwaysOnHotwordDetector { private int mAvailability = STATE_NOT_READY; /** + * A ModelParamRange is a representation of supported parameter range for a + * given loaded model. + */ + public static final class ModelParamRange { + private final SoundTrigger.ModelParamRange mModelParamRange; + + /** @hide */ + ModelParamRange(SoundTrigger.ModelParamRange modelParamRange) { + mModelParamRange = modelParamRange; + } + + /** + * The inclusive start of supported range. + * + * @return start of range + */ + public int start() { + return mModelParamRange.start; + } + + /** + * The inclusive end of supported range. + * + * @return end of range + */ + public int end() { + return mModelParamRange.end; + } + + @Override + @NonNull + public String toString() { + return mModelParamRange.toString(); + } + + @Override + public boolean equals(@Nullable Object obj) { + return mModelParamRange.equals(obj); + } + + @Override + public int hashCode() { + return mModelParamRange.hashCode(); + } + } + + /** * Additional payload for {@link Callback#onDetected}. */ public static class EventPayload { @@ -445,6 +508,83 @@ public class AlwaysOnHotwordDetector { } /** + * Set a model specific {@link ModelParams} with the given value. This + * parameter will keep its value for the duration the model is loaded regardless of starting and + * stopping recognition. Once the model is unloaded, the value will be lost. + * {@link AlwaysOnHotwordDetector#queryParameter} should be checked first before calling this + * method. + * + * @param modelParam {@link ModelParams} + * @param value Value to set + * @return - {@link SoundTrigger#STATUS_OK} in case of success + * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached + * - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter + * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or + * if API is not supported by HAL + */ + public int setParameter(@ModelParams int modelParam, int value) { + if (DBG) { + Slog.d(TAG, "setParameter(" + modelParam + ", " + value + ")"); + } + + synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("setParameter called on an invalid detector"); + } + + return setParameterLocked(modelParam, value); + } + } + + /** + * Get a model specific {@link ModelParams}. This parameter will keep its value + * for the duration the model is loaded regardless of starting and stopping recognition. + * Once the model is unloaded, the value will be lost. If the value is not set, a default + * value is returned. See {@link ModelParams} for parameter default values. + * {@link AlwaysOnHotwordDetector#queryParameter} should be checked first before + * calling this method. + * + * @param modelParam {@link ModelParams} + * @return value of parameter + */ + public int getParameter(@ModelParams int modelParam) { + if (DBG) { + Slog.d(TAG, "getParameter(" + modelParam + ")"); + } + + synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("getParameter called on an invalid detector"); + } + + return getParameterLocked(modelParam); + } + } + + /** + * Determine if parameter control is supported for the given model handle. + * This method should be checked prior to calling {@link AlwaysOnHotwordDetector#setParameter} + * or {@link AlwaysOnHotwordDetector#getParameter}. + * + * @param modelParam {@link ModelParams} + * @return supported range of parameter, null if not supported + */ + @Nullable + public ModelParamRange queryParameter(@ModelParams int modelParam) { + if (DBG) { + Slog.d(TAG, "queryParameter(" + modelParam + ")"); + } + + synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("queryParameter called on an invalid detector"); + } + + return queryParameterLocked(modelParam); + } + } + + /** * Creates an intent to start the enrollment for the associated keyphrase. * This intent must be invoked using {@link Context#startForegroundService(Intent)}. * Starting re-enrollment is only valid if the keyphrase is un-enrolled, @@ -601,6 +741,47 @@ public class AlwaysOnHotwordDetector { return code; } + private int setParameterLocked(@ModelParams int modelParam, int value) { + try { + int code = mModelManagementService.setParameter(mVoiceInteractionService, + mKeyphraseMetadata.id, modelParam, value); + + if (code != STATUS_OK) { + Slog.w(TAG, "setParameter failed with error code " + code); + } + + return code; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private int getParameterLocked(@ModelParams int modelParam) { + try { + return mModelManagementService.getParameter(mVoiceInteractionService, + mKeyphraseMetadata.id, modelParam); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Nullable + private ModelParamRange queryParameterLocked(@ModelParams int modelParam) { + try { + SoundTrigger.ModelParamRange modelParamRange = + mModelManagementService.queryParameter(mVoiceInteractionService, + mKeyphraseMetadata.id, modelParam); + + if (modelParamRange == null) { + return null; + } + + return new ModelParamRange(modelParamRange); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private void notifyStateChangedLocked() { Message message = Message.obtain(mHandler, MSG_AVAILABILITY_CHANGED); message.arg1 = mAvailability; diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl index d94294f0aa22..74bfb963c6b0 100644 --- a/core/java/com/android/internal/app/ISoundTriggerService.aidl +++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl @@ -61,10 +61,6 @@ interface ISoundTriggerService { int setParameter(in ParcelUuid soundModelId, in ModelParams modelParam, int value); - /** - * @throws UnsupportedOperationException if hal or model do not support this API. - * @throws IllegalArgumentException if invalid model handle or parameter is passed. - */ int getParameter(in ParcelUuid soundModelId, in ModelParams modelParam); @nullable SoundTrigger.ModelParamRange queryParameter(in ParcelUuid soundModelId, diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index f462f5d2571d..be2d1d60e9a2 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -26,6 +26,7 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback; import com.android.internal.app.IVoiceInteractor; import com.android.internal.app.IVoiceInteractionSessionListener; import android.hardware.soundtrigger.IRecognitionStatusCallback; +import android.hardware.soundtrigger.ModelParams; import android.hardware.soundtrigger.SoundTrigger; import android.service.voice.IVoiceInteractionService; import android.service.voice.IVoiceInteractionSession; @@ -91,6 +92,49 @@ interface IVoiceInteractionManagerService { */ int stopRecognition(in IVoiceInteractionService service, int keyphraseId, in IRecognitionStatusCallback callback); + /** + * Set a model specific ModelParams with the given value. This + * parameter will keep its value for the duration the model is loaded regardless of starting and + * stopping recognition. Once the model is unloaded, the value will be lost. + * queryParameter should be checked first before calling this method. + * + * @param service The current VoiceInteractionService. + * @param keyphraseId The unique identifier for the keyphrase. + * @param modelParam ModelParams + * @param value Value to set + * @return - {@link SoundTrigger#STATUS_OK} in case of success + * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached + * - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter + * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or + * if API is not supported by HAL + */ + int setParameter(in IVoiceInteractionService service, int keyphraseId, + in ModelParams modelParam, int value); + /** + * Get a model specific ModelParams. This parameter will keep its value + * for the duration the model is loaded regardless of starting and stopping recognition. + * Once the model is unloaded, the value will be lost. If the value is not set, a default + * value is returned. See ModelParams for parameter default values. + * queryParameter should be checked first before calling this method. + * + * @param service The current VoiceInteractionService. + * @param keyphraseId The unique identifier for the keyphrase. + * @param modelParam ModelParams + * @return value of parameter + */ + int getParameter(in IVoiceInteractionService service, int keyphraseId, + in ModelParams modelParam); + /** + * Determine if parameter control is supported for the given model handle. + * This method should be checked prior to calling setParameter or getParameter. + * + * @param service The current VoiceInteractionService. + * @param keyphraseId The unique identifier for the keyphrase. + * @param modelParam ModelParams + * @return supported range of parameter, null if not supported + */ + @nullable SoundTrigger.ModelParamRange queryParameter(in IVoiceInteractionService service, + int keyphraseId, in ModelParams modelParam); /** * @return the component name for the currently active voice interaction service |
