diff options
author | 2016-02-09 12:15:19 -0800 | |
---|---|---|
committer | 2016-02-17 14:24:03 -0800 | |
commit | 3fff7f5634ca788c1c84b6f1b316819ffd4c7cb2 (patch) | |
tree | 20eda00acc17334e7efc29a22dd552b6900eee05 /tests/SoundTriggerTestApp | |
parent | 93dfc03ba632590e30604dde31b78628df962eff (diff) |
SoundTriggerHelper changes for GenericSoundModels.
- Refactoring SoundTriggerHelper to handle generic sound models.
- Ability to store multiple models, callback and state information.
- Separate out initialization to be done per voice model, per any model
and per generic model.
- Minor change to the API exposed -- removing the Handler from the
createSoundTriggerDetector call.
- Added callback processing for onRecognitionEvent().
- Added logic for stopAll().
- Changes to the SoundTriggerTestApp to start/stop recognition.
- Multiple models (3).
- Ability to start/stop/load/unload individual models.
Bug: 22860713
Bug: 27222043
Change-Id: Ie5d811babb956bead653fb560a43f1e549ed11bd
Diffstat (limited to 'tests/SoundTriggerTestApp')
6 files changed, 223 insertions, 20 deletions
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk index 7bcab5e53772..c327b0956811 100644 --- a/tests/SoundTriggerTestApp/Android.mk +++ b/tests/SoundTriggerTestApp/Android.mk @@ -8,5 +8,6 @@ LOCAL_PACKAGE_NAME := SoundTriggerTestApp LOCAL_MODULE_TAGS := optional LOCAL_PRIVILEGED_MODULE := true +LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml index 40619da156ee..a72b3ddb7c0c 100644 --- a/tests/SoundTriggerTestApp/AndroidManifest.xml +++ b/tests/SoundTriggerTestApp/AndroidManifest.xml @@ -2,16 +2,22 @@ package="com.android.test.soundtrigger"> <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" /> - <application - android:permission="android.permission.MANAGE_SOUND_TRIGGER"> + <application> <activity android:name="TestSoundTriggerActivity" android:label="SoundTrigger Test Application" - android:theme="@android:style/Theme.Material.Light.Voice"> + android:theme="@android:style/Theme.Material"> + <!-- <intent-filter> <action android:name="com.android.intent.action.MANAGE_SOUND_TRIGGER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> + --> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> </activity> </application> </manifest> diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml index 9d2b9d92c016..5ecc7705cd75 100644 --- a/tests/SoundTriggerTestApp/res/layout/main.xml +++ b/tests/SoundTriggerTestApp/res/layout/main.xml @@ -18,6 +18,11 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" + android:orientation="vertical" + > +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" > <Button @@ -37,7 +42,57 @@ <Button android:layout_width="wrap_content" android:layout_height="wrap_content" + android:text="@string/start_recog" + android:onClick="onStartRecognitionButtonClicked" + android:padding="20dp" /> + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/stop_recog" + android:onClick="onStopRecognitionButtonClicked" + android:padding="20dp" /> + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:text="@string/unenroll" android:onClick="onUnEnrollButtonClicked" android:padding="20dp" /> -</LinearLayout>
\ No newline at end of file + +</LinearLayout> + +<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:padding="20dp" + android:orientation="vertical"> + <RadioButton android:id="@+id/model_one" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/model_one" + android:onClick="onRadioButtonClicked"/> + <RadioButton android:id="@+id/model_two" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/model_two" + android:onClick="onRadioButtonClicked"/> + <RadioButton android:id="@+id/model_three" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/model_three" + android:onClick="onRadioButtonClicked"/> +</RadioGroup> + + <TextView + android:id="@+id/console" + android:gravity="left" + android:paddingTop="20pt" + android:layout_height="fill_parent" + android:layout_width="match_parent" + android:maxLines="40" + android:textSize="14dp" + android:scrollbars = "vertical" + android:text="@string/none"> + </TextView> +</LinearLayout> diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml index 07bac2a263ef..5f0fb1daf3e9 100644 --- a/tests/SoundTriggerTestApp/res/values/strings.xml +++ b/tests/SoundTriggerTestApp/res/values/strings.xml @@ -16,7 +16,13 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enroll">Enroll</string> - <string name="reenroll">Re-enroll</string> - <string name="unenroll">Un-enroll</string> -</resources>
\ No newline at end of file + <string name="enroll">Load</string> + <string name="reenroll">Re-load</string> + <string name="unenroll">Un-load</string> + <string name="start_recog">Start</string> + <string name="stop_recog">Stop</string> + <string name="model_one">Model One</string> + <string name="model_two">Model Two</string> + <string name="model_three">Model Three</string> + <string name="none">Debug messages appear here:</string> +</resources> diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java index 4702835eae43..1c95c25370d2 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.soundtrigger.SoundTrigger; import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel; +import android.media.soundtrigger.SoundTriggerDetector; import android.media.soundtrigger.SoundTriggerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -28,6 +29,7 @@ import android.util.Log; import com.android.internal.app.ISoundTriggerService; +import java.lang.RuntimeException; import java.util.UUID; /** @@ -56,6 +58,9 @@ public class SoundTriggerUtil { */ public boolean addOrUpdateSoundModel(GenericSoundModel soundModel) { try { + if (soundModel == null) { + throw new RuntimeException("Bad sound model"); + } mSoundTriggerService.updateSoundModel(soundModel); } catch (RemoteException e) { Log.e(TAG, "RemoteException in updateSoundModel", e); @@ -112,4 +117,10 @@ public class SoundTriggerUtil { public void deleteSoundModelUsingManager(UUID modelId) { mSoundTriggerManager.deleteModel(modelId); } + + public SoundTriggerDetector createSoundTriggerDetector(UUID modelId, + SoundTriggerDetector.Callback callback) { + return mSoundTriggerManager.createSoundTriggerDetector(modelId, callback, null); + } + } diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java index 966179b8dbd5..96a69661a7aa 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java @@ -22,11 +22,17 @@ import java.util.UUID; import android.app.Activity; import android.hardware.soundtrigger.SoundTrigger; import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel; +import android.media.AudioFormat; +import android.media.soundtrigger.SoundTriggerDetector; import android.media.soundtrigger.SoundTriggerManager; +import android.text.Editable; +import android.text.method.ScrollingMovementMethod; import android.os.Bundle; import android.os.UserManager; import android.util.Log; import android.view.View; +import android.widget.RadioButton; +import android.widget.TextView; import android.widget.Toast; public class TestSoundTriggerActivity extends Activity { @@ -35,42 +41,75 @@ public class TestSoundTriggerActivity extends Activity { private SoundTriggerUtil mSoundTriggerUtil; private Random mRandom; - private UUID mModelUuid = UUID.randomUUID(); + private UUID mModelUuid1 = UUID.randomUUID(); private UUID mModelUuid2 = UUID.randomUUID(); + private UUID mModelUuid3 = UUID.randomUUID(); private UUID mVendorUuid = UUID.randomUUID(); + private SoundTriggerDetector mDetector1 = null; + private SoundTriggerDetector mDetector2 = null; + private SoundTriggerDetector mDetector3 = null; + + private TextView mDebugView = null; + private int mSelectedModelId = 1; + @Override protected void onCreate(Bundle savedInstanceState) { if (DBG) Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.main); + mDebugView = (TextView) findViewById(R.id.console); + mDebugView.setText(mDebugView.getText(), TextView.BufferType.EDITABLE); + mDebugView.setMovementMethod(new ScrollingMovementMethod()); mSoundTriggerUtil = new SoundTriggerUtil(this); mRandom = new Random(); } + private void postMessage(String msg) { + Log.i(TAG, "Posted: " + msg); + ((Editable) mDebugView.getText()).append(msg + "\n"); + } + + private UUID getSelectedUuid() { + if (mSelectedModelId == 2) return mModelUuid2; + if (mSelectedModelId == 3) return mModelUuid3; + return mModelUuid1; // Default. + } + + private void setDetector(SoundTriggerDetector detector) { + if (mSelectedModelId == 2) mDetector2 = detector; + if (mSelectedModelId == 3) mDetector3 = detector; + mDetector1 = detector; + } + + private SoundTriggerDetector getDetector() { + if (mSelectedModelId == 2) return mDetector2; + if (mSelectedModelId == 3) return mDetector3; + return mDetector1; + } + /** * Called when the user clicks the enroll button. * Performs a fresh enrollment. */ public void onEnrollButtonClicked(View v) { + postMessage("Loading model: " + mSelectedModelId); // Generate a fake model to push. byte[] data = new byte[1024]; mRandom.nextBytes(data); - GenericSoundModel model = new GenericSoundModel(mModelUuid, mVendorUuid, data); + UUID modelUuid = getSelectedUuid(); + GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data); boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(model); if (status) { Toast.makeText( - this, "Successfully created sound trigger model UUID=" + mModelUuid, Toast.LENGTH_SHORT) - .show(); + this, "Successfully created sound trigger model UUID=" + modelUuid, + Toast.LENGTH_SHORT).show(); } else { - Toast.makeText(this, "Failed to enroll!!!" + mModelUuid, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "Failed to enroll!!!" + modelUuid, Toast.LENGTH_SHORT).show(); } // Test the SoundManager API. - SoundTriggerManager.Model tmpModel = SoundTriggerManager.Model.create(mModelUuid2, - mVendorUuid, data); - mSoundTriggerUtil.addOrUpdateSoundModel(tmpModel); } /** @@ -78,12 +117,14 @@ public class TestSoundTriggerActivity extends Activity { * Clears the enrollment information for the user. */ public void onUnEnrollButtonClicked(View v) { - GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid); + postMessage("Unloading model: " + mSelectedModelId); + UUID modelUuid = getSelectedUuid(); + GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(modelUuid); if (soundModel == null) { Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show(); return; } - boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid); + boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid1); if (status) { Toast.makeText(this, "Successfully deleted model UUID=" + soundModel.uuid, Toast.LENGTH_SHORT) @@ -91,7 +132,6 @@ public class TestSoundTriggerActivity extends Activity { } else { Toast.makeText(this, "Failed to delete sound model!!!", Toast.LENGTH_SHORT).show(); } - mSoundTriggerUtil.deleteSoundModelUsingManager(mModelUuid2); } /** @@ -99,7 +139,9 @@ public class TestSoundTriggerActivity extends Activity { * Uses the previously enrolled sound model and makes changes to it before pushing it back. */ public void onReEnrollButtonClicked(View v) { - GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid); + postMessage("Re-loading model: " + mSelectedModelId); + UUID modelUuid = getSelectedUuid(); + GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(modelUuid); if (soundModel == null) { Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show(); return; @@ -118,4 +160,86 @@ public class TestSoundTriggerActivity extends Activity { Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show(); } } + + public void onStartRecognitionButtonClicked(View v) { + UUID modelUuid = getSelectedUuid(); + SoundTriggerDetector detector = getDetector(); + if (detector == null) { + Log.i(TAG, "Created an instance of the SoundTriggerDetector."); + detector = mSoundTriggerUtil.createSoundTriggerDetector(modelUuid, + new DetectorCallback()); + setDetector(detector); + } + postMessage("Triggering start recognition for model: " + mSelectedModelId); + if (!detector.startRecognition( + SoundTriggerDetector.RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS)) { + Log.e(TAG, "Fast failure attempting to start recognition."); + } + } + + public void onStopRecognitionButtonClicked(View v) { + SoundTriggerDetector detector = getDetector(); + if (detector == null) { + Log.e(TAG, "Stop called on null detector."); + return; + } + postMessage("Triggering stop recognition for model: " + mSelectedModelId); + if (!detector.stopRecognition()) { + Log.e(TAG, "Fast failure attempting to stop recognition."); + } + } + + public void onRadioButtonClicked(View view) { + // Is the button now checked? + boolean checked = ((RadioButton) view).isChecked(); + // Check which radio button was clicked + switch(view.getId()) { + case R.id.model_one: + if (checked) mSelectedModelId = 1; + postMessage("Selected model one."); + break; + case R.id.model_two: + if (checked) mSelectedModelId = 2; + postMessage("Selected model two."); + break; + case R.id.model_three: + if (checked) mSelectedModelId = 3; + postMessage("Selected model three."); + break; + } + } + + // Implementation of SoundTriggerDetector.Callback. + public class DetectorCallback extends SoundTriggerDetector.Callback { + public void onAvailabilityChanged(int status) { + postMessage("Availability changed to: " + status); + } + + public void onDetected(SoundTriggerDetector.EventPayload event) { + postMessage("onDetected(): " + eventPayloadToString(event)); + } + + public void onError() { + postMessage("onError()"); + } + + public void onRecognitionPaused() { + postMessage("onRecognitionPaused()"); + } + + public void onRecognitionResumed() { + postMessage("onRecognitionResumed()"); + } + } + + private String eventPayloadToString(SoundTriggerDetector.EventPayload event) { + String result = "EventPayload("; + AudioFormat format = event.getCaptureAudioFormat(); + result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString()); + byte[] triggerAudio = event.getTriggerAudio(); + result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length); + result = result + "CaptureSession: " + event.getCaptureSession(); + result += " )"; + return result; + } } |