blob: 46f388b90e60c35327bae1309d67413eeeb93701 [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
753 switch (event->mType) {
754 case CallbackEvent::TYPE_RECOGNITION: {
755 struct sound_trigger_recognition_event *recognitionEvent =
756 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700757 sp<ISoundTriggerClient> client;
758 {
759 AutoMutex lock(mLock);
760 sp<Model> model = getModel(recognitionEvent->model);
761 if (model == 0) {
762 ALOGW("%s model == 0", __func__);
763 return;
764 }
765 if (model->mState != Model::STATE_ACTIVE) {
766 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
767 return;
768 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700769
Eric Laurent886561f2014-08-28 19:45:37 -0700770 recognitionEvent->capture_session = model->mCaptureSession;
771 model->mState = Model::STATE_IDLE;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700772 client = model->mModuleClient->client();
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700773 }
Eric Laurent886561f2014-08-28 19:45:37 -0700774 if (client != 0) {
775 client->onRecognitionEvent(eventMemory);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700776 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700777 } break;
778 case CallbackEvent::TYPE_SOUNDMODEL: {
779 struct sound_trigger_model_event *soundmodelEvent =
780 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700781 sp<ISoundTriggerClient> client;
782 {
783 AutoMutex lock(mLock);
784 sp<Model> model = getModel(soundmodelEvent->model);
785 if (model == 0) {
786 ALOGW("%s model == 0", __func__);
787 return;
788 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700789 client = model->mModuleClient->client();
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700790 }
Eric Laurent886561f2014-08-28 19:45:37 -0700791 if (client != 0) {
792 client->onSoundModelEvent(eventMemory);
793 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700794 } break;
795 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700796 Vector< sp<ISoundTriggerClient> > clients;
Eric Laurent886561f2014-08-28 19:45:37 -0700797 {
798 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700799 for (size_t i = 0; i < mModuleClients.size(); i++) {
800 if (mModuleClients[i] != 0) {
801 clients.add(mModuleClients[i]->client());
802 }
803 }
Eric Laurent886561f2014-08-28 19:45:37 -0700804 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700805 for (size_t i = 0; i < clients.size(); i++) {
806 clients[i]->onServiceStateChange(eventMemory);
Eric Laurent886561f2014-08-28 19:45:37 -0700807 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700808 } break;
809 default:
810 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
811 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700812}
813
814sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
815 sound_model_handle_t handle)
816{
817 sp<Model> model;
818 ssize_t index = mModels.indexOfKey(handle);
819 if (index >= 0) {
820 model = mModels.valueAt(index);
821 }
822 return model;
823}
824
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825// Called with mServiceLock held
826void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700827{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700828 ALOGV("Module::setCaptureState_l %d", active);
829 sp<SoundTriggerHwService> service;
830 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700831
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700832 Vector< sp<IMemory> > events;
833 {
834 AutoMutex lock(mLock);
835 state = (active && !mDescriptor.properties.concurrent_capture) ?
836 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700837
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700838 if (state == mServiceState) {
839 return;
840 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700841
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700842 mServiceState = state;
843
844 service = mService.promote();
845 if (service == 0) {
846 return;
847 }
848
849 if (state == SOUND_TRIGGER_STATE_ENABLED) {
850 goto exit;
851 }
852
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700853 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700854 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700855
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700856 for (size_t i = 0; i < mModels.size(); i++) {
857 sp<Model> model = mModels.valueAt(i);
858 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700859 if (mHalInterface != 0 && !supports_stop_all) {
860 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700861 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700862 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800863 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
864 struct sound_trigger_phrase_recognition_event event;
865 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
866 event.num_phrases = model->mConfig.num_phrases;
867 for (size_t i = 0; i < event.num_phrases; i++) {
868 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700869 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800870 event.common.status = RECOGNITION_STATUS_ABORT;
871 event.common.type = model->mType;
872 event.common.model = model->mHandle;
873 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700874 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800875 if (eventMemory != 0) {
876 events.add(eventMemory);
877 }
878 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
879 struct sound_trigger_generic_recognition_event event;
880 memset(&event, 0, sizeof(struct sound_trigger_generic_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;
Chris Thornton79c56612017-10-25 14:47:44 -0700885 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800886 if (eventMemory != 0) {
887 events.add(eventMemory);
888 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800889 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
890 struct sound_trigger_phrase_recognition_event event;
891 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
892 event.common.status = RECOGNITION_STATUS_ABORT;
893 event.common.type = model->mType;
894 event.common.model = model->mHandle;
895 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700896 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800897 if (eventMemory != 0) {
898 events.add(eventMemory);
899 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800900 } else {
901 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700902 }
903 }
904 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700905 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700906
907 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700908 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
909 events[i]);
910 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700911 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700912 }
913
914exit:
915 service->sendServiceStateEvent_l(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700916}
917
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700918
919SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
920 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700921 sound_trigger_sound_model_type_t type,
922 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700923 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700924 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
925 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700926{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700927}
928
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700929#undef LOG_TAG
930#define LOG_TAG "SoundTriggerHwService::ModuleClient"
931
932SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
933 const sp<ISoundTriggerClient>& client)
934 : mModule(module), mClient(client)
935{
936}
937
938void SoundTriggerHwService::ModuleClient::onFirstRef()
939{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800940 sp<IBinder> binder = IInterface::asBinder(mClient);
941 if (binder != 0) {
942 binder->linkToDeath(this);
943 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700944}
945
946SoundTriggerHwService::ModuleClient::~ModuleClient()
947{
948}
949
950status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
951 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700952 String8 result;
953 return NO_ERROR;
954}
955
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700956void SoundTriggerHwService::ModuleClient::detach() {
957 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700958 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
959 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700960 return;
961 }
962
963 {
964 AutoMutex lock(mLock);
965 if (mClient != 0) {
966 IInterface::asBinder(mClient)->unlinkToDeath(this);
967 mClient.clear();
968 }
969 }
970
971 sp<Module> module = mModule.promote();
972 if (module == 0) {
973 return;
974 }
975 module->detach(this);
976}
977
978status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
979 sound_model_handle_t *handle)
980{
981 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700982 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
983 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700984 return PERMISSION_DENIED;
985 }
986
987 sp<Module> module = mModule.promote();
988 if (module == 0) {
989 return NO_INIT;
990 }
991 return module->loadSoundModel(modelMemory, this, handle);
992}
993
994status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
995{
996 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700997 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
998 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700999 return PERMISSION_DENIED;
1000 }
1001
1002 sp<Module> module = mModule.promote();
1003 if (module == 0) {
1004 return NO_INIT;
1005 }
1006 return module->unloadSoundModel(handle);
1007}
1008
1009status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1010 const sp<IMemory>& dataMemory)
1011{
1012 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001013 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1014 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001015 return PERMISSION_DENIED;
1016 }
1017
1018 sp<Module> module = mModule.promote();
1019 if (module == 0) {
1020 return NO_INIT;
1021 }
1022 return module->startRecognition(handle, dataMemory);
1023}
1024
1025status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1026{
1027 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001028 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1029 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001030 return PERMISSION_DENIED;
1031 }
1032
1033 sp<Module> module = mModule.promote();
1034 if (module == 0) {
1035 return NO_INIT;
1036 }
1037 return module->stopRecognition(handle);
1038}
1039
1040void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1041{
1042 ALOGV("ModuleClient::setCaptureState_l %d", active);
1043 sp<SoundTriggerHwService> service;
1044 sound_trigger_service_state_t state;
1045
1046 sp<Module> module = mModule.promote();
1047 if (module == 0) {
1048 return;
1049 }
1050 {
1051 AutoMutex lock(mLock);
1052 state = (active && !module->isConcurrentCaptureAllowed()) ?
1053 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1054
1055 service = module->service().promote();
1056 if (service == 0) {
1057 return;
1058 }
1059 }
1060 service->sendServiceStateEvent_l(state, this);
1061}
1062
1063void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1064{
1065 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1066
1067 sp<IMemory> eventMemory = event->mMemory;
1068
1069 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1070 return;
1071 }
1072
1073 switch (event->mType) {
1074 case CallbackEvent::TYPE_SERVICE_STATE: {
1075 sp<ISoundTriggerClient> client;
1076 {
1077 AutoMutex lock(mLock);
1078 client = mClient;
1079 }
1080 if (client !=0 ) {
1081 client->onServiceStateChange(eventMemory);
1082 }
1083 } break;
1084 default:
1085 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
1086 }
1087}
1088
1089void SoundTriggerHwService::ModuleClient::binderDied(
1090 const wp<IBinder> &who __unused) {
1091 ALOGW("client binder died for client %p", this);
1092 detach();
1093}
1094
Eric Laurentb7a11d82014-04-18 17:40:41 -07001095}; // namespace android