blob: 79e9e88d871d9f9700359bda40a48695a497b58f [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>
Andy Hungab7ef302018-05-15 19:35:29 -070030#include <mediautils/ServiceUtilities.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000031#include <utils/Errors.h>
32#include <utils/Log.h>
Eric Laurentb7a11d82014-04-18 17:40:41 -070033#include <binder/IServiceManager.h>
34#include <binder/MemoryBase.h>
35#include <binder/MemoryHeapBase.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070036#include <system/sound_trigger.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000037#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 Laurent9b11c022018-06-06 19:19:22 -0700565
Eric Laurentb7a11d82014-04-18 17:40:41 -0700566 struct sound_trigger_sound_model *sound_model =
567 (struct sound_trigger_sound_model *)modelMemory->pointer();
568
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700569 size_t structSize;
570 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
571 structSize = sizeof(struct sound_trigger_phrase_sound_model);
572 } else {
573 structSize = sizeof(struct sound_trigger_sound_model);
574 }
575
576 if (sound_model->data_offset < structSize ||
577 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
578 modelMemory->size() < sound_model->data_offset ||
579 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
580 android_errorWriteLog(0x534e4554, "30148546");
581 ALOGE("loadSoundModel() data_size is too big");
582 return BAD_VALUE;
583 }
584
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700585 audio_session_t session;
586 audio_io_handle_t ioHandle;
587 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700588 // do not call AudioSystem methods with mLock held
589 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700590 if (status != NO_ERROR) {
591 return status;
592 }
593
Eric Laurent338e8ba2017-10-05 10:58:38 -0700594 {
595 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700596
Eric Laurent338e8ba2017-10-05 10:58:38 -0700597 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
598 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
599 mDescriptor.properties.max_sound_models);
600 status = INVALID_OPERATION;
601 goto exit;
602 }
603
604 status = mHalInterface->loadSoundModel(sound_model,
605 SoundTriggerHwService::soundModelCallback,
606 this, handle);
607 if (status != NO_ERROR) {
608 goto exit;
609 }
610
611 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
612 moduleClient);
613 mModels.replaceValueFor(*handle, model);
614 }
615exit:
616 if (status != NO_ERROR) {
617 // do not call AudioSystem methods with mLock held
618 AudioSystem::releaseSoundTriggerSession(session);
619 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700620 return status;
621}
622
623status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
624{
625 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700626 status_t status;
627 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800628
Eric Laurent338e8ba2017-10-05 10:58:38 -0700629 {
630 AutoMutex lock(mLock);
631 if (mHalInterface == 0) {
632 return NO_INIT;
633 }
634 ssize_t index = mModels.indexOfKey(handle);
635 if (index < 0) {
636 return BAD_VALUE;
637 }
638 sp<Model> model = mModels.valueAt(index);
639 mModels.removeItem(handle);
640 if (model->mState == Model::STATE_ACTIVE) {
641 mHalInterface->stopRecognition(model->mHandle);
642 model->mState = Model::STATE_IDLE;
643 }
644 status = mHalInterface->unloadSoundModel(handle);
645 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700646 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700647 // do not call AudioSystem methods with mLock held
648 AudioSystem::releaseSoundTriggerSession(session);
649 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700650}
651
652status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700653 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700654{
655 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700656 if (mHalInterface == 0) {
657 return NO_INIT;
658 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700659
660 struct sound_trigger_recognition_config *config =
661 (struct sound_trigger_recognition_config *)dataMemory->pointer();
662
663 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
664 config->data_size > (UINT_MAX - config->data_offset) ||
665 dataMemory->size() < config->data_offset ||
666 config->data_size > (dataMemory->size() - config->data_offset)) {
667 ALOGE("startRecognition() data_size is too big");
668 return BAD_VALUE;
669 }
670
Eric Laurentb7a11d82014-04-18 17:40:41 -0700671 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700672 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
673 return INVALID_OPERATION;
674 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700675 sp<Model> model = getModel(handle);
676 if (model == 0) {
677 return BAD_VALUE;
678 }
679
680 if (model->mState == Model::STATE_ACTIVE) {
681 return INVALID_OPERATION;
682 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700683
Eric Laurentb7a11d82014-04-18 17:40:41 -0700684
685 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700686 config->capture_handle = model->mCaptureIOHandle;
687 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700688 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700689 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700690 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700691
692 if (status == NO_ERROR) {
693 model->mState = Model::STATE_ACTIVE;
694 model->mConfig = *config;
695 }
696
697 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700698}
699
700status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
701{
702 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700703 if (mHalInterface == 0) {
704 return NO_INIT;
705 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700706 AutoMutex lock(mLock);
707 sp<Model> model = getModel(handle);
708 if (model == 0) {
709 return BAD_VALUE;
710 }
711
712 if (model->mState != Model::STATE_ACTIVE) {
713 return INVALID_OPERATION;
714 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700715 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700716 model->mState = Model::STATE_IDLE;
717 return NO_ERROR;
718}
719
Michael Dooley67e3d412018-10-16 19:51:16 +0000720status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle,
721 sp<IMemory>& eventMemory)
722{
723 ALOGV("getModelState() model handle %d", handle);
724 if (mHalInterface == 0) {
725 return NO_INIT;
726 }
727 AutoMutex lock(mLock);
728 sp<Model> model = getModel(handle);
729 if (model == 0) {
730 return BAD_VALUE;
731 }
732
733 if (model->mState != Model::STATE_ACTIVE) {
734 return INVALID_OPERATION;
735 }
736
737 if (model->mType != SOUND_MODEL_TYPE_GENERIC) {
738 return BAD_VALUE;
739 }
740
741 struct sound_trigger_recognition_event* event = nullptr;
742 status_t status = mHalInterface->getModelState(handle, &event);
743 if (status == NO_ERROR) {
744 sp<SoundTriggerHwService> service;
745 service = mService.promote();
746 if (service != 0) {
747 eventMemory = service->prepareRecognitionEvent(event);
748 }
749 free(event);
750 }
751 return status;
752}
753
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700754void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700755{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700756 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700757
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700758 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700759
760 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
761 return;
762 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700763 if (mModuleClients.isEmpty()) {
764 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700765 return;
766 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700767
Chris Thornton02b74212017-11-06 14:45:30 -0800768 Vector< sp<ModuleClient> > clients;
769
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700770 switch (event->mType) {
771 case CallbackEvent::TYPE_RECOGNITION: {
772 struct sound_trigger_recognition_event *recognitionEvent =
773 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700774 {
775 AutoMutex lock(mLock);
776 sp<Model> model = getModel(recognitionEvent->model);
777 if (model == 0) {
778 ALOGW("%s model == 0", __func__);
779 return;
780 }
781 if (model->mState != Model::STATE_ACTIVE) {
782 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
783 return;
784 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700785
Eric Laurent886561f2014-08-28 19:45:37 -0700786 recognitionEvent->capture_session = model->mCaptureSession;
787 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800788 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700789 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700790 } break;
791 case CallbackEvent::TYPE_SOUNDMODEL: {
792 struct sound_trigger_model_event *soundmodelEvent =
793 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700794 {
795 AutoMutex lock(mLock);
796 sp<Model> model = getModel(soundmodelEvent->model);
797 if (model == 0) {
798 ALOGW("%s model == 0", __func__);
799 return;
800 }
Chris Thornton02b74212017-11-06 14:45:30 -0800801 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700802 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700803 } break;
804 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700805 {
806 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700807 for (size_t i = 0; i < mModuleClients.size(); i++) {
808 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800809 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700810 }
811 }
Eric Laurent886561f2014-08-28 19:45:37 -0700812 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700813 } break;
814 default:
815 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
816 }
Chris Thornton02b74212017-11-06 14:45:30 -0800817
818 for (size_t i = 0; i < clients.size(); i++) {
819 clients[i]->onCallbackEvent(event);
820 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700821}
822
823sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
824 sound_model_handle_t handle)
825{
826 sp<Model> model;
827 ssize_t index = mModels.indexOfKey(handle);
828 if (index >= 0) {
829 model = mModels.valueAt(index);
830 }
831 return model;
832}
833
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700834// Called with mServiceLock held
835void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700836{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700837 ALOGV("Module::setCaptureState_l %d", active);
838 sp<SoundTriggerHwService> service;
839 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700840
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700841 Vector< sp<IMemory> > events;
842 {
843 AutoMutex lock(mLock);
844 state = (active && !mDescriptor.properties.concurrent_capture) ?
845 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700846
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700847 if (state == mServiceState) {
848 return;
849 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700850
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700851 mServiceState = state;
852
853 service = mService.promote();
854 if (service == 0) {
855 return;
856 }
857
858 if (state == SOUND_TRIGGER_STATE_ENABLED) {
859 goto exit;
860 }
861
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700862 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700863 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700864
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700865 for (size_t i = 0; i < mModels.size(); i++) {
866 sp<Model> model = mModels.valueAt(i);
867 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700868 if (mHalInterface != 0 && !supports_stop_all) {
869 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700870 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700871 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800872 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
873 struct sound_trigger_phrase_recognition_event event;
874 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
875 event.num_phrases = model->mConfig.num_phrases;
876 for (size_t i = 0; i < event.num_phrases; i++) {
877 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700878 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800879 event.common.status = RECOGNITION_STATUS_ABORT;
880 event.common.type = model->mType;
881 event.common.model = model->mHandle;
882 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700883 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800884 if (eventMemory != 0) {
885 events.add(eventMemory);
886 }
887 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
888 struct sound_trigger_generic_recognition_event event;
889 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
890 event.common.status = RECOGNITION_STATUS_ABORT;
891 event.common.type = model->mType;
892 event.common.model = model->mHandle;
893 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700894 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800895 if (eventMemory != 0) {
896 events.add(eventMemory);
897 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800898 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
899 struct sound_trigger_phrase_recognition_event event;
900 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
901 event.common.status = RECOGNITION_STATUS_ABORT;
902 event.common.type = model->mType;
903 event.common.model = model->mHandle;
904 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700905 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800906 if (eventMemory != 0) {
907 events.add(eventMemory);
908 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800909 } else {
910 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700911 }
912 }
913 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700914 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700915
916 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700917 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
918 events[i]);
919 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700920 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700921 }
922
923exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800924 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700925}
926
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700927
928SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
929 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700930 sound_trigger_sound_model_type_t type,
931 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700932 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700933 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
934 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700935{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700936}
937
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700938#undef LOG_TAG
939#define LOG_TAG "SoundTriggerHwService::ModuleClient"
940
941SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
942 const sp<ISoundTriggerClient>& client)
943 : mModule(module), mClient(client)
944{
945}
946
947void SoundTriggerHwService::ModuleClient::onFirstRef()
948{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800949 sp<IBinder> binder = IInterface::asBinder(mClient);
950 if (binder != 0) {
951 binder->linkToDeath(this);
952 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700953}
954
955SoundTriggerHwService::ModuleClient::~ModuleClient()
956{
957}
958
959status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
960 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700961 String8 result;
962 return NO_ERROR;
963}
964
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700965void SoundTriggerHwService::ModuleClient::detach() {
966 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700967 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
968 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700969 return;
970 }
971
972 {
973 AutoMutex lock(mLock);
974 if (mClient != 0) {
975 IInterface::asBinder(mClient)->unlinkToDeath(this);
976 mClient.clear();
977 }
978 }
979
980 sp<Module> module = mModule.promote();
981 if (module == 0) {
982 return;
983 }
984 module->detach(this);
985}
986
987status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
988 sound_model_handle_t *handle)
989{
990 ALOGV("loadSoundModel() 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 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700995 if (checkIMemory(modelMemory) != NO_ERROR) {
996 return BAD_VALUE;
997 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700998
999 sp<Module> module = mModule.promote();
1000 if (module == 0) {
1001 return NO_INIT;
1002 }
1003 return module->loadSoundModel(modelMemory, this, handle);
1004}
1005
1006status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
1007{
1008 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001009 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1010 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001011 return PERMISSION_DENIED;
1012 }
1013
1014 sp<Module> module = mModule.promote();
1015 if (module == 0) {
1016 return NO_INIT;
1017 }
1018 return module->unloadSoundModel(handle);
1019}
1020
1021status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1022 const sp<IMemory>& dataMemory)
1023{
1024 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001025 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1026 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001027 return PERMISSION_DENIED;
1028 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001029 if (checkIMemory(dataMemory) != NO_ERROR) {
1030 return BAD_VALUE;
1031 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001032
1033 sp<Module> module = mModule.promote();
1034 if (module == 0) {
1035 return NO_INIT;
1036 }
1037 return module->startRecognition(handle, dataMemory);
1038}
1039
1040status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1041{
1042 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001043 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1044 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001045 return PERMISSION_DENIED;
1046 }
1047
1048 sp<Module> module = mModule.promote();
1049 if (module == 0) {
1050 return NO_INIT;
1051 }
1052 return module->stopRecognition(handle);
1053}
1054
Michael Dooley67e3d412018-10-16 19:51:16 +00001055status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle,
1056 sp<IMemory>& eventMemory)
1057{
1058 ALOGV("getModelState() model handle %d", handle);
1059 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1060 IPCThreadState::self()->getCallingUid())) {
1061 return PERMISSION_DENIED;
1062 }
1063
1064 sp<Module> module = mModule.promote();
1065 if (module == 0) {
1066 return NO_INIT;
1067 }
1068 return module->getModelState(handle, eventMemory);
1069}
1070
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001071void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1072{
1073 ALOGV("ModuleClient::setCaptureState_l %d", active);
1074 sp<SoundTriggerHwService> service;
1075 sound_trigger_service_state_t state;
1076
1077 sp<Module> module = mModule.promote();
1078 if (module == 0) {
1079 return;
1080 }
1081 {
1082 AutoMutex lock(mLock);
1083 state = (active && !module->isConcurrentCaptureAllowed()) ?
1084 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1085
1086 service = module->service().promote();
1087 if (service == 0) {
1088 return;
1089 }
1090 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001091 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001092}
1093
1094void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1095{
1096 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1097
1098 sp<IMemory> eventMemory = event->mMemory;
1099
1100 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1101 return;
1102 }
1103
Chris Thornton02b74212017-11-06 14:45:30 -08001104 sp<ISoundTriggerClient> client;
1105 {
1106 AutoMutex lock(mLock);
1107 client = mClient;
1108 }
1109
1110 if (client != 0) {
1111 switch (event->mType) {
1112 case CallbackEvent::TYPE_RECOGNITION: {
1113 client->onRecognitionEvent(eventMemory);
1114 } break;
1115 case CallbackEvent::TYPE_SOUNDMODEL: {
1116 client->onSoundModelEvent(eventMemory);
1117 } break;
1118 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001119 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001120 } break;
1121 default:
1122 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001123 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001124 }
1125}
1126
1127void SoundTriggerHwService::ModuleClient::binderDied(
1128 const wp<IBinder> &who __unused) {
1129 ALOGW("client binder died for client %p", this);
1130 detach();
1131}
1132
Eric Laurentb7a11d82014-04-18 17:40:41 -07001133}; // namespace android