blob: 952acd74395850d38068c1d86a86c28b62d19bc3 [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
Eric Laurent8ba53d82014-08-01 23:15:05 +000025#include <system/sound_trigger.h>
26#include <cutils/atomic.h>
27#include <cutils/properties.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070028#include <hardware/hardware.h>
29#include <media/AudioSystem.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000030#include <utils/Errors.h>
31#include <utils/Log.h>
Eric Laurentb7a11d82014-04-18 17:40:41 -070032#include <binder/IServiceManager.h>
33#include <binder/MemoryBase.h>
34#include <binder/MemoryHeapBase.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070035#include <system/sound_trigger.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000036#include <ServiceUtilities.h>
37#include "SoundTriggerHwService.h"
Eric Laurentb7a11d82014-04-18 17:40:41 -070038
Eric Laurentb7a11d82014-04-18 17:40:41 -070039#ifdef SOUND_TRIGGER_USE_STUB_MODULE
40#define HW_MODULE_PREFIX "stub"
41#else
42#define HW_MODULE_PREFIX "primary"
43#endif
Eric Laurent7a544b42016-08-05 19:01:13 -070044namespace android {
Eric Laurentb7a11d82014-04-18 17:40:41 -070045
46SoundTriggerHwService::SoundTriggerHwService()
47 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070048 mNextUniqueId(1),
49 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
50 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070051{
52}
53
54void SoundTriggerHwService::onFirstRef()
55{
Eric Laurentb7a11d82014-04-18 17:40:41 -070056 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070057
Eric Laurent7a544b42016-08-05 19:01:13 -070058 sp<SoundTriggerHalInterface> halInterface =
59 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070060
Eric Laurent7a544b42016-08-05 19:01:13 -070061 if (halInterface == 0) {
62 ALOGW("could not connect to HAL");
63 return;
64 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070065 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070066 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070067 if (rc != 0) {
68 ALOGE("could not read implementation properties");
69 return;
70 }
71 descriptor.handle =
72 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
73 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
74 descriptor.handle);
75
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070076 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -070077 mModules.add(descriptor.handle, module);
78 mCallbackThread = new CallbackThread(this);
79}
80
81SoundTriggerHwService::~SoundTriggerHwService()
82{
83 if (mCallbackThread != 0) {
84 mCallbackThread->exit();
85 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070086}
87
88status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
89 uint32_t *numModules)
90{
91 ALOGV("listModules");
Eric Laurent7504b9e2017-08-15 18:17:26 -070092 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
93 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +000094 return PERMISSION_DENIED;
95 }
96
Eric Laurentb7a11d82014-04-18 17:40:41 -070097 AutoMutex lock(mServiceLock);
98 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
99 return BAD_VALUE;
100 }
101 size_t maxModules = *numModules;
102 *numModules = mModules.size();
103 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
104 modules[i] = mModules.valueAt(i)->descriptor();
105 }
106 return NO_ERROR;
107}
108
109status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
110 const sp<ISoundTriggerClient>& client,
111 sp<ISoundTrigger>& moduleInterface)
112{
113 ALOGV("attach module %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700114 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
115 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000116 return PERMISSION_DENIED;
117 }
118
Eric Laurentb7a11d82014-04-18 17:40:41 -0700119 AutoMutex lock(mServiceLock);
120 moduleInterface.clear();
121 if (client == 0) {
122 return BAD_VALUE;
123 }
124 ssize_t index = mModules.indexOfKey(handle);
125 if (index < 0) {
126 return BAD_VALUE;
127 }
128 sp<Module> module = mModules.valueAt(index);
129
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700130 sp<ModuleClient> moduleClient = module->addClient(client);
131 if (moduleClient == 0) {
132 return NO_INIT;
133 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700134
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700135 moduleClient->setCaptureState_l(mCaptureState);
136 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700137
Eric Laurentb7a11d82014-04-18 17:40:41 -0700138 return NO_ERROR;
139}
140
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700141status_t SoundTriggerHwService::setCaptureState(bool active)
142{
143 ALOGV("setCaptureState %d", active);
144 AutoMutex lock(mServiceLock);
145 mCaptureState = active;
146 for (size_t i = 0; i < mModules.size(); i++) {
147 mModules.valueAt(i)->setCaptureState_l(active);
148 }
149 return NO_ERROR;
150}
151
152
Eric Laurentb7a11d82014-04-18 17:40:41 -0700153static const int kDumpLockRetries = 50;
154static const int kDumpLockSleep = 60000;
155
156static bool tryLock(Mutex& mutex)
157{
158 bool locked = false;
159 for (int i = 0; i < kDumpLockRetries; ++i) {
160 if (mutex.tryLock() == NO_ERROR) {
161 locked = true;
162 break;
163 }
164 usleep(kDumpLockSleep);
165 }
166 return locked;
167}
168
169status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
170 String8 result;
171 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
172 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
173 write(fd, result.string(), result.size());
174 } else {
175 bool locked = tryLock(mServiceLock);
176 // failed to lock - SoundTriggerHwService is probably deadlocked
177 if (!locked) {
178 result.append("SoundTriggerHwService may be deadlocked\n");
179 write(fd, result.string(), result.size());
180 }
181
182 if (locked) mServiceLock.unlock();
183 }
184 return NO_ERROR;
185}
186
187status_t SoundTriggerHwService::onTransact(
188 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
189 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
190}
191
192
193// static
194void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
195 void *cookie)
196{
197 Module *module = (Module *)cookie;
198 if (module == NULL) {
199 return;
200 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700201 sp<SoundTriggerHwService> service = module->service().promote();
202 if (service == 0) {
203 return;
204 }
205
206 service->sendRecognitionEvent(event, module);
207}
208
209sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l(
210 struct sound_trigger_recognition_event *event)
211{
212 sp<IMemory> eventMemory;
213
214 //sanitize event
215 switch (event->type) {
216 case SOUND_MODEL_TYPE_KEYPHRASE:
217 ALOGW_IF(event->data_size != 0 && event->data_offset !=
218 sizeof(struct sound_trigger_phrase_recognition_event),
219 "prepareRecognitionEvent_l(): invalid data offset %u for keyphrase event type",
220 event->data_offset);
221 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
222 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800223 case SOUND_MODEL_TYPE_GENERIC:
224 ALOGW_IF(event->data_size != 0 && event->data_offset !=
225 sizeof(struct sound_trigger_generic_recognition_event),
226 "prepareRecognitionEvent_l(): invalid data offset %u for generic event type",
227 event->data_offset);
228 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
229 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700230 case SOUND_MODEL_TYPE_UNKNOWN:
231 ALOGW_IF(event->data_size != 0 && event->data_offset !=
232 sizeof(struct sound_trigger_recognition_event),
233 "prepareRecognitionEvent_l(): invalid data offset %u for unknown event type",
234 event->data_offset);
235 event->data_offset = sizeof(struct sound_trigger_recognition_event);
236 break;
237 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700238 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700239 }
240
241 size_t size = event->data_offset + event->data_size;
242 eventMemory = mMemoryDealer->allocate(size);
243 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
244 eventMemory.clear();
245 return eventMemory;
246 }
247 memcpy(eventMemory->pointer(), event, size);
248
249 return eventMemory;
250}
251
252void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
253 Module *module)
254 {
255 AutoMutex lock(mServiceLock);
256 if (module == NULL) {
257 return;
258 }
259 sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
260 if (eventMemory == 0) {
261 return;
262 }
263 sp<Module> strongModule;
264 for (size_t i = 0; i < mModules.size(); i++) {
265 if (mModules.valueAt(i).get() == module) {
266 strongModule = mModules.valueAt(i);
267 break;
268 }
269 }
270 if (strongModule == 0) {
271 return;
272 }
273
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700274 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
275 eventMemory);
276 callbackEvent->setModule(strongModule);
277 sendCallbackEvent_l(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700278}
279
280// static
281void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
282 void *cookie)
283{
284 Module *module = (Module *)cookie;
285 if (module == NULL) {
286 return;
287 }
288 sp<SoundTriggerHwService> service = module->service().promote();
289 if (service == 0) {
290 return;
291 }
292
293 service->sendSoundModelEvent(event, module);
294}
295
296sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent_l(struct sound_trigger_model_event *event)
297{
298 sp<IMemory> eventMemory;
299
300 size_t size = event->data_offset + event->data_size;
301 eventMemory = mMemoryDealer->allocate(size);
302 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
303 eventMemory.clear();
304 return eventMemory;
305 }
306 memcpy(eventMemory->pointer(), event, size);
307
308 return eventMemory;
309}
310
311void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
312 Module *module)
313{
314 AutoMutex lock(mServiceLock);
315 sp<IMemory> eventMemory = prepareSoundModelEvent_l(event);
316 if (eventMemory == 0) {
317 return;
318 }
319 sp<Module> strongModule;
320 for (size_t i = 0; i < mModules.size(); i++) {
321 if (mModules.valueAt(i).get() == module) {
322 strongModule = mModules.valueAt(i);
323 break;
324 }
325 }
326 if (strongModule == 0) {
327 return;
328 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700329 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
330 eventMemory);
331 callbackEvent->setModule(strongModule);
332 sendCallbackEvent_l(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700333}
334
335
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700336sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700337{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700338 sp<IMemory> eventMemory;
339
340 size_t size = sizeof(sound_trigger_service_state_t);
341 eventMemory = mMemoryDealer->allocate(size);
342 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
343 eventMemory.clear();
344 return eventMemory;
345 }
346 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
347 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700348}
349
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700350// call with mServiceLock held
351void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
352 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700353{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700354 sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
355 if (eventMemory == 0) {
356 return;
357 }
358 sp<Module> strongModule;
359 for (size_t i = 0; i < mModules.size(); i++) {
360 if (mModules.valueAt(i).get() == module) {
361 strongModule = mModules.valueAt(i);
362 break;
363 }
364 }
365 if (strongModule == 0) {
366 return;
367 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700368 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
369 eventMemory);
370 callbackEvent->setModule(strongModule);
371 sendCallbackEvent_l(callbackEvent);
372}
373
374void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
375 ModuleClient *moduleClient)
376{
377 sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
378 if (eventMemory == 0) {
379 return;
380 }
381 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
382 eventMemory);
383 callbackEvent->setModuleClient(moduleClient);
384 sendCallbackEvent_l(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700385}
386
387// call with mServiceLock held
388void SoundTriggerHwService::sendCallbackEvent_l(const sp<CallbackEvent>& event)
389{
390 mCallbackThread->sendCallbackEvent(event);
391}
392
393void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
394{
395 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700396 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700397 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700398 {
399 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700400 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700401 module = event->mModule.promote();
402 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700403 moduleClient = event->mModuleClient.promote();
404 if (moduleClient == 0) {
405 return;
406 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700407 }
408 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700409 if (module != 0) {
410 ALOGV("onCallbackEvent for module");
411 module->onCallbackEvent(event);
412 } else if (moduleClient != 0) {
413 ALOGV("onCallbackEvent for moduleClient");
414 moduleClient->onCallbackEvent(event);
415 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700416 {
417 AutoMutex lock(mServiceLock);
418 // clear now to execute with mServiceLock locked
419 event->mMemory.clear();
420 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700421}
422
423#undef LOG_TAG
424#define LOG_TAG "SoundTriggerHwService::CallbackThread"
425
426SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
427 : mService(service)
428{
429}
430
431SoundTriggerHwService::CallbackThread::~CallbackThread()
432{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700433 while (!mEventQueue.isEmpty()) {
434 mEventQueue[0]->mMemory.clear();
435 mEventQueue.removeAt(0);
436 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700437}
438
439void SoundTriggerHwService::CallbackThread::onFirstRef()
440{
441 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
442}
443
444bool SoundTriggerHwService::CallbackThread::threadLoop()
445{
446 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700447 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700448 sp<SoundTriggerHwService> service;
449 {
450 Mutex::Autolock _l(mCallbackLock);
451 while (mEventQueue.isEmpty() && !exitPending()) {
452 ALOGV("CallbackThread::threadLoop() sleep");
453 mCallbackCond.wait(mCallbackLock);
454 ALOGV("CallbackThread::threadLoop() wake up");
455 }
456 if (exitPending()) {
457 break;
458 }
459 event = mEventQueue[0];
460 mEventQueue.removeAt(0);
461 service = mService.promote();
462 }
463 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700464 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700465 }
466 }
467 return false;
468}
469
470void SoundTriggerHwService::CallbackThread::exit()
471{
472 Mutex::Autolock _l(mCallbackLock);
473 requestExit();
474 mCallbackCond.broadcast();
475}
476
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700477void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
478 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700479{
480 AutoMutex lock(mCallbackLock);
481 mEventQueue.add(event);
482 mCallbackCond.signal();
483}
484
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700485SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
486 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700487{
488}
489
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700490SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700491{
492}
493
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700494
Eric Laurentb7a11d82014-04-18 17:40:41 -0700495#undef LOG_TAG
496#define LOG_TAG "SoundTriggerHwService::Module"
497
498SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700499 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700500 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700501 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700502 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700503{
504}
505
506SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700507 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700508}
509
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700510sp<SoundTriggerHwService::ModuleClient>
511SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
512{
513 AutoMutex lock(mLock);
514 sp<ModuleClient> moduleClient;
515
516 for (size_t i = 0; i < mModuleClients.size(); i++) {
517 if (mModuleClients[i]->client() == client) {
518 // Client already present, reuse client
519 return moduleClient;
520 }
521 }
522 moduleClient = new ModuleClient(this, client);
523
524 ALOGV("addClient() client %p", moduleClient.get());
525 mModuleClients.add(moduleClient);
526
527 return moduleClient;
528}
529
530void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
531{
532 ALOGV("Module::detach()");
533 AutoMutex lock(mLock);
534 ssize_t index = -1;
535
536 for (size_t i = 0; i < mModuleClients.size(); i++) {
537 if (mModuleClients[i] == moduleClient) {
538 index = i;
539 break;
540 }
541 }
542 if (index == -1) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000543 return;
544 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700545
546 ALOGV("remove client %p", moduleClient.get());
547 mModuleClients.removeAt(index);
548
Dhananjay Kumar00124172017-02-28 15:08:29 +0530549 // Iterate in reverse order as models are removed from list inside the loop.
550 for (size_t i = mModels.size(); i > 0; i--) {
551 sp<Model> model = mModels.valueAt(i - 1);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700552 if (moduleClient == model->mModuleClient) {
Dhananjay Kumar00124172017-02-28 15:08:29 +0530553 mModels.removeItemsAt(i - 1);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700554 ALOGV("detach() unloading model %d", model->mHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700555 if (mHalInterface != 0) {
556 if (model->mState == Model::STATE_ACTIVE) {
557 mHalInterface->stopRecognition(model->mHandle);
558 }
559 mHalInterface->unloadSoundModel(model->mHandle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700560 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700561 AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
562 mHalInterface->unloadSoundModel(model->mHandle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700563 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700564 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700565}
566
567status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700568 sp<ModuleClient> moduleClient,
569 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700570{
571 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700572 if (mHalInterface == 0) {
573 return NO_INIT;
574 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700575 if (modelMemory == 0 || modelMemory->pointer() == NULL) {
576 ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
577 return BAD_VALUE;
578 }
579 struct sound_trigger_sound_model *sound_model =
580 (struct sound_trigger_sound_model *)modelMemory->pointer();
581
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700582 size_t structSize;
583 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
584 structSize = sizeof(struct sound_trigger_phrase_sound_model);
585 } else {
586 structSize = sizeof(struct sound_trigger_sound_model);
587 }
588
589 if (sound_model->data_offset < structSize ||
590 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
591 modelMemory->size() < sound_model->data_offset ||
592 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
593 android_errorWriteLog(0x534e4554, "30148546");
594 ALOGE("loadSoundModel() data_size is too big");
595 return BAD_VALUE;
596 }
597
Eric Laurentb7a11d82014-04-18 17:40:41 -0700598 AutoMutex lock(mLock);
Eric Laurent02eb47c2014-11-20 10:10:20 -0800599
600 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
Ryan Bavettaad658992016-04-11 14:25:21 -0700601 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
602 mDescriptor.properties.max_sound_models);
603 return INVALID_OPERATION;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800604 }
605
Eric Laurent7a544b42016-08-05 19:01:13 -0700606 status_t status = mHalInterface->loadSoundModel(sound_model,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700607 SoundTriggerHwService::soundModelCallback,
Ryan Bavetta2c561202016-02-16 14:17:31 -0800608 this, handle);
609
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700610 if (status != NO_ERROR) {
611 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700612 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700613 audio_session_t session;
614 audio_io_handle_t ioHandle;
615 audio_devices_t device;
616
617 status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
618 if (status != NO_ERROR) {
619 return status;
620 }
621
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700622 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
623 moduleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700624 mModels.replaceValueFor(*handle, model);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700625
626 return status;
627}
628
629status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
630{
631 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700632 AutoMutex lock(mLock);
Eric Laurent02eb47c2014-11-20 10:10:20 -0800633 return unloadSoundModel_l(handle);
634}
635
636status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
637{
Eric Laurent7a544b42016-08-05 19:01:13 -0700638 if (mHalInterface == 0) {
639 return NO_INIT;
640 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700641 ssize_t index = mModels.indexOfKey(handle);
642 if (index < 0) {
643 return BAD_VALUE;
644 }
Eric Laurent1a1cba82014-06-09 16:20:05 -0700645 sp<Model> model = mModels.valueAt(index);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700646 mModels.removeItem(handle);
Eric Laurent1a1cba82014-06-09 16:20:05 -0700647 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700648 mHalInterface->stopRecognition(model->mHandle);
Eric Laurent02eb47c2014-11-20 10:10:20 -0800649 model->mState = Model::STATE_IDLE;
Eric Laurent1a1cba82014-06-09 16:20:05 -0700650 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700651 AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
Eric Laurent7a544b42016-08-05 19:01:13 -0700652 return mHalInterface->unloadSoundModel(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700653}
654
655status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700656 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700657{
658 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700659 if (mHalInterface == 0) {
660 return NO_INIT;
661 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700662 if (dataMemory == 0 || dataMemory->pointer() == NULL) {
663 ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700664 return BAD_VALUE;
665
666 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700667
668 struct sound_trigger_recognition_config *config =
669 (struct sound_trigger_recognition_config *)dataMemory->pointer();
670
671 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
672 config->data_size > (UINT_MAX - config->data_offset) ||
673 dataMemory->size() < config->data_offset ||
674 config->data_size > (dataMemory->size() - config->data_offset)) {
675 ALOGE("startRecognition() data_size is too big");
676 return BAD_VALUE;
677 }
678
Eric Laurentb7a11d82014-04-18 17:40:41 -0700679 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700680 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
681 return INVALID_OPERATION;
682 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700683 sp<Model> model = getModel(handle);
684 if (model == 0) {
685 return BAD_VALUE;
686 }
687
688 if (model->mState == Model::STATE_ACTIVE) {
689 return INVALID_OPERATION;
690 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700691
Eric Laurentb7a11d82014-04-18 17:40:41 -0700692
693 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700694 config->capture_handle = model->mCaptureIOHandle;
695 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700696 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700697 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700698 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700699
700 if (status == NO_ERROR) {
701 model->mState = Model::STATE_ACTIVE;
702 model->mConfig = *config;
703 }
704
705 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700706}
707
708status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
709{
710 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700711 if (mHalInterface == 0) {
712 return NO_INIT;
713 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700714 AutoMutex lock(mLock);
715 sp<Model> model = getModel(handle);
716 if (model == 0) {
717 return BAD_VALUE;
718 }
719
720 if (model->mState != Model::STATE_ACTIVE) {
721 return INVALID_OPERATION;
722 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700723 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700724 model->mState = Model::STATE_IDLE;
725 return NO_ERROR;
726}
727
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700728void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700729{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700730 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700731
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700732 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700733
734 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
735 return;
736 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700737 if (mModuleClients.isEmpty()) {
738 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700739 return;
740 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700741
742 switch (event->mType) {
743 case CallbackEvent::TYPE_RECOGNITION: {
744 struct sound_trigger_recognition_event *recognitionEvent =
745 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700746 sp<ISoundTriggerClient> client;
747 {
748 AutoMutex lock(mLock);
749 sp<Model> model = getModel(recognitionEvent->model);
750 if (model == 0) {
751 ALOGW("%s model == 0", __func__);
752 return;
753 }
754 if (model->mState != Model::STATE_ACTIVE) {
755 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
756 return;
757 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700758
Eric Laurent886561f2014-08-28 19:45:37 -0700759 recognitionEvent->capture_session = model->mCaptureSession;
760 model->mState = Model::STATE_IDLE;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700761 client = model->mModuleClient->client();
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700762 }
Eric Laurent886561f2014-08-28 19:45:37 -0700763 if (client != 0) {
764 client->onRecognitionEvent(eventMemory);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700765 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700766 } break;
767 case CallbackEvent::TYPE_SOUNDMODEL: {
768 struct sound_trigger_model_event *soundmodelEvent =
769 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700770 sp<ISoundTriggerClient> client;
771 {
772 AutoMutex lock(mLock);
773 sp<Model> model = getModel(soundmodelEvent->model);
774 if (model == 0) {
775 ALOGW("%s model == 0", __func__);
776 return;
777 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700778 client = model->mModuleClient->client();
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700779 }
Eric Laurent886561f2014-08-28 19:45:37 -0700780 if (client != 0) {
781 client->onSoundModelEvent(eventMemory);
782 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700783 } break;
784 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700785 Vector< sp<ISoundTriggerClient> > clients;
Eric Laurent886561f2014-08-28 19:45:37 -0700786 {
787 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700788 for (size_t i = 0; i < mModuleClients.size(); i++) {
789 if (mModuleClients[i] != 0) {
790 clients.add(mModuleClients[i]->client());
791 }
792 }
Eric Laurent886561f2014-08-28 19:45:37 -0700793 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700794 for (size_t i = 0; i < clients.size(); i++) {
795 clients[i]->onServiceStateChange(eventMemory);
Eric Laurent886561f2014-08-28 19:45:37 -0700796 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700797 } break;
798 default:
799 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
800 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700801}
802
803sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
804 sound_model_handle_t handle)
805{
806 sp<Model> model;
807 ssize_t index = mModels.indexOfKey(handle);
808 if (index >= 0) {
809 model = mModels.valueAt(index);
810 }
811 return model;
812}
813
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700814// Called with mServiceLock held
815void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700816{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700817 ALOGV("Module::setCaptureState_l %d", active);
818 sp<SoundTriggerHwService> service;
819 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700820
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700821 Vector< sp<IMemory> > events;
822 {
823 AutoMutex lock(mLock);
824 state = (active && !mDescriptor.properties.concurrent_capture) ?
825 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700826
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700827 if (state == mServiceState) {
828 return;
829 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700830
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700831 mServiceState = state;
832
833 service = mService.promote();
834 if (service == 0) {
835 return;
836 }
837
838 if (state == SOUND_TRIGGER_STATE_ENABLED) {
839 goto exit;
840 }
841
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700842 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700843 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700844
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700845 for (size_t i = 0; i < mModels.size(); i++) {
846 sp<Model> model = mModels.valueAt(i);
847 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700848 if (mHalInterface != 0 && !supports_stop_all) {
849 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700850 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700851 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800852 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
853 struct sound_trigger_phrase_recognition_event event;
854 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
855 event.num_phrases = model->mConfig.num_phrases;
856 for (size_t i = 0; i < event.num_phrases; i++) {
857 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700858 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800859 event.common.status = RECOGNITION_STATUS_ABORT;
860 event.common.type = model->mType;
861 event.common.model = model->mHandle;
862 event.common.data_size = 0;
863 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
864 if (eventMemory != 0) {
865 events.add(eventMemory);
866 }
867 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
868 struct sound_trigger_generic_recognition_event event;
869 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
870 event.common.status = RECOGNITION_STATUS_ABORT;
871 event.common.type = model->mType;
872 event.common.model = model->mHandle;
873 event.common.data_size = 0;
874 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
875 if (eventMemory != 0) {
876 events.add(eventMemory);
877 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800878 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
879 struct sound_trigger_phrase_recognition_event event;
880 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
881 event.common.status = RECOGNITION_STATUS_ABORT;
882 event.common.type = model->mType;
883 event.common.model = model->mHandle;
884 event.common.data_size = 0;
885 sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
886 if (eventMemory != 0) {
887 events.add(eventMemory);
888 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800889 } else {
890 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700891 }
892 }
893 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700894 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700895
896 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700897 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
898 events[i]);
899 callbackEvent->setModule(this);
900 service->sendCallbackEvent_l(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700901 }
902
903exit:
904 service->sendServiceStateEvent_l(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700905}
906
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700907
908SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
909 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700910 sound_trigger_sound_model_type_t type,
911 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700912 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700913 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
914 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700915{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700916}
917
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700918#undef LOG_TAG
919#define LOG_TAG "SoundTriggerHwService::ModuleClient"
920
921SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
922 const sp<ISoundTriggerClient>& client)
923 : mModule(module), mClient(client)
924{
925}
926
927void SoundTriggerHwService::ModuleClient::onFirstRef()
928{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800929 sp<IBinder> binder = IInterface::asBinder(mClient);
930 if (binder != 0) {
931 binder->linkToDeath(this);
932 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700933}
934
935SoundTriggerHwService::ModuleClient::~ModuleClient()
936{
937}
938
939status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
940 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700941 String8 result;
942 return NO_ERROR;
943}
944
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700945void SoundTriggerHwService::ModuleClient::detach() {
946 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700947 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
948 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700949 return;
950 }
951
952 {
953 AutoMutex lock(mLock);
954 if (mClient != 0) {
955 IInterface::asBinder(mClient)->unlinkToDeath(this);
956 mClient.clear();
957 }
958 }
959
960 sp<Module> module = mModule.promote();
961 if (module == 0) {
962 return;
963 }
964 module->detach(this);
965}
966
967status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
968 sound_model_handle_t *handle)
969{
970 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700971 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
972 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700973 return PERMISSION_DENIED;
974 }
975
976 sp<Module> module = mModule.promote();
977 if (module == 0) {
978 return NO_INIT;
979 }
980 return module->loadSoundModel(modelMemory, this, handle);
981}
982
983status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
984{
985 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700986 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
987 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700988 return PERMISSION_DENIED;
989 }
990
991 sp<Module> module = mModule.promote();
992 if (module == 0) {
993 return NO_INIT;
994 }
995 return module->unloadSoundModel(handle);
996}
997
998status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
999 const sp<IMemory>& dataMemory)
1000{
1001 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001002 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1003 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001004 return PERMISSION_DENIED;
1005 }
1006
1007 sp<Module> module = mModule.promote();
1008 if (module == 0) {
1009 return NO_INIT;
1010 }
1011 return module->startRecognition(handle, dataMemory);
1012}
1013
1014status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1015{
1016 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001017 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1018 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001019 return PERMISSION_DENIED;
1020 }
1021
1022 sp<Module> module = mModule.promote();
1023 if (module == 0) {
1024 return NO_INIT;
1025 }
1026 return module->stopRecognition(handle);
1027}
1028
1029void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1030{
1031 ALOGV("ModuleClient::setCaptureState_l %d", active);
1032 sp<SoundTriggerHwService> service;
1033 sound_trigger_service_state_t state;
1034
1035 sp<Module> module = mModule.promote();
1036 if (module == 0) {
1037 return;
1038 }
1039 {
1040 AutoMutex lock(mLock);
1041 state = (active && !module->isConcurrentCaptureAllowed()) ?
1042 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1043
1044 service = module->service().promote();
1045 if (service == 0) {
1046 return;
1047 }
1048 }
1049 service->sendServiceStateEvent_l(state, this);
1050}
1051
1052void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1053{
1054 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1055
1056 sp<IMemory> eventMemory = event->mMemory;
1057
1058 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1059 return;
1060 }
1061
1062 switch (event->mType) {
1063 case CallbackEvent::TYPE_SERVICE_STATE: {
1064 sp<ISoundTriggerClient> client;
1065 {
1066 AutoMutex lock(mLock);
1067 client = mClient;
1068 }
1069 if (client !=0 ) {
1070 client->onServiceStateChange(eventMemory);
1071 }
1072 } break;
1073 default:
1074 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1075 }
1076}
1077
1078void SoundTriggerHwService::ModuleClient::binderDied(
1079 const wp<IBinder> &who __unused) {
1080 ALOGW("client binder died for client %p", this);
1081 detach();
1082}
1083
Eric Laurentb7a11d82014-04-18 17:40:41 -07001084}; // namespace android