diff options
author | 2021-02-24 16:39:05 +0000 | |
---|---|---|
committer | 2021-02-24 16:39:05 +0000 | |
commit | 974f84eae23ee9bd01918b985b5bc42028f6b75c (patch) | |
tree | 2e30cf52d823d11cc014f1c184863255e21deee1 /tests/SoundTriggerTestApp | |
parent | d6a7bfed7137fb91d1652393489d2d267375b4c0 (diff) | |
parent | 09539c9d6051107be804ce6399d87bc030319470 (diff) |
Merge "Adding GetModelState button to SoundTriggerTestApp"
Diffstat (limited to 'tests/SoundTriggerTestApp')
5 files changed, 112 insertions, 8 deletions
diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml index 2c6c8d7cae20..1381c0a43c30 100644 --- a/tests/SoundTriggerTestApp/res/layout/main.xml +++ b/tests/SoundTriggerTestApp/res/layout/main.xml @@ -73,6 +73,14 @@ android:text="@string/play_trigger" android:onClick="onPlayTriggerButtonClicked" android:padding="20dp" /> + + <Button + android:id="@+id/get_state_id" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/get_model_state" + android:onClick="onGetModelStateButtonClicked" + android:padding="20dp" /> </LinearLayout> <LinearLayout diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml index c48b64884c5e..adb0fcf8e185 100644 --- a/tests/SoundTriggerTestApp/res/values/strings.xml +++ b/tests/SoundTriggerTestApp/res/values/strings.xml @@ -22,6 +22,7 @@ <string name="start_recog">Start</string> <string name="stop_recog">Stop</string> <string name="play_trigger">Play Trigger Audio</string> + <string name="get_model_state">Get State</string> <string name="capture">Capture Audio</string> <string name="stop_capture">Stop Capturing Audio</string> <string name="play_capture">Play Captured Audio</string> diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java index c3c4cf556986..72aa38dc7e4b 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java @@ -257,6 +257,14 @@ public class SoundTriggerTestActivity extends Activity implements SoundTriggerTe } } + public synchronized void onGetModelStateButtonClicked(View v) { + if (mService == null) { + Log.e(TAG, "Can't get model state: not bound to SoundTriggerTestService"); + } else { + mService.getModelState(mSelectedModelUuid); + } + } + public synchronized void onCaptureAudioCheckboxClicked(View v) { // See if we have the right permissions if (!mService.hasMicrophonePermission()) { diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java index 380e29984c63..6d4ffcff7d45 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java @@ -23,6 +23,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent; +import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel; import android.media.AudioAttributes; import android.media.AudioFormat; import android.media.AudioManager; @@ -46,6 +48,7 @@ import java.util.Properties; import java.util.Random; import java.util.UUID; + public class SoundTriggerTestService extends Service { private static final String TAG = "SoundTriggerTestSrv"; private static final String INTENT_ACTION = "com.android.intent.action.MANAGE_SOUND_TRIGGER"; @@ -57,6 +60,8 @@ public class SoundTriggerTestService extends Service { private Random mRandom; private UserActivity mUserActivity; + private static int captureCount; + public interface UserActivity { void addModel(UUID modelUuid, String state); void setModelState(UUID modelUuid, String state); @@ -131,6 +136,8 @@ public class SoundTriggerTestService extends Service { } else if (command.equals("set_capture_timeout")) { setCaptureAudioTimeout(getModelUuidFromIntent(intent), intent.getIntExtra("timeout", 5000)); + } else if (command.equals("get_model_state")) { + getModelState(getModelUuidFromIntent(intent)); } else { Log.e(TAG, "Unknown command '" + command + "'"); } @@ -432,6 +439,17 @@ public class SoundTriggerTestService extends Service { return modelInfo != null && modelInfo.captureAudioTrack != null; } + public synchronized void getModelState(UUID modelUuid) { + ModelInfo modelInfo = mModelInfoMap.get(modelUuid); + if (modelInfo == null) { + postError("Could not find model for: " + modelUuid.toString()); + return; + } + int status = mSoundTriggerUtil.getModelState(modelUuid); + postMessage("GetModelState for: " + modelInfo.name + " returns: " + + status); + } + private void loadModelsInDataDir() { // Load all the models in the data dir. boolean loadedModel = false; @@ -527,18 +545,29 @@ public class SoundTriggerTestService extends Service { } } + private class CaptureAudioRecorder implements Runnable { private final ModelInfo mModelInfo; + + // EventPayload and RecognitionEvent are equivalant. Only one will be non-null. private final SoundTriggerDetector.EventPayload mEvent; + private final RecognitionEvent mRecognitionEvent; public CaptureAudioRecorder(ModelInfo modelInfo, SoundTriggerDetector.EventPayload event) { mModelInfo = modelInfo; mEvent = event; + mRecognitionEvent = null; + } + + public CaptureAudioRecorder(ModelInfo modelInfo, RecognitionEvent event) { + mModelInfo = modelInfo; + mEvent = null; + mRecognitionEvent = event; } @Override public void run() { - AudioFormat format = mEvent.getCaptureAudioFormat(); + AudioFormat format = getAudioFormat(); if (format == null) { postErrorToast("No audio format in recognition event."); return; @@ -600,18 +629,21 @@ public class SoundTriggerTestService extends Service { } audioRecord = new AudioRecord(attributes, format, bytesRequired, - mEvent.getCaptureSession()); + getCaptureSession()); byte[] buffer = new byte[bytesRequired]; // Create a file so we can save the output data there for analysis later. FileOutputStream fos = null; try { - fos = new FileOutputStream( new File( - getFilesDir() + File.separator - + mModelInfo.name.replace(' ', '_') - + "_capture_" + format.getChannelCount() + "ch_" - + format.getSampleRate() + "hz_" + encoding + ".pcm")); + File file = new File( + getFilesDir() + File.separator + + mModelInfo.name.replace(' ', '_') + + "_capture_" + format.getChannelCount() + "ch_" + + format.getSampleRate() + "hz_" + encoding + + "_" + (++captureCount) + ".pcm"); + Log.i(TAG, "Writing audio to: " + file); + fos = new FileOutputStream(file); } catch (IOException e) { Log.e(TAG, "Failed to open output for saving PCM data", e); postErrorToast("Failed to open output for saving PCM data: " @@ -635,6 +667,10 @@ public class SoundTriggerTestService extends Service { bytesRequired -= bytesRead; } audioRecord.stop(); + if (fos != null) { + fos.flush(); + fos.close(); + } } catch (Exception e) { Log.e(TAG, "Error recording trigger audio", e); postErrorToast("Error recording trigger audio: " + e.getMessage()); @@ -651,6 +687,26 @@ public class SoundTriggerTestService extends Service { setModelState(mModelInfo, "Recording finished"); } } + + private AudioFormat getAudioFormat() { + if (mEvent != null) { + return mEvent.getCaptureAudioFormat(); + } + if (mRecognitionEvent != null) { + return mRecognitionEvent.captureFormat; + } + return null; + } + + private int getCaptureSession() { + if (mEvent != null) { + return mEvent.getCaptureSession(); + } + if (mRecognitionEvent != null) { + return mRecognitionEvent.captureSession; + } + return 0; + } } // Implementation of SoundTriggerDetector.Callback. diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java index cfe8c855ac81..996a78f2e42a 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java @@ -18,6 +18,8 @@ package com.android.test.soundtrigger; import android.annotation.Nullable; import android.content.Context; +import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent; +import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel; import android.media.soundtrigger.SoundTriggerDetector; import android.media.soundtrigger.SoundTriggerManager; import android.os.RemoteException; @@ -27,6 +29,7 @@ import android.util.Log; import com.android.internal.app.ISoundTriggerService; +import java.lang.reflect.Method; import java.lang.RuntimeException; import java.util.UUID; @@ -50,13 +53,31 @@ public class SoundTriggerUtil { * The sound model must contain a valid UUID. * * @param soundModel The sound model to add/update. + * @return The true if the model was loaded successfully, false otherwise. */ public boolean addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) { if (soundModel == null) { throw new RuntimeException("Bad sound model"); } mSoundTriggerManager.updateModel(soundModel); - return true; + // TODO: call loadSoundModel in the soundtrigger manager updateModel method + // instead of here. It is needed to keep soundtrigger manager internal + // state consistent. + return mSoundTriggerManager + .loadSoundModel(getGenericSoundModel(soundModel)) == 0; + } + + private GenericSoundModel getGenericSoundModel( + SoundTriggerManager.Model soundModel) { + try { + Method method = SoundTriggerManager.Model.class + .getDeclaredMethod("getGenericSoundModel"); + method.setAccessible(true); + return (GenericSoundModel) method.invoke(soundModel); + } catch (ReflectiveOperationException e) { + Log.e(TAG, "Failed to getGenericSoundModel: " + soundModel, e); + return null; + } } /** @@ -92,6 +113,16 @@ public class SoundTriggerUtil { return true; } + /** + * Get the current model state + * + * @param modelId The model ID to look-up the sound model for. + * @return 0 if the call succeeds, or an error code if it fails. + */ + public int getModelState(UUID modelId) { + return mSoundTriggerManager.getModelState(modelId); + } + public SoundTriggerDetector createSoundTriggerDetector(UUID modelId, SoundTriggerDetector.Callback callback) { return mSoundTriggerManager.createSoundTriggerDetector(modelId, callback, null); |