diff options
author | Arunesh Mishra <arunesh@google.com> | 2016-01-25 10:33:11 -0800 |
---|---|---|
committer | Arunesh Mishra <arunesh@google.com> | 2016-01-27 12:49:20 -0800 |
commit | a772e5fc062c8de48cb9c1d61755110f6b2e189b (patch) | |
tree | 3ee387dd521a8d8d6c3bbc8841542ca07a5078aa /tests/SoundTriggerTestApp | |
parent | 5c461fc36d79d13b037ef928beb38fdb64e94057 (diff) |
SoundTrigger API improvements.
This CL implements the SoundTrigger API improvements as given in b/22860713. Only the java-level
parts are implemented in this CL.
Key changes include:
* Addition of a SoundTriggerManager/SoundTriggerDetector system API to manage
the sound-trigger based sound models.
* Addition of a SoundTriggerService service that manages all sound models
including voice (keyphrase) and sound-trigger based models.
* Includes logic to write sound-trigger based models to the database.
* VoiceInteractionManager service now uses SoundTriggerService instead of
SoundTriggerHelper.
Bug: 22860713
Change-Id: I7b5c0ed80702527c4460372efeb5e542d3693a69
Diffstat (limited to 'tests/SoundTriggerTestApp')
6 files changed, 330 insertions, 0 deletions
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk new file mode 100644 index 000000000000..7bcab5e53772 --- /dev/null +++ b/tests/SoundTriggerTestApp/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := SoundTriggerTestApp + +LOCAL_MODULE_TAGS := optional + +LOCAL_PRIVILEGED_MODULE := true + +include $(BUILD_PACKAGE) diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml new file mode 100644 index 000000000000..40619da156ee --- /dev/null +++ b/tests/SoundTriggerTestApp/AndroidManifest.xml @@ -0,0 +1,17 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.test.soundtrigger"> + + <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" /> + <application + android:permission="android.permission.MANAGE_SOUND_TRIGGER"> + <activity + android:name="TestSoundTriggerActivity" + android:label="SoundTrigger Test Application" + android:theme="@android:style/Theme.Material.Light.Voice"> + <intent-filter> + <action android:name="com.android.intent.action.MANAGE_SOUND_TRIGGER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml new file mode 100644 index 000000000000..9d2b9d92c016 --- /dev/null +++ b/tests/SoundTriggerTestApp/res/layout/main.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 Google Inc. + + 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/enroll" + android:onClick="onEnrollButtonClicked" + android:padding="20dp" /> + + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/reenroll" + android:onClick="onReEnrollButtonClicked" + 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 diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml new file mode 100644 index 000000000000..07bac2a263ef --- /dev/null +++ b/tests/SoundTriggerTestApp/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 Google Inc. + + 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. +--> +<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 diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java new file mode 100644 index 000000000000..98713bd2c6f9 --- /dev/null +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 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 com.android.test.soundtrigger; + +import android.annotation.Nullable; +import android.content.Context; +import android.hardware.soundtrigger.SoundTrigger; +import android.hardware.soundtrigger.SoundTrigger.SoundTriggerModel; +import android.media.soundtrigger.SoundTriggerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.ParcelUuid; +import android.util.Log; + +import com.android.internal.app.ISoundTriggerService; + +import java.util.UUID; + +/** + * Utility class for the managing sound trigger sound models. + */ +public class SoundTriggerUtil { + private static final String TAG = "TestSoundTriggerUtil:Hotsound"; + + private final ISoundTriggerService mSoundTriggerService; + private final SoundTriggerManager mSoundTriggerManager; + private final Context mContext; + + public SoundTriggerUtil(Context context) { + mSoundTriggerService = ISoundTriggerService.Stub.asInterface( + ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE)); + mSoundTriggerManager = (SoundTriggerManager) context.getSystemService( + Context.SOUND_TRIGGER_SERVICE); + mContext = context; + } + + /** + * Adds/Updates a sound model. + * The sound model must contain a valid UUID. + * + * @param soundModel The sound model to add/update. + */ + public boolean addOrUpdateSoundModel(SoundTriggerModel soundModel) { + try { + mSoundTriggerService.updateSoundModel(soundModel); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in updateSoundModel", e); + } + return true; + } + + public void addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) { + mSoundTriggerManager.updateModel(soundModel); + } + + /** + * Gets the sound model for the given keyphrase, null if none exists. + * If a sound model for a given keyphrase exists, and it needs to be updated, + * it should be obtained using this method, updated and then passed in to + * {@link #addOrUpdateSoundModel(SoundTriggerModel)} without changing the IDs. + * + * @param modelId The model ID to look-up the sound model for. + * @return The sound model if one was found, null otherwise. + */ + @Nullable + public SoundTriggerModel getSoundModel(UUID modelId) { + SoundTriggerModel model = null; + try { + model = mSoundTriggerService.getSoundModel(new ParcelUuid(modelId)); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in updateKeyphraseSoundModel"); + } + + if (model == null) { + Log.w(TAG, "No models present for the gien keyphrase ID"); + return null; + } else { + return model; + } + } + + /** + * Deletes the sound model for the given keyphrase id. + * + * @param modelId The model ID to look-up the sound model for. + * @return {@code true} if the call succeeds, {@code false} otherwise. + */ + @Nullable + public boolean deleteSoundModel(UUID modelId) { + try { + mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelId)); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in updateSoundModel"); + } + return true; + } + + public void deleteSoundModelUsingManager(UUID modelId) { + mSoundTriggerManager.deleteModel(modelId); + } +} diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java new file mode 100644 index 000000000000..82890c1717c4 --- /dev/null +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 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 com.android.test.soundtrigger; + +import java.util.Random; +import java.util.UUID; + +import android.app.Activity; +import android.hardware.soundtrigger.SoundTrigger; +import android.hardware.soundtrigger.SoundTrigger.SoundTriggerModel; +import android.media.soundtrigger.SoundTriggerManager; +import android.os.Bundle; +import android.os.UserManager; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +public class TestSoundTriggerActivity extends Activity { + private static final String TAG = "TestSoundTriggerActivity"; + private static final boolean DBG = true; + + private SoundTriggerUtil mSoundTriggerUtil; + private Random mRandom; + private UUID mModelUuid = UUID.randomUUID(); + private UUID mModelUuid2 = UUID.randomUUID(); + private UUID mVendorUuid = UUID.randomUUID(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + if (DBG) Log.d(TAG, "onCreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + mSoundTriggerUtil = new SoundTriggerUtil(this); + mRandom = new Random(); + } + + /** + * Called when the user clicks the enroll button. + * Performs a fresh enrollment. + */ + public void onEnrollButtonClicked(View v) { + // Generate a fake model to push. + byte[] data = new byte[1024]; + mRandom.nextBytes(data); + SoundTriggerModel model = new SoundTriggerModel(mModelUuid, mVendorUuid, data); + + boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(model); + if (status) { + Toast.makeText( + this, "Successfully created sound trigger model UUID=" + mModelUuid, Toast.LENGTH_SHORT) + .show(); + } else { + Toast.makeText(this, "Failed to enroll!!!" + mModelUuid, Toast.LENGTH_SHORT).show(); + } + + // Test the SoundManager API. + SoundTriggerManager.Model tmpModel = SoundTriggerManager.Model.create(mModelUuid2, + mVendorUuid, data); + mSoundTriggerUtil.addOrUpdateSoundModel(tmpModel); + } + + /** + * Called when the user clicks the un-enroll button. + * Clears the enrollment information for the user. + */ + public void onUnEnrollButtonClicked(View v) { + SoundTriggerModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid); + if (soundModel == null) { + Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show(); + return; + } + boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid); + if (status) { + Toast.makeText(this, "Successfully deleted model UUID=" + soundModel.uuid, + Toast.LENGTH_SHORT) + .show(); + } else { + Toast.makeText(this, "Failed to delete sound model!!!", Toast.LENGTH_SHORT).show(); + } + mSoundTriggerUtil.deleteSoundModelUsingManager(mModelUuid2); + } + + /** + * Called when the user clicks the re-enroll button. + * Uses the previously enrolled sound model and makes changes to it before pushing it back. + */ + public void onReEnrollButtonClicked(View v) { + SoundTriggerModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid); + if (soundModel == null) { + Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show(); + return; + } + // Generate a fake model to push. + byte[] data = new byte[2048]; + mRandom.nextBytes(data); + SoundTriggerModel updated = new SoundTriggerModel(soundModel.uuid, + soundModel.vendorUuid, data); + boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(updated); + if (status) { + Toast.makeText(this, "Successfully re-enrolled, model UUID=" + updated.uuid, + Toast.LENGTH_SHORT) + .show(); + } else { + Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show(); + } + } +} |