blob: 6d833aaa5d34c0fb14ca74deb4f09e8bbf4ce9d5 [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
Chris Thornton79c56612017-10-25 14:47:44 -0700209sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700210 struct sound_trigger_recognition_event *event)
211{
Chris Thornton79c56612017-10-25 14:47:44 -0700212 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700213 sp<IMemory> eventMemory;
214
215 //sanitize event
216 switch (event->type) {
217 case SOUND_MODEL_TYPE_KEYPHRASE:
218 ALOGW_IF(event->data_size != 0 && event->data_offset !=
219 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700220 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700221 event->data_offset);
222 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
223 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800224 case SOUND_MODEL_TYPE_GENERIC:
225 ALOGW_IF(event->data_size != 0 && event->data_offset !=
226 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700227 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800228 event->data_offset);
229 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
230 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700231 case SOUND_MODEL_TYPE_UNKNOWN:
232 ALOGW_IF(event->data_size != 0 && event->data_offset !=
233 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700234 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700235 event->data_offset);
236 event->data_offset = sizeof(struct sound_trigger_recognition_event);
237 break;
238 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700239 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700240 }
241
242 size_t size = event->data_offset + event->data_size;
243 eventMemory = mMemoryDealer->allocate(size);
244 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
245 eventMemory.clear();
246 return eventMemory;
247 }
248 memcpy(eventMemory->pointer(), event, size);
249
250 return eventMemory;
251}
252
253void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
254 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700255{
256 if (module == NULL) {
257 return;
258 }
259 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
260 if (eventMemory == 0) {
261 return;
262 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700263
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700264 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
265 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700266 callbackEvent->setModule(module);
267 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700268}
269
270// static
271void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
272 void *cookie)
273{
274 Module *module = (Module *)cookie;
275 if (module == NULL) {
276 return;
277 }
278 sp<SoundTriggerHwService> service = module->service().promote();
279 if (service == 0) {
280 return;
281 }
282
283 service->sendSoundModelEvent(event, module);
284}
285
Chris Thornton79c56612017-10-25 14:47:44 -0700286sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700287{
Chris Thornton79c56612017-10-25 14:47:44 -0700288 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700289 sp<IMemory> eventMemory;
290
291 size_t size = event->data_offset + event->data_size;
292 eventMemory = mMemoryDealer->allocate(size);
293 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
294 eventMemory.clear();
295 return eventMemory;
296 }
297 memcpy(eventMemory->pointer(), event, size);
298
299 return eventMemory;
300}
301
302void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
303 Module *module)
304{
Chris Thornton79c56612017-10-25 14:47:44 -0700305 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700306 if (eventMemory == 0) {
307 return;
308 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700309 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
310 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700311 callbackEvent->setModule(module);
312 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700313}
314
315
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700316sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700317{
Chris Thornton79c56612017-10-25 14:47:44 -0700318 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700319 sp<IMemory> eventMemory;
320
321 size_t size = sizeof(sound_trigger_service_state_t);
322 eventMemory = mMemoryDealer->allocate(size);
323 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
324 eventMemory.clear();
325 return eventMemory;
326 }
327 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
328 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700329}
330
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700331// call with mServiceLock held
332void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
333 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700334{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700335 sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
336 if (eventMemory == 0) {
337 return;
338 }
339 sp<Module> strongModule;
340 for (size_t i = 0; i < mModules.size(); i++) {
341 if (mModules.valueAt(i).get() == module) {
342 strongModule = mModules.valueAt(i);
343 break;
344 }
345 }
346 if (strongModule == 0) {
347 return;
348 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700349 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
350 eventMemory);
351 callbackEvent->setModule(strongModule);
Chris Thornton79c56612017-10-25 14:47:44 -0700352 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700353}
354
355void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
356 ModuleClient *moduleClient)
357{
358 sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
359 if (eventMemory == 0) {
360 return;
361 }
362 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
363 eventMemory);
364 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700365 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700366}
367
Chris Thornton79c56612017-10-25 14:47:44 -0700368void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700369{
370 mCallbackThread->sendCallbackEvent(event);
371}
372
373void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
374{
375 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700376 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700377 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700378 {
379 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700380 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700381 module = event->mModule.promote();
382 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700383 moduleClient = event->mModuleClient.promote();
384 if (moduleClient == 0) {
385 return;
386 }
Chris Thornton79c56612017-10-25 14:47:44 -0700387 } else {
388 // Sanity check on this being a Module we know about.
389 bool foundModule = false;
390 for (size_t i = 0; i < mModules.size(); i++) {
391 if (mModules.valueAt(i).get() == module.get()) {
392 foundModule = true;
393 break;
394 }
395 }
396 if (!foundModule) {
397 ALOGE("onCallbackEvent for unknown module");
398 return;
399 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700400 }
401 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700402 if (module != 0) {
403 ALOGV("onCallbackEvent for module");
404 module->onCallbackEvent(event);
405 } else if (moduleClient != 0) {
406 ALOGV("onCallbackEvent for moduleClient");
407 moduleClient->onCallbackEvent(event);
408 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700409 {
410 AutoMutex lock(mServiceLock);
411 // clear now to execute with mServiceLock locked
412 event->mMemory.clear();
413 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700414}
415
416#undef LOG_TAG
417#define LOG_TAG "SoundTriggerHwService::CallbackThread"
418
419SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
420 : mService(service)
421{
422}
423
424SoundTriggerHwService::CallbackThread::~CallbackThread()
425{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700426 while (!mEventQueue.isEmpty()) {
427 mEventQueue[0]->mMemory.clear();
428 mEventQueue.removeAt(0);
429 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700430}
431
432void SoundTriggerHwService::CallbackThread::onFirstRef()
433{
434 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
435}
436
437bool SoundTriggerHwService::CallbackThread::threadLoop()
438{
439 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700440 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700441 sp<SoundTriggerHwService> service;
442 {
443 Mutex::Autolock _l(mCallbackLock);
444 while (mEventQueue.isEmpty() && !exitPending()) {
445 ALOGV("CallbackThread::threadLoop() sleep");
446 mCallbackCond.wait(mCallbackLock);
447 ALOGV("CallbackThread::threadLoop() wake up");
448 }
449 if (exitPending()) {
450 break;
451 }
452 event = mEventQueue[0];
453 mEventQueue.removeAt(0);
454 service = mService.promote();
455 }
456 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700457 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700458 }
459 }
460 return false;
461}
462
463void SoundTriggerHwService::CallbackThread::exit()
464{
465 Mutex::Autolock _l(mCallbackLock);
466 requestExit();
467 mCallbackCond.broadcast();
468}
469
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700470void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
471 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700472{
473 AutoMutex lock(mCallbackLock);
474 mEventQueue.add(event);
475 mCallbackCond.signal();
476}
477
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700478SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
479 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700480{
481}
482
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700483SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700484{
485}
486
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700487
Eric Laurentb7a11d82014-04-18 17:40:41 -0700488#undef LOG_TAG
489#define LOG_TAG "SoundTriggerHwService::Module"
490
491SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700492 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700493 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700494 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700495 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700496{
497}
498
499SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700500 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700501}
502
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700503sp<SoundTriggerHwService::ModuleClient>
504SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
505{
506 AutoMutex lock(mLock);
507 sp<ModuleClient> moduleClient;
508
509 for (size_t i = 0; i < mModuleClients.size(); i++) {
510 if (mModuleClients[i]->client() == client) {
511 // Client already present, reuse client
512 return moduleClient;
513 }
514 }
515 moduleClient = new ModuleClient(this, client);
516
517 ALOGV("addClient() client %p", moduleClient.get());
518 mModuleClients.add(moduleClient);
519
520 return moduleClient;
521}
522
523void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
524{
525 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700526 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700527
Eric Laurent338e8ba2017-10-05 10:58:38 -0700528 {
529 AutoMutex lock(mLock);
530 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700531
Eric Laurent338e8ba2017-10-05 10:58:38 -0700532 for (size_t i = 0; i < mModuleClients.size(); i++) {
533 if (mModuleClients[i] == moduleClient) {
534 index = i;
535 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700536 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700537 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700538 if (index == -1) {
539 return;
540 }
541
542 ALOGV("remove client %p", moduleClient.get());
543 mModuleClients.removeAt(index);
544
545 // Iterate in reverse order as models are removed from list inside the loop.
546 for (size_t i = mModels.size(); i > 0; i--) {
547 sp<Model> model = mModels.valueAt(i - 1);
548 if (moduleClient == model->mModuleClient) {
549 mModels.removeItemsAt(i - 1);
550 ALOGV("detach() unloading model %d", model->mHandle);
551 if (mHalInterface != 0) {
552 if (model->mState == Model::STATE_ACTIVE) {
553 mHalInterface->stopRecognition(model->mHandle);
554 }
555 mHalInterface->unloadSoundModel(model->mHandle);
556 }
557 releasedSessions.add(model->mCaptureSession);
558 }
559 }
560 }
561
562 for (size_t i = 0; i < releasedSessions.size(); i++) {
563 // do not call AudioSystem methods with mLock held
564 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700565 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700566}
567
568status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700569 sp<ModuleClient> moduleClient,
570 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700571{
572 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700573 if (mHalInterface == 0) {
574 return NO_INIT;
575 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700576 if (modelMemory == 0 || modelMemory->pointer() == NULL) {
577 ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
578 return BAD_VALUE;
579 }
580 struct sound_trigger_sound_model *sound_model =
581 (struct sound_trigger_sound_model *)modelMemory->pointer();
582
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700583 size_t structSize;
584 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
585 structSize = sizeof(struct sound_trigger_phrase_sound_model);
586 } else {
587 structSize = sizeof(struct sound_trigger_sound_model);
588 }
589
590 if (sound_model->data_offset < structSize ||
591 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
592 modelMemory->size() < sound_model->data_offset ||
593 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
594 android_errorWriteLog(0x534e4554, "30148546");
595 ALOGE("loadSoundModel() data_size is too big");
596 return BAD_VALUE;
597 }
598
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700599 audio_session_t session;
600 audio_io_handle_t ioHandle;
601 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700602 // do not call AudioSystem methods with mLock held
603 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700604 if (status != NO_ERROR) {
605 return status;
606 }
607
Eric Laurent338e8ba2017-10-05 10:58:38 -0700608 {
609 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700610
Eric Laurent338e8ba2017-10-05 10:58:38 -0700611 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
612 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
613 mDescriptor.properties.max_sound_models);
614 status = INVALID_OPERATION;
615 goto exit;
616 }
617
618 status = mHalInterface->loadSoundModel(sound_model,
619 SoundTriggerHwService::soundModelCallback,
620 this, handle);
621 if (status != NO_ERROR) {
622 goto exit;
623 }
624
625 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
626 moduleClient);
627 mModels.replaceValueFor(*handle, model);
628 }
629exit:
630 if (status != NO_ERROR) {
631 // do not call AudioSystem methods with mLock held
632 AudioSystem::releaseSoundTriggerSession(session);
633 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700634 return status;
635}
636
637status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
638{
639 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700640 status_t status;
641 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800642
Eric Laurent338e8ba2017-10-05 10:58:38 -0700643 {
644 AutoMutex lock(mLock);
645 if (mHalInterface == 0) {
646 return NO_INIT;
647 }
648 ssize_t index = mModels.indexOfKey(handle);
649 if (index < 0) {
650 return BAD_VALUE;
651 }
652 sp<Model> model = mModels.valueAt(index);
653 mModels.removeItem(handle);
654 if (model->mState == Model::STATE_ACTIVE) {
655 mHalInterface->stopRecognition(model->mHandle);
656 model->mState = Model::STATE_IDLE;
657 }
658 status = mHalInterface->unloadSoundModel(handle);
659 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700660 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700661 // do not call AudioSystem methods with mLock held
662 AudioSystem::releaseSoundTriggerSession(session);
663 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700664}
665
666status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700667 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700668{
669 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700670 if (mHalInterface == 0) {
671 return NO_INIT;
672 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700673 if (dataMemory == 0 || dataMemory->pointer() == NULL) {
674 ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700675 return BAD_VALUE;
676
677 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700678
679 struct sound_trigger_recognition_config *config =
680 (struct sound_trigger_recognition_config *)dataMemory->pointer();
681
682 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
683 config->data_size > (UINT_MAX - config->data_offset) ||
684 dataMemory->size() < config->data_offset ||
685 config->data_size > (dataMemory->size() - config->data_offset)) {
686 ALOGE("startRecognition() data_size is too big");
687 return BAD_VALUE;
688 }
689
Eric Laurentb7a11d82014-04-18 17:40:41 -0700690 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700691 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
692 return INVALID_OPERATION;
693 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700694 sp<Model> model = getModel(handle);
695 if (model == 0) {
696 return BAD_VALUE;
697 }
698
699 if (model->mState == Model::STATE_ACTIVE) {
700 return INVALID_OPERATION;
701 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700702
Eric Laurentb7a11d82014-04-18 17:40:41 -0700703
704 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700705 config->capture_handle = model->mCaptureIOHandle;
706 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700707 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700708 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700709 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700710
711 if (status == NO_ERROR) {
712 model->mState = Model::STATE_ACTIVE;
713 model->mConfig = *config;
714 }
715
716 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700717}
718
719status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
720{
721 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700722 if (mHalInterface == 0) {
723 return NO_INIT;
724 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700725 AutoMutex lock(mLock);
726 sp<Model> model = getModel(handle);
727 if (model == 0) {
728 return BAD_VALUE;
729 }
730
731 if (model->mState != Model::STATE_ACTIVE) {
732 return INVALID_OPERATION;
733 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700734 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700735 model->mState = Model::STATE_IDLE;
736 return NO_ERROR;
737}
738
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700739void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700740{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700741 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700742
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700743 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700744
745 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
746 return;
747 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700748 if (mModuleClients.isEmpty()) {
749 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700750 return;
751 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700752
Chris Thornton02b74212017-11-06 14:45:30 -0800753 Vector< sp<ModuleClient> > clients;
754
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700755 switch (event->mType) {
756 case CallbackEvent::TYPE_RECOGNITION: {
757 struct sound_trigger_recognition_event *recognitionEvent =
758 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700759 {
760 AutoMutex lock(mLock);
761 sp<Model> model = getModel(recognitionEvent->model);
762 if (model == 0) {
763 ALOGW("%s model == 0", __func__);
764 return;
765 }
766 if (model->mState != Model::STATE_ACTIVE) {
767 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
768 return;
769 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700770
Eric Laurent886561f2014-08-28 19:45:37 -0700771 recognitionEvent->capture_session = model->mCaptureSession;
772 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800773 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700774 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700775 } break;
776 case CallbackEvent::TYPE_SOUNDMODEL: {
777 struct sound_trigger_model_event *soundmodelEvent =
778 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700779 {
780 AutoMutex lock(mLock);
781 sp<Model> model = getModel(soundmodelEvent->model);
782 if (model == 0) {
783 ALOGW("%s model == 0", __func__);
784 return;
785 }
Chris Thornton02b74212017-11-06 14:45:30 -0800786 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700787 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700788 } break;
789 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700790 {
791 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700792 for (size_t i = 0; i < mModuleClients.size(); i++) {
793 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800794 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700795 }
796 }
Eric Laurent886561f2014-08-28 19:45:37 -0700797 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700798 } break;
799 default:
800 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
801 }
Chris Thornton02b74212017-11-06 14:45:30 -0800802
803 for (size_t i = 0; i < clients.size(); i++) {
804 clients[i]->onCallbackEvent(event);
805 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700806}
807
808sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
809 sound_model_handle_t handle)
810{
811 sp<Model> model;
812 ssize_t index = mModels.indexOfKey(handle);
813 if (index >= 0) {
814 model = mModels.valueAt(index);
815 }
816 return model;
817}
818
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700819// Called with mServiceLock held
820void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700821{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700822 ALOGV("Module::setCaptureState_l %d", active);
823 sp<SoundTriggerHwService> service;
824 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700825
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700826 Vector< sp<IMemory> > events;
827 {
828 AutoMutex lock(mLock);
829 state = (active && !mDescriptor.properties.concurrent_capture) ?
830 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700831
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700832 if (state == mServiceState) {
833 return;
834 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700835
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700836 mServiceState = state;
837
838 service = mService.promote();
839 if (service == 0) {
840 return;
841 }
842
843 if (state == SOUND_TRIGGER_STATE_ENABLED) {
844 goto exit;
845 }
846
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700847 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700848 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700849
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700850 for (size_t i = 0; i < mModels.size(); i++) {
851 sp<Model> model = mModels.valueAt(i);
852 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700853 if (mHalInterface != 0 && !supports_stop_all) {
854 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700855 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700856 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800857 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
858 struct sound_trigger_phrase_recognition_event event;
859 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
860 event.num_phrases = model->mConfig.num_phrases;
861 for (size_t i = 0; i < event.num_phrases; i++) {
862 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700863 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800864 event.common.status = RECOGNITION_STATUS_ABORT;
865 event.common.type = model->mType;
866 event.common.model = model->mHandle;
867 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700868 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800869 if (eventMemory != 0) {
870 events.add(eventMemory);
871 }
872 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
873 struct sound_trigger_generic_recognition_event event;
874 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
875 event.common.status = RECOGNITION_STATUS_ABORT;
876 event.common.type = model->mType;
877 event.common.model = model->mHandle;
878 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700879 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800880 if (eventMemory != 0) {
881 events.add(eventMemory);
882 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800883 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
884 struct sound_trigger_phrase_recognition_event event;
885 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
886 event.common.status = RECOGNITION_STATUS_ABORT;
887 event.common.type = model->mType;
888 event.common.model = model->mHandle;
889 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700890 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800891 if (eventMemory != 0) {
892 events.add(eventMemory);
893 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800894 } else {
895 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700896 }
897 }
898 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700899 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700900
901 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700902 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
903 events[i]);
904 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700905 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700906 }
907
908exit:
909 service->sendServiceStateEvent_l(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700910}
911
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700912
913SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
914 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700915 sound_trigger_sound_model_type_t type,
916 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700917 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700918 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
919 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700920{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700921}
922
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700923#undef LOG_TAG
924#define LOG_TAG "SoundTriggerHwService::ModuleClient"
925
926SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
927 const sp<ISoundTriggerClient>& client)
928 : mModule(module), mClient(client)
929{
930}
931
932void SoundTriggerHwService::ModuleClient::onFirstRef()
933{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800934 sp<IBinder> binder = IInterface::asBinder(mClient);
935 if (binder != 0) {
936 binder->linkToDeath(this);
937 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700938}
939
940SoundTriggerHwService::ModuleClient::~ModuleClient()
941{
942}
943
944status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
945 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700946 String8 result;
947 return NO_ERROR;
948}
949
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700950void SoundTriggerHwService::ModuleClient::detach() {
951 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700952 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
953 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700954 return;
955 }
956
957 {
958 AutoMutex lock(mLock);
959 if (mClient != 0) {
960 IInterface::asBinder(mClient)->unlinkToDeath(this);
961 mClient.clear();
962 }
963 }
964
965 sp<Module> module = mModule.promote();
966 if (module == 0) {
967 return;
968 }
969 module->detach(this);
970}
971
972status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
973 sound_model_handle_t *handle)
974{
975 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700976 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
977 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700978 return PERMISSION_DENIED;
979 }
980
981 sp<Module> module = mModule.promote();
982 if (module == 0) {
983 return NO_INIT;
984 }
985 return module->loadSoundModel(modelMemory, this, handle);
986}
987
988status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
989{
990 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700991 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
992 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700993 return PERMISSION_DENIED;
994 }
995
996 sp<Module> module = mModule.promote();
997 if (module == 0) {
998 return NO_INIT;
999 }
1000 return module->unloadSoundModel(handle);
1001}
1002
1003status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1004 const sp<IMemory>& dataMemory)
1005{
1006 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001007 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1008 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001009 return PERMISSION_DENIED;
1010 }
1011
1012 sp<Module> module = mModule.promote();
1013 if (module == 0) {
1014 return NO_INIT;
1015 }
1016 return module->startRecognition(handle, dataMemory);
1017}
1018
1019status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1020{
1021 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001022 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1023 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001024 return PERMISSION_DENIED;
1025 }
1026
1027 sp<Module> module = mModule.promote();
1028 if (module == 0) {
1029 return NO_INIT;
1030 }
1031 return module->stopRecognition(handle);
1032}
1033
1034void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1035{
1036 ALOGV("ModuleClient::setCaptureState_l %d", active);
1037 sp<SoundTriggerHwService> service;
1038 sound_trigger_service_state_t state;
1039
1040 sp<Module> module = mModule.promote();
1041 if (module == 0) {
1042 return;
1043 }
1044 {
1045 AutoMutex lock(mLock);
1046 state = (active && !module->isConcurrentCaptureAllowed()) ?
1047 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1048
1049 service = module->service().promote();
1050 if (service == 0) {
1051 return;
1052 }
1053 }
1054 service->sendServiceStateEvent_l(state, this);
1055}
1056
1057void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1058{
1059 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1060
1061 sp<IMemory> eventMemory = event->mMemory;
1062
1063 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1064 return;
1065 }
1066
Chris Thornton02b74212017-11-06 14:45:30 -08001067 sp<ISoundTriggerClient> client;
1068 {
1069 AutoMutex lock(mLock);
1070 client = mClient;
1071 }
1072
1073 if (client != 0) {
1074 switch (event->mType) {
1075 case CallbackEvent::TYPE_RECOGNITION: {
1076 client->onRecognitionEvent(eventMemory);
1077 } break;
1078 case CallbackEvent::TYPE_SOUNDMODEL: {
1079 client->onSoundModelEvent(eventMemory);
1080 } break;
1081 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001082 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001083 } break;
1084 default:
1085 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001086 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001087 }
1088}
1089
1090void SoundTriggerHwService::ModuleClient::binderDied(
1091 const wp<IBinder> &who __unused) {
1092 ALOGW("client binder died for client %p", this);
1093 detach();
1094}
1095
Eric Laurentb7a11d82014-04-18 17:40:41 -07001096}; // namespace android