Merge "Converting sound trigger v2.2 getModelState to be asynchronous"
This commit is contained in:
committed by
Android (Google) Code Review
commit
4d75ccd328
@@ -611,6 +611,13 @@ public class SoundTrigger {
|
||||
* @hide
|
||||
*/
|
||||
public static final int RECOGNITION_STATUS_FAILURE = 2;
|
||||
/**
|
||||
* Recognition event was triggered by a getModelState request, not by the
|
||||
* DSP.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int RECOGNITION_STATUS_GET_STATE_RESPONSE = 3;
|
||||
|
||||
/**
|
||||
* A RecognitionEvent is provided by the
|
||||
|
||||
@@ -133,12 +133,21 @@ public class SoundTriggerModule {
|
||||
public native int stopRecognition(int soundModelHandle);
|
||||
|
||||
/**
|
||||
* Get the current state of a {@link SoundTrigger.SoundModel}
|
||||
* Get the current state of a {@link SoundTrigger.SoundModel}.
|
||||
* The state will be returned asynchronously as a {@link SoundTrigger#RecognitionEvent}
|
||||
* in the callback registered in the {@link SoundTrigger.startRecognition} method.
|
||||
* @param soundModelHandle The sound model handle indicating which model's state to return
|
||||
* @return - {@link SoundTrigger#RecognitionEvent} in case of success
|
||||
* - null in case of an error or if not supported
|
||||
* @return - {@link SoundTrigger#STATUS_OK} in case of success
|
||||
* - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
|
||||
* - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
|
||||
* system permission
|
||||
* - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
|
||||
* - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
|
||||
* - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
|
||||
* service fails
|
||||
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
|
||||
*/
|
||||
public native SoundTrigger.RecognitionEvent getModelState(int soundModelHandle);
|
||||
public native int getModelState(int soundModelHandle);
|
||||
|
||||
private class NativeEventHandlerDelegate {
|
||||
private final Handler mHandler;
|
||||
|
||||
@@ -53,5 +53,5 @@ interface ISoundTriggerService {
|
||||
/** For both ...Intent and ...Service based usage */
|
||||
boolean isRecognitionActive(in ParcelUuid parcelUuid);
|
||||
|
||||
SoundTrigger.RecognitionEvent getModelState(in ParcelUuid parcelUuid);
|
||||
int getModelState(in ParcelUuid soundModelId);
|
||||
}
|
||||
|
||||
@@ -788,61 +788,18 @@ android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
|
||||
return status;
|
||||
}
|
||||
|
||||
static jobject
|
||||
static jint
|
||||
android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz,
|
||||
jint jHandle)
|
||||
{
|
||||
jint status = SOUNDTRIGGER_STATUS_OK;
|
||||
ALOGV("getModelState");
|
||||
sp<SoundTrigger> module = getSoundTrigger(env, thiz);
|
||||
if (module == NULL) {
|
||||
return NULL;
|
||||
return SOUNDTRIGGER_STATUS_ERROR;
|
||||
}
|
||||
sp<IMemory> memory;
|
||||
jint status = module->getModelState(jHandle, memory);
|
||||
if (status != 0 || memory == NULL) {
|
||||
ALOGW("getModelState, failed to get model state, status: %d", status);
|
||||
return NULL;
|
||||
}
|
||||
struct sound_trigger_recognition_event* event =
|
||||
(struct sound_trigger_recognition_event *)memory->pointer();
|
||||
if (event == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (event->type != SOUND_MODEL_TYPE_GENERIC) {
|
||||
ALOGW("getModelState, unsupported model type: %d", event->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jbyteArray jData = NULL;
|
||||
if (event->data_size) {
|
||||
jData = env->NewByteArray(event->data_size);
|
||||
jbyte *nData = env->GetByteArrayElements(jData, NULL);
|
||||
memcpy(nData, (char *)event + event->data_offset, event->data_size);
|
||||
env->ReleaseByteArrayElements(jData, nData, 0);
|
||||
}
|
||||
|
||||
jobject jAudioFormat = NULL;
|
||||
if (event->trigger_in_data || event->capture_available) {
|
||||
jAudioFormat = env->NewObject(gAudioFormatClass,
|
||||
gAudioFormatCstor,
|
||||
audioFormatFromNative(event->audio_config.format),
|
||||
event->audio_config.sample_rate,
|
||||
inChannelMaskFromNative(event->audio_config.channel_mask));
|
||||
|
||||
}
|
||||
jobject jEvent = NULL;
|
||||
jEvent = env->NewObject(gGenericRecognitionEventClass, gGenericRecognitionEventCstor,
|
||||
event->status, event->model, event->capture_available,
|
||||
event->capture_session, event->capture_delay_ms,
|
||||
event->capture_preamble_ms, event->trigger_in_data,
|
||||
jAudioFormat, jData);
|
||||
if (jAudioFormat != NULL) {
|
||||
env->DeleteLocalRef(jAudioFormat);
|
||||
}
|
||||
if (jData != NULL) {
|
||||
env->DeleteLocalRef(jData);
|
||||
}
|
||||
return jEvent;
|
||||
status = module->getModelState(jHandle);
|
||||
return status;
|
||||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
@@ -875,7 +832,7 @@ static const JNINativeMethod gModuleMethods[] = {
|
||||
"(I)I",
|
||||
(void *)android_hardware_SoundTrigger_stopRecognition},
|
||||
{"getModelState",
|
||||
"(I)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;",
|
||||
"(I)I",
|
||||
(void *)android_hardware_SoundTrigger_getModelState},
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.hardware.soundtrigger.SoundTrigger;
|
||||
@@ -367,15 +366,15 @@ public final class SoundTriggerManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously get state of the indicated model. The model state is returned as
|
||||
* a recognition event, or null if the model is not loaded, or if this method
|
||||
* is not supported.
|
||||
* Asynchronously get state of the indicated model. The model state is returned as
|
||||
* a recognition event in the callback that was registered in the startRecognition
|
||||
* method.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
|
||||
public SoundTrigger.RecognitionEvent getModelState(UUID soundModelId) {
|
||||
public int getModelState(UUID soundModelId) {
|
||||
if (soundModelId == null) {
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
try {
|
||||
return mSoundTriggerService.getModelState(new ParcelUuid(soundModelId));
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.os.RemoteException;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -566,38 +567,34 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
||||
}
|
||||
}
|
||||
|
||||
SoundTrigger.RecognitionEvent getGenericModelState(UUID modelId) {
|
||||
int getGenericModelState(UUID modelId) {
|
||||
synchronized (mLock) {
|
||||
MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
|
||||
if (modelId == null || mModule == null) {
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
ModelData modelData = mModelDataMap.get(modelId);
|
||||
if (modelData == null || !modelData.isGenericModel()) {
|
||||
Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
|
||||
modelId);
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if (!modelData.isModelLoaded()) {
|
||||
Slog.i(TAG, "GetGenericModelState: Given generic model is not loaded:" + modelId);
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if (!modelData.isModelStarted()) {
|
||||
Slog.i(TAG, "GetGenericModelState: Given generic model is not started:" + modelId);
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
SoundTrigger.RecognitionEvent ret = mModule.getModelState(modelData.getHandle());
|
||||
if (ret == null) {
|
||||
Slog.w(TAG, "GetGenericModelState() call failed");
|
||||
}
|
||||
return ret;
|
||||
return mModule.getModelState(modelData.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
SoundTrigger.RecognitionEvent getKeyphraseModelState(UUID modelId) {
|
||||
int getKeyphraseModelState(UUID modelId) {
|
||||
Slog.w(TAG, "GetKeyphraseModelState error: Not implemented");
|
||||
return null;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
//---- SoundTrigger.StatusListener methods
|
||||
|
||||
@@ -436,9 +436,10 @@ public class SoundTriggerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundTrigger.RecognitionEvent getModelState(ParcelUuid soundModelId) {
|
||||
public int getModelState(ParcelUuid soundModelId) {
|
||||
enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
|
||||
if (!isInitialized()) return null;
|
||||
int ret = STATUS_ERROR;
|
||||
if (!isInitialized()) return ret;
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "getModelState(): id = " + soundModelId);
|
||||
}
|
||||
@@ -447,9 +448,8 @@ public class SoundTriggerService extends SystemService {
|
||||
SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
|
||||
if (soundModel == null) {
|
||||
Slog.e(TAG, soundModelId + " is not loaded");
|
||||
return null;
|
||||
return ret;
|
||||
}
|
||||
SoundTrigger.RecognitionEvent ret = null;
|
||||
switch (soundModel.type) {
|
||||
case SoundModel.TYPE_KEYPHRASE:
|
||||
ret = mSoundTriggerHelper.getKeyphraseModelState(soundModel.uuid);
|
||||
@@ -461,9 +461,6 @@ public class SoundTriggerService extends SystemService {
|
||||
Slog.e(TAG, "Unknown model type");
|
||||
break;
|
||||
}
|
||||
if (ret == null) {
|
||||
Slog.e(TAG, "Failed to get model state");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -942,7 +939,11 @@ public class SoundTriggerService extends SystemService {
|
||||
runOrAddOperation(new Operation(
|
||||
// always execute:
|
||||
() -> {
|
||||
if (!mRecognitionConfig.allowMultipleTriggers) {
|
||||
// Don't remove the callback if multiple triggers are allowed or
|
||||
// if this event was triggered by a getModelState request
|
||||
if (!mRecognitionConfig.allowMultipleTriggers
|
||||
&& event.status
|
||||
!= SoundTrigger.RECOGNITION_STATUS_GET_STATE_RESPONSE) {
|
||||
// Unregister this remoteService once op is done
|
||||
synchronized (mCallbacksLock) {
|
||||
mCallbacks.remove(mPuuid.getUuid());
|
||||
|
||||
Reference in New Issue
Block a user