blob: 944abcc31d58275ea672301cb04bd0db27e934c9 [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#define HW_MODULE_PREFIX "primary"
Eric Laurent7a544b42016-08-05 19:01:13 -070040namespace android {
Eric Laurentb7a11d82014-04-18 17:40:41 -070041
42SoundTriggerHwService::SoundTriggerHwService()
43 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070044 mNextUniqueId(1),
45 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
46 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070047{
48}
49
50void SoundTriggerHwService::onFirstRef()
51{
Eric Laurentb7a11d82014-04-18 17:40:41 -070052 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070053
Eric Laurent7a544b42016-08-05 19:01:13 -070054 sp<SoundTriggerHalInterface> halInterface =
55 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070056
Eric Laurent7a544b42016-08-05 19:01:13 -070057 if (halInterface == 0) {
58 ALOGW("could not connect to HAL");
59 return;
60 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070061 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070062 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070063 if (rc != 0) {
64 ALOGE("could not read implementation properties");
65 return;
66 }
67 descriptor.handle =
68 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
69 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
70 descriptor.handle);
71
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070072 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -070073 mModules.add(descriptor.handle, module);
74 mCallbackThread = new CallbackThread(this);
75}
76
77SoundTriggerHwService::~SoundTriggerHwService()
78{
79 if (mCallbackThread != 0) {
80 mCallbackThread->exit();
81 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070082}
83
84status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
85 uint32_t *numModules)
86{
87 ALOGV("listModules");
Eric Laurent7504b9e2017-08-15 18:17:26 -070088 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
89 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +000090 return PERMISSION_DENIED;
91 }
92
Eric Laurentb7a11d82014-04-18 17:40:41 -070093 AutoMutex lock(mServiceLock);
94 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
95 return BAD_VALUE;
96 }
97 size_t maxModules = *numModules;
98 *numModules = mModules.size();
99 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
100 modules[i] = mModules.valueAt(i)->descriptor();
101 }
102 return NO_ERROR;
103}
104
105status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
106 const sp<ISoundTriggerClient>& client,
107 sp<ISoundTrigger>& moduleInterface)
108{
109 ALOGV("attach module %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700110 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
111 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000112 return PERMISSION_DENIED;
113 }
114
Eric Laurentb7a11d82014-04-18 17:40:41 -0700115 AutoMutex lock(mServiceLock);
116 moduleInterface.clear();
117 if (client == 0) {
118 return BAD_VALUE;
119 }
120 ssize_t index = mModules.indexOfKey(handle);
121 if (index < 0) {
122 return BAD_VALUE;
123 }
124 sp<Module> module = mModules.valueAt(index);
125
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700126 sp<ModuleClient> moduleClient = module->addClient(client);
127 if (moduleClient == 0) {
128 return NO_INIT;
129 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700130
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700131 moduleClient->setCaptureState_l(mCaptureState);
132 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700133
Eric Laurentb7a11d82014-04-18 17:40:41 -0700134 return NO_ERROR;
135}
136
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700137status_t SoundTriggerHwService::setCaptureState(bool active)
138{
139 ALOGV("setCaptureState %d", active);
140 AutoMutex lock(mServiceLock);
141 mCaptureState = active;
142 for (size_t i = 0; i < mModules.size(); i++) {
143 mModules.valueAt(i)->setCaptureState_l(active);
144 }
145 return NO_ERROR;
146}
147
148
Eric Laurentb7a11d82014-04-18 17:40:41 -0700149static const int kDumpLockRetries = 50;
150static const int kDumpLockSleep = 60000;
151
152static bool tryLock(Mutex& mutex)
153{
154 bool locked = false;
155 for (int i = 0; i < kDumpLockRetries; ++i) {
156 if (mutex.tryLock() == NO_ERROR) {
157 locked = true;
158 break;
159 }
160 usleep(kDumpLockSleep);
161 }
162 return locked;
163}
164
165status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
166 String8 result;
167 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
168 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
169 write(fd, result.string(), result.size());
170 } else {
171 bool locked = tryLock(mServiceLock);
172 // failed to lock - SoundTriggerHwService is probably deadlocked
173 if (!locked) {
174 result.append("SoundTriggerHwService may be deadlocked\n");
175 write(fd, result.string(), result.size());
176 }
177
178 if (locked) mServiceLock.unlock();
179 }
180 return NO_ERROR;
181}
182
183status_t SoundTriggerHwService::onTransact(
184 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
185 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
186}
187
188
189// static
190void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
191 void *cookie)
192{
193 Module *module = (Module *)cookie;
194 if (module == NULL) {
195 return;
196 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700197 sp<SoundTriggerHwService> service = module->service().promote();
198 if (service == 0) {
199 return;
200 }
201
202 service->sendRecognitionEvent(event, module);
203}
204
Chris Thornton79c56612017-10-25 14:47:44 -0700205sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700206 struct sound_trigger_recognition_event *event)
207{
Chris Thornton79c56612017-10-25 14:47:44 -0700208 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700209 sp<IMemory> eventMemory;
210
211 //sanitize event
212 switch (event->type) {
213 case SOUND_MODEL_TYPE_KEYPHRASE:
214 ALOGW_IF(event->data_size != 0 && event->data_offset !=
215 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700216 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700217 event->data_offset);
218 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
219 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800220 case SOUND_MODEL_TYPE_GENERIC:
221 ALOGW_IF(event->data_size != 0 && event->data_offset !=
222 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700223 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800224 event->data_offset);
225 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
226 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700227 case SOUND_MODEL_TYPE_UNKNOWN:
228 ALOGW_IF(event->data_size != 0 && event->data_offset !=
229 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700230 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700231 event->data_offset);
232 event->data_offset = sizeof(struct sound_trigger_recognition_event);
233 break;
234 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700235 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700236 }
237
238 size_t size = event->data_offset + event->data_size;
239 eventMemory = mMemoryDealer->allocate(size);
240 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
241 eventMemory.clear();
242 return eventMemory;
243 }
244 memcpy(eventMemory->pointer(), event, size);
245
246 return eventMemory;
247}
248
249void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
250 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700251{
252 if (module == NULL) {
253 return;
254 }
255 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
256 if (eventMemory == 0) {
257 return;
258 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700259
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700260 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
261 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700262 callbackEvent->setModule(module);
263 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700264}
265
266// static
267void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
268 void *cookie)
269{
270 Module *module = (Module *)cookie;
271 if (module == NULL) {
272 return;
273 }
274 sp<SoundTriggerHwService> service = module->service().promote();
275 if (service == 0) {
276 return;
277 }
278
279 service->sendSoundModelEvent(event, module);
280}
281
Chris Thornton79c56612017-10-25 14:47:44 -0700282sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700283{
Chris Thornton79c56612017-10-25 14:47:44 -0700284 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700285 sp<IMemory> eventMemory;
286
287 size_t size = event->data_offset + event->data_size;
288 eventMemory = mMemoryDealer->allocate(size);
289 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
290 eventMemory.clear();
291 return eventMemory;
292 }
293 memcpy(eventMemory->pointer(), event, size);
294
295 return eventMemory;
296}
297
298void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
299 Module *module)
300{
Chris Thornton79c56612017-10-25 14:47:44 -0700301 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700302 if (eventMemory == 0) {
303 return;
304 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700305 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
306 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700307 callbackEvent->setModule(module);
308 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700309}
310
311
Chris Thornton07405ee2017-11-14 20:45:27 -0800312sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700313{
Chris Thornton79c56612017-10-25 14:47:44 -0700314 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700315 sp<IMemory> eventMemory;
316
317 size_t size = sizeof(sound_trigger_service_state_t);
318 eventMemory = mMemoryDealer->allocate(size);
319 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
320 eventMemory.clear();
321 return eventMemory;
322 }
323 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
324 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700325}
326
Chris Thornton07405ee2017-11-14 20:45:27 -0800327void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700328 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700329{
Chris Thornton07405ee2017-11-14 20:45:27 -0800330 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700331 if (eventMemory == 0) {
332 return;
333 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700334 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
335 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800336 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700337 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700338}
339
Chris Thornton07405ee2017-11-14 20:45:27 -0800340void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
341 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700342{
Chris Thornton07405ee2017-11-14 20:45:27 -0800343 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700344 if (eventMemory == 0) {
345 return;
346 }
347 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
348 eventMemory);
349 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700350 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700351}
352
Chris Thornton79c56612017-10-25 14:47:44 -0700353void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700354{
355 mCallbackThread->sendCallbackEvent(event);
356}
357
358void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
359{
360 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700361 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700362 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700363 {
364 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700365 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700366 module = event->mModule.promote();
367 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700368 moduleClient = event->mModuleClient.promote();
369 if (moduleClient == 0) {
370 return;
371 }
Chris Thornton79c56612017-10-25 14:47:44 -0700372 } else {
373 // Sanity check on this being a Module we know about.
374 bool foundModule = false;
375 for (size_t i = 0; i < mModules.size(); i++) {
376 if (mModules.valueAt(i).get() == module.get()) {
377 foundModule = true;
378 break;
379 }
380 }
381 if (!foundModule) {
382 ALOGE("onCallbackEvent for unknown module");
383 return;
384 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700385 }
386 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700387 if (module != 0) {
388 ALOGV("onCallbackEvent for module");
389 module->onCallbackEvent(event);
390 } else if (moduleClient != 0) {
391 ALOGV("onCallbackEvent for moduleClient");
392 moduleClient->onCallbackEvent(event);
393 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700394 {
395 AutoMutex lock(mServiceLock);
396 // clear now to execute with mServiceLock locked
397 event->mMemory.clear();
398 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700399}
400
401#undef LOG_TAG
402#define LOG_TAG "SoundTriggerHwService::CallbackThread"
403
404SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
405 : mService(service)
406{
407}
408
409SoundTriggerHwService::CallbackThread::~CallbackThread()
410{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700411 while (!mEventQueue.isEmpty()) {
412 mEventQueue[0]->mMemory.clear();
413 mEventQueue.removeAt(0);
414 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700415}
416
417void SoundTriggerHwService::CallbackThread::onFirstRef()
418{
419 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
420}
421
422bool SoundTriggerHwService::CallbackThread::threadLoop()
423{
424 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700425 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700426 sp<SoundTriggerHwService> service;
427 {
428 Mutex::Autolock _l(mCallbackLock);
429 while (mEventQueue.isEmpty() && !exitPending()) {
430 ALOGV("CallbackThread::threadLoop() sleep");
431 mCallbackCond.wait(mCallbackLock);
432 ALOGV("CallbackThread::threadLoop() wake up");
433 }
434 if (exitPending()) {
435 break;
436 }
437 event = mEventQueue[0];
438 mEventQueue.removeAt(0);
439 service = mService.promote();
440 }
441 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700442 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700443 }
444 }
445 return false;
446}
447
448void SoundTriggerHwService::CallbackThread::exit()
449{
450 Mutex::Autolock _l(mCallbackLock);
451 requestExit();
452 mCallbackCond.broadcast();
453}
454
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700455void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
456 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700457{
458 AutoMutex lock(mCallbackLock);
459 mEventQueue.add(event);
460 mCallbackCond.signal();
461}
462
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700463SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
464 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700465{
466}
467
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700468SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700469{
470}
471
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700472
Eric Laurentb7a11d82014-04-18 17:40:41 -0700473#undef LOG_TAG
474#define LOG_TAG "SoundTriggerHwService::Module"
475
476SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700477 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700478 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700479 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700480 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700481{
482}
483
484SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700485 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700486}
487
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700488sp<SoundTriggerHwService::ModuleClient>
489SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
490{
491 AutoMutex lock(mLock);
492 sp<ModuleClient> moduleClient;
493
494 for (size_t i = 0; i < mModuleClients.size(); i++) {
495 if (mModuleClients[i]->client() == client) {
496 // Client already present, reuse client
497 return moduleClient;
498 }
499 }
500 moduleClient = new ModuleClient(this, client);
501
502 ALOGV("addClient() client %p", moduleClient.get());
503 mModuleClients.add(moduleClient);
504
505 return moduleClient;
506}
507
508void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
509{
510 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700511 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700512
Eric Laurent338e8ba2017-10-05 10:58:38 -0700513 {
514 AutoMutex lock(mLock);
515 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700516
Eric Laurent338e8ba2017-10-05 10:58:38 -0700517 for (size_t i = 0; i < mModuleClients.size(); i++) {
518 if (mModuleClients[i] == moduleClient) {
519 index = i;
520 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700521 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700522 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700523 if (index == -1) {
524 return;
525 }
526
527 ALOGV("remove client %p", moduleClient.get());
528 mModuleClients.removeAt(index);
529
530 // Iterate in reverse order as models are removed from list inside the loop.
531 for (size_t i = mModels.size(); i > 0; i--) {
532 sp<Model> model = mModels.valueAt(i - 1);
533 if (moduleClient == model->mModuleClient) {
534 mModels.removeItemsAt(i - 1);
535 ALOGV("detach() unloading model %d", model->mHandle);
536 if (mHalInterface != 0) {
537 if (model->mState == Model::STATE_ACTIVE) {
538 mHalInterface->stopRecognition(model->mHandle);
539 }
540 mHalInterface->unloadSoundModel(model->mHandle);
541 }
542 releasedSessions.add(model->mCaptureSession);
543 }
544 }
545 }
546
547 for (size_t i = 0; i < releasedSessions.size(); i++) {
548 // do not call AudioSystem methods with mLock held
549 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700550 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700551}
552
553status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700554 sp<ModuleClient> moduleClient,
555 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700556{
557 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700558 if (mHalInterface == 0) {
559 return NO_INIT;
560 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700561
Eric Laurentb7a11d82014-04-18 17:40:41 -0700562 struct sound_trigger_sound_model *sound_model =
563 (struct sound_trigger_sound_model *)modelMemory->pointer();
564
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700565 size_t structSize;
566 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
567 structSize = sizeof(struct sound_trigger_phrase_sound_model);
568 } else {
569 structSize = sizeof(struct sound_trigger_sound_model);
570 }
571
572 if (sound_model->data_offset < structSize ||
573 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
574 modelMemory->size() < sound_model->data_offset ||
575 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
576 android_errorWriteLog(0x534e4554, "30148546");
577 ALOGE("loadSoundModel() data_size is too big");
578 return BAD_VALUE;
579 }
580
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700581 audio_session_t session;
582 audio_io_handle_t ioHandle;
583 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700584 // do not call AudioSystem methods with mLock held
585 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700586 if (status != NO_ERROR) {
587 return status;
588 }
589
Eric Laurent338e8ba2017-10-05 10:58:38 -0700590 {
591 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700592
Eric Laurent338e8ba2017-10-05 10:58:38 -0700593 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
594 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
595 mDescriptor.properties.max_sound_models);
596 status = INVALID_OPERATION;
597 goto exit;
598 }
599
600 status = mHalInterface->loadSoundModel(sound_model,
601 SoundTriggerHwService::soundModelCallback,
602 this, handle);
603 if (status != NO_ERROR) {
604 goto exit;
605 }
606
607 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
608 moduleClient);
609 mModels.replaceValueFor(*handle, model);
610 }
611exit:
612 if (status != NO_ERROR) {
613 // do not call AudioSystem methods with mLock held
614 AudioSystem::releaseSoundTriggerSession(session);
615 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700616 return status;
617}
618
619status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
620{
621 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700622 status_t status;
623 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800624
Eric Laurent338e8ba2017-10-05 10:58:38 -0700625 {
626 AutoMutex lock(mLock);
627 if (mHalInterface == 0) {
628 return NO_INIT;
629 }
630 ssize_t index = mModels.indexOfKey(handle);
631 if (index < 0) {
632 return BAD_VALUE;
633 }
634 sp<Model> model = mModels.valueAt(index);
635 mModels.removeItem(handle);
636 if (model->mState == Model::STATE_ACTIVE) {
637 mHalInterface->stopRecognition(model->mHandle);
638 model->mState = Model::STATE_IDLE;
639 }
640 status = mHalInterface->unloadSoundModel(handle);
641 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700642 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700643 // do not call AudioSystem methods with mLock held
644 AudioSystem::releaseSoundTriggerSession(session);
645 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700646}
647
648status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700649 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700650{
651 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700652 if (mHalInterface == 0) {
653 return NO_INIT;
654 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700655
656 struct sound_trigger_recognition_config *config =
657 (struct sound_trigger_recognition_config *)dataMemory->pointer();
658
659 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
660 config->data_size > (UINT_MAX - config->data_offset) ||
661 dataMemory->size() < config->data_offset ||
662 config->data_size > (dataMemory->size() - config->data_offset)) {
663 ALOGE("startRecognition() data_size is too big");
664 return BAD_VALUE;
665 }
666
Eric Laurentb7a11d82014-04-18 17:40:41 -0700667 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700668 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
669 return INVALID_OPERATION;
670 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700671 sp<Model> model = getModel(handle);
672 if (model == 0) {
673 return BAD_VALUE;
674 }
675
676 if (model->mState == Model::STATE_ACTIVE) {
677 return INVALID_OPERATION;
678 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700679
Eric Laurentb7a11d82014-04-18 17:40:41 -0700680
681 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700682 config->capture_handle = model->mCaptureIOHandle;
683 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700684 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700685 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700686 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700687
688 if (status == NO_ERROR) {
689 model->mState = Model::STATE_ACTIVE;
690 model->mConfig = *config;
691 }
692
693 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700694}
695
696status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
697{
698 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700699 if (mHalInterface == 0) {
700 return NO_INIT;
701 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700702 AutoMutex lock(mLock);
703 sp<Model> model = getModel(handle);
704 if (model == 0) {
705 return BAD_VALUE;
706 }
707
708 if (model->mState != Model::STATE_ACTIVE) {
709 return INVALID_OPERATION;
710 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700711 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700712 model->mState = Model::STATE_IDLE;
713 return NO_ERROR;
714}
715
mike dooley6e189b12018-11-07 15:44:37 +0100716status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000717{
718 ALOGV("getModelState() model handle %d", handle);
719 if (mHalInterface == 0) {
720 return NO_INIT;
721 }
722 AutoMutex lock(mLock);
723 sp<Model> model = getModel(handle);
724 if (model == 0) {
725 return BAD_VALUE;
726 }
727
728 if (model->mState != Model::STATE_ACTIVE) {
729 return INVALID_OPERATION;
730 }
731
mike dooley6e189b12018-11-07 15:44:37 +0100732 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000733}
734
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700735void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700736{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700737 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700738
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700739 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700740
741 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
742 return;
743 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700744 if (mModuleClients.isEmpty()) {
745 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700746 return;
747 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700748
Chris Thornton02b74212017-11-06 14:45:30 -0800749 Vector< sp<ModuleClient> > clients;
750
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700751 switch (event->mType) {
752 case CallbackEvent::TYPE_RECOGNITION: {
753 struct sound_trigger_recognition_event *recognitionEvent =
754 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700755 {
756 AutoMutex lock(mLock);
757 sp<Model> model = getModel(recognitionEvent->model);
758 if (model == 0) {
759 ALOGW("%s model == 0", __func__);
760 return;
761 }
762 if (model->mState != Model::STATE_ACTIVE) {
763 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
764 return;
765 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700766
Eric Laurent886561f2014-08-28 19:45:37 -0700767 recognitionEvent->capture_session = model->mCaptureSession;
mike dooley6e189b12018-11-07 15:44:37 +0100768 // Don't reset the model state if this recognition event is a get-state response
769 if (recognitionEvent->status != RECOGNITION_STATUS_GET_STATE_RESPONSE) {
770 model->mState = Model::STATE_IDLE;
771 }
Chris Thornton02b74212017-11-06 14:45:30 -0800772 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700773 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700774 } break;
775 case CallbackEvent::TYPE_SOUNDMODEL: {
776 struct sound_trigger_model_event *soundmodelEvent =
777 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700778 {
779 AutoMutex lock(mLock);
780 sp<Model> model = getModel(soundmodelEvent->model);
781 if (model == 0) {
782 ALOGW("%s model == 0", __func__);
783 return;
784 }
Chris Thornton02b74212017-11-06 14:45:30 -0800785 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700786 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700787 } break;
788 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700789 {
790 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700791 for (size_t i = 0; i < mModuleClients.size(); i++) {
792 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800793 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700794 }
795 }
Eric Laurent886561f2014-08-28 19:45:37 -0700796 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700797 } break;
798 default:
799 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
800 }
Chris Thornton02b74212017-11-06 14:45:30 -0800801
802 for (size_t i = 0; i < clients.size(); i++) {
803 clients[i]->onCallbackEvent(event);
804 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700805}
806
807sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
808 sound_model_handle_t handle)
809{
810 sp<Model> model;
811 ssize_t index = mModels.indexOfKey(handle);
812 if (index >= 0) {
813 model = mModels.valueAt(index);
814 }
815 return model;
816}
817
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700818// Called with mServiceLock held
819void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700820{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700821 ALOGV("Module::setCaptureState_l %d", active);
822 sp<SoundTriggerHwService> service;
823 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700824
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825 Vector< sp<IMemory> > events;
826 {
827 AutoMutex lock(mLock);
828 state = (active && !mDescriptor.properties.concurrent_capture) ?
829 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700830
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700831 if (state == mServiceState) {
832 return;
833 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700834
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700835 mServiceState = state;
836
837 service = mService.promote();
838 if (service == 0) {
839 return;
840 }
841
842 if (state == SOUND_TRIGGER_STATE_ENABLED) {
843 goto exit;
844 }
845
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700846 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700847 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700848
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700849 for (size_t i = 0; i < mModels.size(); i++) {
850 sp<Model> model = mModels.valueAt(i);
851 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700852 if (mHalInterface != 0 && !supports_stop_all) {
853 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700854 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700855 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800856 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
857 struct sound_trigger_phrase_recognition_event event;
858 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
859 event.num_phrases = model->mConfig.num_phrases;
860 for (size_t i = 0; i < event.num_phrases; i++) {
861 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700862 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800863 event.common.status = RECOGNITION_STATUS_ABORT;
864 event.common.type = model->mType;
865 event.common.model = model->mHandle;
866 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700867 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800868 if (eventMemory != 0) {
869 events.add(eventMemory);
870 }
871 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
872 struct sound_trigger_generic_recognition_event event;
873 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
874 event.common.status = RECOGNITION_STATUS_ABORT;
875 event.common.type = model->mType;
876 event.common.model = model->mHandle;
877 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700878 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800879 if (eventMemory != 0) {
880 events.add(eventMemory);
881 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800882 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
883 struct sound_trigger_phrase_recognition_event event;
884 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
885 event.common.status = RECOGNITION_STATUS_ABORT;
886 event.common.type = model->mType;
887 event.common.model = model->mHandle;
888 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700889 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800890 if (eventMemory != 0) {
891 events.add(eventMemory);
892 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800893 } else {
894 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700895 }
896 }
897 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700898 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700899
900 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700901 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
902 events[i]);
903 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700904 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700905 }
906
907exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800908 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700909}
910
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700911
912SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
913 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700914 sound_trigger_sound_model_type_t type,
915 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700916 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700917 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
918 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700919{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700920}
921
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700922#undef LOG_TAG
923#define LOG_TAG "SoundTriggerHwService::ModuleClient"
924
925SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
926 const sp<ISoundTriggerClient>& client)
927 : mModule(module), mClient(client)
928{
929}
930
931void SoundTriggerHwService::ModuleClient::onFirstRef()
932{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800933 sp<IBinder> binder = IInterface::asBinder(mClient);
934 if (binder != 0) {
935 binder->linkToDeath(this);
936 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700937}
938
939SoundTriggerHwService::ModuleClient::~ModuleClient()
940{
941}
942
943status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
944 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700945 String8 result;
946 return NO_ERROR;
947}
948
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700949void SoundTriggerHwService::ModuleClient::detach() {
950 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700951 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
952 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700953 return;
954 }
955
956 {
957 AutoMutex lock(mLock);
958 if (mClient != 0) {
959 IInterface::asBinder(mClient)->unlinkToDeath(this);
960 mClient.clear();
961 }
962 }
963
964 sp<Module> module = mModule.promote();
965 if (module == 0) {
966 return;
967 }
968 module->detach(this);
969}
970
971status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
972 sound_model_handle_t *handle)
973{
974 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700975 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
976 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700977 return PERMISSION_DENIED;
978 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700979 if (checkIMemory(modelMemory) != NO_ERROR) {
980 return BAD_VALUE;
981 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700982
983 sp<Module> module = mModule.promote();
984 if (module == 0) {
985 return NO_INIT;
986 }
987 return module->loadSoundModel(modelMemory, this, handle);
988}
989
990status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
991{
992 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700993 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
994 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700995 return PERMISSION_DENIED;
996 }
997
998 sp<Module> module = mModule.promote();
999 if (module == 0) {
1000 return NO_INIT;
1001 }
1002 return module->unloadSoundModel(handle);
1003}
1004
1005status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1006 const sp<IMemory>& dataMemory)
1007{
1008 ALOGV("startRecognition() 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 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001013 if (checkIMemory(dataMemory) != NO_ERROR) {
1014 return BAD_VALUE;
1015 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001016
1017 sp<Module> module = mModule.promote();
1018 if (module == 0) {
1019 return NO_INIT;
1020 }
1021 return module->startRecognition(handle, dataMemory);
1022}
1023
1024status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1025{
1026 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001027 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1028 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001029 return PERMISSION_DENIED;
1030 }
1031
1032 sp<Module> module = mModule.promote();
1033 if (module == 0) {
1034 return NO_INIT;
1035 }
1036 return module->stopRecognition(handle);
1037}
1038
mike dooley6e189b12018-11-07 15:44:37 +01001039status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001040{
1041 ALOGV("getModelState() model handle %d", handle);
1042 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1043 IPCThreadState::self()->getCallingUid())) {
1044 return PERMISSION_DENIED;
1045 }
1046
1047 sp<Module> module = mModule.promote();
1048 if (module == 0) {
1049 return NO_INIT;
1050 }
mike dooley6e189b12018-11-07 15:44:37 +01001051 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001052}
1053
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001054void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1055{
1056 ALOGV("ModuleClient::setCaptureState_l %d", active);
1057 sp<SoundTriggerHwService> service;
1058 sound_trigger_service_state_t state;
1059
1060 sp<Module> module = mModule.promote();
1061 if (module == 0) {
1062 return;
1063 }
1064 {
1065 AutoMutex lock(mLock);
1066 state = (active && !module->isConcurrentCaptureAllowed()) ?
1067 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1068
1069 service = module->service().promote();
1070 if (service == 0) {
1071 return;
1072 }
1073 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001074 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001075}
1076
1077void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1078{
1079 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1080
1081 sp<IMemory> eventMemory = event->mMemory;
1082
1083 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1084 return;
1085 }
1086
Chris Thornton02b74212017-11-06 14:45:30 -08001087 sp<ISoundTriggerClient> client;
1088 {
1089 AutoMutex lock(mLock);
1090 client = mClient;
1091 }
1092
1093 if (client != 0) {
1094 switch (event->mType) {
1095 case CallbackEvent::TYPE_RECOGNITION: {
1096 client->onRecognitionEvent(eventMemory);
1097 } break;
1098 case CallbackEvent::TYPE_SOUNDMODEL: {
1099 client->onSoundModelEvent(eventMemory);
1100 } break;
1101 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001102 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001103 } break;
1104 default:
1105 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001106 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001107 }
1108}
1109
1110void SoundTriggerHwService::ModuleClient::binderDied(
1111 const wp<IBinder> &who __unused) {
1112 ALOGW("client binder died for client %p", this);
1113 detach();
1114}
1115
Eric Laurentb7a11d82014-04-18 17:40:41 -07001116}; // namespace android