Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 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; |
Ytai Ben-Tsvi | 0996ac8 | 2022-01-20 13:40:39 -0800 | [diff] [blame] | 21 | import android.media.soundtrigger.ModelParameter; |
| 22 | import android.media.soundtrigger.ModelParameterRange; |
Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 23 | import android.media.soundtrigger.PhraseSoundModel; |
| 24 | import android.media.soundtrigger.Properties; |
| 25 | import android.media.soundtrigger.RecognitionConfig; |
| 26 | import android.media.soundtrigger.SoundModel; |
Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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. |
Ytai Ben-Tsvi | 0996ac8 | 2022-01-20 13:40:39 -0800 | [diff] [blame] | 196 | * @throws ServiceSpecificException(RESOURCE_CONTENTION) if the model cannot be started due |
Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 197 | * to resource constraints. This is typically a temporary condition and the client may |
| 198 | * retry after the onResourcesAvailable() global callback is invoked. |
Ytai Ben-Tsvi | 0996ac8 | 2022-01-20 13:40:39 -0800 | [diff] [blame] | 199 | */ |
| 200 | void startRecognition( |
| 201 | in int modelHandle, in int deviceHandle, in int ioHandle, in RecognitionConfig config); |
Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 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 | */ |
| 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 | */ |
| 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 | */ |
Ytai Ben-Tsvi | 0996ac8 | 2022-01-20 13:40:39 -0800 | [diff] [blame] | 235 | @nullable ModelParameterRange queryParameter( |
| 236 | in int modelHandle, in ModelParameter modelParam); |
Ytai Ben-Tsvi | fb55702 | 2021-03-05 17:05:19 -0800 | [diff] [blame] | 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 | */ |
| 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 | */ |
| 266 | void setParameter(in int modelHandle, in ModelParameter modelParam, in int value); |
| 267 | } |