blob: fe2ccf24ca5b6795a597ead88e5003783c94a333 [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 dooleyfd018722019-01-04 09:31:31 +0100768 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800769 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700770 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700771 } break;
772 case CallbackEvent::TYPE_SOUNDMODEL: {
773 struct sound_trigger_model_event *soundmodelEvent =
774 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700775 {
776 AutoMutex lock(mLock);
777 sp<Model> model = getModel(soundmodelEvent->model);
778 if (model == 0) {
779 ALOGW("%s model == 0", __func__);
780 return;
781 }
Chris Thornton02b74212017-11-06 14:45:30 -0800782 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700783 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700784 } break;
785 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700786 {
787 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700788 for (size_t i = 0; i < mModuleClients.size(); i++) {
789 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800790 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700791 }
792 }
Eric Laurent886561f2014-08-28 19:45:37 -0700793 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700794 } break;
795 default:
796 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
797 }
Chris Thornton02b74212017-11-06 14:45:30 -0800798
799 for (size_t i = 0; i < clients.size(); i++) {
800 clients[i]->onCallbackEvent(event);
801 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700802}
803
804sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
805 sound_model_handle_t handle)
806{
807 sp<Model> model;
808 ssize_t index = mModels.indexOfKey(handle);
809 if (index >= 0) {
810 model = mModels.valueAt(index);
811 }
812 return model;
813}
814
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700815// Called with mServiceLock held
816void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700817{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700818 ALOGV("Module::setCaptureState_l %d", active);
819 sp<SoundTriggerHwService> service;
820 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700821
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700822 Vector< sp<IMemory> > events;
823 {
824 AutoMutex lock(mLock);
825 state = (active && !mDescriptor.properties.concurrent_capture) ?
826 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700827
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700828 if (state == mServiceState) {
829 return;
830 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700831
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700832 mServiceState = state;
833
834 service = mService.promote();
835 if (service == 0) {
836 return;
837 }
838
839 if (state == SOUND_TRIGGER_STATE_ENABLED) {
840 goto exit;
841 }
842
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700843 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700844 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700845
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700846 for (size_t i = 0; i < mModels.size(); i++) {
847 sp<Model> model = mModels.valueAt(i);
848 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700849 if (mHalInterface != 0 && !supports_stop_all) {
850 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700851 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700852 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800853 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
854 struct sound_trigger_phrase_recognition_event event;
855 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
856 event.num_phrases = model->mConfig.num_phrases;
857 for (size_t i = 0; i < event.num_phrases; i++) {
858 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700859 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800860 event.common.status = RECOGNITION_STATUS_ABORT;
861 event.common.type = model->mType;
862 event.common.model = model->mHandle;
863 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700864 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800865 if (eventMemory != 0) {
866 events.add(eventMemory);
867 }
868 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
869 struct sound_trigger_generic_recognition_event event;
870 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
871 event.common.status = RECOGNITION_STATUS_ABORT;
872 event.common.type = model->mType;
873 event.common.model = model->mHandle;
874 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700875 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800876 if (eventMemory != 0) {
877 events.add(eventMemory);
878 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800879 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
880 struct sound_trigger_phrase_recognition_event event;
881 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
882 event.common.status = RECOGNITION_STATUS_ABORT;
883 event.common.type = model->mType;
884 event.common.model = model->mHandle;
885 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700886 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800887 if (eventMemory != 0) {
888 events.add(eventMemory);
889 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800890 } else {
891 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700892 }
893 }
894 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700895 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700896
897 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700898 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
899 events[i]);
900 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700901 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700902 }
903
904exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800905 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700906}
907
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700908
909SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
910 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700911 sound_trigger_sound_model_type_t type,
912 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700913 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700914 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
915 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700916{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700917}
918
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700919#undef LOG_TAG
920#define LOG_TAG "SoundTriggerHwService::ModuleClient"
921
922SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
923 const sp<ISoundTriggerClient>& client)
924 : mModule(module), mClient(client)
925{
926}
927
928void SoundTriggerHwService::ModuleClient::onFirstRef()
929{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800930 sp<IBinder> binder = IInterface::asBinder(mClient);
931 if (binder != 0) {
932 binder->linkToDeath(this);
933 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700934}
935
936SoundTriggerHwService::ModuleClient::~ModuleClient()
937{
938}
939
940status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
941 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700942 String8 result;
943 return NO_ERROR;
944}
945
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700946void SoundTriggerHwService::ModuleClient::detach() {
947 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700948 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
949 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700950 return;
951 }
952
953 {
954 AutoMutex lock(mLock);
955 if (mClient != 0) {
956 IInterface::asBinder(mClient)->unlinkToDeath(this);
957 mClient.clear();
958 }
959 }
960
961 sp<Module> module = mModule.promote();
962 if (module == 0) {
963 return;
964 }
965 module->detach(this);
966}
967
968status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
969 sound_model_handle_t *handle)
970{
971 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700972 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
973 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700974 return PERMISSION_DENIED;
975 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700976 if (checkIMemory(modelMemory) != NO_ERROR) {
977 return BAD_VALUE;
978 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700979
980 sp<Module> module = mModule.promote();
981 if (module == 0) {
982 return NO_INIT;
983 }
984 return module->loadSoundModel(modelMemory, this, handle);
985}
986
987status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
988{
989 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700990 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
991 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700992 return PERMISSION_DENIED;
993 }
994
995 sp<Module> module = mModule.promote();
996 if (module == 0) {
997 return NO_INIT;
998 }
999 return module->unloadSoundModel(handle);
1000}
1001
1002status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1003 const sp<IMemory>& dataMemory)
1004{
1005 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001006 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1007 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001008 return PERMISSION_DENIED;
1009 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001010 if (checkIMemory(dataMemory) != NO_ERROR) {
1011 return BAD_VALUE;
1012 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001013
1014 sp<Module> module = mModule.promote();
1015 if (module == 0) {
1016 return NO_INIT;
1017 }
1018 return module->startRecognition(handle, dataMemory);
1019}
1020
1021status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1022{
1023 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001024 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1025 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001026 return PERMISSION_DENIED;
1027 }
1028
1029 sp<Module> module = mModule.promote();
1030 if (module == 0) {
1031 return NO_INIT;
1032 }
1033 return module->stopRecognition(handle);
1034}
1035
mike dooley6e189b12018-11-07 15:44:37 +01001036status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001037{
1038 ALOGV("getModelState() model handle %d", handle);
1039 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1040 IPCThreadState::self()->getCallingUid())) {
1041 return PERMISSION_DENIED;
1042 }
1043
1044 sp<Module> module = mModule.promote();
1045 if (module == 0) {
1046 return NO_INIT;
1047 }
mike dooley6e189b12018-11-07 15:44:37 +01001048 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001049}
1050
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001051void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1052{
1053 ALOGV("ModuleClient::setCaptureState_l %d", active);
1054 sp<SoundTriggerHwService> service;
1055 sound_trigger_service_state_t state;
1056
1057 sp<Module> module = mModule.promote();
1058 if (module == 0) {
1059 return;
1060 }
1061 {
1062 AutoMutex lock(mLock);
1063 state = (active && !module->isConcurrentCaptureAllowed()) ?
1064 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1065
1066 service = module->service().promote();
1067 if (service == 0) {
1068 return;
1069 }
1070 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001071 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001072}
1073
1074void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1075{
1076 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1077
1078 sp<IMemory> eventMemory = event->mMemory;
1079
1080 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1081 return;
1082 }
1083
Chris Thornton02b74212017-11-06 14:45:30 -08001084 sp<ISoundTriggerClient> client;
1085 {
1086 AutoMutex lock(mLock);
1087 client = mClient;
1088 }
1089
1090 if (client != 0) {
1091 switch (event->mType) {
1092 case CallbackEvent::TYPE_RECOGNITION: {
1093 client->onRecognitionEvent(eventMemory);
1094 } break;
1095 case CallbackEvent::TYPE_SOUNDMODEL: {
1096 client->onSoundModelEvent(eventMemory);
1097 } break;
1098 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001099 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001100 } break;
1101 default:
1102 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001103 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001104 }
1105}
1106
1107void SoundTriggerHwService::ModuleClient::binderDied(
1108 const wp<IBinder> &who __unused) {
1109 ALOGW("client binder died for client %p", this);
1110 detach();
1111}
1112
Eric Laurentb7a11d82014-04-18 17:40:41 -07001113}; // namespace android