diff options
author | 2018-10-24 06:04:42 +0000 | |
---|---|---|
committer | 2018-10-24 06:04:42 +0000 | |
commit | 0bf1666c51f181dc9d8bbf1e5928891e7e10f17c (patch) | |
tree | 385bce94b074bb85979d2339e1cee72bec752c01 | |
parent | 366d890f6db280fe238128e281f991373632a50e (diff) | |
parent | 73486ddbf35e6d74a6d1bcf94692469d4ef08bdc (diff) |
Merge changes from topic "getmodelstate-redo"
* changes:
Rolling forward with indentation fix.
Revert "Revert "Adding getModelState API to sound trigger""
6 files changed, 157 insertions, 1 deletions
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java index 838765b67dff..e970747d6642 100644 --- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java +++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java @@ -20,6 +20,7 @@ import android.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; + import java.lang.ref.WeakReference; /** @@ -131,6 +132,14 @@ public class SoundTriggerModule { @UnsupportedAppUsage public native int stopRecognition(int soundModelHandle); + /** + * Get the current state of a {@link SoundTrigger.SoundModel} + * @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 + */ + public native SoundTrigger.RecognitionEvent getModelState(int soundModelHandle); + private class NativeEventHandlerDelegate { private final Handler mHandler; @@ -207,4 +216,3 @@ public class SoundTriggerModule { } } } - diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl index b8a2dff95c37..c0c689ced521 100644 --- a/core/java/com/android/internal/app/ISoundTriggerService.aidl +++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl @@ -52,4 +52,6 @@ interface ISoundTriggerService { /** For both ...Intent and ...Service based usage */ boolean isRecognitionActive(in ParcelUuid parcelUuid); + + SoundTrigger.RecognitionEvent getModelState(in ParcelUuid parcelUuid); } diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp index 9dbb8d757e15..b417a5629f62 100644 --- a/core/jni/android_hardware_SoundTrigger.cpp +++ b/core/jni/android_hardware_SoundTrigger.cpp @@ -788,6 +788,63 @@ android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz, return status; } +static jobject +android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz, + jint jHandle) +{ + ALOGV("getModelState"); + sp<SoundTrigger> module = getSoundTrigger(env, thiz); + if (module == NULL) { + return NULL; + } + 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; +} + static const JNINativeMethod gMethods[] = { {"listModules", "(Ljava/util/ArrayList;)I", @@ -817,6 +874,9 @@ static const JNINativeMethod gModuleMethods[] = { {"stopRecognition", "(I)I", (void *)android_hardware_SoundTrigger_stopRecognition}, + {"getModelState", + "(I)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;", + (void *)android_hardware_SoundTrigger_getModelState}, }; int register_android_hardware_SoundTrigger(JNIEnv *env) diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java index 9eb0c6d70cfe..cf7bf19909d9 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerManager.java +++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java @@ -365,4 +365,22 @@ public final class SoundTriggerManager { return Integer.MAX_VALUE; } } + + /** + * 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. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) + public SoundTrigger.RecognitionEvent getModelState(UUID soundModelId) { + if (soundModelId == null) { + return null; + } + try { + return mSoundTriggerService.getModelState(new ParcelUuid(soundModelId)); + } 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 bafb0a2fd683..ad2501d7c8cf 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java @@ -566,6 +566,40 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } + SoundTrigger.RecognitionEvent getGenericModelState(UUID modelId) { + synchronized (mLock) { + MetricsLogger.count(mContext, "sth_get_generic_model_state", 1); + if (modelId == null || mModule == null) { + return null; + } + ModelData modelData = mModelDataMap.get(modelId); + if (modelData == null || !modelData.isGenericModel()) { + Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" + + modelId); + return null; + } + if (!modelData.isModelLoaded()) { + Slog.i(TAG, "GetGenericModelState: Given generic model is not loaded:" + modelId); + return null; + } + if (!modelData.isModelStarted()) { + Slog.i(TAG, "GetGenericModelState: Given generic model is not started:" + modelId); + return null; + } + + SoundTrigger.RecognitionEvent ret = mModule.getModelState(modelData.getHandle()); + if (ret == null) { + Slog.w(TAG, "GetGenericModelState() call failed"); + } + return ret; + } + } + + SoundTrigger.RecognitionEvent getKeyphraseModelState(UUID modelId) { + Slog.w(TAG, "GetKeyphraseModelState error: Not implemented"); + return null; + } + //---- SoundTrigger.StatusListener methods @Override public void onRecognition(RecognitionEvent event) { diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java index 7c22613664a5..d57fcb105f9b 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java @@ -434,6 +434,40 @@ public class SoundTriggerService extends SystemService { } return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid()); } + + @Override + public SoundTrigger.RecognitionEvent getModelState(ParcelUuid soundModelId) { + enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER); + if (!isInitialized()) return null; + if (DEBUG) { + Slog.i(TAG, "getModelState(): id = " + soundModelId); + } + + synchronized (mLock) { + SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid()); + if (soundModel == null) { + Slog.e(TAG, soundModelId + " is not loaded"); + return null; + } + SoundTrigger.RecognitionEvent ret = null; + switch (soundModel.type) { + case SoundModel.TYPE_KEYPHRASE: + ret = mSoundTriggerHelper.getKeyphraseModelState(soundModel.uuid); + break; + case SoundModel.TYPE_GENERIC_SOUND: + ret = mSoundTriggerHelper.getGenericModelState(soundModel.uuid); + break; + default: + Slog.e(TAG, "Unknown model type"); + break; + } + if (ret == null) { + Slog.e(TAG, "Failed to get model state"); + } + + return ret; + } + } } /** |