add SoundTrigger HAL 2.3 per model parameter apis

add support for model parameter control APIs with THRESHOLD_FACTOR
as the first supported parameter

Bug: 141929369
Test: Tested manually with test app and confirmed with GTS test
gts-tradefed run gts-dev -m GtsAssistIntentTestCases
Change-Id: I06874fcf2ae2ef8796e7c52c4475252e8a026e2c
This commit is contained in:
Nicholas Ambur
2019-10-01 10:11:39 -07:00
parent baccb2d071
commit a0be6be387
10 changed files with 540 additions and 12 deletions

View File

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

View File

@@ -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,
}

View File

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

View File

@@ -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
*/

View File

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

View File

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

View File

@@ -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>",

View File

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

View File

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

View File

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