blob: f89683a86c71f5daca17ee8cf6fee65a870fc7cc [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
Mikhail Naganov959e2d02019-03-28 11:08:19 -070025#include <audio_utils/clock.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000026#include <system/sound_trigger.h>
27#include <cutils/atomic.h>
28#include <cutils/properties.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070029#include <hardware/hardware.h>
30#include <media/AudioSystem.h>
Andy Hungab7ef302018-05-15 19:35:29 -070031#include <mediautils/ServiceUtilities.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000032#include <utils/Errors.h>
33#include <utils/Log.h>
Eric Laurentb7a11d82014-04-18 17:40:41 -070034#include <binder/IServiceManager.h>
35#include <binder/MemoryBase.h>
36#include <binder/MemoryHeapBase.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070037#include <system/sound_trigger.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000038#include "SoundTriggerHwService.h"
Eric Laurentb7a11d82014-04-18 17:40:41 -070039
Eric Laurentb7a11d82014-04-18 17:40:41 -070040#define HW_MODULE_PREFIX "primary"
Eric Laurent7a544b42016-08-05 19:01:13 -070041namespace android {
Eric Laurentb7a11d82014-04-18 17:40:41 -070042
43SoundTriggerHwService::SoundTriggerHwService()
44 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070045 mNextUniqueId(1),
46 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
47 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070048{
49}
50
51void SoundTriggerHwService::onFirstRef()
52{
Eric Laurentb7a11d82014-04-18 17:40:41 -070053 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070054
Eric Laurent7a544b42016-08-05 19:01:13 -070055 sp<SoundTriggerHalInterface> halInterface =
56 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070057
Eric Laurent7a544b42016-08-05 19:01:13 -070058 if (halInterface == 0) {
59 ALOGW("could not connect to HAL");
60 return;
61 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070062 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070063 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070064 if (rc != 0) {
65 ALOGE("could not read implementation properties");
66 return;
67 }
68 descriptor.handle =
69 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
70 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
71 descriptor.handle);
72
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070073 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -070074 mModules.add(descriptor.handle, module);
75 mCallbackThread = new CallbackThread(this);
76}
77
78SoundTriggerHwService::~SoundTriggerHwService()
79{
80 if (mCallbackThread != 0) {
81 mCallbackThread->exit();
82 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070083}
84
85status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
86 uint32_t *numModules)
87{
88 ALOGV("listModules");
Eric Laurent7504b9e2017-08-15 18:17:26 -070089 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
90 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +000091 return PERMISSION_DENIED;
92 }
93
Eric Laurentb7a11d82014-04-18 17:40:41 -070094 AutoMutex lock(mServiceLock);
95 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
96 return BAD_VALUE;
97 }
98 size_t maxModules = *numModules;
99 *numModules = mModules.size();
100 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
101 modules[i] = mModules.valueAt(i)->descriptor();
102 }
103 return NO_ERROR;
104}
105
106status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
107 const sp<ISoundTriggerClient>& client,
108 sp<ISoundTrigger>& moduleInterface)
109{
110 ALOGV("attach module %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700111 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
112 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000113 return PERMISSION_DENIED;
114 }
115
Eric Laurentb7a11d82014-04-18 17:40:41 -0700116 AutoMutex lock(mServiceLock);
117 moduleInterface.clear();
118 if (client == 0) {
119 return BAD_VALUE;
120 }
121 ssize_t index = mModules.indexOfKey(handle);
122 if (index < 0) {
123 return BAD_VALUE;
124 }
125 sp<Module> module = mModules.valueAt(index);
126
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700127 sp<ModuleClient> moduleClient = module->addClient(client);
128 if (moduleClient == 0) {
129 return NO_INIT;
130 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700131
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700132 moduleClient->setCaptureState_l(mCaptureState);
133 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700134
Eric Laurentb7a11d82014-04-18 17:40:41 -0700135 return NO_ERROR;
136}
137
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700138status_t SoundTriggerHwService::setCaptureState(bool active)
139{
140 ALOGV("setCaptureState %d", active);
141 AutoMutex lock(mServiceLock);
142 mCaptureState = active;
143 for (size_t i = 0; i < mModules.size(); i++) {
144 mModules.valueAt(i)->setCaptureState_l(active);
145 }
146 return NO_ERROR;
147}
148
149
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700150static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700151
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700152static bool dumpTryLock(Mutex& mutex)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700153{
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700154 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
155 return err == NO_ERROR;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700156}
157
158status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
159 String8 result;
160 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
161 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
162 write(fd, result.string(), result.size());
163 } else {
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700164 bool locked = dumpTryLock(mServiceLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700165 // failed to lock - SoundTriggerHwService is probably deadlocked
166 if (!locked) {
167 result.append("SoundTriggerHwService may be deadlocked\n");
168 write(fd, result.string(), result.size());
169 }
170
171 if (locked) mServiceLock.unlock();
172 }
173 return NO_ERROR;
174}
175
176status_t SoundTriggerHwService::onTransact(
177 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
178 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
179}
180
181
182// static
183void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
184 void *cookie)
185{
186 Module *module = (Module *)cookie;
187 if (module == NULL) {
188 return;
189 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700190 sp<SoundTriggerHwService> service = module->service().promote();
191 if (service == 0) {
192 return;
193 }
194
195 service->sendRecognitionEvent(event, module);
196}
197
Chris Thornton79c56612017-10-25 14:47:44 -0700198sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700199 struct sound_trigger_recognition_event *event)
200{
Chris Thornton79c56612017-10-25 14:47:44 -0700201 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700202 sp<IMemory> eventMemory;
203
204 //sanitize event
205 switch (event->type) {
206 case SOUND_MODEL_TYPE_KEYPHRASE:
207 ALOGW_IF(event->data_size != 0 && event->data_offset !=
208 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700209 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700210 event->data_offset);
211 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
212 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800213 case SOUND_MODEL_TYPE_GENERIC:
214 ALOGW_IF(event->data_size != 0 && event->data_offset !=
215 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700216 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800217 event->data_offset);
218 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
219 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700220 case SOUND_MODEL_TYPE_UNKNOWN:
221 ALOGW_IF(event->data_size != 0 && event->data_offset !=
222 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700223 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700224 event->data_offset);
225 event->data_offset = sizeof(struct sound_trigger_recognition_event);
226 break;
227 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700228 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700229 }
230
231 size_t size = event->data_offset + event->data_size;
232 eventMemory = mMemoryDealer->allocate(size);
233 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
234 eventMemory.clear();
235 return eventMemory;
236 }
237 memcpy(eventMemory->pointer(), event, size);
238
239 return eventMemory;
240}
241
242void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
243 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700244{
245 if (module == NULL) {
246 return;
247 }
248 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
249 if (eventMemory == 0) {
250 return;
251 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700252
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700253 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
254 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700255 callbackEvent->setModule(module);
256 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700257}
258
259// static
260void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
261 void *cookie)
262{
263 Module *module = (Module *)cookie;
264 if (module == NULL) {
265 return;
266 }
267 sp<SoundTriggerHwService> service = module->service().promote();
268 if (service == 0) {
269 return;
270 }
271
272 service->sendSoundModelEvent(event, module);
273}
274
Chris Thornton79c56612017-10-25 14:47:44 -0700275sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700276{
Chris Thornton79c56612017-10-25 14:47:44 -0700277 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700278 sp<IMemory> eventMemory;
279
280 size_t size = event->data_offset + event->data_size;
281 eventMemory = mMemoryDealer->allocate(size);
282 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
283 eventMemory.clear();
284 return eventMemory;
285 }
286 memcpy(eventMemory->pointer(), event, size);
287
288 return eventMemory;
289}
290
291void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
292 Module *module)
293{
Chris Thornton79c56612017-10-25 14:47:44 -0700294 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700295 if (eventMemory == 0) {
296 return;
297 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700298 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
299 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700300 callbackEvent->setModule(module);
301 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700302}
303
304
Chris Thornton07405ee2017-11-14 20:45:27 -0800305sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700306{
Chris Thornton79c56612017-10-25 14:47:44 -0700307 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700308 sp<IMemory> eventMemory;
309
310 size_t size = sizeof(sound_trigger_service_state_t);
311 eventMemory = mMemoryDealer->allocate(size);
312 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
313 eventMemory.clear();
314 return eventMemory;
315 }
316 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
317 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700318}
319
Chris Thornton07405ee2017-11-14 20:45:27 -0800320void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700321 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700322{
Chris Thornton07405ee2017-11-14 20:45:27 -0800323 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700324 if (eventMemory == 0) {
325 return;
326 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700327 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
328 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800329 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700330 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700331}
332
Chris Thornton07405ee2017-11-14 20:45:27 -0800333void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
334 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700335{
Chris Thornton07405ee2017-11-14 20:45:27 -0800336 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700337 if (eventMemory == 0) {
338 return;
339 }
340 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
341 eventMemory);
342 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700343 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700344}
345
Chris Thornton79c56612017-10-25 14:47:44 -0700346void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700347{
348 mCallbackThread->sendCallbackEvent(event);
349}
350
351void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
352{
353 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700354 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700355 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700356 {
357 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700358 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700359 module = event->mModule.promote();
360 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700361 moduleClient = event->mModuleClient.promote();
362 if (moduleClient == 0) {
363 return;
364 }
Chris Thornton79c56612017-10-25 14:47:44 -0700365 } else {
366 // Sanity check on this being a Module we know about.
367 bool foundModule = false;
368 for (size_t i = 0; i < mModules.size(); i++) {
369 if (mModules.valueAt(i).get() == module.get()) {
370 foundModule = true;
371 break;
372 }
373 }
374 if (!foundModule) {
375 ALOGE("onCallbackEvent for unknown module");
376 return;
377 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700378 }
379 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700380 if (module != 0) {
381 ALOGV("onCallbackEvent for module");
382 module->onCallbackEvent(event);
383 } else if (moduleClient != 0) {
384 ALOGV("onCallbackEvent for moduleClient");
385 moduleClient->onCallbackEvent(event);
386 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700387 {
388 AutoMutex lock(mServiceLock);
389 // clear now to execute with mServiceLock locked
390 event->mMemory.clear();
391 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700392}
393
394#undef LOG_TAG
395#define LOG_TAG "SoundTriggerHwService::CallbackThread"
396
397SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
398 : mService(service)
399{
400}
401
402SoundTriggerHwService::CallbackThread::~CallbackThread()
403{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700404 while (!mEventQueue.isEmpty()) {
405 mEventQueue[0]->mMemory.clear();
406 mEventQueue.removeAt(0);
407 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700408}
409
410void SoundTriggerHwService::CallbackThread::onFirstRef()
411{
412 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
413}
414
415bool SoundTriggerHwService::CallbackThread::threadLoop()
416{
417 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700418 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700419 sp<SoundTriggerHwService> service;
420 {
421 Mutex::Autolock _l(mCallbackLock);
422 while (mEventQueue.isEmpty() && !exitPending()) {
423 ALOGV("CallbackThread::threadLoop() sleep");
424 mCallbackCond.wait(mCallbackLock);
425 ALOGV("CallbackThread::threadLoop() wake up");
426 }
427 if (exitPending()) {
428 break;
429 }
430 event = mEventQueue[0];
431 mEventQueue.removeAt(0);
432 service = mService.promote();
433 }
434 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700435 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700436 }
437 }
438 return false;
439}
440
441void SoundTriggerHwService::CallbackThread::exit()
442{
443 Mutex::Autolock _l(mCallbackLock);
444 requestExit();
445 mCallbackCond.broadcast();
446}
447
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700448void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
449 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700450{
451 AutoMutex lock(mCallbackLock);
452 mEventQueue.add(event);
453 mCallbackCond.signal();
454}
455
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700456SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
457 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700458{
459}
460
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700461SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700462{
463}
464
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700465
Eric Laurentb7a11d82014-04-18 17:40:41 -0700466#undef LOG_TAG
467#define LOG_TAG "SoundTriggerHwService::Module"
468
469SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700470 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700471 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700472 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700473 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700474{
475}
476
477SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700478 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700479}
480
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700481sp<SoundTriggerHwService::ModuleClient>
482SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client)
483{
484 AutoMutex lock(mLock);
485 sp<ModuleClient> moduleClient;
486
487 for (size_t i = 0; i < mModuleClients.size(); i++) {
488 if (mModuleClients[i]->client() == client) {
489 // Client already present, reuse client
490 return moduleClient;
491 }
492 }
493 moduleClient = new ModuleClient(this, client);
494
495 ALOGV("addClient() client %p", moduleClient.get());
496 mModuleClients.add(moduleClient);
497
498 return moduleClient;
499}
500
501void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
502{
503 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700504 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700505
Eric Laurent338e8ba2017-10-05 10:58:38 -0700506 {
507 AutoMutex lock(mLock);
508 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700509
Eric Laurent338e8ba2017-10-05 10:58:38 -0700510 for (size_t i = 0; i < mModuleClients.size(); i++) {
511 if (mModuleClients[i] == moduleClient) {
512 index = i;
513 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700514 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700515 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700516 if (index == -1) {
517 return;
518 }
519
520 ALOGV("remove client %p", moduleClient.get());
521 mModuleClients.removeAt(index);
522
523 // Iterate in reverse order as models are removed from list inside the loop.
524 for (size_t i = mModels.size(); i > 0; i--) {
525 sp<Model> model = mModels.valueAt(i - 1);
526 if (moduleClient == model->mModuleClient) {
527 mModels.removeItemsAt(i - 1);
528 ALOGV("detach() unloading model %d", model->mHandle);
529 if (mHalInterface != 0) {
530 if (model->mState == Model::STATE_ACTIVE) {
531 mHalInterface->stopRecognition(model->mHandle);
532 }
533 mHalInterface->unloadSoundModel(model->mHandle);
534 }
535 releasedSessions.add(model->mCaptureSession);
536 }
537 }
538 }
539
540 for (size_t i = 0; i < releasedSessions.size(); i++) {
541 // do not call AudioSystem methods with mLock held
542 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700543 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700544}
545
546status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700547 sp<ModuleClient> moduleClient,
548 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700549{
550 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700551 if (mHalInterface == 0) {
552 return NO_INIT;
553 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700554
Eric Laurentb7a11d82014-04-18 17:40:41 -0700555 struct sound_trigger_sound_model *sound_model =
556 (struct sound_trigger_sound_model *)modelMemory->pointer();
557
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700558 size_t structSize;
559 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
560 structSize = sizeof(struct sound_trigger_phrase_sound_model);
561 } else {
562 structSize = sizeof(struct sound_trigger_sound_model);
563 }
564
565 if (sound_model->data_offset < structSize ||
566 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
567 modelMemory->size() < sound_model->data_offset ||
568 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
569 android_errorWriteLog(0x534e4554, "30148546");
570 ALOGE("loadSoundModel() data_size is too big");
571 return BAD_VALUE;
572 }
573
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700574 audio_session_t session;
575 audio_io_handle_t ioHandle;
576 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700577 // do not call AudioSystem methods with mLock held
578 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700579 if (status != NO_ERROR) {
580 return status;
581 }
582
Eric Laurent338e8ba2017-10-05 10:58:38 -0700583 {
584 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700585
Eric Laurent338e8ba2017-10-05 10:58:38 -0700586 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
587 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
588 mDescriptor.properties.max_sound_models);
589 status = INVALID_OPERATION;
590 goto exit;
591 }
592
593 status = mHalInterface->loadSoundModel(sound_model,
594 SoundTriggerHwService::soundModelCallback,
595 this, handle);
596 if (status != NO_ERROR) {
597 goto exit;
598 }
599
600 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
601 moduleClient);
602 mModels.replaceValueFor(*handle, model);
603 }
604exit:
605 if (status != NO_ERROR) {
606 // do not call AudioSystem methods with mLock held
607 AudioSystem::releaseSoundTriggerSession(session);
608 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700609 return status;
610}
611
612status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
613{
614 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700615 status_t status;
616 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800617
Eric Laurent338e8ba2017-10-05 10:58:38 -0700618 {
619 AutoMutex lock(mLock);
620 if (mHalInterface == 0) {
621 return NO_INIT;
622 }
623 ssize_t index = mModels.indexOfKey(handle);
624 if (index < 0) {
625 return BAD_VALUE;
626 }
627 sp<Model> model = mModels.valueAt(index);
628 mModels.removeItem(handle);
629 if (model->mState == Model::STATE_ACTIVE) {
630 mHalInterface->stopRecognition(model->mHandle);
631 model->mState = Model::STATE_IDLE;
632 }
633 status = mHalInterface->unloadSoundModel(handle);
634 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700635 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700636 // do not call AudioSystem methods with mLock held
637 AudioSystem::releaseSoundTriggerSession(session);
638 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700639}
640
641status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700642 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700643{
644 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700645 if (mHalInterface == 0) {
646 return NO_INIT;
647 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700648
649 struct sound_trigger_recognition_config *config =
650 (struct sound_trigger_recognition_config *)dataMemory->pointer();
651
652 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
653 config->data_size > (UINT_MAX - config->data_offset) ||
654 dataMemory->size() < config->data_offset ||
655 config->data_size > (dataMemory->size() - config->data_offset)) {
656 ALOGE("startRecognition() data_size is too big");
657 return BAD_VALUE;
658 }
659
Eric Laurentb7a11d82014-04-18 17:40:41 -0700660 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700661 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
662 return INVALID_OPERATION;
663 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700664 sp<Model> model = getModel(handle);
665 if (model == 0) {
666 return BAD_VALUE;
667 }
668
669 if (model->mState == Model::STATE_ACTIVE) {
670 return INVALID_OPERATION;
671 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700672
Eric Laurentb7a11d82014-04-18 17:40:41 -0700673
674 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700675 config->capture_handle = model->mCaptureIOHandle;
676 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700677 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700678 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700679 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700680
681 if (status == NO_ERROR) {
682 model->mState = Model::STATE_ACTIVE;
683 model->mConfig = *config;
684 }
685
686 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700687}
688
689status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
690{
691 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700692 if (mHalInterface == 0) {
693 return NO_INIT;
694 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700695 AutoMutex lock(mLock);
696 sp<Model> model = getModel(handle);
697 if (model == 0) {
698 return BAD_VALUE;
699 }
700
701 if (model->mState != Model::STATE_ACTIVE) {
702 return INVALID_OPERATION;
703 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700704 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700705 model->mState = Model::STATE_IDLE;
706 return NO_ERROR;
707}
708
mike dooley6e189b12018-11-07 15:44:37 +0100709status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000710{
711 ALOGV("getModelState() model handle %d", handle);
712 if (mHalInterface == 0) {
713 return NO_INIT;
714 }
715 AutoMutex lock(mLock);
716 sp<Model> model = getModel(handle);
717 if (model == 0) {
718 return BAD_VALUE;
719 }
720
721 if (model->mState != Model::STATE_ACTIVE) {
722 return INVALID_OPERATION;
723 }
724
mike dooley6e189b12018-11-07 15:44:37 +0100725 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000726}
727
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700728void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700729{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700730 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700731
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700732 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700733
734 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
735 return;
736 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700737 if (mModuleClients.isEmpty()) {
738 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700739 return;
740 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700741
Chris Thornton02b74212017-11-06 14:45:30 -0800742 Vector< sp<ModuleClient> > clients;
743
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700744 switch (event->mType) {
745 case CallbackEvent::TYPE_RECOGNITION: {
746 struct sound_trigger_recognition_event *recognitionEvent =
747 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700748 {
749 AutoMutex lock(mLock);
750 sp<Model> model = getModel(recognitionEvent->model);
751 if (model == 0) {
752 ALOGW("%s model == 0", __func__);
753 return;
754 }
755 if (model->mState != Model::STATE_ACTIVE) {
756 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
757 return;
758 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700759
Eric Laurent886561f2014-08-28 19:45:37 -0700760 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100761 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800762 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700763 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700764 } break;
765 case CallbackEvent::TYPE_SOUNDMODEL: {
766 struct sound_trigger_model_event *soundmodelEvent =
767 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700768 {
769 AutoMutex lock(mLock);
770 sp<Model> model = getModel(soundmodelEvent->model);
771 if (model == 0) {
772 ALOGW("%s model == 0", __func__);
773 return;
774 }
Chris Thornton02b74212017-11-06 14:45:30 -0800775 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700776 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700777 } break;
778 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700779 {
780 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700781 for (size_t i = 0; i < mModuleClients.size(); i++) {
782 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800783 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700784 }
785 }
Eric Laurent886561f2014-08-28 19:45:37 -0700786 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700787 } break;
788 default:
789 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
790 }
Chris Thornton02b74212017-11-06 14:45:30 -0800791
792 for (size_t i = 0; i < clients.size(); i++) {
793 clients[i]->onCallbackEvent(event);
794 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700795}
796
797sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
798 sound_model_handle_t handle)
799{
800 sp<Model> model;
801 ssize_t index = mModels.indexOfKey(handle);
802 if (index >= 0) {
803 model = mModels.valueAt(index);
804 }
805 return model;
806}
807
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700808// Called with mServiceLock held
809void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700810{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700811 ALOGV("Module::setCaptureState_l %d", active);
812 sp<SoundTriggerHwService> service;
813 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700814
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700815 Vector< sp<IMemory> > events;
816 {
817 AutoMutex lock(mLock);
818 state = (active && !mDescriptor.properties.concurrent_capture) ?
819 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700820
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700821 if (state == mServiceState) {
822 return;
823 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700824
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700825 mServiceState = state;
826
827 service = mService.promote();
828 if (service == 0) {
829 return;
830 }
831
832 if (state == SOUND_TRIGGER_STATE_ENABLED) {
833 goto exit;
834 }
835
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700836 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700837 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700838
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700839 for (size_t i = 0; i < mModels.size(); i++) {
840 sp<Model> model = mModels.valueAt(i);
841 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700842 if (mHalInterface != 0 && !supports_stop_all) {
843 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700844 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700845 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800846 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
847 struct sound_trigger_phrase_recognition_event event;
848 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
849 event.num_phrases = model->mConfig.num_phrases;
850 for (size_t i = 0; i < event.num_phrases; i++) {
851 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700852 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800853 event.common.status = RECOGNITION_STATUS_ABORT;
854 event.common.type = model->mType;
855 event.common.model = model->mHandle;
856 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700857 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800858 if (eventMemory != 0) {
859 events.add(eventMemory);
860 }
861 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
862 struct sound_trigger_generic_recognition_event event;
863 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
864 event.common.status = RECOGNITION_STATUS_ABORT;
865 event.common.type = model->mType;
866 event.common.model = model->mHandle;
867 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700868 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800869 if (eventMemory != 0) {
870 events.add(eventMemory);
871 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800872 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
873 struct sound_trigger_phrase_recognition_event event;
874 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
875 event.common.status = RECOGNITION_STATUS_ABORT;
876 event.common.type = model->mType;
877 event.common.model = model->mHandle;
878 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700879 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800880 if (eventMemory != 0) {
881 events.add(eventMemory);
882 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800883 } else {
884 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700885 }
886 }
887 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700888 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700889
890 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700891 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
892 events[i]);
893 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700894 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700895 }
896
897exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800898 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700899}
900
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700901
902SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
903 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700904 sound_trigger_sound_model_type_t type,
905 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700906 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700907 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
908 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700909{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700910}
911
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700912#undef LOG_TAG
913#define LOG_TAG "SoundTriggerHwService::ModuleClient"
914
915SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
916 const sp<ISoundTriggerClient>& client)
917 : mModule(module), mClient(client)
918{
919}
920
921void SoundTriggerHwService::ModuleClient::onFirstRef()
922{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800923 sp<IBinder> binder = IInterface::asBinder(mClient);
924 if (binder != 0) {
925 binder->linkToDeath(this);
926 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700927}
928
929SoundTriggerHwService::ModuleClient::~ModuleClient()
930{
931}
932
933status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
934 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700935 String8 result;
936 return NO_ERROR;
937}
938
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700939void SoundTriggerHwService::ModuleClient::detach() {
940 ALOGV("detach()");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700941 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
942 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700943 return;
944 }
945
946 {
947 AutoMutex lock(mLock);
948 if (mClient != 0) {
949 IInterface::asBinder(mClient)->unlinkToDeath(this);
950 mClient.clear();
951 }
952 }
953
954 sp<Module> module = mModule.promote();
955 if (module == 0) {
956 return;
957 }
958 module->detach(this);
959}
960
961status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
962 sound_model_handle_t *handle)
963{
964 ALOGV("loadSoundModel() handle");
Eric Laurent7504b9e2017-08-15 18:17:26 -0700965 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
966 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700967 return PERMISSION_DENIED;
968 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700969 if (checkIMemory(modelMemory) != NO_ERROR) {
970 return BAD_VALUE;
971 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700972
973 sp<Module> module = mModule.promote();
974 if (module == 0) {
975 return NO_INIT;
976 }
977 return module->loadSoundModel(modelMemory, this, handle);
978}
979
980status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
981{
982 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700983 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
984 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700985 return PERMISSION_DENIED;
986 }
987
988 sp<Module> module = mModule.promote();
989 if (module == 0) {
990 return NO_INIT;
991 }
992 return module->unloadSoundModel(handle);
993}
994
995status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
996 const sp<IMemory>& dataMemory)
997{
998 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -0700999 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1000 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001001 return PERMISSION_DENIED;
1002 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001003 if (checkIMemory(dataMemory) != NO_ERROR) {
1004 return BAD_VALUE;
1005 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001006
1007 sp<Module> module = mModule.promote();
1008 if (module == 0) {
1009 return NO_INIT;
1010 }
1011 return module->startRecognition(handle, dataMemory);
1012}
1013
1014status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1015{
1016 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7504b9e2017-08-15 18:17:26 -07001017 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1018 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001019 return PERMISSION_DENIED;
1020 }
1021
1022 sp<Module> module = mModule.promote();
1023 if (module == 0) {
1024 return NO_INIT;
1025 }
1026 return module->stopRecognition(handle);
1027}
1028
mike dooley6e189b12018-11-07 15:44:37 +01001029status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001030{
1031 ALOGV("getModelState() model handle %d", handle);
1032 if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
1033 IPCThreadState::self()->getCallingUid())) {
1034 return PERMISSION_DENIED;
1035 }
1036
1037 sp<Module> module = mModule.promote();
1038 if (module == 0) {
1039 return NO_INIT;
1040 }
mike dooley6e189b12018-11-07 15:44:37 +01001041 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001042}
1043
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001044void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1045{
1046 ALOGV("ModuleClient::setCaptureState_l %d", active);
1047 sp<SoundTriggerHwService> service;
1048 sound_trigger_service_state_t state;
1049
1050 sp<Module> module = mModule.promote();
1051 if (module == 0) {
1052 return;
1053 }
1054 {
1055 AutoMutex lock(mLock);
1056 state = (active && !module->isConcurrentCaptureAllowed()) ?
1057 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1058
1059 service = module->service().promote();
1060 if (service == 0) {
1061 return;
1062 }
1063 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001064 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001065}
1066
1067void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1068{
1069 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1070
1071 sp<IMemory> eventMemory = event->mMemory;
1072
1073 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1074 return;
1075 }
1076
Chris Thornton02b74212017-11-06 14:45:30 -08001077 sp<ISoundTriggerClient> client;
1078 {
1079 AutoMutex lock(mLock);
1080 client = mClient;
1081 }
1082
1083 if (client != 0) {
1084 switch (event->mType) {
1085 case CallbackEvent::TYPE_RECOGNITION: {
1086 client->onRecognitionEvent(eventMemory);
1087 } break;
1088 case CallbackEvent::TYPE_SOUNDMODEL: {
1089 client->onSoundModelEvent(eventMemory);
1090 } break;
1091 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001092 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001093 } break;
1094 default:
1095 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001096 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001097 }
1098}
1099
1100void SoundTriggerHwService::ModuleClient::binderDied(
1101 const wp<IBinder> &who __unused) {
1102 ALOGW("client binder died for client %p", this);
1103 detach();
1104}
1105
Eric Laurentb7a11d82014-04-18 17:40:41 -07001106}; // namespace android