blob: 79150683a6b7138de4c464f3bf5966786ce459a7 [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
mike dooley6e189b12018-11-07 15:44:37 +0100720status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000721{
722 ALOGV("getModelState() model handle %d", handle);
723 if (mHalInterface == 0) {
724 return NO_INIT;
725 }
726 AutoMutex lock(mLock);
727 sp<Model> model = getModel(handle);
728 if (model == 0) {
729 return BAD_VALUE;
730 }
731
732 if (model->mState != Model::STATE_ACTIVE) {
733 return INVALID_OPERATION;
734 }
735
mike dooley6e189b12018-11-07 15:44:37 +0100736 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000737}
738
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700739void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700740{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700741 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700742
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700743 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700744
745 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
746 return;
747 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700748 if (mModuleClients.isEmpty()) {
749 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700750 return;
751 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700752
Chris Thornton02b74212017-11-06 14:45:30 -0800753 Vector< sp<ModuleClient> > clients;
754
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700755 switch (event->mType) {
756 case CallbackEvent::TYPE_RECOGNITION: {
757 struct sound_trigger_recognition_event *recognitionEvent =
758 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700759 {
760 AutoMutex lock(mLock);
761 sp<Model> model = getModel(recognitionEvent->model);
762 if (model == 0) {
763 ALOGW("%s model == 0", __func__);
764 return;
765 }
766 if (model->mState != Model::STATE_ACTIVE) {
767 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
768 return;
769 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700770
Eric Laurent886561f2014-08-28 19:45:37 -0700771 recognitionEvent->capture_session = model->mCaptureSession;
mike dooley6e189b12018-11-07 15:44:37 +0100772 // Don't reset the model state if this recognition event is a get-state response
773 if (recognitionEvent->status != RECOGNITION_STATUS_GET_STATE_RESPONSE) {
774 model->mState = Model::STATE_IDLE;
775 }
Chris Thornton02b74212017-11-06 14:45:30 -0800776 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700777 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700778 } break;
779 case CallbackEvent::TYPE_SOUNDMODEL: {
780 struct sound_trigger_model_event *soundmodelEvent =
781 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700782 {
783 AutoMutex lock(mLock);
784 sp<Model> model = getModel(soundmodelEvent->model);
785 if (model == 0) {
786 ALOGW("%s model == 0", __func__);
787 return;
788 }
Chris Thornton02b74212017-11-06 14:45:30 -0800789 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700790 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700791 } break;
792 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700793 {
794 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700795 for (size_t i = 0; i < mModuleClients.size(); i++) {
796 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800797 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700798 }
799 }
Eric Laurent886561f2014-08-28 19:45:37 -0700800 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700801 } break;
802 default:
803 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
804 }
Chris Thornton02b74212017-11-06 14:45:30 -0800805
806 for (size_t i = 0; i < clients.size(); i++) {
807 clients[i]->onCallbackEvent(event);
808 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700809}
810
811sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
812 sound_model_handle_t handle)
813{
814 sp<Model> model;
815 ssize_t index = mModels.indexOfKey(handle);
816 if (index >= 0) {
817 model = mModels.valueAt(index);
818 }
819 return model;
820}
821
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700822// Called with mServiceLock held
823void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700824{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825 ALOGV("Module::setCaptureState_l %d", active);
826 sp<SoundTriggerHwService> service;
827 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700828
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700829 Vector< sp<IMemory> > events;
830 {
831 AutoMutex lock(mLock);
832 state = (active && !mDescriptor.properties.concurrent_capture) ?
833 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700834
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700835 if (state == mServiceState) {
836 return;
837 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700838
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700839 mServiceState = state;
840
841 service = mService.promote();
842 if (service == 0) {
843 return;
844 }
845
846 if (state == SOUND_TRIGGER_STATE_ENABLED) {
847 goto exit;
848 }
849
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700850 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700851 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700852
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700853 for (size_t i = 0; i < mModels.size(); i++) {
854 sp<Model> model = mModels.valueAt(i);
855 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700856 if (mHalInterface != 0 && !supports_stop_all) {
857 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700858 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700859 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800860 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
861 struct sound_trigger_phrase_recognition_event event;
862 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
863 event.num_phrases = model->mConfig.num_phrases;
864 for (size_t i = 0; i < event.num_phrases; i++) {
865 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700866 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800867 event.common.status = RECOGNITION_STATUS_ABORT;
868 event.common.type = model->mType;
869 event.common.model = model->mHandle;
870 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700871 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800872 if (eventMemory != 0) {
873 events.add(eventMemory);
874 }
875 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
876 struct sound_trigger_generic_recognition_event event;
877 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
878 event.common.status = RECOGNITION_STATUS_ABORT;
879 event.common.type = model->mType;
880 event.common.model = model->mHandle;
881 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700882 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800883 if (eventMemory != 0) {
884 events.add(eventMemory);
885 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800886 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
887 struct sound_trigger_phrase_recognition_event event;
888 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
889 event.common.status = RECOGNITION_STATUS_ABORT;
890 event.common.type = model->mType;
891 event.common.model = model->mHandle;
892 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700893 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800894 if (eventMemory != 0) {
895 events.add(eventMemory);
896 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800897 } else {
898 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700899 }
900 }
901 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700902 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700903
904 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700905 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
906 events[i]);
907 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700908 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700909 }
910
911exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800912 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700913}
914
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700915
916SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
917 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700918 sound_trigger_sound_model_type_t type,
919 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700920 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700921 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
922 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700923{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700924}
925
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700926#undef LOG_TAG
927#define LOG_TAG "SoundTriggerHwService::ModuleClient"
928
929SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
930 const sp<ISoundTriggerClient>& client)
931 : mModule(module), mClient(client)
932{
933}
934
935void SoundTriggerHwService::ModuleClient::onFirstRef()
936{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800937 sp<IBinder> binder = IInterface::asBinder(mClient);
938 if (binder != 0) {
939 binder->linkToDeath(this);
940 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700941}
942
943SoundTriggerHwService::ModuleClient::~ModuleClient()
944{
945}
946
947status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
948 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700949 String8 result;
950 return NO_ERROR;
951}
952
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700953void SoundTriggerHwService::ModuleClient::detach() {
954 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700955 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
956 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700957 return;
958 }
959
960 {
961 AutoMutex lock(mLock);
962 if (mClient != 0) {
963 IInterface::asBinder(mClient)->unlinkToDeath(this);
964 mClient.clear();
965 }
966 }
967
968 sp<Module> module = mModule.promote();
969 if (module == 0) {
970 return;
971 }
972 module->detach(this);
973}
974
975status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
976 sound_model_handle_t *handle)
977{
978 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700979 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
980 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700981 return PERMISSION_DENIED;
982 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700983 if (checkIMemory(modelMemory) != NO_ERROR) {
984 return BAD_VALUE;
985 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700986
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 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001017 if (checkIMemory(dataMemory) != NO_ERROR) {
1018 return BAD_VALUE;
1019 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001020
1021 sp<Module> module = mModule.promote();
1022 if (module == 0) {
1023 return NO_INIT;
1024 }
1025 return module->startRecognition(handle, dataMemory);
1026}
1027
1028status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1029{
1030 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001031 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1032 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001033 return PERMISSION_DENIED;
1034 }
1035
1036 sp<Module> module = mModule.promote();
1037 if (module == 0) {
1038 return NO_INIT;
1039 }
1040 return module->stopRecognition(handle);
1041}
1042
mike dooley6e189b12018-11-07 15:44:37 +01001043status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001044{
1045 ALOGV("getModelState() model handle %d", handle);
1046 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1047 IPCThreadState::self()->getCallingUid())) {
1048 return PERMISSION_DENIED;
1049 }
1050
1051 sp<Module> module = mModule.promote();
1052 if (module == 0) {
1053 return NO_INIT;
1054 }
mike dooley6e189b12018-11-07 15:44:37 +01001055 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001056}
1057
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001058void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1059{
1060 ALOGV("ModuleClient::setCaptureState_l %d", active);
1061 sp<SoundTriggerHwService> service;
1062 sound_trigger_service_state_t state;
1063
1064 sp<Module> module = mModule.promote();
1065 if (module == 0) {
1066 return;
1067 }
1068 {
1069 AutoMutex lock(mLock);
1070 state = (active && !module->isConcurrentCaptureAllowed()) ?
1071 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1072
1073 service = module->service().promote();
1074 if (service == 0) {
1075 return;
1076 }
1077 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001078 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001079}
1080
1081void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1082{
1083 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1084
1085 sp<IMemory> eventMemory = event->mMemory;
1086
1087 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1088 return;
1089 }
1090
Chris Thornton02b74212017-11-06 14:45:30 -08001091 sp<ISoundTriggerClient> client;
1092 {
1093 AutoMutex lock(mLock);
1094 client = mClient;
1095 }
1096
1097 if (client != 0) {
1098 switch (event->mType) {
1099 case CallbackEvent::TYPE_RECOGNITION: {
1100 client->onRecognitionEvent(eventMemory);
1101 } break;
1102 case CallbackEvent::TYPE_SOUNDMODEL: {
1103 client->onSoundModelEvent(eventMemory);
1104 } break;
1105 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001106 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001107 } break;
1108 default:
1109 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001110 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001111 }
1112}
1113
1114void SoundTriggerHwService::ModuleClient::binderDied(
1115 const wp<IBinder> &who __unused) {
1116 ALOGW("client binder died for client %p", this);
1117 detach();
1118}
1119
Eric Laurentb7a11d82014-04-18 17:40:41 -07001120}; // namespace android