diff options
Diffstat (limited to 'tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java')
-rw-r--r-- | tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java new file mode 100644 index 0000000..9e544a5 --- /dev/null +++ b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java @@ -0,0 +1,198 @@ +/* + * 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.voiceenrollment; + +import android.annotation.Nullable; +import android.content.Context; +import android.hardware.soundtrigger.KeyphraseEnrollmentInfo; +import android.hardware.soundtrigger.SoundTrigger; +import android.hardware.soundtrigger.SoundTrigger.Keyphrase; +import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.service.voice.AlwaysOnHotwordDetector; +import android.util.Log; + +import com.android.internal.app.IVoiceInteractionManagerService; + +/** + * Utility class for the enrollment operations like enroll;re-enroll & un-enroll. + */ +public class EnrollmentUtil { + private static final String TAG = "TestEnrollmentUtil"; + + /** + * Activity Action: Show activity for managing the keyphrases for hotword detection. + * This needs to be defined by an activity that supports enrolling users for hotword/keyphrase + * detection. + */ + public static final String ACTION_MANAGE_VOICE_KEYPHRASES = + KeyphraseEnrollmentInfo.ACTION_MANAGE_VOICE_KEYPHRASES; + + /** + * Intent extra: The intent extra for the specific manage action that needs to be performed. + * Possible values are {@link AlwaysOnHotwordDetector#MANAGE_ACTION_ENROLL}, + * {@link AlwaysOnHotwordDetector#MANAGE_ACTION_RE_ENROLL} + * or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL}. + */ + public static final String EXTRA_VOICE_KEYPHRASE_ACTION = + KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_ACTION; + + /** + * Intent extra: The hint text to be shown on the voice keyphrase management UI. + */ + public static final String EXTRA_VOICE_KEYPHRASE_HINT_TEXT = + KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_HINT_TEXT; + /** + * Intent extra: The voice locale to use while managing the keyphrase. + */ + public static final String EXTRA_VOICE_KEYPHRASE_LOCALE = + KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_LOCALE; + + /** Simple recognition of the key phrase */ + public static final int RECOGNITION_MODE_VOICE_TRIGGER = + SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER; + /** Trigger only if one user is identified */ + public static final int RECOGNITION_MODE_USER_IDENTIFICATION = + SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION; + + private final IVoiceInteractionManagerService mModelManagementService; + + public EnrollmentUtil() { + mModelManagementService = IVoiceInteractionManagerService.Stub.asInterface( + ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)); + } + + /** + * Adds/Updates a sound model. + * The sound model must contain a valid UUID, + * exactly 1 keyphrase, + * and users for which the keyphrase is valid - typically the current user. + * + * @param soundModel The sound model to add/update. + * @return {@code true} if the call succeeds, {@code false} otherwise. + */ + public boolean addOrUpdateSoundModel(KeyphraseSoundModel soundModel) { + if (!verifyKeyphraseSoundModel(soundModel)) { + return false; + } + + int status = SoundTrigger.STATUS_ERROR; + try { + status = mModelManagementService.updateKeyphraseSoundModel(soundModel); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in updateKeyphraseSoundModel", e); + } + return status == SoundTrigger.STATUS_OK; + } + + /** + * Gets the sound model for the given keyphrase, null if none exists. + * This should be used for re-enrollment purposes. + * 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(KeyphraseSoundModel)} without changing the IDs. + * + * @param keyphraseId The keyphrase ID to look-up the sound model for. + * @param bcp47Locale The locale for with to look up the sound model for. + * @return The sound model if one was found, null otherwise. + */ + @Nullable + public KeyphraseSoundModel getSoundModel(int keyphraseId, String bcp47Locale) { + if (keyphraseId <= 0) { + Log.e(TAG, "Keyphrase must have a valid ID"); + return null; + } + + KeyphraseSoundModel model = null; + try { + model = mModelManagementService.getKeyphraseSoundModel(keyphraseId, bcp47Locale); + } 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 keyphraseId The keyphrase ID to look-up the sound model for. + * @return {@code true} if the call succeeds, {@code false} otherwise. + */ + @Nullable + public boolean deleteSoundModel(int keyphraseId, String bcp47Locale) { + if (keyphraseId <= 0) { + Log.e(TAG, "Keyphrase must have a valid ID"); + return false; + } + + int status = SoundTrigger.STATUS_ERROR; + try { + status = mModelManagementService.deleteKeyphraseSoundModel(keyphraseId, bcp47Locale); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in updateKeyphraseSoundModel"); + } + return status == SoundTrigger.STATUS_OK; + } + + private boolean verifyKeyphraseSoundModel(KeyphraseSoundModel soundModel) { + if (soundModel == null) { + Log.e(TAG, "KeyphraseSoundModel must be non-null"); + return false; + } + if (soundModel.uuid == null) { + Log.e(TAG, "KeyphraseSoundModel must have a UUID"); + return false; + } + if (soundModel.data == null) { + Log.e(TAG, "KeyphraseSoundModel must have data"); + return false; + } + if (soundModel.keyphrases == null || soundModel.keyphrases.length != 1) { + Log.e(TAG, "Keyphrase must be exactly 1"); + return false; + } + Keyphrase keyphrase = soundModel.keyphrases[0]; + if (keyphrase.id <= 0) { + Log.e(TAG, "Keyphrase must have a valid ID"); + return false; + } + if (keyphrase.recognitionModes < 0) { + Log.e(TAG, "Recognition modes must be valid"); + return false; + } + if (keyphrase.locale == null) { + Log.e(TAG, "Locale must not be null"); + return false; + } + if (keyphrase.text == null) { + Log.e(TAG, "Text must not be null"); + return false; + } + if (keyphrase.users == null || keyphrase.users.length == 0) { + Log.e(TAG, "Keyphrase must have valid user(s)"); + return false; + } + return true; + } +} |