blob: a7d6e839e13bb84ee390810acf8b379fb8b73a44 [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
Chris Thornton07405ee2017-11-14 20:45:27 -0800316sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(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
Chris Thornton07405ee2017-11-14 20:45:27 -0800331void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700332 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700333{
Chris Thornton07405ee2017-11-14 20:45:27 -0800334 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700335 if (eventMemory == 0) {
336 return;
337 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700338 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
339 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800340 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700341 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700342}
343
Chris Thornton07405ee2017-11-14 20:45:27 -0800344void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
345 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700346{
Chris Thornton07405ee2017-11-14 20:45:27 -0800347 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700348 if (eventMemory == 0) {
349 return;
350 }
351 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
352 eventMemory);
353 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700354 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700355}
356
Chris Thornton79c56612017-10-25 14:47:44 -0700357void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700358{
359 mCallbackThread->sendCallbackEvent(event);
360}
361
362void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
363{
364 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700365 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700366 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700367 {
368 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700369 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700370 module = event->mModule.promote();
371 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700372 moduleClient = event->mModuleClient.promote();
373 if (moduleClient == 0) {
374 return;
375 }
Chris Thornton79c56612017-10-25 14:47:44 -0700376 } else {
377 // Sanity check on this being a Module we know about.
378 bool foundModule = false;
379 for (size_t i = 0; i < mModules.size(); i++) {
380 if (mModules.valueAt(i).get() == module.get()) {
381 foundModule = true;
382 break;
383 }
384 }
385 if (!foundModule) {
386 ALOGE("onCallbackEvent for unknown module");
387 return;
388 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700389 }
390 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700391 if (module != 0) {
392 ALOGV("onCallbackEvent for module");
393 module->onCallbackEvent(event);
394 } else if (moduleClient != 0) {
395 ALOGV("onCallbackEvent for moduleClient");
396 moduleClient->onCallbackEvent(event);
397 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700398 {
399 AutoMutex lock(mServiceLock);
400 // clear now to execute with mServiceLock locked
401 event->mMemory.clear();
402 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700403}
404
405#undef LOG_TAG
406#define LOG_TAG "SoundTriggerHwService::CallbackThread"
407
408SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
409 : mService(service)
410{
411}
412
413SoundTriggerHwService::CallbackThread::~CallbackThread()
414{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700415 while (!mEventQueue.isEmpty()) {
416 mEventQueue[0]->mMemory.clear();
417 mEventQueue.removeAt(0);
418 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700419}
420
421void SoundTriggerHwService::CallbackThread::onFirstRef()
422{
423 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
424}
425
426bool SoundTriggerHwService::CallbackThread::threadLoop()
427{
428 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700429 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700430 sp<SoundTriggerHwService> service;
431 {
432 Mutex::Autolock _l(mCallbackLock);
433 while (mEventQueue.isEmpty() && !exitPending()) {
434 ALOGV("CallbackThread::threadLoop() sleep");
435 mCallbackCond.wait(mCallbackLock);
436 ALOGV("CallbackThread::threadLoop() wake up");
437 }
438 if (exitPending()) {
439 break;
440 }
441 event = mEventQueue[0];
442 mEventQueue.removeAt(0);
443 service = mService.promote();
444 }
445 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700446 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700447 }
448 }
449 return false;
450}
451
452void SoundTriggerHwService::CallbackThread::exit()
453{
454 Mutex::Autolock _l(mCallbackLock);
455 requestExit();
456 mCallbackCond.broadcast();
457}
458
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700459void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
460 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700461{
462 AutoMutex lock(mCallbackLock);
463 mEventQueue.add(event);
464 mCallbackCond.signal();
465}
466
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700467SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
468 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700469{
470}
471
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700472SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700473{
474}
475
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700476
Eric Laurentb7a11d82014-04-18 17:40:41 -0700477#undef LOG_TAG
478#define LOG_TAG "SoundTriggerHwService::Module"
479
480SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700481 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700482 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700483 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700484 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700485{
486}
487
488SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700489 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700490}
491
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700492sp<SoundTriggerHwService::ModuleClient>
493SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
494{
495 AutoMutex lock(mLock);
496 sp<ModuleClient> moduleClient;
497
498 for (size_t i = 0; i < mModuleClients.size(); i++) {
499 if (mModuleClients[i]->client() == client) {
500 // Client already present, reuse client
501 return moduleClient;
502 }
503 }
504 moduleClient = new ModuleClient(this, client);
505
506 ALOGV("addClient() client %p", moduleClient.get());
507 mModuleClients.add(moduleClient);
508
509 return moduleClient;
510}
511
512void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
513{
514 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700515 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700516
Eric Laurent338e8ba2017-10-05 10:58:38 -0700517 {
518 AutoMutex lock(mLock);
519 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700520
Eric Laurent338e8ba2017-10-05 10:58:38 -0700521 for (size_t i = 0; i < mModuleClients.size(); i++) {
522 if (mModuleClients[i] == moduleClient) {
523 index = i;
524 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700525 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700526 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700527 if (index == -1) {
528 return;
529 }
530
531 ALOGV("remove client %p", moduleClient.get());
532 mModuleClients.removeAt(index);
533
534 // Iterate in reverse order as models are removed from list inside the loop.
535 for (size_t i = mModels.size(); i > 0; i--) {
536 sp<Model> model = mModels.valueAt(i - 1);
537 if (moduleClient == model->mModuleClient) {
538 mModels.removeItemsAt(i - 1);
539 ALOGV("detach() unloading model %d", model->mHandle);
540 if (mHalInterface != 0) {
541 if (model->mState == Model::STATE_ACTIVE) {
542 mHalInterface->stopRecognition(model->mHandle);
543 }
544 mHalInterface->unloadSoundModel(model->mHandle);
545 }
546 releasedSessions.add(model->mCaptureSession);
547 }
548 }
549 }
550
551 for (size_t i = 0; i < releasedSessions.size(); i++) {
552 // do not call AudioSystem methods with mLock held
553 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700554 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700555}
556
557status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700558 sp<ModuleClient> moduleClient,
559 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700560{
561 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700562 if (mHalInterface == 0) {
563 return NO_INIT;
564 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700565 if (modelMemory == 0 || modelMemory->pointer() == NULL) {
566 ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
567 return BAD_VALUE;
568 }
569 struct sound_trigger_sound_model *sound_model =
570 (struct sound_trigger_sound_model *)modelMemory->pointer();
571
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700572 size_t structSize;
573 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
574 structSize = sizeof(struct sound_trigger_phrase_sound_model);
575 } else {
576 structSize = sizeof(struct sound_trigger_sound_model);
577 }
578
579 if (sound_model->data_offset < structSize ||
580 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
581 modelMemory->size() < sound_model->data_offset ||
582 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
583 android_errorWriteLog(0x534e4554, "30148546");
584 ALOGE("loadSoundModel() data_size is too big");
585 return BAD_VALUE;
586 }
587
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700588 audio_session_t session;
589 audio_io_handle_t ioHandle;
590 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700591 // do not call AudioSystem methods with mLock held
592 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700593 if (status != NO_ERROR) {
594 return status;
595 }
596
Eric Laurent338e8ba2017-10-05 10:58:38 -0700597 {
598 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700599
Eric Laurent338e8ba2017-10-05 10:58:38 -0700600 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
601 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
602 mDescriptor.properties.max_sound_models);
603 status = INVALID_OPERATION;
604 goto exit;
605 }
606
607 status = mHalInterface->loadSoundModel(sound_model,
608 SoundTriggerHwService::soundModelCallback,
609 this, handle);
610 if (status != NO_ERROR) {
611 goto exit;
612 }
613
614 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
615 moduleClient);
616 mModels.replaceValueFor(*handle, model);
617 }
618exit:
619 if (status != NO_ERROR) {
620 // do not call AudioSystem methods with mLock held
621 AudioSystem::releaseSoundTriggerSession(session);
622 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700623 return status;
624}
625
626status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
627{
628 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700629 status_t status;
630 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800631
Eric Laurent338e8ba2017-10-05 10:58:38 -0700632 {
633 AutoMutex lock(mLock);
634 if (mHalInterface == 0) {
635 return NO_INIT;
636 }
637 ssize_t index = mModels.indexOfKey(handle);
638 if (index < 0) {
639 return BAD_VALUE;
640 }
641 sp<Model> model = mModels.valueAt(index);
642 mModels.removeItem(handle);
643 if (model->mState == Model::STATE_ACTIVE) {
644 mHalInterface->stopRecognition(model->mHandle);
645 model->mState = Model::STATE_IDLE;
646 }
647 status = mHalInterface->unloadSoundModel(handle);
648 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700649 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700650 // do not call AudioSystem methods with mLock held
651 AudioSystem::releaseSoundTriggerSession(session);
652 return status;
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
Chris Thornton02b74212017-11-06 14:45:30 -0800742 Vector< sp<ModuleClient> > clients;
743
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700744 switch (event->mType) {
745 case CallbackEvent::TYPE_RECOGNITION: {
746 struct sound_trigger_recognition_event *recognitionEvent =
747 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700748 {
749 AutoMutex lock(mLock);
750 sp<Model> model = getModel(recognitionEvent->model);
751 if (model == 0) {
752 ALOGW("%s model == 0", __func__);
753 return;
754 }
755 if (model->mState != Model::STATE_ACTIVE) {
756 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
757 return;
758 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700759
Eric Laurent886561f2014-08-28 19:45:37 -0700760 recognitionEvent->capture_session = model->mCaptureSession;
761 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800762 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700763 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700764 } break;
765 case CallbackEvent::TYPE_SOUNDMODEL: {
766 struct sound_trigger_model_event *soundmodelEvent =
767 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700768 {
769 AutoMutex lock(mLock);
770 sp<Model> model = getModel(soundmodelEvent->model);
771 if (model == 0) {
772 ALOGW("%s model == 0", __func__);
773 return;
774 }
Chris Thornton02b74212017-11-06 14:45:30 -0800775 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700776 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700777 } break;
778 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700779 {
780 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700781 for (size_t i = 0; i < mModuleClients.size(); i++) {
782 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800783 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700784 }
785 }
Eric Laurent886561f2014-08-28 19:45:37 -0700786 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700787 } break;
788 default:
789 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
790 }
Chris Thornton02b74212017-11-06 14:45:30 -0800791
792 for (size_t i = 0; i < clients.size(); i++) {
793 clients[i]->onCallbackEvent(event);
794 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700795}
796
797sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
798 sound_model_handle_t handle)
799{
800 sp<Model> model;
801 ssize_t index = mModels.indexOfKey(handle);
802 if (index >= 0) {
803 model = mModels.valueAt(index);
804 }
805 return model;
806}
807
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700808// Called with mServiceLock held
809void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700810{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700811 ALOGV("Module::setCaptureState_l %d", active);
812 sp<SoundTriggerHwService> service;
813 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700814
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700815 Vector< sp<IMemory> > events;
816 {
817 AutoMutex lock(mLock);
818 state = (active && !mDescriptor.properties.concurrent_capture) ?
819 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700820
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700821 if (state == mServiceState) {
822 return;
823 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700824
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825 mServiceState = state;
826
827 service = mService.promote();
828 if (service == 0) {
829 return;
830 }
831
832 if (state == SOUND_TRIGGER_STATE_ENABLED) {
833 goto exit;
834 }
835
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700836 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700837 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700838
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700839 for (size_t i = 0; i < mModels.size(); i++) {
840 sp<Model> model = mModels.valueAt(i);
841 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700842 if (mHalInterface != 0 && !supports_stop_all) {
843 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700844 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700845 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800846 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
847 struct sound_trigger_phrase_recognition_event event;
848 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
849 event.num_phrases = model->mConfig.num_phrases;
850 for (size_t i = 0; i < event.num_phrases; i++) {
851 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700852 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800853 event.common.status = RECOGNITION_STATUS_ABORT;
854 event.common.type = model->mType;
855 event.common.model = model->mHandle;
856 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700857 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800858 if (eventMemory != 0) {
859 events.add(eventMemory);
860 }
861 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
862 struct sound_trigger_generic_recognition_event event;
863 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
864 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 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800872 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
873 struct sound_trigger_phrase_recognition_event event;
874 memset(&event, 0, sizeof(struct sound_trigger_phrase_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 Bavetta9609a912016-01-28 19:22:29 -0800880 if (eventMemory != 0) {
881 events.add(eventMemory);
882 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800883 } else {
884 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700885 }
886 }
887 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700888 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700889
890 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700891 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
892 events[i]);
893 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700894 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700895 }
896
897exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800898 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700899}
900
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700901
902SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
903 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700904 sound_trigger_sound_model_type_t type,
905 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700906 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700907 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
908 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700909{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700910}
911
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700912#undef LOG_TAG
913#define LOG_TAG "SoundTriggerHwService::ModuleClient"
914
915SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
916 const sp<ISoundTriggerClient>& client)
917 : mModule(module), mClient(client)
918{
919}
920
921void SoundTriggerHwService::ModuleClient::onFirstRef()
922{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800923 sp<IBinder> binder = IInterface::asBinder(mClient);
924 if (binder != 0) {
925 binder->linkToDeath(this);
926 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700927}
928
929SoundTriggerHwService::ModuleClient::~ModuleClient()
930{
931}
932
933status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
934 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700935 String8 result;
936 return NO_ERROR;
937}
938
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700939void SoundTriggerHwService::ModuleClient::detach() {
940 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700941 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
942 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700943 return;
944 }
945
946 {
947 AutoMutex lock(mLock);
948 if (mClient != 0) {
949 IInterface::asBinder(mClient)->unlinkToDeath(this);
950 mClient.clear();
951 }
952 }
953
954 sp<Module> module = mModule.promote();
955 if (module == 0) {
956 return;
957 }
958 module->detach(this);
959}
960
961status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
962 sound_model_handle_t *handle)
963{
964 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700965 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
966 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700967 return PERMISSION_DENIED;
968 }
969
970 sp<Module> module = mModule.promote();
971 if (module == 0) {
972 return NO_INIT;
973 }
974 return module->loadSoundModel(modelMemory, this, handle);
975}
976
977status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
978{
979 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700980 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
981 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700982 return PERMISSION_DENIED;
983 }
984
985 sp<Module> module = mModule.promote();
986 if (module == 0) {
987 return NO_INIT;
988 }
989 return module->unloadSoundModel(handle);
990}
991
992status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
993 const sp<IMemory>& dataMemory)
994{
995 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700996 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
997 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700998 return PERMISSION_DENIED;
999 }
1000
1001 sp<Module> module = mModule.promote();
1002 if (module == 0) {
1003 return NO_INIT;
1004 }
1005 return module->startRecognition(handle, dataMemory);
1006}
1007
1008status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1009{
1010 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001011 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1012 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001013 return PERMISSION_DENIED;
1014 }
1015
1016 sp<Module> module = mModule.promote();
1017 if (module == 0) {
1018 return NO_INIT;
1019 }
1020 return module->stopRecognition(handle);
1021}
1022
1023void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1024{
1025 ALOGV("ModuleClient::setCaptureState_l %d", active);
1026 sp<SoundTriggerHwService> service;
1027 sound_trigger_service_state_t state;
1028
1029 sp<Module> module = mModule.promote();
1030 if (module == 0) {
1031 return;
1032 }
1033 {
1034 AutoMutex lock(mLock);
1035 state = (active && !module->isConcurrentCaptureAllowed()) ?
1036 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1037
1038 service = module->service().promote();
1039 if (service == 0) {
1040 return;
1041 }
1042 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001043 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001044}
1045
1046void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1047{
1048 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1049
1050 sp<IMemory> eventMemory = event->mMemory;
1051
1052 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1053 return;
1054 }
1055
Chris Thornton02b74212017-11-06 14:45:30 -08001056 sp<ISoundTriggerClient> client;
1057 {
1058 AutoMutex lock(mLock);
1059 client = mClient;
1060 }
1061
1062 if (client != 0) {
1063 switch (event->mType) {
1064 case CallbackEvent::TYPE_RECOGNITION: {
1065 client->onRecognitionEvent(eventMemory);
1066 } break;
1067 case CallbackEvent::TYPE_SOUNDMODEL: {
1068 client->onSoundModelEvent(eventMemory);
1069 } break;
1070 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001071 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001072 } break;
1073 default:
1074 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001075 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001076 }
1077}
1078
1079void SoundTriggerHwService::ModuleClient::binderDied(
1080 const wp<IBinder> &who __unused) {
1081 ALOGW("client binder died for client %p", this);
1082 detach();
1083}
1084
Eric Laurentb7a11d82014-04-18 17:40:41 -07001085}; // namespace android