1 /** 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media.soundtrigger; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.content.Context; 23 import android.hardware.soundtrigger.SoundTrigger; 24 import android.os.Handler; 25 import android.os.ParcelUuid; 26 import android.os.RemoteException; 27 import android.util.Slog; 28 29 import com.android.internal.app.ISoundTriggerService; 30 31 import java.util.HashMap; 32 import java.util.UUID; 33 34 /** 35 * This class provides management of non-voice (general sound trigger) based sound recognition 36 * models. Usage of this class is restricted to system or signature applications only. This allows 37 * OEMs to write apps that can manage non-voice based sound trigger models. 38 * 39 * @hide 40 */ 41 @SystemApi 42 public final class SoundTriggerManager { 43 private static final boolean DBG = false; 44 private static final String TAG = "SoundTriggerManager"; 45 46 private final Context mContext; 47 private final ISoundTriggerService mSoundTriggerService; 48 49 // Stores a mapping from the sound model UUID to the SoundTriggerInstance created by 50 // the createSoundTriggerDetector() call. 51 private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap; 52 53 /** 54 * @hide 55 */ 56 public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService ) { 57 if (DBG) { 58 Slog.i(TAG, "SoundTriggerManager created."); 59 } 60 mSoundTriggerService = soundTriggerService; 61 mContext = context; 62 mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>(); 63 } 64 65 /** 66 * Updates the given sound trigger model. 67 */ 68 public void updateModel(Model model) { 69 try { 70 mSoundTriggerService.updateSoundModel(model.getGenericSoundModel()); 71 } catch (RemoteException e) { 72 throw e.rethrowFromSystemServer(); 73 } 74 } 75 76 /** 77 * Returns the sound trigger model represented by the given UUID. An instance of {@link Model} 78 * is returned. 79 */ 80 public Model getModel(UUID soundModelId) { 81 try { 82 return new Model(mSoundTriggerService.getSoundModel( 83 new ParcelUuid(soundModelId))); 84 } catch (RemoteException e) { 85 throw e.rethrowFromSystemServer(); 86 } 87 } 88 89 /** 90 * Deletes the sound model represented by the provided UUID. 91 */ 92 public void deleteModel(UUID soundModelId) { 93 try { 94 mSoundTriggerService.deleteSoundModel(new ParcelUuid(soundModelId)); 95 } catch (RemoteException e) { 96 throw e.rethrowFromSystemServer(); 97 } 98 } 99 100 /** 101 * Creates an instance of {@link SoundTriggerDetector} which can be used to start/stop 102 * recognition on the model and register for triggers from the model. Note that this call 103 * invalidates any previously returned instances for the same sound model Uuid. 104 * 105 * @param soundModelId UUID of the sound model to create the receiver object for. 106 * @param callback Instance of the {@link SoundTriggerDetector#Callback} object for the 107 * callbacks for the given sound model. 108 * @param handler The Handler to use for the callback operations. A null value will use the 109 * current thread's Looper. 110 * @return Instance of {@link SoundTriggerDetector} or null on error. 111 */ 112 @Nullable 113 public SoundTriggerDetector createSoundTriggerDetector(UUID soundModelId, 114 @NonNull SoundTriggerDetector.Callback callback, @Nullable Handler handler) { 115 if (soundModelId == null) { 116 return null; 117 } 118 119 SoundTriggerDetector oldInstance = mReceiverInstanceMap.get(soundModelId); 120 if (oldInstance != null) { 121 // Shutdown old instance. 122 } 123 SoundTriggerDetector newInstance = new SoundTriggerDetector(mSoundTriggerService, 124 soundModelId, callback, handler); 125 mReceiverInstanceMap.put(soundModelId, newInstance); 126 return newInstance; 127 } 128 129 /** 130 * Class captures the data and fields that represent a non-keyphrase sound model. Use the 131 * factory constructor {@link Model#create()} to create an instance. 132 */ 133 // We use encapsulation to expose the SoundTrigger.GenericSoundModel as a SystemApi. This 134 // prevents us from exposing SoundTrigger.GenericSoundModel as an Api. 135 public static class Model { 136 137 private SoundTrigger.GenericSoundModel mGenericSoundModel; 138 139 /** 140 * @hide 141 */ 142 Model(SoundTrigger.GenericSoundModel soundTriggerModel) { 143 mGenericSoundModel = soundTriggerModel; 144 } 145 146 /** 147 * Factory constructor to create a SoundModel instance for use with methods in this 148 * class. 149 */ 150 public static Model create(UUID modelUuid, UUID vendorUuid, byte[] data) { 151 return new Model(new SoundTrigger.GenericSoundModel(modelUuid, 152 vendorUuid, data)); 153 } 154 155 public UUID getModelUuid() { 156 return mGenericSoundModel.uuid; 157 } 158 159 public UUID getVendorUuid() { 160 return mGenericSoundModel.vendorUuid; 161 } 162 163 public byte[] getModelData() { 164 return mGenericSoundModel.data; 165 } 166 167 /** 168 * @hide 169 */ 170 SoundTrigger.GenericSoundModel getGenericSoundModel() { 171 return mGenericSoundModel; 172 } 173 } 174 } 175