blob: 69e5f500cf41e6d385cbeb1246b8a67a8bafed60 [file] [log] [blame]
Eric Laurentb7a11d82014-04-18 17:40:41 -07001/*
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#define LOG_TAG "SoundTriggerHwService"
18//#define LOG_NDEBUG 0
19
20#include <stdio.h>
21#include <string.h>
22#include <sys/types.h>
23#include <pthread.h>
24
Mikhail Naganov959e2d02019-03-28 11:08:19 -070025#include <audio_utils/clock.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000026#include <system/sound_trigger.h>
27#include <cutils/atomic.h>
28#include <cutils/properties.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070029#include <hardware/hardware.h>
30#include <media/AudioSystem.h>
Andy Hungab7ef302018-05-15 19:35:29 -070031#include <mediautils/ServiceUtilities.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000032#include <utils/Errors.h>
33#include <utils/Log.h>
Eric Laurentb7a11d82014-04-18 17:40:41 -070034#include <binder/IServiceManager.h>
35#include <binder/MemoryBase.h>
36#include <binder/MemoryHeapBase.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070037#include <system/sound_trigger.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000038#include "SoundTriggerHwService.h"
Eric Laurentb7a11d82014-04-18 17:40:41 -070039
Eric Laurentb7a11d82014-04-18 17:40:41 -070040#define HW_MODULE_PREFIX "primary"
Eric Laurent7a544b42016-08-05 19:01:13 -070041namespace android {
Eric Laurentb7a11d82014-04-18 17:40:41 -070042
43SoundTriggerHwService::SoundTriggerHwService()
44 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070045 mNextUniqueId(1),
46 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
47 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070048{
49}
50
51void SoundTriggerHwService::onFirstRef()
52{
Eric Laurentb7a11d82014-04-18 17:40:41 -070053 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070054
Eric Laurent7a544b42016-08-05 19:01:13 -070055 sp<SoundTriggerHalInterface> halInterface =
56 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070057
Eric Laurent7a544b42016-08-05 19:01:13 -070058 if (halInterface == 0) {
59 ALOGW("could not connect to HAL");
60 return;
61 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070062 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070063 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070064 if (rc != 0) {
65 ALOGE("could not read implementation properties");
66 return;
67 }
68 descriptor.handle =
69 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
70 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
71 descriptor.handle);
72
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070073 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -070074 mModules.add(descriptor.handle, module);
75 mCallbackThread = new CallbackThread(this);
76}
77
78SoundTriggerHwService::~SoundTriggerHwService()
79{
80 if (mCallbackThread != 0) {
81 mCallbackThread->exit();
82 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070083}
84
jiabin68e0df72019-03-18 17:55:35 -070085status_t SoundTriggerHwService::listModules(const String16& opPackageName,
86 struct sound_trigger_module_descriptor *modules,
Eric Laurentb7a11d82014-04-18 17:40:41 -070087 uint32_t *numModules)
88{
89 ALOGV("listModules");
jiabin68e0df72019-03-18 17:55:35 -070090 if (!captureHotwordAllowed(opPackageName,
91 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -070092 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +000093 return PERMISSION_DENIED;
94 }
95
Eric Laurentb7a11d82014-04-18 17:40:41 -070096 AutoMutex lock(mServiceLock);
97 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
98 return BAD_VALUE;
99 }
100 size_t maxModules = *numModules;
101 *numModules = mModules.size();
102 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
103 modules[i] = mModules.valueAt(i)->descriptor();
104 }
105 return NO_ERROR;
106}
107
jiabin68e0df72019-03-18 17:55:35 -0700108status_t SoundTriggerHwService::attach(const String16& opPackageName,
109 const sound_trigger_module_handle_t handle,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700110 const sp<ISoundTriggerClient>& client,
111 sp<ISoundTrigger>& moduleInterface)
112{
113 ALOGV("attach module %d", handle);
jiabin68e0df72019-03-18 17:55:35 -0700114 if (!captureHotwordAllowed(opPackageName,
115 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700116 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000117 return PERMISSION_DENIED;
118 }
119
Eric Laurentb7a11d82014-04-18 17:40:41 -0700120 AutoMutex lock(mServiceLock);
121 moduleInterface.clear();
122 if (client == 0) {
123 return BAD_VALUE;
124 }
125 ssize_t index = mModules.indexOfKey(handle);
126 if (index < 0) {
127 return BAD_VALUE;
128 }
129 sp<Module> module = mModules.valueAt(index);
130
jiabin68e0df72019-03-18 17:55:35 -0700131 sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700132 if (moduleClient == 0) {
133 return NO_INIT;
134 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700135
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700136 moduleClient->setCaptureState_l(mCaptureState);
137 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700138
Eric Laurentb7a11d82014-04-18 17:40:41 -0700139 return NO_ERROR;
140}
141
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700142status_t SoundTriggerHwService::setCaptureState(bool active)
143{
144 ALOGV("setCaptureState %d", active);
145 AutoMutex lock(mServiceLock);
146 mCaptureState = active;
147 for (size_t i = 0; i < mModules.size(); i++) {
148 mModules.valueAt(i)->setCaptureState_l(active);
149 }
150 return NO_ERROR;
151}
152
153
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700154static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700155
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700156static bool dumpTryLock(Mutex& mutex)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700157{
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700158 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
159 return err == NO_ERROR;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700160}
161
162status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
163 String8 result;
164 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
165 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
166 write(fd, result.string(), result.size());
167 } else {
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700168 bool locked = dumpTryLock(mServiceLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700169 // failed to lock - SoundTriggerHwService is probably deadlocked
170 if (!locked) {
171 result.append("SoundTriggerHwService may be deadlocked\n");
172 write(fd, result.string(), result.size());
173 }
174
175 if (locked) mServiceLock.unlock();
176 }
177 return NO_ERROR;
178}
179
180status_t SoundTriggerHwService::onTransact(
181 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
182 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
183}
184
185
186// static
187void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
188 void *cookie)
189{
190 Module *module = (Module *)cookie;
191 if (module == NULL) {
192 return;
193 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700194 sp<SoundTriggerHwService> service = module->service().promote();
195 if (service == 0) {
196 return;
197 }
198
199 service->sendRecognitionEvent(event, module);
200}
201
Chris Thornton79c56612017-10-25 14:47:44 -0700202sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700203 struct sound_trigger_recognition_event *event)
204{
Chris Thornton79c56612017-10-25 14:47:44 -0700205 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700206 sp<IMemory> eventMemory;
207
208 //sanitize event
209 switch (event->type) {
210 case SOUND_MODEL_TYPE_KEYPHRASE:
211 ALOGW_IF(event->data_size != 0 && event->data_offset !=
212 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700213 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700214 event->data_offset);
215 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
216 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800217 case SOUND_MODEL_TYPE_GENERIC:
218 ALOGW_IF(event->data_size != 0 && event->data_offset !=
219 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700220 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800221 event->data_offset);
222 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
223 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700224 case SOUND_MODEL_TYPE_UNKNOWN:
225 ALOGW_IF(event->data_size != 0 && event->data_offset !=
226 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700227 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700228 event->data_offset);
229 event->data_offset = sizeof(struct sound_trigger_recognition_event);
230 break;
231 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700232 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700233 }
234
235 size_t size = event->data_offset + event->data_size;
236 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700237 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700238 eventMemory.clear();
239 return eventMemory;
240 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700241 memcpy(eventMemory->unsecurePointer(), event, size);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700242
243 return eventMemory;
244}
245
246void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
247 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700248{
249 if (module == NULL) {
250 return;
251 }
252 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
253 if (eventMemory == 0) {
254 return;
255 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700256
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700257 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
258 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700259 callbackEvent->setModule(module);
260 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700261}
262
263// static
264void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
265 void *cookie)
266{
267 Module *module = (Module *)cookie;
268 if (module == NULL) {
269 return;
270 }
271 sp<SoundTriggerHwService> service = module->service().promote();
272 if (service == 0) {
273 return;
274 }
275
276 service->sendSoundModelEvent(event, module);
277}
278
Chris Thornton79c56612017-10-25 14:47:44 -0700279sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700280{
Chris Thornton79c56612017-10-25 14:47:44 -0700281 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700282 sp<IMemory> eventMemory;
283
284 size_t size = event->data_offset + event->data_size;
285 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700286 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700287 eventMemory.clear();
288 return eventMemory;
289 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700290 memcpy(eventMemory->unsecurePointer(), event, size);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700291
292 return eventMemory;
293}
294
295void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
296 Module *module)
297{
Chris Thornton79c56612017-10-25 14:47:44 -0700298 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700299 if (eventMemory == 0) {
300 return;
301 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700302 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
303 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700304 callbackEvent->setModule(module);
305 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700306}
307
308
Chris Thornton07405ee2017-11-14 20:45:27 -0800309sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700310{
Chris Thornton79c56612017-10-25 14:47:44 -0700311 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700312 sp<IMemory> eventMemory;
313
314 size_t size = sizeof(sound_trigger_service_state_t);
315 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700316 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700317 eventMemory.clear();
318 return eventMemory;
319 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700320 *((sound_trigger_service_state_t *)eventMemory->unsecurePointer()) = state;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700321 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700322}
323
Chris Thornton07405ee2017-11-14 20:45:27 -0800324void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700325 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700326{
Chris Thornton07405ee2017-11-14 20:45:27 -0800327 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700328 if (eventMemory == 0) {
329 return;
330 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700331 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
332 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800333 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700334 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700335}
336
Chris Thornton07405ee2017-11-14 20:45:27 -0800337void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
338 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700339{
Chris Thornton07405ee2017-11-14 20:45:27 -0800340 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700341 if (eventMemory == 0) {
342 return;
343 }
344 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
345 eventMemory);
346 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700347 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700348}
349
Chris Thornton79c56612017-10-25 14:47:44 -0700350void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700351{
352 mCallbackThread->sendCallbackEvent(event);
353}
354
355void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
356{
357 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700358 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700359 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700360 {
361 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700362 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700363 module = event->mModule.promote();
364 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700365 moduleClient = event->mModuleClient.promote();
366 if (moduleClient == 0) {
367 return;
368 }
Chris Thornton79c56612017-10-25 14:47:44 -0700369 } else {
370 // Sanity check on this being a Module we know about.
371 bool foundModule = false;
372 for (size_t i = 0; i < mModules.size(); i++) {
373 if (mModules.valueAt(i).get() == module.get()) {
374 foundModule = true;
375 break;
376 }
377 }
378 if (!foundModule) {
379 ALOGE("onCallbackEvent for unknown module");
380 return;
381 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700382 }
383 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700384 if (module != 0) {
385 ALOGV("onCallbackEvent for module");
386 module->onCallbackEvent(event);
387 } else if (moduleClient != 0) {
388 ALOGV("onCallbackEvent for moduleClient");
389 moduleClient->onCallbackEvent(event);
390 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700391 {
392 AutoMutex lock(mServiceLock);
393 // clear now to execute with mServiceLock locked
394 event->mMemory.clear();
395 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700396}
397
398#undef LOG_TAG
399#define LOG_TAG "SoundTriggerHwService::CallbackThread"
400
401SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
402 : mService(service)
403{
404}
405
406SoundTriggerHwService::CallbackThread::~CallbackThread()
407{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700408 while (!mEventQueue.isEmpty()) {
409 mEventQueue[0]->mMemory.clear();
410 mEventQueue.removeAt(0);
411 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700412}
413
414void SoundTriggerHwService::CallbackThread::onFirstRef()
415{
416 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
417}
418
419bool SoundTriggerHwService::CallbackThread::threadLoop()
420{
421 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700422 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700423 sp<SoundTriggerHwService> service;
424 {
425 Mutex::Autolock _l(mCallbackLock);
426 while (mEventQueue.isEmpty() && !exitPending()) {
427 ALOGV("CallbackThread::threadLoop() sleep");
428 mCallbackCond.wait(mCallbackLock);
429 ALOGV("CallbackThread::threadLoop() wake up");
430 }
431 if (exitPending()) {
432 break;
433 }
434 event = mEventQueue[0];
435 mEventQueue.removeAt(0);
436 service = mService.promote();
437 }
438 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700439 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700440 }
441 }
442 return false;
443}
444
445void SoundTriggerHwService::CallbackThread::exit()
446{
447 Mutex::Autolock _l(mCallbackLock);
448 requestExit();
449 mCallbackCond.broadcast();
450}
451
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700452void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
453 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700454{
455 AutoMutex lock(mCallbackLock);
456 mEventQueue.add(event);
457 mCallbackCond.signal();
458}
459
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700460SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
461 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700462{
463}
464
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700465SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700466{
467}
468
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700469
Eric Laurentb7a11d82014-04-18 17:40:41 -0700470#undef LOG_TAG
471#define LOG_TAG "SoundTriggerHwService::Module"
472
473SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700474 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700475 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700476 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700477 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700478{
479}
480
481SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700482 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700483}
484
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700485sp<SoundTriggerHwService::ModuleClient>
jiabin68e0df72019-03-18 17:55:35 -0700486SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
487 const String16& opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700488{
489 AutoMutex lock(mLock);
490 sp<ModuleClient> moduleClient;
491
492 for (size_t i = 0; i < mModuleClients.size(); i++) {
493 if (mModuleClients[i]->client() == client) {
494 // Client already present, reuse client
495 return moduleClient;
496 }
497 }
jiabin68e0df72019-03-18 17:55:35 -0700498 moduleClient = new ModuleClient(this, client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700499
500 ALOGV("addClient() client %p", moduleClient.get());
501 mModuleClients.add(moduleClient);
502
503 return moduleClient;
504}
505
506void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
507{
508 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700509 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700510
Eric Laurent338e8ba2017-10-05 10:58:38 -0700511 {
512 AutoMutex lock(mLock);
513 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700514
Eric Laurent338e8ba2017-10-05 10:58:38 -0700515 for (size_t i = 0; i < mModuleClients.size(); i++) {
516 if (mModuleClients[i] == moduleClient) {
517 index = i;
518 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700519 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700520 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700521 if (index == -1) {
522 return;
523 }
524
525 ALOGV("remove client %p", moduleClient.get());
526 mModuleClients.removeAt(index);
527
528 // Iterate in reverse order as models are removed from list inside the loop.
529 for (size_t i = mModels.size(); i > 0; i--) {
530 sp<Model> model = mModels.valueAt(i - 1);
531 if (moduleClient == model->mModuleClient) {
532 mModels.removeItemsAt(i - 1);
533 ALOGV("detach() unloading model %d", model->mHandle);
534 if (mHalInterface != 0) {
535 if (model->mState == Model::STATE_ACTIVE) {
536 mHalInterface->stopRecognition(model->mHandle);
537 }
538 mHalInterface->unloadSoundModel(model->mHandle);
539 }
540 releasedSessions.add(model->mCaptureSession);
541 }
542 }
543 }
544
545 for (size_t i = 0; i < releasedSessions.size(); i++) {
546 // do not call AudioSystem methods with mLock held
547 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700548 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700549}
550
551status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700552 sp<ModuleClient> moduleClient,
553 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700554{
555 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700556 if (mHalInterface == 0) {
557 return NO_INIT;
558 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700559
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700560 // TODO: Using unsecurePointer() has some associated security pitfalls
561 // (see declaration for details).
562 // Either document why it is safe in this case or address the
563 // issue (e.g. by copying).
Eric Laurentb7a11d82014-04-18 17:40:41 -0700564 struct sound_trigger_sound_model *sound_model =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700565 (struct sound_trigger_sound_model *)modelMemory->unsecurePointer();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700566
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700567 size_t structSize;
568 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
569 structSize = sizeof(struct sound_trigger_phrase_sound_model);
570 } else {
571 structSize = sizeof(struct sound_trigger_sound_model);
572 }
573
574 if (sound_model->data_offset < structSize ||
575 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
576 modelMemory->size() < sound_model->data_offset ||
577 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
578 android_errorWriteLog(0x534e4554, "30148546");
579 ALOGE("loadSoundModel() data_size is too big");
580 return BAD_VALUE;
581 }
582
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700583 audio_session_t session;
584 audio_io_handle_t ioHandle;
585 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700586 // do not call AudioSystem methods with mLock held
587 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700588 if (status != NO_ERROR) {
589 return status;
590 }
591
Eric Laurent338e8ba2017-10-05 10:58:38 -0700592 {
593 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700594
Eric Laurent338e8ba2017-10-05 10:58:38 -0700595 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
596 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
597 mDescriptor.properties.max_sound_models);
598 status = INVALID_OPERATION;
599 goto exit;
600 }
601
602 status = mHalInterface->loadSoundModel(sound_model,
603 SoundTriggerHwService::soundModelCallback,
604 this, handle);
605 if (status != NO_ERROR) {
606 goto exit;
607 }
608
609 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
610 moduleClient);
611 mModels.replaceValueFor(*handle, model);
612 }
613exit:
614 if (status != NO_ERROR) {
615 // do not call AudioSystem methods with mLock held
616 AudioSystem::releaseSoundTriggerSession(session);
617 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700618 return status;
619}
620
621status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
622{
623 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700624 status_t status;
625 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800626
Eric Laurent338e8ba2017-10-05 10:58:38 -0700627 {
628 AutoMutex lock(mLock);
629 if (mHalInterface == 0) {
630 return NO_INIT;
631 }
632 ssize_t index = mModels.indexOfKey(handle);
633 if (index < 0) {
634 return BAD_VALUE;
635 }
636 sp<Model> model = mModels.valueAt(index);
637 mModels.removeItem(handle);
638 if (model->mState == Model::STATE_ACTIVE) {
639 mHalInterface->stopRecognition(model->mHandle);
640 model->mState = Model::STATE_IDLE;
641 }
642 status = mHalInterface->unloadSoundModel(handle);
643 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700644 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700645 // do not call AudioSystem methods with mLock held
646 AudioSystem::releaseSoundTriggerSession(session);
647 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700648}
649
650status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700651 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700652{
653 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700654 if (mHalInterface == 0) {
655 return NO_INIT;
656 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700657
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700658 // TODO: Using unsecurePointer() has some associated security pitfalls
659 // (see declaration for details).
660 // Either document why it is safe in this case or address the
661 // issue (e.g. by copying).
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700662 struct sound_trigger_recognition_config *config =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700663 (struct sound_trigger_recognition_config *)dataMemory->unsecurePointer();
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700664
665 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
666 config->data_size > (UINT_MAX - config->data_offset) ||
667 dataMemory->size() < config->data_offset ||
668 config->data_size > (dataMemory->size() - config->data_offset)) {
669 ALOGE("startRecognition() data_size is too big");
670 return BAD_VALUE;
671 }
672
Eric Laurentb7a11d82014-04-18 17:40:41 -0700673 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700674 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
675 return INVALID_OPERATION;
676 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700677 sp<Model> model = getModel(handle);
678 if (model == 0) {
679 return BAD_VALUE;
680 }
681
682 if (model->mState == Model::STATE_ACTIVE) {
683 return INVALID_OPERATION;
684 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700685
Eric Laurentb7a11d82014-04-18 17:40:41 -0700686
687 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700688 config->capture_handle = model->mCaptureIOHandle;
689 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700690 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700691 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700692 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700693
694 if (status == NO_ERROR) {
695 model->mState = Model::STATE_ACTIVE;
696 model->mConfig = *config;
697 }
698
699 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700700}
701
702status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
703{
704 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700705 if (mHalInterface == 0) {
706 return NO_INIT;
707 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700708 AutoMutex lock(mLock);
709 sp<Model> model = getModel(handle);
710 if (model == 0) {
711 return BAD_VALUE;
712 }
713
714 if (model->mState != Model::STATE_ACTIVE) {
715 return INVALID_OPERATION;
716 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700717 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700718 model->mState = Model::STATE_IDLE;
719 return NO_ERROR;
720}
721
mike dooley6e189b12018-11-07 15:44:37 +0100722status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000723{
724 ALOGV("getModelState() model handle %d", handle);
725 if (mHalInterface == 0) {
726 return NO_INIT;
727 }
728 AutoMutex lock(mLock);
729 sp<Model> model = getModel(handle);
730 if (model == 0) {
731 return BAD_VALUE;
732 }
733
734 if (model->mState != Model::STATE_ACTIVE) {
735 return INVALID_OPERATION;
736 }
737
mike dooley6e189b12018-11-07 15:44:37 +0100738 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000739}
740
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700741void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700742{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700743 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700744
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700745 // Memory is coming from a trusted process.
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700746 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700747
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700748 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700749 return;
750 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700751 if (mModuleClients.isEmpty()) {
752 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700753 return;
754 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700755
Chris Thornton02b74212017-11-06 14:45:30 -0800756 Vector< sp<ModuleClient> > clients;
757
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700758 switch (event->mType) {
759 case CallbackEvent::TYPE_RECOGNITION: {
760 struct sound_trigger_recognition_event *recognitionEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700761 (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700762 {
763 AutoMutex lock(mLock);
764 sp<Model> model = getModel(recognitionEvent->model);
765 if (model == 0) {
766 ALOGW("%s model == 0", __func__);
767 return;
768 }
769 if (model->mState != Model::STATE_ACTIVE) {
770 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
771 return;
772 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700773
Eric Laurent886561f2014-08-28 19:45:37 -0700774 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100775 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800776 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700777 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700778 } break;
779 case CallbackEvent::TYPE_SOUNDMODEL: {
780 struct sound_trigger_model_event *soundmodelEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700781 (struct sound_trigger_model_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700782 {
783 AutoMutex lock(mLock);
784 sp<Model> model = getModel(soundmodelEvent->model);
785 if (model == 0) {
786 ALOGW("%s model == 0", __func__);
787 return;
788 }
Chris Thornton02b74212017-11-06 14:45:30 -0800789 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700790 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700791 } break;
792 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700793 {
794 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700795 for (size_t i = 0; i < mModuleClients.size(); i++) {
796 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800797 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700798 }
799 }
Eric Laurent886561f2014-08-28 19:45:37 -0700800 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700801 } break;
802 default:
803 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
804 }
Chris Thornton02b74212017-11-06 14:45:30 -0800805
806 for (size_t i = 0; i < clients.size(); i++) {
807 clients[i]->onCallbackEvent(event);
808 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700809}
810
811sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
812 sound_model_handle_t handle)
813{
814 sp<Model> model;
815 ssize_t index = mModels.indexOfKey(handle);
816 if (index >= 0) {
817 model = mModels.valueAt(index);
818 }
819 return model;
820}
821
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700822// Called with mServiceLock held
823void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700824{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825 ALOGV("Module::setCaptureState_l %d", active);
826 sp<SoundTriggerHwService> service;
827 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700828
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700829 Vector< sp<IMemory> > events;
830 {
831 AutoMutex lock(mLock);
832 state = (active && !mDescriptor.properties.concurrent_capture) ?
833 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700834
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700835 if (state == mServiceState) {
836 return;
837 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700838
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700839 mServiceState = state;
840
841 service = mService.promote();
842 if (service == 0) {
843 return;
844 }
845
846 if (state == SOUND_TRIGGER_STATE_ENABLED) {
847 goto exit;
848 }
849
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700850 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700851 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700852
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700853 for (size_t i = 0; i < mModels.size(); i++) {
854 sp<Model> model = mModels.valueAt(i);
855 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700856 if (mHalInterface != 0 && !supports_stop_all) {
857 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700858 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700859 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800860 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
861 struct sound_trigger_phrase_recognition_event event;
862 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
863 event.num_phrases = model->mConfig.num_phrases;
864 for (size_t i = 0; i < event.num_phrases; i++) {
865 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700866 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800867 event.common.status = RECOGNITION_STATUS_ABORT;
868 event.common.type = model->mType;
869 event.common.model = model->mHandle;
870 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700871 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800872 if (eventMemory != 0) {
873 events.add(eventMemory);
874 }
875 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
876 struct sound_trigger_generic_recognition_event event;
877 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
878 event.common.status = RECOGNITION_STATUS_ABORT;
879 event.common.type = model->mType;
880 event.common.model = model->mHandle;
881 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700882 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800883 if (eventMemory != 0) {
884 events.add(eventMemory);
885 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800886 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
887 struct sound_trigger_phrase_recognition_event event;
888 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
889 event.common.status = RECOGNITION_STATUS_ABORT;
890 event.common.type = model->mType;
891 event.common.model = model->mHandle;
892 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700893 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800894 if (eventMemory != 0) {
895 events.add(eventMemory);
896 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800897 } else {
898 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700899 }
900 }
901 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700902 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700903
904 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700905 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
906 events[i]);
907 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700908 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700909 }
910
911exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800912 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700913}
914
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700915
916SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
917 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700918 sound_trigger_sound_model_type_t type,
919 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700920 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700921 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
922 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700923{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700924}
925
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700926#undef LOG_TAG
927#define LOG_TAG "SoundTriggerHwService::ModuleClient"
928
929SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
jiabin68e0df72019-03-18 17:55:35 -0700930 const sp<ISoundTriggerClient>& client,
931 const String16& opPackageName)
932 : mModule(module), mClient(client), mOpPackageName(opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700933{
934}
935
936void SoundTriggerHwService::ModuleClient::onFirstRef()
937{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800938 sp<IBinder> binder = IInterface::asBinder(mClient);
939 if (binder != 0) {
940 binder->linkToDeath(this);
941 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700942}
943
944SoundTriggerHwService::ModuleClient::~ModuleClient()
945{
946}
947
948status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
949 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700950 String8 result;
951 return NO_ERROR;
952}
953
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700954void SoundTriggerHwService::ModuleClient::detach() {
955 ALOGV("detach()");
jiabin68e0df72019-03-18 17:55:35 -0700956 if (!captureHotwordAllowed(mOpPackageName,
957 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700958 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700959 return;
960 }
961
962 {
963 AutoMutex lock(mLock);
964 if (mClient != 0) {
965 IInterface::asBinder(mClient)->unlinkToDeath(this);
966 mClient.clear();
967 }
968 }
969
970 sp<Module> module = mModule.promote();
971 if (module == 0) {
972 return;
973 }
974 module->detach(this);
975}
976
977status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
978 sound_model_handle_t *handle)
979{
980 ALOGV("loadSoundModel() handle");
jiabin68e0df72019-03-18 17:55:35 -0700981 if (!captureHotwordAllowed(mOpPackageName,
982 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700983 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700984 return PERMISSION_DENIED;
985 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700986 if (checkIMemory(modelMemory) != NO_ERROR) {
987 return BAD_VALUE;
988 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700989
990 sp<Module> module = mModule.promote();
991 if (module == 0) {
992 return NO_INIT;
993 }
994 return module->loadSoundModel(modelMemory, this, handle);
995}
996
997status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
998{
999 ALOGV("unloadSoundModel() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001000 if (!captureHotwordAllowed(mOpPackageName,
1001 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001002 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001003 return PERMISSION_DENIED;
1004 }
1005
1006 sp<Module> module = mModule.promote();
1007 if (module == 0) {
1008 return NO_INIT;
1009 }
1010 return module->unloadSoundModel(handle);
1011}
1012
1013status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1014 const sp<IMemory>& dataMemory)
1015{
1016 ALOGV("startRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001017 if (!captureHotwordAllowed(mOpPackageName,
1018 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001019 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001020 return PERMISSION_DENIED;
1021 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001022 if (checkIMemory(dataMemory) != NO_ERROR) {
1023 return BAD_VALUE;
1024 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001025
1026 sp<Module> module = mModule.promote();
1027 if (module == 0) {
1028 return NO_INIT;
1029 }
1030 return module->startRecognition(handle, dataMemory);
1031}
1032
1033status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1034{
1035 ALOGV("stopRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001036 if (!captureHotwordAllowed(mOpPackageName,
1037 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001038 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001039 return PERMISSION_DENIED;
1040 }
1041
1042 sp<Module> module = mModule.promote();
1043 if (module == 0) {
1044 return NO_INIT;
1045 }
1046 return module->stopRecognition(handle);
1047}
1048
mike dooley6e189b12018-11-07 15:44:37 +01001049status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001050{
1051 ALOGV("getModelState() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001052 if (!captureHotwordAllowed(mOpPackageName,
1053 IPCThreadState::self()->getCallingPid(),
Michael Dooley67e3d412018-10-16 19:51:16 +00001054 IPCThreadState::self()->getCallingUid())) {
1055 return PERMISSION_DENIED;
1056 }
1057
1058 sp<Module> module = mModule.promote();
1059 if (module == 0) {
1060 return NO_INIT;
1061 }
mike dooley6e189b12018-11-07 15:44:37 +01001062 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001063}
1064
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001065void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1066{
1067 ALOGV("ModuleClient::setCaptureState_l %d", active);
1068 sp<SoundTriggerHwService> service;
1069 sound_trigger_service_state_t state;
1070
1071 sp<Module> module = mModule.promote();
1072 if (module == 0) {
1073 return;
1074 }
1075 {
1076 AutoMutex lock(mLock);
1077 state = (active && !module->isConcurrentCaptureAllowed()) ?
1078 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1079
1080 service = module->service().promote();
1081 if (service == 0) {
1082 return;
1083 }
1084 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001085 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001086}
1087
1088void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1089{
1090 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1091
1092 sp<IMemory> eventMemory = event->mMemory;
1093
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -07001094 // Memory is coming from a trusted process.
1095 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001096 return;
1097 }
1098
Chris Thornton02b74212017-11-06 14:45:30 -08001099 sp<ISoundTriggerClient> client;
1100 {
1101 AutoMutex lock(mLock);
1102 client = mClient;
1103 }
1104
1105 if (client != 0) {
1106 switch (event->mType) {
1107 case CallbackEvent::TYPE_RECOGNITION: {
1108 client->onRecognitionEvent(eventMemory);
1109 } break;
1110 case CallbackEvent::TYPE_SOUNDMODEL: {
1111 client->onSoundModelEvent(eventMemory);
1112 } break;
1113 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001114 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001115 } break;
1116 default:
1117 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001118 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001119 }
1120}
1121
1122void SoundTriggerHwService::ModuleClient::binderDied(
1123 const wp<IBinder> &who __unused) {
1124 ALOGW("client binder died for client %p", this);
1125 detach();
1126}
1127
Eric Laurentb7a11d82014-04-18 17:40:41 -07001128}; // namespace android