1 /* 2 * Copyright 2021 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.hardware.soundtrigger3; 18 19 import android.hardware.soundtrigger3.ISoundTriggerHwCallback; 20 import android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback; 21 import android.media.soundtrigger.ModelParameter; 22 import android.media.soundtrigger.ModelParameterRange; 23 import android.media.soundtrigger.PhraseSoundModel; 24 import android.media.soundtrigger.Properties; 25 import android.media.soundtrigger.RecognitionConfig; 26 import android.media.soundtrigger.SoundModel; 27 28 /** 29 * SoundTrigger HAL interface. Used for hardware recognition of hotwords 30 * and other sounds. 31 * 32 * Basic usage: 33 * ============ 34 * ISoundTriggerHw supports the ability to have one of more detection sessions running at a given 35 * time, and listening to acoustic events. The basic flow of setting up such a session is: 36 * - Load a model using loadSoundModel() or loadPhraseSoundModel(). The provided model object would 37 * indicate the (implementation-specific) detection algorithm (engine) to use, as well as any 38 * parameters applicable for this agorithm. Upon success, those methods would return a handle 39 * which will be used to reference this model in subsequent calls. 40 * - Once the model had been successfully loaded, detection can begin by calling startRecognition(). 41 * - Recognition will continue running in the background until one of the following events occurs: 42 * - stopRecognition() has been called on this model. 43 * - A detection has occurred. 44 * - Detection was aborted, typically for resource constraints, for example, when a higher- 45 * priority use-case has been initiated. 46 * - In the latter two cases, a recognition event will be sent via a the callback interface that was 47 * registered by the client upon loading. In either case, after any of these events occur, the 48 * detection becomes inactive and no more recognition callbacks are allowed. 49 * - The same model maybe started again at a later time, and this process may repeat as many times 50 * as needed. 51 * - Finally, an inactive model that is no longer needed may be unloaded via unloadModel(). 52 * 53 * Important notes about the threading model: 54 * ========================================== 55 * Both this interface and the corresponding callback interface use a synchronous calling 56 * convention. This model comes with some advantages, but also with some risks of deadlocks if the 57 * implementation does not handle this correctly. Please consider the following: 58 * - After stopRecognition() returns, no more recognition events for that model may be sent. This 59 * implies that any queues holding such events must be flushed before the call returns and that 60 * may imply that callback from the HAL to the client are done while stopRecognition() is blocked. 61 * This is OK, and supported by the framework. 62 * - Similarly, the same relationship applies between unloadModel() and subsequent callbacks to 63 * modelUnloaded(). 64 * - Other than these two cases, calls into the HAL *MAY NOT* block on callbacks from the HAL, or 65 * else deadlock conditions may result, which may be handled by rebooting of the HAL process and 66 * cause service outages. 67 * 68 * Due to the asynchronous nature of recognition events and preemptive model unloading, the HAL must 69 * correctly handle requests that would have been valid before an event has been delivered, but 70 * became moot as result of the event. Namely: 71 * - stopRecognition() may be called on a model that has already delivered an event and became 72 * inactive as a result. The HAL must return a successful return code in this case. 73 * - Furthermore, if a model is preemptively unloaded after it triggers (typically, this would 74 * happen when it is first aborted and immediately preemptively unloaded), stopRecognition() may 75 * be called on it. The HAL must return successfully in this case. 76 * - startRecognition() may be called on a model that has been preemptively unloaded. In this case, 77 * the HAL must signal a ServiceSpecificException(RESOURCE_CONTENTION) to indicate that the 78 * operation is temporarily unsuccessful. 79 * - unloadSoundModel() may be called on a model that has been preemptively unloaded. The HAL must 80 * return a successful return code in this case. This also implies that model handles should 81 * generally not be reused until explicitly unloaded. To avoid the rare possibility of running out 82 * of handles, the framework may call unloadModel() on models that have been preemptively unloaded 83 * by the HAL. 84 * 85 * Important notes about resource constraints and concurrency 86 * ========================================================= 87 * Up until this version, the framework would enforce concurrency constraints expressed by the 88 * Properties presented by the soundtrigger instance. These include constraints on the maximum 89 * amount of models that can be loaded at the same time and on running recognition while capturing 90 * from the microphone. 91 * This version changes the approach for how these constraints are modeled, both offering the HAL 92 * implementation more flexibility and simplifying the framework's job in enforcing these 93 * limitations. Note that there is no change for how the framework behaves with earlier versions, 94 * everything described below only applies to this version and onward. 95 * The way this is achieved is as following: 96 * - The framework will no longer enforce constraints on concurrent loading of models, as expressed 97 * in the Properties.maxSoundModels field (this property is merely a hint at this point and may be 98 * deprecated in the future), or any other implicit constraints. 99 * - The framework will no longer enforce constraints on concurrency of audio recording and 100 * soundtrigger operation, as expressed in the Properties.concurrentCapture field (this property 101 * is merely a hint at this point and may be deprecated in the future). 102 * - The HAL implementation is free to reject loading of any model at any time by having the 103 * respective load*() method signal a ServiceSpecificException(RESOURCE_CONTENTION). 104 * - The HAL implementation is free to reject starting of any model at any time by having the 105 * respective start*() method signal a ServiceSpecificException(RESOURCE_CONTENTION). 106 * - The HAL implementation is free to preemptively stop a previously started model at its own 107 * discretion (for example, if a higher priority use-case which cannot coexist with detection 108 * has been requested). The HAL must notify the framework of the preemption by sending a 109 * recognition event with an `ABORTED` status. The implementation must NOT attempt to restart the 110 * recognition automatically when conditions change. 111 * - The HAL implementation is free to preemptively unload a previously loaded model at its own 112 * discretion (for example, if a higher-priority model is being loaded and the two cannot 113 * coexist). When doing so, it must first abort the detection if active (as per above) and then 114 * notify the framework of the unload using the modelUnloaded() callback. 115 * - When conditions change, such that a model that couldn't previously load or start or that had 116 * previously been preemptively stopped or unloaded, the HAL must notify the framework via the 117 * newly added onResourcesAvailable() callback. This callback is not a guarantee that any 118 * operation would now succeed, but merely a hint that retrying something that had previously 119 * failed, now MAY succeed. Until this callback is invoked, the client may assume that any 120 * operation that had previously failed or aborted would still fail if retried, so the 121 * implementation should not forget to deliver it. 122 * There are no guarantees regarding how the framework may respond to this event and the order in 123 * which it may choose to reload/restart its models. Typically, as result of this event the 124 * framework will make a single attempt per model to bring this model to its desired state 125 * (loaded, started). 126 */ 127 @VintfStability 128 interface ISoundTriggerHw { 129 /** 130 * Retrieve implementation properties. 131 * 132 * @return A Properties structure containing implementation description and capabilities. 133 */ getProperties()134 Properties getProperties(); 135 136 /** 137 * This will get called at most once per every attachment to the service. 138 * 139 * All events not tied to a specific model should go through this callback. 140 * 141 * @param callback An interface to receive global event callbacks. 142 */ registerGlobalCallback(in ISoundTriggerHwGlobalCallback callback)143 void registerGlobalCallback(in ISoundTriggerHwGlobalCallback callback); 144 145 /** 146 * Load a sound model. Once loaded, recognition of this model can be started and stopped. 147 * 148 * @param soundModel A SoundModel structure describing the sound model to load. 149 * @param callback The callback interface on which the recognitionCallback() 150 * method will be called upon completion and modelUnloaded() upon preemptive unload. 151 * @return A unique handle assigned by the HAL for use by the client when controlling 152 * activity for this sound model. 153 * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be loaded due 154 * to resource constraints. This is typically a temporary condition and the client may 155 * retry after the onResourcesAvailable() global callback is invoked. 156 */ loadSoundModel(in SoundModel soundModel, in ISoundTriggerHwCallback callback)157 int loadSoundModel(in SoundModel soundModel, in ISoundTriggerHwCallback callback); 158 159 /** 160 * Load a key phrase sound model. Once loaded, recognition of this model can be started and 161 * stopped. 162 * 163 * @param soundModel A PhraseSoundModel structure describing the sound model to load. 164 * @param callback The callback interface on which the phraseRecognitionCallback() method will 165 * be called upon completion and modelUnloaded() upon preempted unload. 166 * @return A unique handle assigned by the HAL for use by the framework when controlling 167 * activity for this sound model. 168 * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be loaded due 169 * to resource constraints. This is typically a temporary condition and the client may 170 * retry after the onResourcesAvailable() global callback is invoked. 171 */ loadPhraseSoundModel(in PhraseSoundModel soundModel, in ISoundTriggerHwCallback callback)172 int loadPhraseSoundModel(in PhraseSoundModel soundModel, in ISoundTriggerHwCallback callback); 173 174 /** 175 * Unload a sound model. A sound model may be unloaded to free up resources and make room for a 176 * new one to overcome implementation limitations. 177 * This call is idempotent, to avoid any race conditions. 178 * 179 * @param modelHandle the handle of the sound model to unload. 180 */ unloadSoundModel(in int modelHandle)181 void unloadSoundModel(in int modelHandle); 182 183 /** 184 * Start recognition on a given model. 185 * This must be called on a model that is in the stopped state. 186 * The state of this model becomes active and will remain so until explicitly stopped, or a 187 * recognition event had been delivered to the client. 188 * 189 * @param modelHandle the handle of the sound model to use for recognition 190 * @param deviceHandle The handle of the audio device to be used for recognition, as declared by 191 * the audio subsystem. 192 * @param ioHandle A handle assigned by the framework, which will later be used to retrieve 193 * an audio stream associated with this recognition session. 194 * @param config A RecognitionConfig structure containing attributes of the recognition to 195 * perform. 196 * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be started due 197 * to resource constraints. This is typically a temporary condition and the client may 198 * retry after the onResourcesAvailable() global callback is invoked. 199 */ startRecognition( in int modelHandle, in int deviceHandle, in int ioHandle, in RecognitionConfig config)200 void startRecognition( 201 in int modelHandle, in int deviceHandle, in int ioHandle, in RecognitionConfig config); 202 203 /** 204 * Stop recognition on a given model. 205 * This call is idempotent, to avoid any race conditions. 206 * 207 * @param modelHandle The handle of the sound model to use for recognition 208 */ stopRecognition(in int modelHandle)209 void stopRecognition(in int modelHandle); 210 211 /** 212 * Request a recognition event to be generated. 213 * The model must be in the started state and will remain started after the event is sent. 214 * The model state is returned asynchronously as a RecognitionEvent via the callback that was 215 * registered upon loading. That event must have a RecognitionStatus.FORCED status. 216 * 217 * @param modelHandle The handle of the sound model whose state is being 218 * queried. 219 */ forceRecognitionEvent(in int modelHandle)220 void forceRecognitionEvent(in int modelHandle); 221 222 /** 223 * Get supported parameter attributes with respect to the provided model handle. 224 * Model parameters are used to query/control model-specific detection behavior during a 225 * detection session. 226 * Along with determining the valid range, this API is also used to determine if a given 227 * parameter ID is supported at all by the modelHandle for use with getParameter() and 228 * setParameter() APIs. 229 * 230 * @param modelHandle The sound model handle indicating which model to query. 231 * @param modelParam Parameter to set which will be validated against the ModelParameter type. 232 * @return This structure indicates supported attributes of the parameter for the given model 233 * handle. If the parameter is not supported, null is returned. 234 */ queryParameter( in int modelHandle, in ModelParameter modelParam)235 @nullable ModelParameterRange queryParameter( 236 in int modelHandle, in ModelParameter modelParam); 237 238 /** 239 * Get a model specific parameter. 240 * If the value has not been set, a default value is returned. See ModelParameter for parameter 241 * default values. 242 * The caller must check if the handle supports the parameter via the queryParameter API prior 243 * to calling this method. 244 * 245 * @param modelHandle The sound model associated with given modelParam 246 * @param modelParam Parameter to set which will be validated against the ModelParameter type. 247 * Not putting ModelParameter type directly in the definition and validating internally 248 * allows for forward compatibility. 249 * @return Value set to the requested parameter. 250 */ getParameter(in int modelHandle, in ModelParameter modelParam)251 int getParameter(in int modelHandle, in ModelParameter modelParam); 252 253 /** 254 * Set a model specific parameter with the given value. 255 * This parameter will keep its value for the duration the model is loaded regardless of 256 * starting and stopping recognition. Once the model is unloaded, the value will be lost. 257 * The caller must check if the handle supports the parameter via the queryParameter API prior 258 * to calling this method. 259 * 260 * @param modelHandle The sound model handle indicating which model to modify parameters 261 * @param modelParam Parameter to set which will be validated against the ModelParameter type. 262 * Not putting ModelParameter type directly in the definition and validating internally 263 * allows for forward compatibility. 264 * @param value The value to set for the given model parameter. 265 */ setParameter(in int modelHandle, in ModelParameter modelParam, in int value)266 void setParameter(in int modelHandle, in ModelParameter modelParam, in int value); 267 } 268