summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt13
-rw-r--r--core/java/android/hardware/soundtrigger/ModelParams.aidl37
-rw-r--r--core/java/android/hardware/soundtrigger/SoundTrigger.aidl1
-rw-r--r--core/java/android/hardware/soundtrigger/SoundTrigger.java59
-rw-r--r--core/java/android/hardware/soundtrigger/SoundTriggerModule.java53
-rw-r--r--core/java/com/android/internal/app/ISoundTriggerService.aidl13
-rw-r--r--core/jni/android_hardware_SoundTrigger.cpp104
-rw-r--r--media/java/android/media/soundtrigger/SoundTriggerManager.java96
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java77
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java99
10 files changed, 540 insertions, 12 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 6b51eabf6f34..713d77d2a88f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3410,6 +3410,14 @@ package android.hardware.soundtrigger {
field public static final int STATUS_OK = 0; // 0x0
}
+ public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModelParamRange> CREATOR;
+ field public final int end;
+ field public final int start;
+ }
+
public static final class SoundTrigger.ModuleProperties implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
@@ -4198,8 +4206,11 @@ package android.media.soundtrigger {
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerDetector createSoundTriggerDetector(java.util.UUID, @NonNull android.media.soundtrigger.SoundTriggerDetector.Callback, @Nullable android.os.Handler);
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void deleteModel(java.util.UUID);
method public int getDetectionServiceOperationsTimeout();
- method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerManager.Model getModel(java.util.UUID);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerManager.Model getModel(java.util.UUID);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.hardware.soundtrigger.SoundTrigger.ModuleProperties getModuleProperties();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int getParameter(@NonNull java.util.UUID, int) throws java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException;
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.hardware.soundtrigger.SoundTrigger.ModelParamRange queryParameter(@Nullable java.util.UUID, int);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int setParameter(@Nullable java.util.UUID, int, int) throws java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException;
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void updateModel(android.media.soundtrigger.SoundTriggerManager.Model);
}
diff --git a/core/java/android/hardware/soundtrigger/ModelParams.aidl b/core/java/android/hardware/soundtrigger/ModelParams.aidl
new file mode 100644
index 000000000000..d90dc811fc32
--- /dev/null
+++ b/core/java/android/hardware/soundtrigger/ModelParams.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.hardware.soundtrigger;
+
+/**
+ * Model specific parameters to be used with parameter set and get APIs
+ * {@hide}
+ */
+@Backing(type="int")
+enum ModelParams {
+ /**
+ * Placeholder for invalid model parameter used for returning error or
+ * passing an invalid value.
+ */
+ INVALID = -1,
+ /**
+ * 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.
+ */
+ THRESHOLD_FACTOR = 0,
+}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
index 325a9addc8ff..94c4216227bc 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
@@ -24,5 +24,6 @@ parcelable SoundTrigger.GenericRecognitionEvent;
parcelable SoundTrigger.KeyphraseRecognitionExtra;
parcelable SoundTrigger.KeyphraseSoundModel;
parcelable SoundTrigger.GenericSoundModel;
+parcelable SoundTrigger.ModelParamRange;
parcelable SoundTrigger.ModuleProperties;
parcelable SoundTrigger.RecognitionConfig;
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index b1134e120df2..86f3eec4109e 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -567,6 +567,65 @@ 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
+ */
+ public final int start;
+
+ /**
+ * end of supported range inclusive
+ */
+ public final int end;
+
+ ModelParamRange(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ 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];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(start);
+ dest.writeInt(end);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ return "ModelParamRange [start=" + start + ", end=" + end + "]";
+ }
+ }
+
/**
* Modes for key phrase recognition
*/
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index 911354862ff4..b16ef5c43346 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -16,7 +16,9 @@
package android.hardware.soundtrigger;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
+import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -150,6 +152,57 @@ public class SoundTriggerModule {
*/
public native int getModelState(int soundModelHandle);
+ /**
+ * 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 SoundTriggerModule#isParameterSupported} should be checked first before calling this
+ * method.
+ *
+ * @param soundModelHandle handle of model to apply parameter
+ * @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 native int setParameter(int soundModelHandle,
+ @ModelParams int modelParam, int 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 SoundTriggerModule#isParameterSupported} should be checked first before
+ * calling this method. Otherwise, an exception can be thrown.
+ *
+ * @param soundModelHandle handle of model to get parameter
+ * @param modelParam {@link ModelParams}
+ * @return value of parameter
+ * @throws UnsupportedOperationException if hal or model do not support this API.
+ * {@link SoundTriggerModule#isParameterSupported} should be checked first.
+ * @throws IllegalArgumentException if invalid model handle or parameter is passed.
+ * {@link SoundTriggerModule#isParameterSupported} should be checked first.
+ */
+ public native int getParameter(int soundModelHandle,
+ @ModelParams int modelParam)
+ throws UnsupportedOperationException, IllegalArgumentException;
+
+ /**
+ * Determine if parameter control is supported for the given model handle.
+ * This method should be checked prior to calling {@link SoundTriggerModule#setParameter} or
+ * {@link SoundTriggerModule#getParameter}.
+ *
+ * @param soundModelHandle handle of model to get parameter
+ * @param modelParam {@link ModelParams}
+ * @return supported range of parameter, null if not supported
+ */
+ @Nullable
+ public native ModelParamRange queryParameter(int soundModelHandle, @ModelParams int modelParam);
+
private class NativeEventHandlerDelegate {
private final Handler mHandler;
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index ea24d5fbb2f7..d94294f0aa22 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -20,6 +20,7 @@ import android.app.PendingIntent;
import android.content.ComponentName;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.ModelParams;
import android.os.Bundle;
import android.os.ParcelUuid;
@@ -56,4 +57,16 @@ interface ISoundTriggerService {
int getModelState(in ParcelUuid soundModelId);
@nullable SoundTrigger.ModuleProperties getModuleProperties();
+
+ 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,
+ in ModelParams modelParam);
}
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index 0002f8b4048a..4376b0b4ac42 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -44,6 +44,13 @@ static struct {
jmethodID toString;
} gUUIDMethods;
+static const char* const kUnsupportedOperationExceptionClassPathName =
+ "java/lang/UnsupportedOperationException";
+static jclass gUnsupportedOperationExceptionClass;
+static const char* const kIllegalArgumentExceptionClassPathName =
+ "java/lang/IllegalArgumentException";
+static jclass gIllegalArgumentExceptionClass;
+
static const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
static jclass gSoundTriggerClass;
@@ -91,6 +98,11 @@ static struct {
jfieldID keyphrases;
} gKeyphraseSoundModelFields;
+static const char* const kModelParamRangeClassPathName =
+ "android/hardware/soundtrigger/SoundTrigger$ModelParamRange";
+static jclass gModelParamRangeClass;
+static jmethodID gModelParamRangeCstor;
+
static const char* const kRecognitionConfigClassPathName =
"android/hardware/soundtrigger/SoundTrigger$RecognitionConfig";
static jclass gRecognitionConfigClass;
@@ -164,6 +176,16 @@ enum {
SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4,
};
+static jint throwUnsupportedOperationException(JNIEnv *env)
+{
+ return env->ThrowNew(gUnsupportedOperationExceptionClass, nullptr);
+}
+
+static jint throwIllegalArgumentException(JNIEnv *env)
+{
+ return env->ThrowNew(gIllegalArgumentExceptionClass, nullptr);
+}
+
// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class JNISoundTriggerCallback: public SoundTriggerCallback
@@ -822,6 +844,69 @@ android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz,
return status;
}
+static jint
+android_hardware_SoundTrigger_setParameter(JNIEnv *env, jobject thiz,
+ jint jHandle, jint jModelParam, jint jValue)
+{
+ ALOGV("setParameter");
+ sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+ if (module == NULL) {
+ return SOUNDTRIGGER_STATUS_NO_INIT;
+ }
+ return module->setParameter(jHandle, (sound_trigger_model_parameter_t) jModelParam, jValue);
+}
+
+static jint
+android_hardware_SoundTrigger_getParameter(JNIEnv *env, jobject thiz,
+ jint jHandle, jint jModelParam)
+{
+ ALOGV("getParameter");
+ sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+ if (module == NULL) {
+ throwUnsupportedOperationException(env);
+ return -1;
+ }
+
+ jint nValue;
+ jint status = module->getParameter(jHandle,
+ (sound_trigger_model_parameter_t) jModelParam, &nValue);
+
+ switch (status) {
+ case 0:
+ return nValue;
+ case -EINVAL:
+ throwIllegalArgumentException(env);
+ break;
+ default:
+ throwUnsupportedOperationException(env);
+ break;
+ }
+
+ return -1;
+}
+
+static jobject
+android_hardware_SoundTrigger_queryParameter(JNIEnv *env, jobject thiz,
+ jint jHandle, jint jModelParam)
+{
+ ALOGV("queryParameter");
+ sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+ if (module == nullptr) {
+ return nullptr;
+ }
+
+ sound_trigger_model_parameter_range_t nRange;
+ jint nValue = module->queryParameter(jHandle,
+ (sound_trigger_model_parameter_t) jModelParam, &nRange);
+
+ if (nValue != 0) {
+ ALOGE("failed to query parameter error code: %d", nValue);
+ return nullptr;
+ }
+
+ return env->NewObject(gModelParamRangeClass, gModelParamRangeCstor, nRange.start, nRange.end);
+}
+
static const JNINativeMethod gMethods[] = {
{"listModules",
"(Ljava/lang/String;Ljava/util/ArrayList;)I",
@@ -854,6 +939,15 @@ static const JNINativeMethod gModuleMethods[] = {
{"getModelState",
"(I)I",
(void *)android_hardware_SoundTrigger_getModelState},
+ {"setParameter",
+ "(III)I",
+ (void *)android_hardware_SoundTrigger_setParameter},
+ {"getParameter",
+ "(II)I",
+ (void *)android_hardware_SoundTrigger_getParameter},
+ {"queryParameter",
+ "(II)Landroid/hardware/soundtrigger/SoundTrigger$ModelParamRange;",
+ (void *)android_hardware_SoundTrigger_queryParameter}
};
int register_android_hardware_SoundTrigger(JNIEnv *env)
@@ -866,6 +960,12 @@ int register_android_hardware_SoundTrigger(JNIEnv *env)
gUUIDClass = MakeGlobalRefOrDie(env, uuidClass);
gUUIDMethods.toString = GetMethodIDOrDie(env, uuidClass, "toString", "()Ljava/lang/String;");
+ jclass exUClass = FindClassOrDie(env, kUnsupportedOperationExceptionClassPathName);
+ gUnsupportedOperationExceptionClass = MakeGlobalRefOrDie(env, exUClass);
+
+ jclass exIClass = FindClassOrDie(env, kIllegalArgumentExceptionClassPathName);
+ gIllegalArgumentExceptionClass = MakeGlobalRefOrDie(env, exIClass);
+
jclass lClass = FindClassOrDie(env, kSoundTriggerClassPathName);
gSoundTriggerClass = MakeGlobalRefOrDie(env, lClass);
@@ -906,6 +1006,10 @@ int register_android_hardware_SoundTrigger(JNIEnv *env)
"keyphrases",
"[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");
+ jclass modelParamRangeClass = FindClassOrDie(env, kModelParamRangeClassPathName);
+ gModelParamRangeClass = MakeGlobalRefOrDie(env, modelParamRangeClass);
+ gModelParamRangeCstor = GetMethodIDOrDie(env, modelParamRangeClass, "<init>", "(II)V");
+
jclass recognitionEventClass = FindClassOrDie(env, kRecognitionEventClassPathName);
gRecognitionEventClass = MakeGlobalRefOrDie(env, recognitionEventClass);
gRecognitionEventCstor = GetMethodIDOrDie(env, recognitionEventClass, "<init>",
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index dc400ad26eed..61b3e76e7cee 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -26,9 +26,11 @@ import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
+import android.hardware.soundtrigger.ModelParams;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.hardware.soundtrigger.SoundTrigger.SoundModel;
import android.os.Bundle;
@@ -67,7 +69,7 @@ public final class SoundTriggerManager {
/**
* @hide
*/
- public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService ) {
+ public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService) {
if (DBG) {
Slog.i(TAG, "SoundTriggerManager created.");
}
@@ -89,14 +91,22 @@ public final class SoundTriggerManager {
}
/**
- * Returns the sound trigger model represented by the given UUID. An instance of {@link Model}
- * is returned.
+ * Get {@link SoundTriggerManager.Model} which is registered with the passed UUID
+ *
+ * @param soundModelId UUID associated with a loaded model
+ * @return {@link SoundTriggerManager.Model} associated with UUID soundModelId
*/
@RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+ @Nullable
public Model getModel(UUID soundModelId) {
try {
- return new Model(mSoundTriggerService.getSoundModel(
- new ParcelUuid(soundModelId)));
+ GenericSoundModel model =
+ mSoundTriggerService.getSoundModel(new ParcelUuid(soundModelId));
+ if (model == null) {
+ return null;
+ }
+
+ return new Model(model);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -399,4 +409,80 @@ public final class SoundTriggerManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * 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 SoundTriggerManager#queryParameter} should be checked first before calling this
+ * method.
+ *
+ * @param soundModelId UUID of model to apply the parameter value to.
+ * @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
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+ public int setParameter(@Nullable UUID soundModelId,
+ @ModelParams int modelParam, int value)
+ throws UnsupportedOperationException, IllegalArgumentException {
+ try {
+ return mSoundTriggerService.setParameter(new ParcelUuid(soundModelId), modelParam,
+ value);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * 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 SoundTriggerManager#queryParameter} should be checked first before
+ * calling this method. Otherwise, an exception can be thrown.
+ *
+ * @param soundModelId UUID of model to get parameter
+ * @param modelParam {@link ModelParams}
+ * @return value of parameter
+ * @throws UnsupportedOperationException if hal or model do not support this API.
+ * {@link SoundTriggerManager#queryParameter} should be checked first.
+ * @throws IllegalArgumentException if invalid model handle or parameter is passed.
+ * {@link SoundTriggerManager#queryParameter} should be checked first.
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+ public int getParameter(@NonNull UUID soundModelId,
+ @ModelParams int modelParam)
+ throws UnsupportedOperationException, IllegalArgumentException {
+ try {
+ return mSoundTriggerService.getParameter(new ParcelUuid(soundModelId), modelParam);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Determine if parameter control is supported for the given model handle.
+ * This method should be checked prior to calling {@link SoundTriggerManager#setParameter} or
+ * {@link SoundTriggerManager#getParameter}.
+ *
+ * @param soundModelId handle of model to get parameter
+ * @param modelParam {@link ModelParams}
+ * @return supported range of parameter, null if not supported
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+ @Nullable
+ public ModelParamRange queryParameter(@Nullable UUID soundModelId,
+ @ModelParams int modelParam) {
+ try {
+ return mSoundTriggerService.queryParameter(new ParcelUuid(soundModelId),
+ modelParam);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 735b9a1dcf2e..198b4c31249a 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -16,11 +16,14 @@
package com.android.server.soundtrigger;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.ModelParams;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.GenericRecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
@@ -28,6 +31,7 @@ import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
@@ -605,6 +609,67 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return STATUS_ERROR;
}
+ int setParameter(UUID modelId, @ModelParams int modelParam, int value) {
+ synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_set_parameter", 1);
+ if (modelId == null || mModule == null) {
+ return SoundTrigger.STATUS_ERROR;
+ }
+ ModelData modelData = mModelDataMap.get(modelId);
+ if (modelData == null) {
+ Slog.w(TAG, "SetParameter: Invalid model id:" + modelId);
+ return SoundTrigger.STATUS_BAD_VALUE;
+ }
+ if (!modelData.isModelLoaded()) {
+ Slog.i(TAG, "SetParameter: Given model is not loaded:" + modelId);
+ return SoundTrigger.STATUS_BAD_VALUE;
+ }
+
+ return mModule.setParameter(modelData.getHandle(), modelParam, value);
+ }
+ }
+
+ int getParameter(@NonNull UUID modelId, @ModelParams int modelParam)
+ throws UnsupportedOperationException, IllegalArgumentException {
+ synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_get_parameter", 1);
+ if (mModule == null) {
+ throw new UnsupportedOperationException("SoundTriggerModule not initialized");
+ }
+
+ ModelData modelData = mModelDataMap.get(modelId);
+ if (modelData == null) {
+ throw new IllegalArgumentException("Invalid model id:" + modelId);
+ }
+ if (!modelData.isModelLoaded()) {
+ throw new UnsupportedOperationException("Given model is not loaded:" + modelId);
+ }
+
+ return mModule.getParameter(modelData.getHandle(), modelParam);
+ }
+ }
+
+ @Nullable
+ ModelParamRange queryParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
+ synchronized (mLock) {
+ MetricsLogger.count(mContext, "sth_query_parameter", 1);
+ if (mModule == null) {
+ return null;
+ }
+ ModelData modelData = mModelDataMap.get(modelId);
+ if (modelData == null) {
+ Slog.w(TAG, "queryParameter: Invalid model id:" + modelId);
+ return null;
+ }
+ if (!modelData.isModelLoaded()) {
+ Slog.i(TAG, "queryParameter: Given model is not loaded:" + modelId);
+ return null;
+ }
+
+ return mModule.queryParameter(modelData.getHandle(), modelParam);
+ }
+ }
+
//---- SoundTrigger.StatusListener methods
@Override
public void onRecognition(RecognitionEvent event) {
@@ -653,15 +718,15 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
ModelData model = getModelDataForLocked(event.soundModelHandle);
if (model == null || !model.isGenericModel()) {
- Slog.w(TAG, "Generic recognition event: Model does not exist for handle: " +
- event.soundModelHandle);
+ Slog.w(TAG, "Generic recognition event: Model does not exist for handle: "
+ + event.soundModelHandle);
return;
}
IRecognitionStatusCallback callback = model.getCallback();
if (callback == null) {
- Slog.w(TAG, "Generic recognition event: Null callback for model handle: " +
- event.soundModelHandle);
+ Slog.w(TAG, "Generic recognition event: Null callback for model handle: "
+ + event.soundModelHandle);
return;
}
@@ -678,8 +743,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
RecognitionConfig config = model.getRecognitionConfig();
if (config == null) {
- Slog.w(TAG, "Generic recognition event: Null RecognitionConfig for model handle: " +
- event.soundModelHandle);
+ Slog.w(TAG, "Generic recognition event: Null RecognitionConfig for model handle: "
+ + event.soundModelHandle);
return;
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 1dd3972b56b4..96d2df125a3c 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -22,7 +22,9 @@ import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_BAD_VALUE;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_NO_INIT;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK;
import static android.provider.Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY;
import static android.provider.Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT;
@@ -39,9 +41,11 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.ModelParams;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.hardware.soundtrigger.SoundTrigger.SoundModel;
@@ -683,6 +687,101 @@ public class SoundTriggerService extends SystemService {
return properties;
}
}
+
+ @Override
+ public int setParameter(ParcelUuid soundModelId,
+ @ModelParams int modelParam, int value) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (!isInitialized()) return STATUS_NO_INIT;
+ if (DEBUG) {
+ Slog.d(TAG, "setParameter(): id=" + soundModelId
+ + ", param=" + modelParam
+ + ", value=" + value);
+ }
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "setParameter(): id=" + soundModelId
+ + ", param=" + modelParam
+ + ", value=" + value));
+
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded. Loaded models: "
+ + mLoadedModels.toString());
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("setParameter(): "
+ + soundModelId + " is not loaded"));
+
+ return STATUS_BAD_VALUE;
+ }
+
+ return mSoundTriggerHelper.setParameter(soundModel.uuid, modelParam, value);
+ }
+ }
+
+ @Override
+ public int getParameter(@NonNull ParcelUuid soundModelId,
+ @ModelParams int modelParam)
+ throws UnsupportedOperationException, IllegalArgumentException {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (!isInitialized()) {
+ throw new UnsupportedOperationException("SoundTriggerHelper not initialized");
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "getParameter(): id=" + soundModelId
+ + ", param=" + modelParam);
+ }
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "getParameter(): id=" + soundModelId
+ + ", param=" + modelParam));
+
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("getParameter(): "
+ + soundModelId + " is not loaded"));
+
+ throw new IllegalArgumentException("sound model is not loaded");
+ }
+
+ return mSoundTriggerHelper.getParameter(soundModel.uuid, modelParam);
+ }
+ }
+
+ @Override
+ @Nullable
+ public ModelParamRange queryParameter(@NonNull ParcelUuid soundModelId,
+ @ModelParams int modelParam) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (!isInitialized()) return null;
+ if (DEBUG) {
+ Slog.d(TAG, "queryParameter(): id=" + soundModelId
+ + ", param=" + modelParam);
+ }
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "queryParameter(): id=" + soundModelId
+ + ", param=" + modelParam));
+
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "queryParameter(): "
+ + soundModelId + " is not loaded"));
+
+ return null;
+ }
+
+ return mSoundTriggerHelper.queryParameter(soundModel.uuid, modelParam);
+ }
+ }
}
/**