blob: 4d8b0da0a659ab8446d0756021e04cec73ad8215 [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
Nicholas Ambur41947e22019-10-01 11:53:40 -0700771status_t SoundTriggerHwService::Module::setParameter(sound_model_handle_t handle,
772 sound_trigger_model_parameter_t param,
773 int32_t value)
774{
775 ALOGV("setParameter() handle=%d, param=%d, value=%d", handle, param, value);
776 if (mHalInterface == 0) {
777 return NO_INIT;
778 }
779
780 AutoMutex lock(mLock);
781 return mHalInterface->setParameter(handle, param, value);
782}
783
784status_t SoundTriggerHwService::Module::getParameter(sound_model_handle_t handle,
785 sound_trigger_model_parameter_t param,
786 int32_t* value)
787{
788 ALOGV("getParameter() handle=%d, param=%d", handle, param);
789 if (mHalInterface == 0) {
790 return NO_INIT;
791 }
792
793 AutoMutex lock(mLock);
794 return mHalInterface->getParameter(handle, param, value);
795}
796
797status_t SoundTriggerHwService::Module::queryParameter(sound_model_handle_t handle,
798 sound_trigger_model_parameter_t param,
799 sound_trigger_model_parameter_range_t* param_range)
800{
801 ALOGV("queryParameter() handle=%d, param=%d", handle, param);
802 if (mHalInterface == 0) {
803 return NO_INIT;
804 }
805
806 AutoMutex lock(mLock);
807 return mHalInterface->queryParameter(handle, param, param_range);
808}
809
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700810void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700811{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700812 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700813
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700814 // Memory is coming from a trusted process.
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700815 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700816
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700817 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700818 return;
819 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700820 if (mModuleClients.isEmpty()) {
821 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700822 return;
823 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700824
Chris Thornton02b74212017-11-06 14:45:30 -0800825 Vector< sp<ModuleClient> > clients;
826
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700827 switch (event->mType) {
828 case CallbackEvent::TYPE_RECOGNITION: {
829 struct sound_trigger_recognition_event *recognitionEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700830 (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700831 {
832 AutoMutex lock(mLock);
833 sp<Model> model = getModel(recognitionEvent->model);
834 if (model == 0) {
835 ALOGW("%s model == 0", __func__);
836 return;
837 }
838 if (model->mState != Model::STATE_ACTIVE) {
839 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
840 return;
841 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700842
Eric Laurent886561f2014-08-28 19:45:37 -0700843 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100844 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800845 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700846 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700847 } break;
848 case CallbackEvent::TYPE_SOUNDMODEL: {
849 struct sound_trigger_model_event *soundmodelEvent =
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -0700850 (struct sound_trigger_model_event *)eventMemory->unsecurePointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700851 {
852 AutoMutex lock(mLock);
853 sp<Model> model = getModel(soundmodelEvent->model);
854 if (model == 0) {
855 ALOGW("%s model == 0", __func__);
856 return;
857 }
Chris Thornton02b74212017-11-06 14:45:30 -0800858 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700859 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700860 } break;
861 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700862 {
863 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700864 for (size_t i = 0; i < mModuleClients.size(); i++) {
865 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800866 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700867 }
868 }
Eric Laurent886561f2014-08-28 19:45:37 -0700869 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700870 } break;
871 default:
872 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
873 }
Chris Thornton02b74212017-11-06 14:45:30 -0800874
875 for (size_t i = 0; i < clients.size(); i++) {
876 clients[i]->onCallbackEvent(event);
877 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700878}
879
880sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
881 sound_model_handle_t handle)
882{
883 sp<Model> model;
884 ssize_t index = mModels.indexOfKey(handle);
885 if (index >= 0) {
886 model = mModels.valueAt(index);
887 }
888 return model;
889}
890
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700891// Called with mServiceLock held
892void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700893{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700894 ALOGV("Module::setCaptureState_l %d", active);
895 sp<SoundTriggerHwService> service;
896 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700897
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700898 Vector< sp<IMemory> > events;
899 {
900 AutoMutex lock(mLock);
901 state = (active && !mDescriptor.properties.concurrent_capture) ?
902 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700903
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700904 if (state == mServiceState) {
905 return;
906 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700907
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700908 mServiceState = state;
909
910 service = mService.promote();
911 if (service == 0) {
912 return;
913 }
914
915 if (state == SOUND_TRIGGER_STATE_ENABLED) {
916 goto exit;
917 }
918
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700919 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700920 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700921
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700922 for (size_t i = 0; i < mModels.size(); i++) {
923 sp<Model> model = mModels.valueAt(i);
924 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700925 if (mHalInterface != 0 && !supports_stop_all) {
926 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700927 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700928 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800929 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
930 struct sound_trigger_phrase_recognition_event event;
931 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
932 event.num_phrases = model->mConfig.num_phrases;
933 for (size_t i = 0; i < event.num_phrases; i++) {
934 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700935 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800936 event.common.status = RECOGNITION_STATUS_ABORT;
937 event.common.type = model->mType;
938 event.common.model = model->mHandle;
939 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700940 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800941 if (eventMemory != 0) {
942 events.add(eventMemory);
943 }
944 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
945 struct sound_trigger_generic_recognition_event event;
946 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
947 event.common.status = RECOGNITION_STATUS_ABORT;
948 event.common.type = model->mType;
949 event.common.model = model->mHandle;
950 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700951 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800952 if (eventMemory != 0) {
953 events.add(eventMemory);
954 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800955 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
956 struct sound_trigger_phrase_recognition_event event;
957 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
958 event.common.status = RECOGNITION_STATUS_ABORT;
959 event.common.type = model->mType;
960 event.common.model = model->mHandle;
961 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700962 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800963 if (eventMemory != 0) {
964 events.add(eventMemory);
965 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800966 } else {
967 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700968 }
969 }
970 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700971 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700972
973 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700974 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
975 events[i]);
976 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700977 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700978 }
979
980exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800981 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700982}
983
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700984
985SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
986 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700987 sound_trigger_sound_model_type_t type,
988 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700989 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700990 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
991 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700992{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700993}
994
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700995#undef LOG_TAG
996#define LOG_TAG "SoundTriggerHwService::ModuleClient"
997
998SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
jiabin68e0df72019-03-18 17:55:35 -0700999 const sp<ISoundTriggerClient>& client,
1000 const String16& opPackageName)
1001 : mModule(module), mClient(client), mOpPackageName(opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001002{
1003}
1004
1005void SoundTriggerHwService::ModuleClient::onFirstRef()
1006{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -08001007 sp<IBinder> binder = IInterface::asBinder(mClient);
1008 if (binder != 0) {
1009 binder->linkToDeath(this);
1010 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001011}
1012
1013SoundTriggerHwService::ModuleClient::~ModuleClient()
1014{
1015}
1016
1017status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
1018 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -07001019 String8 result;
1020 return NO_ERROR;
1021}
1022
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001023void SoundTriggerHwService::ModuleClient::detach() {
1024 ALOGV("detach()");
jiabin68e0df72019-03-18 17:55:35 -07001025 if (!captureHotwordAllowed(mOpPackageName,
1026 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001027 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001028 return;
1029 }
1030
1031 {
1032 AutoMutex lock(mLock);
1033 if (mClient != 0) {
1034 IInterface::asBinder(mClient)->unlinkToDeath(this);
1035 mClient.clear();
1036 }
1037 }
1038
1039 sp<Module> module = mModule.promote();
1040 if (module == 0) {
1041 return;
1042 }
1043 module->detach(this);
1044}
1045
1046status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
1047 sound_model_handle_t *handle)
1048{
1049 ALOGV("loadSoundModel() handle");
jiabin68e0df72019-03-18 17:55:35 -07001050 if (!captureHotwordAllowed(mOpPackageName,
1051 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001052 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001053 return PERMISSION_DENIED;
1054 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001055 if (checkIMemory(modelMemory) != NO_ERROR) {
1056 return BAD_VALUE;
1057 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001058
1059 sp<Module> module = mModule.promote();
1060 if (module == 0) {
1061 return NO_INIT;
1062 }
1063 return module->loadSoundModel(modelMemory, this, handle);
1064}
1065
1066status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
1067{
1068 ALOGV("unloadSoundModel() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001069 if (!captureHotwordAllowed(mOpPackageName,
1070 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001071 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001072 return PERMISSION_DENIED;
1073 }
1074
1075 sp<Module> module = mModule.promote();
1076 if (module == 0) {
1077 return NO_INIT;
1078 }
1079 return module->unloadSoundModel(handle);
1080}
1081
1082status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1083 const sp<IMemory>& dataMemory)
1084{
1085 ALOGV("startRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001086 if (!captureHotwordAllowed(mOpPackageName,
1087 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001088 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001089 return PERMISSION_DENIED;
1090 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001091 if (checkIMemory(dataMemory) != NO_ERROR) {
1092 return BAD_VALUE;
1093 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001094
1095 sp<Module> module = mModule.promote();
1096 if (module == 0) {
1097 return NO_INIT;
1098 }
1099 return module->startRecognition(handle, dataMemory);
1100}
1101
1102status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1103{
1104 ALOGV("stopRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001105 if (!captureHotwordAllowed(mOpPackageName,
1106 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001107 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001108 return PERMISSION_DENIED;
1109 }
1110
1111 sp<Module> module = mModule.promote();
1112 if (module == 0) {
1113 return NO_INIT;
1114 }
1115 return module->stopRecognition(handle);
1116}
1117
mike dooley6e189b12018-11-07 15:44:37 +01001118status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001119{
1120 ALOGV("getModelState() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001121 if (!captureHotwordAllowed(mOpPackageName,
1122 IPCThreadState::self()->getCallingPid(),
Michael Dooley67e3d412018-10-16 19:51:16 +00001123 IPCThreadState::self()->getCallingUid())) {
1124 return PERMISSION_DENIED;
1125 }
1126
1127 sp<Module> module = mModule.promote();
1128 if (module == 0) {
1129 return NO_INIT;
1130 }
mike dooley6e189b12018-11-07 15:44:37 +01001131 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001132}
1133
Nicholas Ambur41947e22019-10-01 11:53:40 -07001134status_t SoundTriggerHwService::ModuleClient::setParameter(sound_model_handle_t handle,
1135 sound_trigger_model_parameter_t param, int32_t value)
1136{
1137 ALOGV("setParameter() handle=%d, param=%d, value=%d", handle, param, value);
1138 if (!captureHotwordAllowed(mOpPackageName,
1139 IPCThreadState::self()->getCallingPid(),
1140 IPCThreadState::self()->getCallingUid())) {
1141 return PERMISSION_DENIED;
1142 }
1143
1144 sp<Module> module = mModule.promote();
1145 if (module == 0) {
1146 return NO_INIT;
1147 }
1148 return module->setParameter(handle, param, value);
1149}
1150
1151status_t SoundTriggerHwService::ModuleClient::getParameter(sound_model_handle_t handle,
1152 sound_trigger_model_parameter_t param, int32_t* value)
1153{
1154 ALOGV("getParameter() handle=%d, param=%d", handle, param);
1155 if (!captureHotwordAllowed(mOpPackageName,
1156 IPCThreadState::self()->getCallingPid(),
1157 IPCThreadState::self()->getCallingUid())) {
1158 return PERMISSION_DENIED;
1159 }
1160
1161 sp<Module> module = mModule.promote();
1162 if (module == 0) {
1163 return NO_INIT;
1164 }
1165 return module->getParameter(handle, param, value);
1166}
1167
1168status_t SoundTriggerHwService::ModuleClient::queryParameter(sound_model_handle_t handle,
1169 sound_trigger_model_parameter_t param,
1170 sound_trigger_model_parameter_range_t* param_range)
1171{
1172 ALOGV("isParameterSupported() handle=%d, param=%d", handle, param);
1173 if (!captureHotwordAllowed(mOpPackageName,
1174 IPCThreadState::self()->getCallingPid(),
1175 IPCThreadState::self()->getCallingUid())) {
1176 return PERMISSION_DENIED;
1177 }
1178
1179 sp<Module> module = mModule.promote();
1180 if (module == 0) {
1181 return NO_INIT;
1182 }
1183 return module->queryParameter(handle, param, param_range);
1184}
1185
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001186void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1187{
1188 ALOGV("ModuleClient::setCaptureState_l %d", active);
1189 sp<SoundTriggerHwService> service;
1190 sound_trigger_service_state_t state;
1191
1192 sp<Module> module = mModule.promote();
1193 if (module == 0) {
1194 return;
1195 }
1196 {
1197 AutoMutex lock(mLock);
1198 state = (active && !module->isConcurrentCaptureAllowed()) ?
1199 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1200
1201 service = module->service().promote();
1202 if (service == 0) {
1203 return;
1204 }
1205 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001206 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001207}
1208
1209void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1210{
1211 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1212
1213 sp<IMemory> eventMemory = event->mMemory;
1214
Ytai Ben-Tsvi7dd39722019-09-05 15:14:30 -07001215 // Memory is coming from a trusted process.
1216 if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001217 return;
1218 }
1219
Chris Thornton02b74212017-11-06 14:45:30 -08001220 sp<ISoundTriggerClient> client;
1221 {
1222 AutoMutex lock(mLock);
1223 client = mClient;
1224 }
1225
1226 if (client != 0) {
1227 switch (event->mType) {
1228 case CallbackEvent::TYPE_RECOGNITION: {
1229 client->onRecognitionEvent(eventMemory);
1230 } break;
1231 case CallbackEvent::TYPE_SOUNDMODEL: {
1232 client->onSoundModelEvent(eventMemory);
1233 } break;
1234 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001235 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001236 } break;
1237 default:
1238 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001239 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001240 }
1241}
1242
1243void SoundTriggerHwService::ModuleClient::binderDied(
1244 const wp<IBinder> &who __unused) {
1245 ALOGW("client binder died for client %p", this);
1246 detach();
1247}
1248
Eric Laurentb7a11d82014-04-18 17:40:41 -07001249}; // namespace android