blob: ccbeb772503b86520429ca20d4383df5854f043d [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
Ytai Ben-Tsviea51ad62019-09-18 15:24:09 -070043namespace {
44
45// Given an IMemory, returns a copy of its content along with its size.
46// Returns nullptr on failure or if input is nullptr.
47std::pair<std::unique_ptr<uint8_t[]>,
48 size_t> CopyToArray(const sp<IMemory>& mem) {
49 if (mem == nullptr) {
50 return std::make_pair(nullptr, 0);
51 }
52
53 const size_t size = mem->size();
54 if (size == 0) {
55 return std::make_pair(nullptr, 0);
56 }
57
58 std::unique_ptr<uint8_t[]> ar = std::make_unique<uint8_t[]>(size);
59 if (ar == nullptr) {
60 return std::make_pair(nullptr, 0);
61 }
62
63 memcpy(ar.get(), mem->unsecurePointer(), size);
64 return std::make_pair(std::move(ar), size);
65}
66
67}
68
Eric Laurentb7a11d82014-04-18 17:40:41 -070069SoundTriggerHwService::SoundTriggerHwService()
70 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070071 mNextUniqueId(1),
72 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
73 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070074{
75}
76
77void SoundTriggerHwService::onFirstRef()
78{
Eric Laurentb7a11d82014-04-18 17:40:41 -070079 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070080
Eric Laurent7a544b42016-08-05 19:01:13 -070081 sp<SoundTriggerHalInterface> halInterface =
82 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070083
Eric Laurent7a544b42016-08-05 19:01:13 -070084 if (halInterface == 0) {
85 ALOGW("could not connect to HAL");
86 return;
87 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070088 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070089 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070090 if (rc != 0) {
91 ALOGE("could not read implementation properties");
92 return;
93 }
94 descriptor.handle =
95 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
96 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
97 descriptor.handle);
98
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070099 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700100 mModules.add(descriptor.handle, module);
101 mCallbackThread = new CallbackThread(this);
102}
103
104SoundTriggerHwService::~SoundTriggerHwService()
105{
106 if (mCallbackThread != 0) {
107 mCallbackThread->exit();
108 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700109}
110
jiabin68e0df72019-03-18 17:55:35 -0700111status_t SoundTriggerHwService::listModules(const String16& opPackageName,
112 struct sound_trigger_module_descriptor *modules,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700113 uint32_t *numModules)
114{
115 ALOGV("listModules");
jiabin68e0df72019-03-18 17:55:35 -0700116 if (!captureHotwordAllowed(opPackageName,
117 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700118 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000119 return PERMISSION_DENIED;
120 }
121
Eric Laurentb7a11d82014-04-18 17:40:41 -0700122 AutoMutex lock(mServiceLock);
123 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
124 return BAD_VALUE;
125 }
126 size_t maxModules = *numModules;
127 *numModules = mModules.size();
128 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
129 modules[i] = mModules.valueAt(i)->descriptor();
130 }
131 return NO_ERROR;
132}
133
jiabin68e0df72019-03-18 17:55:35 -0700134status_t SoundTriggerHwService::attach(const String16& opPackageName,
135 const sound_trigger_module_handle_t handle,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700136 const sp<ISoundTriggerClient>& client,
137 sp<ISoundTrigger>& moduleInterface)
138{
139 ALOGV("attach module %d", handle);
jiabin68e0df72019-03-18 17:55:35 -0700140 if (!captureHotwordAllowed(opPackageName,
141 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700142 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000143 return PERMISSION_DENIED;
144 }
145
Eric Laurentb7a11d82014-04-18 17:40:41 -0700146 AutoMutex lock(mServiceLock);
147 moduleInterface.clear();
148 if (client == 0) {
149 return BAD_VALUE;
150 }
151 ssize_t index = mModules.indexOfKey(handle);
152 if (index < 0) {
153 return BAD_VALUE;
154 }
155 sp<Module> module = mModules.valueAt(index);
156
jiabin68e0df72019-03-18 17:55:35 -0700157 sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700158 if (moduleClient == 0) {
159 return NO_INIT;
160 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700161
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700162 moduleClient->setCaptureState_l(mCaptureState);
163 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700164
Eric Laurentb7a11d82014-04-18 17:40:41 -0700165 return NO_ERROR;
166}
167
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700168status_t SoundTriggerHwService::setCaptureState(bool active)
169{
170 ALOGV("setCaptureState %d", active);
171 AutoMutex lock(mServiceLock);
172 mCaptureState = active;
173 for (size_t i = 0; i < mModules.size(); i++) {
174 mModules.valueAt(i)->setCaptureState_l(active);
175 }
176 return NO_ERROR;
177}
178
179
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700180static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700181
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700182static bool dumpTryLock(Mutex& mutex)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700183{
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700184 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
185 return err == NO_ERROR;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700186}
187
188status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
189 String8 result;
190 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
191 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
192 write(fd, result.string(), result.size());
193 } else {
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700194 bool locked = dumpTryLock(mServiceLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700195 // failed to lock - SoundTriggerHwService is probably deadlocked
196 if (!locked) {
197 result.append("SoundTriggerHwService may be deadlocked\n");
198 write(fd, result.string(), result.size());
199 }
200
201 if (locked) mServiceLock.unlock();
202 }
203 return NO_ERROR;
204}
205
206status_t SoundTriggerHwService::onTransact(
207 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
208 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
209}
210
211
212// static
213void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
214 void *cookie)
215{
216 Module *module = (Module *)cookie;
217 if (module == NULL) {
218 return;
219 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700220 sp<SoundTriggerHwService> service = module->service().promote();
221 if (service == 0) {
222 return;
223 }
224
225 service->sendRecognitionEvent(event, module);
226}
227
Chris Thornton79c56612017-10-25 14:47:44 -0700228sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700229 struct sound_trigger_recognition_event *event)
230{
Chris Thornton79c56612017-10-25 14:47:44 -0700231 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700232 sp<IMemory> eventMemory;
233
234 //sanitize event
235 switch (event->type) {
236 case SOUND_MODEL_TYPE_KEYPHRASE:
237 ALOGW_IF(event->data_size != 0 && event->data_offset !=
238 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700239 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700240 event->data_offset);
241 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
242 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800243 case SOUND_MODEL_TYPE_GENERIC:
244 ALOGW_IF(event->data_size != 0 && event->data_offset !=
245 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700246 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800247 event->data_offset);
248 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
249 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700250 case SOUND_MODEL_TYPE_UNKNOWN:
251 ALOGW_IF(event->data_size != 0 && event->data_offset !=
252 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700253 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700254 event->data_offset);
255 event->data_offset = sizeof(struct sound_trigger_recognition_event);
256 break;
257 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700258 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700259 }
260
261 size_t size = event->data_offset + event->data_size;
262 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700263 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700264 eventMemory.clear();
265 return eventMemory;
266 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700267 memcpy(eventMemory->unsecurePointer(), event, size);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700268
269 return eventMemory;
270}
271
272void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
273 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700274{
275 if (module == NULL) {
276 return;
277 }
278 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
279 if (eventMemory == 0) {
280 return;
281 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700282
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700283 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
284 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700285 callbackEvent->setModule(module);
286 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700287}
288
289// static
290void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
291 void *cookie)
292{
293 Module *module = (Module *)cookie;
294 if (module == NULL) {
295 return;
296 }
297 sp<SoundTriggerHwService> service = module->service().promote();
298 if (service == 0) {
299 return;
300 }
301
302 service->sendSoundModelEvent(event, module);
303}
304
Chris Thornton79c56612017-10-25 14:47:44 -0700305sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -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 = event->data_offset + event->data_size;
311 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700312 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700313 eventMemory.clear();
314 return eventMemory;
315 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700316 memcpy(eventMemory->unsecurePointer(), event, size);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700317
318 return eventMemory;
319}
320
321void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
322 Module *module)
323{
Chris Thornton79c56612017-10-25 14:47:44 -0700324 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700325 if (eventMemory == 0) {
326 return;
327 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700328 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
329 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700330 callbackEvent->setModule(module);
331 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700332}
333
334
Chris Thornton07405ee2017-11-14 20:45:27 -0800335sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700336{
Chris Thornton79c56612017-10-25 14:47:44 -0700337 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700338 sp<IMemory> eventMemory;
339
340 size_t size = sizeof(sound_trigger_service_state_t);
341 eventMemory = mMemoryDealer->allocate(size);
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700342 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700343 eventMemory.clear();
344 return eventMemory;
345 }
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700346 *((sound_trigger_service_state_t *)eventMemory->unsecurePointer()) = state;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700347 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700348}
349
Chris Thornton07405ee2017-11-14 20:45:27 -0800350void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700351 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700352{
Chris Thornton07405ee2017-11-14 20:45:27 -0800353 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700354 if (eventMemory == 0) {
355 return;
356 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700357 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
358 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800359 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700360 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700361}
362
Chris Thornton07405ee2017-11-14 20:45:27 -0800363void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
364 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700365{
Chris Thornton07405ee2017-11-14 20:45:27 -0800366 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700367 if (eventMemory == 0) {
368 return;
369 }
370 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
371 eventMemory);
372 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700373 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700374}
375
Chris Thornton79c56612017-10-25 14:47:44 -0700376void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700377{
378 mCallbackThread->sendCallbackEvent(event);
379}
380
381void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
382{
383 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700384 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700385 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700386 {
387 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700388 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700389 module = event->mModule.promote();
390 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700391 moduleClient = event->mModuleClient.promote();
392 if (moduleClient == 0) {
393 return;
394 }
Chris Thornton79c56612017-10-25 14:47:44 -0700395 } else {
396 // Sanity check on this being a Module we know about.
397 bool foundModule = false;
398 for (size_t i = 0; i < mModules.size(); i++) {
399 if (mModules.valueAt(i).get() == module.get()) {
400 foundModule = true;
401 break;
402 }
403 }
404 if (!foundModule) {
405 ALOGE("onCallbackEvent for unknown module");
406 return;
407 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700408 }
409 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700410 if (module != 0) {
411 ALOGV("onCallbackEvent for module");
412 module->onCallbackEvent(event);
413 } else if (moduleClient != 0) {
414 ALOGV("onCallbackEvent for moduleClient");
415 moduleClient->onCallbackEvent(event);
416 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700417 {
418 AutoMutex lock(mServiceLock);
419 // clear now to execute with mServiceLock locked
420 event->mMemory.clear();
421 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700422}
423
424#undef LOG_TAG
425#define LOG_TAG "SoundTriggerHwService::CallbackThread"
426
427SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
428 : mService(service)
429{
430}
431
432SoundTriggerHwService::CallbackThread::~CallbackThread()
433{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700434 while (!mEventQueue.isEmpty()) {
435 mEventQueue[0]->mMemory.clear();
436 mEventQueue.removeAt(0);
437 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700438}
439
440void SoundTriggerHwService::CallbackThread::onFirstRef()
441{
442 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
443}
444
445bool SoundTriggerHwService::CallbackThread::threadLoop()
446{
447 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700448 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700449 sp<SoundTriggerHwService> service;
450 {
451 Mutex::Autolock _l(mCallbackLock);
452 while (mEventQueue.isEmpty() && !exitPending()) {
453 ALOGV("CallbackThread::threadLoop() sleep");
454 mCallbackCond.wait(mCallbackLock);
455 ALOGV("CallbackThread::threadLoop() wake up");
456 }
457 if (exitPending()) {
458 break;
459 }
460 event = mEventQueue[0];
461 mEventQueue.removeAt(0);
462 service = mService.promote();
463 }
464 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700465 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700466 }
467 }
468 return false;
469}
470
471void SoundTriggerHwService::CallbackThread::exit()
472{
473 Mutex::Autolock _l(mCallbackLock);
474 requestExit();
475 mCallbackCond.broadcast();
476}
477
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700478void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
479 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700480{
481 AutoMutex lock(mCallbackLock);
482 mEventQueue.add(event);
483 mCallbackCond.signal();
484}
485
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700486SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
487 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700488{
489}
490
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700491SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700492{
493}
494
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700495
Eric Laurentb7a11d82014-04-18 17:40:41 -0700496#undef LOG_TAG
497#define LOG_TAG "SoundTriggerHwService::Module"
498
499SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700500 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700501 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700502 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700503 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700504{
505}
506
507SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700508 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700509}
510
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700511sp<SoundTriggerHwService::ModuleClient>
jiabin68e0df72019-03-18 17:55:35 -0700512SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
513 const String16& opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700514{
515 AutoMutex lock(mLock);
516 sp<ModuleClient> moduleClient;
517
518 for (size_t i = 0; i < mModuleClients.size(); i++) {
519 if (mModuleClients[i]->client() == client) {
520 // Client already present, reuse client
521 return moduleClient;
522 }
523 }
jiabin68e0df72019-03-18 17:55:35 -0700524 moduleClient = new ModuleClient(this, client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700525
526 ALOGV("addClient() client %p", moduleClient.get());
527 mModuleClients.add(moduleClient);
528
529 return moduleClient;
530}
531
532void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
533{
534 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700535 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700536
Eric Laurent338e8ba2017-10-05 10:58:38 -0700537 {
538 AutoMutex lock(mLock);
539 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700540
Eric Laurent338e8ba2017-10-05 10:58:38 -0700541 for (size_t i = 0; i < mModuleClients.size(); i++) {
542 if (mModuleClients[i] == moduleClient) {
543 index = i;
544 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700545 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700546 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700547 if (index == -1) {
548 return;
549 }
550
551 ALOGV("remove client %p", moduleClient.get());
552 mModuleClients.removeAt(index);
553
554 // Iterate in reverse order as models are removed from list inside the loop.
555 for (size_t i = mModels.size(); i > 0; i--) {
556 sp<Model> model = mModels.valueAt(i - 1);
557 if (moduleClient == model->mModuleClient) {
558 mModels.removeItemsAt(i - 1);
559 ALOGV("detach() unloading model %d", model->mHandle);
560 if (mHalInterface != 0) {
561 if (model->mState == Model::STATE_ACTIVE) {
562 mHalInterface->stopRecognition(model->mHandle);
563 }
564 mHalInterface->unloadSoundModel(model->mHandle);
565 }
566 releasedSessions.add(model->mCaptureSession);
567 }
568 }
569 }
570
571 for (size_t i = 0; i < releasedSessions.size(); i++) {
572 // do not call AudioSystem methods with mLock held
573 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700574 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700575}
576
577status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700578 sp<ModuleClient> moduleClient,
579 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700580{
581 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700582 if (mHalInterface == 0) {
583 return NO_INIT;
584 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700585
Ytai Ben-Tsviea51ad62019-09-18 15:24:09 -0700586 auto immutableMemory = CopyToArray(modelMemory);
587 if (immutableMemory.first == nullptr) {
588 return NO_MEMORY;
589 }
590
591 struct sound_trigger_sound_model* sound_model =
592 (struct sound_trigger_sound_model*) immutableMemory.first.get();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700593
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700594 size_t structSize;
595 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
596 structSize = sizeof(struct sound_trigger_phrase_sound_model);
597 } else {
598 structSize = sizeof(struct sound_trigger_sound_model);
599 }
600
601 if (sound_model->data_offset < structSize ||
Ytai Ben-Tsviea51ad62019-09-18 15:24:09 -0700602 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
603 immutableMemory.second < sound_model->data_offset ||
604 sound_model->data_size >
605 (immutableMemory.second - sound_model->data_offset)) {
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700606 android_errorWriteLog(0x534e4554, "30148546");
607 ALOGE("loadSoundModel() data_size is too big");
608 return BAD_VALUE;
609 }
610
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700611 audio_session_t session;
612 audio_io_handle_t ioHandle;
613 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700614 // do not call AudioSystem methods with mLock held
615 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700616 if (status != NO_ERROR) {
617 return status;
618 }
619
Eric Laurent338e8ba2017-10-05 10:58:38 -0700620 {
621 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700622
Eric Laurent338e8ba2017-10-05 10:58:38 -0700623 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
624 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
625 mDescriptor.properties.max_sound_models);
626 status = INVALID_OPERATION;
627 goto exit;
628 }
629
630 status = mHalInterface->loadSoundModel(sound_model,
631 SoundTriggerHwService::soundModelCallback,
632 this, handle);
633 if (status != NO_ERROR) {
634 goto exit;
635 }
636
637 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
638 moduleClient);
639 mModels.replaceValueFor(*handle, model);
640 }
641exit:
642 if (status != NO_ERROR) {
643 // do not call AudioSystem methods with mLock held
644 AudioSystem::releaseSoundTriggerSession(session);
645 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700646 return status;
647}
648
649status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
650{
651 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700652 status_t status;
653 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800654
Eric Laurent338e8ba2017-10-05 10:58:38 -0700655 {
656 AutoMutex lock(mLock);
657 if (mHalInterface == 0) {
658 return NO_INIT;
659 }
660 ssize_t index = mModels.indexOfKey(handle);
661 if (index < 0) {
662 return BAD_VALUE;
663 }
664 sp<Model> model = mModels.valueAt(index);
665 mModels.removeItem(handle);
666 if (model->mState == Model::STATE_ACTIVE) {
667 mHalInterface->stopRecognition(model->mHandle);
668 model->mState = Model::STATE_IDLE;
669 }
670 status = mHalInterface->unloadSoundModel(handle);
671 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700672 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700673 // do not call AudioSystem methods with mLock held
674 AudioSystem::releaseSoundTriggerSession(session);
675 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700676}
677
678status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700679 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700680{
681 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700682 if (mHalInterface == 0) {
683 return NO_INIT;
684 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700685
Ytai Ben-Tsviea51ad62019-09-18 15:24:09 -0700686 auto immutableMemory = CopyToArray(dataMemory);
687 if (immutableMemory.first == nullptr) {
688 return NO_MEMORY;
689 }
690
691 struct sound_trigger_recognition_config* config =
692 (struct sound_trigger_recognition_config*) immutableMemory.first.get();
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700693
694 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
Ytai Ben-Tsviea51ad62019-09-18 15:24:09 -0700695 config->data_size > (UINT_MAX - config->data_offset) ||
696 immutableMemory.second < config->data_offset ||
697 config->data_size >
698 (immutableMemory.second - config->data_offset)) {
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700699 ALOGE("startRecognition() data_size is too big");
700 return BAD_VALUE;
701 }
702
Eric Laurentb7a11d82014-04-18 17:40:41 -0700703 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700704 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
705 return INVALID_OPERATION;
706 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700707 sp<Model> model = getModel(handle);
708 if (model == 0) {
709 return BAD_VALUE;
710 }
711
712 if (model->mState == Model::STATE_ACTIVE) {
713 return INVALID_OPERATION;
714 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700715
Eric Laurentb7a11d82014-04-18 17:40:41 -0700716
717 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700718 config->capture_handle = model->mCaptureIOHandle;
719 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700720 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700721 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700722 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700723
724 if (status == NO_ERROR) {
725 model->mState = Model::STATE_ACTIVE;
726 model->mConfig = *config;
727 }
728
729 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700730}
731
732status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
733{
734 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700735 if (mHalInterface == 0) {
736 return NO_INIT;
737 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700738 AutoMutex lock(mLock);
739 sp<Model> model = getModel(handle);
740 if (model == 0) {
741 return BAD_VALUE;
742 }
743
744 if (model->mState != Model::STATE_ACTIVE) {
745 return INVALID_OPERATION;
746 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700747 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700748 model->mState = Model::STATE_IDLE;
749 return NO_ERROR;
750}
751
mike dooley6e189b12018-11-07 15:44:37 +0100752status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000753{
754 ALOGV("getModelState() model handle %d", handle);
755 if (mHalInterface == 0) {
756 return NO_INIT;
757 }
758 AutoMutex lock(mLock);
759 sp<Model> model = getModel(handle);
760 if (model == 0) {
761 return BAD_VALUE;
762 }
763
764 if (model->mState != Model::STATE_ACTIVE) {
765 return INVALID_OPERATION;
766 }
767
mike dooley6e189b12018-11-07 15:44:37 +0100768 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000769}
770
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700771void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700772{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700773 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700774
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700775 // Memory is coming from a trusted process.
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700776 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700777
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700778 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700779 return;
780 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700781 if (mModuleClients.isEmpty()) {
782 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700783 return;
784 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700785
Chris Thornton02b74212017-11-06 14:45:30 -0800786 Vector< sp<ModuleClient> > clients;
787
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700788 switch (event->mType) {
789 case CallbackEvent::TYPE_RECOGNITION: {
790 struct sound_trigger_recognition_event *recognitionEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700791 (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700792 {
793 AutoMutex lock(mLock);
794 sp<Model> model = getModel(recognitionEvent->model);
795 if (model == 0) {
796 ALOGW("%s model == 0", __func__);
797 return;
798 }
799 if (model->mState != Model::STATE_ACTIVE) {
800 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
801 return;
802 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700803
Eric Laurent886561f2014-08-28 19:45:37 -0700804 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100805 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800806 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700807 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700808 } break;
809 case CallbackEvent::TYPE_SOUNDMODEL: {
810 struct sound_trigger_model_event *soundmodelEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700811 (struct sound_trigger_model_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700812 {
813 AutoMutex lock(mLock);
814 sp<Model> model = getModel(soundmodelEvent->model);
815 if (model == 0) {
816 ALOGW("%s model == 0", __func__);
817 return;
818 }
Chris Thornton02b74212017-11-06 14:45:30 -0800819 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700820 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700821 } break;
822 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700823 {
824 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700825 for (size_t i = 0; i < mModuleClients.size(); i++) {
826 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800827 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700828 }
829 }
Eric Laurent886561f2014-08-28 19:45:37 -0700830 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700831 } break;
832 default:
833 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
834 }
Chris Thornton02b74212017-11-06 14:45:30 -0800835
836 for (size_t i = 0; i < clients.size(); i++) {
837 clients[i]->onCallbackEvent(event);
838 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700839}
840
841sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
842 sound_model_handle_t handle)
843{
844 sp<Model> model;
845 ssize_t index = mModels.indexOfKey(handle);
846 if (index >= 0) {
847 model = mModels.valueAt(index);
848 }
849 return model;
850}
851
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700852// Called with mServiceLock held
853void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700854{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700855 ALOGV("Module::setCaptureState_l %d", active);
856 sp<SoundTriggerHwService> service;
857 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700858
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700859 Vector< sp<IMemory> > events;
860 {
861 AutoMutex lock(mLock);
862 state = (active && !mDescriptor.properties.concurrent_capture) ?
863 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700864
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700865 if (state == mServiceState) {
866 return;
867 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700868
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700869 mServiceState = state;
870
871 service = mService.promote();
872 if (service == 0) {
873 return;
874 }
875
876 if (state == SOUND_TRIGGER_STATE_ENABLED) {
877 goto exit;
878 }
879
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700880 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700881 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700882
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700883 for (size_t i = 0; i < mModels.size(); i++) {
884 sp<Model> model = mModels.valueAt(i);
885 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700886 if (mHalInterface != 0 && !supports_stop_all) {
887 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700888 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700889 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800890 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
891 struct sound_trigger_phrase_recognition_event event;
892 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
893 event.num_phrases = model->mConfig.num_phrases;
894 for (size_t i = 0; i < event.num_phrases; i++) {
895 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700896 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800897 event.common.status = RECOGNITION_STATUS_ABORT;
898 event.common.type = model->mType;
899 event.common.model = model->mHandle;
900 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700901 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800902 if (eventMemory != 0) {
903 events.add(eventMemory);
904 }
905 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
906 struct sound_trigger_generic_recognition_event event;
907 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
908 event.common.status = RECOGNITION_STATUS_ABORT;
909 event.common.type = model->mType;
910 event.common.model = model->mHandle;
911 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700912 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800913 if (eventMemory != 0) {
914 events.add(eventMemory);
915 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800916 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
917 struct sound_trigger_phrase_recognition_event event;
918 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
919 event.common.status = RECOGNITION_STATUS_ABORT;
920 event.common.type = model->mType;
921 event.common.model = model->mHandle;
922 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700923 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800924 if (eventMemory != 0) {
925 events.add(eventMemory);
926 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800927 } else {
928 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700929 }
930 }
931 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700932 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700933
934 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700935 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
936 events[i]);
937 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700938 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700939 }
940
941exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800942 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700943}
944
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700945
946SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
947 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700948 sound_trigger_sound_model_type_t type,
949 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700950 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700951 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
952 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700953{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700954}
955
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700956#undef LOG_TAG
957#define LOG_TAG "SoundTriggerHwService::ModuleClient"
958
959SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
jiabin68e0df72019-03-18 17:55:35 -0700960 const sp<ISoundTriggerClient>& client,
961 const String16& opPackageName)
962 : mModule(module), mClient(client), mOpPackageName(opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700963{
964}
965
966void SoundTriggerHwService::ModuleClient::onFirstRef()
967{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800968 sp<IBinder> binder = IInterface::asBinder(mClient);
969 if (binder != 0) {
970 binder->linkToDeath(this);
971 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700972}
973
974SoundTriggerHwService::ModuleClient::~ModuleClient()
975{
976}
977
978status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
979 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700980 String8 result;
981 return NO_ERROR;
982}
983
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700984void SoundTriggerHwService::ModuleClient::detach() {
985 ALOGV("detach()");
jiabin68e0df72019-03-18 17:55:35 -0700986 if (!captureHotwordAllowed(mOpPackageName,
987 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700988 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700989 return;
990 }
991
992 {
993 AutoMutex lock(mLock);
994 if (mClient != 0) {
995 IInterface::asBinder(mClient)->unlinkToDeath(this);
996 mClient.clear();
997 }
998 }
999
1000 sp<Module> module = mModule.promote();
1001 if (module == 0) {
1002 return;
1003 }
1004 module->detach(this);
1005}
1006
1007status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
1008 sound_model_handle_t *handle)
1009{
1010 ALOGV("loadSoundModel() handle");
jiabin68e0df72019-03-18 17:55:35 -07001011 if (!captureHotwordAllowed(mOpPackageName,
1012 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001013 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001014 return PERMISSION_DENIED;
1015 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001016 if (checkIMemory(modelMemory) != NO_ERROR) {
1017 return BAD_VALUE;
1018 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001019
1020 sp<Module> module = mModule.promote();
1021 if (module == 0) {
1022 return NO_INIT;
1023 }
1024 return module->loadSoundModel(modelMemory, this, handle);
1025}
1026
1027status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
1028{
1029 ALOGV("unloadSoundModel() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001030 if (!captureHotwordAllowed(mOpPackageName,
1031 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001032 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001033 return PERMISSION_DENIED;
1034 }
1035
1036 sp<Module> module = mModule.promote();
1037 if (module == 0) {
1038 return NO_INIT;
1039 }
1040 return module->unloadSoundModel(handle);
1041}
1042
1043status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1044 const sp<IMemory>& dataMemory)
1045{
1046 ALOGV("startRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001047 if (!captureHotwordAllowed(mOpPackageName,
1048 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001049 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001050 return PERMISSION_DENIED;
1051 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001052 if (checkIMemory(dataMemory) != NO_ERROR) {
1053 return BAD_VALUE;
1054 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001055
1056 sp<Module> module = mModule.promote();
1057 if (module == 0) {
1058 return NO_INIT;
1059 }
1060 return module->startRecognition(handle, dataMemory);
1061}
1062
1063status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1064{
1065 ALOGV("stopRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001066 if (!captureHotwordAllowed(mOpPackageName,
1067 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001068 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001069 return PERMISSION_DENIED;
1070 }
1071
1072 sp<Module> module = mModule.promote();
1073 if (module == 0) {
1074 return NO_INIT;
1075 }
1076 return module->stopRecognition(handle);
1077}
1078
mike dooley6e189b12018-11-07 15:44:37 +01001079status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001080{
1081 ALOGV("getModelState() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001082 if (!captureHotwordAllowed(mOpPackageName,
1083 IPCThreadState::self()->getCallingPid(),
Michael Dooley67e3d412018-10-16 19:51:16 +00001084 IPCThreadState::self()->getCallingUid())) {
1085 return PERMISSION_DENIED;
1086 }
1087
1088 sp<Module> module = mModule.promote();
1089 if (module == 0) {
1090 return NO_INIT;
1091 }
mike dooley6e189b12018-11-07 15:44:37 +01001092 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001093}
1094
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001095void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1096{
1097 ALOGV("ModuleClient::setCaptureState_l %d", active);
1098 sp<SoundTriggerHwService> service;
1099 sound_trigger_service_state_t state;
1100
1101 sp<Module> module = mModule.promote();
1102 if (module == 0) {
1103 return;
1104 }
1105 {
1106 AutoMutex lock(mLock);
1107 state = (active && !module->isConcurrentCaptureAllowed()) ?
1108 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1109
1110 service = module->service().promote();
1111 if (service == 0) {
1112 return;
1113 }
1114 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001115 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001116}
1117
1118void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1119{
1120 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1121
1122 sp<IMemory> eventMemory = event->mMemory;
1123
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -07001124 // Memory is coming from a trusted process.
1125 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001126 return;
1127 }
1128
Chris Thornton02b74212017-11-06 14:45:30 -08001129 sp<ISoundTriggerClient> client;
1130 {
1131 AutoMutex lock(mLock);
1132 client = mClient;
1133 }
1134
1135 if (client != 0) {
1136 switch (event->mType) {
1137 case CallbackEvent::TYPE_RECOGNITION: {
1138 client->onRecognitionEvent(eventMemory);
1139 } break;
1140 case CallbackEvent::TYPE_SOUNDMODEL: {
1141 client->onSoundModelEvent(eventMemory);
1142 } break;
1143 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001144 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001145 } break;
1146 default:
1147 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001148 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001149 }
1150}
1151
1152void SoundTriggerHwService::ModuleClient::binderDied(
1153 const wp<IBinder> &who __unused) {
1154 ALOGW("client binder died for client %p", this);
1155 detach();
1156}
1157
Eric Laurentb7a11d82014-04-18 17:40:41 -07001158}; // namespace android