1b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha/* 2b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Copyright (C) 2014 The Android Open Source Project 3b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 4b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Licensed under the Apache License, Version 2.0 (the "License"); 5b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * you may not use this file except in compliance with the License. 6b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * You may obtain a copy of the License at 7b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 8b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * http://www.apache.org/licenses/LICENSE-2.0 9b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 10b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Unless required by applicable law or agreed to in writing, software 11b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * distributed under the License is distributed on an "AS IS" BASIS, 12b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * See the License for the specific language governing permissions and 14b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * limitations under the License. 15b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 16b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 17b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthapackage com.android.test.voiceenrollment; 18b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 19b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.annotation.Nullable; 20b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.content.Context; 21b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.hardware.soundtrigger.KeyphraseEnrollmentInfo; 22b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger; 23b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.Keyphrase; 24b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; 25b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.os.RemoteException; 26b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.os.ServiceManager; 27b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.service.voice.AlwaysOnHotwordDetector; 28b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport android.util.Log; 29b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 30b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthaimport com.android.internal.app.IVoiceInteractionManagerService; 31b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 32b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha/** 33b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Utility class for the enrollment operations like enroll;re-enroll & un-enroll. 34b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 35b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddharthapublic class EnrollmentUtil { 36b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha private static final String TAG = "TestEnrollmentUtil"; 37b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 38b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 39b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Activity Action: Show activity for managing the keyphrases for hotword detection. 40b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * This needs to be defined by an activity that supports enrolling users for hotword/keyphrase 41b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * detection. 42b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 43b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final String ACTION_MANAGE_VOICE_KEYPHRASES = 44b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha KeyphraseEnrollmentInfo.ACTION_MANAGE_VOICE_KEYPHRASES; 45b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 46b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 47b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Intent extra: The intent extra for the specific manage action that needs to be performed. 48b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Possible values are {@link AlwaysOnHotwordDetector#MANAGE_ACTION_ENROLL}, 49b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * {@link AlwaysOnHotwordDetector#MANAGE_ACTION_RE_ENROLL} 50b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL}. 51b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 52b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final String EXTRA_VOICE_KEYPHRASE_ACTION = 53b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_ACTION; 54b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 55b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 56b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Intent extra: The hint text to be shown on the voice keyphrase management UI. 57b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 58b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final String EXTRA_VOICE_KEYPHRASE_HINT_TEXT = 59b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_HINT_TEXT; 60b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 61b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Intent extra: The voice locale to use while managing the keyphrase. 62b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 63b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final String EXTRA_VOICE_KEYPHRASE_LOCALE = 64b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_LOCALE; 65b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 66b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** Simple recognition of the key phrase */ 67b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final int RECOGNITION_MODE_VOICE_TRIGGER = 68b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER; 69b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** Trigger only if one user is identified */ 70b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 71b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION; 72b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 73b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha private final IVoiceInteractionManagerService mModelManagementService; 74b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 75b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public EnrollmentUtil() { 76b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha mModelManagementService = IVoiceInteractionManagerService.Stub.asInterface( 77b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)); 78b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 79b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 80b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 81b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Adds/Updates a sound model. 82b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * The sound model must contain a valid UUID, 83b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * exactly 1 keyphrase, 84b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * and users for which the keyphrase is valid - typically the current user. 85b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 86b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @param soundModel The sound model to add/update. 87b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @return {@code true} if the call succeeds, {@code false} otherwise. 88b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 89b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public boolean addOrUpdateSoundModel(KeyphraseSoundModel soundModel) { 90b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (!verifyKeyphraseSoundModel(soundModel)) { 91b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 92b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 93b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 94b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha int status = SoundTrigger.STATUS_ERROR; 95b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha try { 96b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha status = mModelManagementService.updateKeyphraseSoundModel(soundModel); 97b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } catch (RemoteException e) { 98b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "RemoteException in updateKeyphraseSoundModel", e); 99b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 100b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return status == SoundTrigger.STATUS_OK; 101b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 102b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 103b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 104b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Gets the sound model for the given keyphrase, null if none exists. 105b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * This should be used for re-enrollment purposes. 106b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * If a sound model for a given keyphrase exists, and it needs to be updated, 107b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * it should be obtained using this method, updated and then passed in to 108b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * {@link #addOrUpdateSoundModel(KeyphraseSoundModel)} without changing the IDs. 109b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 110b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @param keyphraseId The keyphrase ID to look-up the sound model for. 111b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @param bcp47Locale The locale for with to look up the sound model for. 112b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @return The sound model if one was found, null otherwise. 113b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 114b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha @Nullable 115b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public KeyphraseSoundModel getSoundModel(int keyphraseId, String bcp47Locale) { 116b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphraseId <= 0) { 117b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Keyphrase must have a valid ID"); 118b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return null; 119b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 120b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 121b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha KeyphraseSoundModel model = null; 122b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha try { 123b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha model = mModelManagementService.getKeyphraseSoundModel(keyphraseId, bcp47Locale); 124b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } catch (RemoteException e) { 125b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "RemoteException in updateKeyphraseSoundModel"); 126b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 127b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 128b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (model == null) { 129b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.w(TAG, "No models present for the gien keyphrase ID"); 130b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return null; 131b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } else { 132b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return model; 133b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 134b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 135b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 136b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha /** 137b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * Deletes the sound model for the given keyphrase id. 138b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * 139b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @param keyphraseId The keyphrase ID to look-up the sound model for. 140b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha * @return {@code true} if the call succeeds, {@code false} otherwise. 141b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha */ 142b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha @Nullable 143b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha public boolean deleteSoundModel(int keyphraseId, String bcp47Locale) { 144b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphraseId <= 0) { 145b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Keyphrase must have a valid ID"); 146b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 147b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 148b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 149b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha int status = SoundTrigger.STATUS_ERROR; 150b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha try { 151b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha status = mModelManagementService.deleteKeyphraseSoundModel(keyphraseId, bcp47Locale); 152b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } catch (RemoteException e) { 153b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "RemoteException in updateKeyphraseSoundModel"); 154b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 155b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return status == SoundTrigger.STATUS_OK; 156b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 157b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha 158b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha private boolean verifyKeyphraseSoundModel(KeyphraseSoundModel soundModel) { 159b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (soundModel == null) { 160b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "KeyphraseSoundModel must be non-null"); 161b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 162b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 163b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (soundModel.uuid == null) { 164b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "KeyphraseSoundModel must have a UUID"); 165b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 166b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 167b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (soundModel.data == null) { 168b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "KeyphraseSoundModel must have data"); 169b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 170b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 171b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (soundModel.keyphrases == null || soundModel.keyphrases.length != 1) { 172b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Keyphrase must be exactly 1"); 173b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 174b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 175b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Keyphrase keyphrase = soundModel.keyphrases[0]; 176b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphrase.id <= 0) { 177b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Keyphrase must have a valid ID"); 178b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 179b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 180b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphrase.recognitionModes < 0) { 181b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Recognition modes must be valid"); 182b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 183b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 184b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphrase.locale == null) { 185b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Locale must not be null"); 186b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 187b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 188b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphrase.text == null) { 189b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Text must not be null"); 190b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 191b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 192b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha if (keyphrase.users == null || keyphrase.users.length == 0) { 193b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha Log.e(TAG, "Keyphrase must have valid user(s)"); 194b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return false; 195b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 196b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha return true; 197b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha } 198b585ac5b5e672c11c80a01eb42a0d3ebd495f21bSandeep Siddhartha} 199