1b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent/*
2b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
3b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Copyright (C) 2014, The Android Open Source Project
4b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
5b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
6b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** you may not use this file except in compliance with the License.
7b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** You may obtain a copy of the License at
8b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
9b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
10b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
11b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Unless required by applicable law or agreed to in writing, software
12b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
13b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** See the License for the specific language governing permissions and
15b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** limitations under the License.
16b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent*/
17b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
18b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#define LOG_TAG "SoundTrigger"
19b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent//#define LOG_NDEBUG 0
20b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
21b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Log.h>
22b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/threads.h>
23b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IPCThreadState.h>
24b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IServiceManager.h>
25b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IMemory.h>
26b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
27b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/SoundTrigger.h>
28b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTrigger.h>
29b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerHwService.h>
30b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerClient.h>
31b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/SoundTriggerCallback.h>
32b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
33b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace android {
34b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
35b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace {
36b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    sp<ISoundTriggerHwService> gSoundTriggerHwService;
37b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    const int                  kSoundTriggerHwServicePollDelay = 500000; // 0.5s
38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    const char*                kSoundTriggerHwServiceName      = "media.sound_trigger_hw";
39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex                      gLock;
40b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    class DeathNotifier : public IBinder::DeathRecipient
42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
43b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    public:
44b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        DeathNotifier() {
45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        virtual void binderDied(const wp<IBinder>& who __unused) {
48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGV("binderDied");
49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            Mutex::Autolock _l(gLock);
50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            gSoundTriggerHwService.clear();
51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGW("Sound trigger service died!");
52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    };
54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    sp<DeathNotifier>         gDeathNotifier;
56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace anonymous
57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
583769871b5998f4bbe6d8fe7c124ee97daa6e7fabEric Laurentconst sp<ISoundTriggerHwService> SoundTrigger::getSoundTriggerHwService()
59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(gLock);
61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (gSoundTriggerHwService.get() == 0) {
62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        sp<IServiceManager> sm = defaultServiceManager();
63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        sp<IBinder> binder;
64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        do {
65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            binder = sm->getService(String16(kSoundTriggerHwServiceName));
66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (binder != 0) {
67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                break;
68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGW("SoundTriggerHwService not published, waiting...");
70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            usleep(kSoundTriggerHwServicePollDelay);
71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } while(true);
72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (gDeathNotifier == NULL) {
73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            gDeathNotifier = new DeathNotifier();
74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        binder->linkToDeath(gDeathNotifier);
76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        gSoundTriggerHwService = interface_cast<ISoundTriggerHwService>(binder);
77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ALOGE_IF(gSoundTriggerHwService == 0, "no SoundTriggerHwService!?");
79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return gSoundTriggerHwService;
80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// Static methods
83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::listModules(struct sound_trigger_module_descriptor *modules,
84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                 uint32_t *numModules)
85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ALOGV("listModules()");
873769871b5998f4bbe6d8fe7c124ee97daa6e7fabEric Laurent    const sp<ISoundTriggerHwService> service = getSoundTriggerHwService();
88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (service == 0) {
89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return NO_INIT;
90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return service->listModules(modules, numModules);
92b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentsp<SoundTrigger> SoundTrigger::attach(const sound_trigger_module_handle_t module,
95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                            const sp<SoundTriggerCallback>& callback)
96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ALOGV("attach()");
98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    sp<SoundTrigger> soundTrigger;
993769871b5998f4bbe6d8fe7c124ee97daa6e7fabEric Laurent    const sp<ISoundTriggerHwService> service = getSoundTriggerHwService();
100b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (service == 0) {
101b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return soundTrigger;
102b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
103b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    soundTrigger = new SoundTrigger(module, callback);
104b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    status_t status = service->attach(module, soundTrigger, soundTrigger->mISoundTrigger);
105b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (status == NO_ERROR && soundTrigger->mISoundTrigger != 0) {
10706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        IInterface::asBinder(soundTrigger->mISoundTrigger)->linkToDeath(soundTrigger);
108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    } else {
109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        ALOGW("Error %d connecting to sound trigger service", status);
110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        soundTrigger.clear();
111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return soundTrigger;
113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
116df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentstatus_t SoundTrigger::setCaptureState(bool active)
117df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
118df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    ALOGV("setCaptureState(%d)", active);
1193769871b5998f4bbe6d8fe7c124ee97daa6e7fabEric Laurent    const sp<ISoundTriggerHwService> service = getSoundTriggerHwService();
120df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    if (service == 0) {
121df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        return NO_INIT;
122df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
123df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    return service->setCaptureState(active);
124df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
125df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// SoundTrigger
1276f51c153ea5e4187a313e47ac8bad9a1a999d4e1Colin CrossSoundTrigger::SoundTrigger(sound_trigger_module_handle_t /*module*/,
128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                 const sp<SoundTriggerCallback>& callback)
1296f51c153ea5e4187a313e47ac8bad9a1a999d4e1Colin Cross    : mCallback(callback)
130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
131b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
133b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentSoundTrigger::~SoundTrigger()
134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
135b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger != 0) {
136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        mISoundTrigger->detach();
137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTrigger::detach() {
142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ALOGV("detach()");
143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    mCallback.clear();
145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger != 0) {
146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        mISoundTrigger->detach();
14706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        IInterface::asBinder(mISoundTrigger)->unlinkToDeath(this);
148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        mISoundTrigger = 0;
149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::loadSoundModel(const sp<IMemory>& modelMemory,
153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                sound_model_handle_t *handle)
154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger == 0) {
157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return NO_INIT;
158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return mISoundTrigger->loadSoundModel(modelMemory, handle);
161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::unloadSoundModel(sound_model_handle_t handle)
164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger == 0) {
167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return NO_INIT;
168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return mISoundTrigger->unloadSoundModel(handle);
170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
171b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
172b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::startRecognition(sound_model_handle_t handle,
173b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                        const sp<IMemory>& dataMemory)
174b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
175b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger == 0) {
177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return NO_INIT;
178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return mISoundTrigger->startRecognition(handle, dataMemory);
180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::stopRecognition(sound_model_handle_t handle)
183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
184b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
185b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mISoundTrigger == 0) {
186b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return NO_INIT;
187b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
188b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return mISoundTrigger->stopRecognition(handle);
189b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
190b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
191b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// BpSoundTriggerClient
192b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTrigger::onRecognitionEvent(const sp<IMemory>& eventMemory)
193b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
194b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
195b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
196b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return;
197b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
198b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
199b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mCallback != 0) {
200b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        mCallback->onRecognitionEvent(
201b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                (struct sound_trigger_recognition_event *)eventMemory->pointer());
202b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
203b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
204b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
205df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTrigger::onSoundModelEvent(const sp<IMemory>& eventMemory)
206df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
207df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    Mutex::Autolock _l(mLock);
208df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
209df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        return;
210df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
211df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
212df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    if (mCallback != 0) {
213df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        mCallback->onSoundModelEvent(
214df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                (struct sound_trigger_model_event *)eventMemory->pointer());
215df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
216df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
217df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
218df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurentvoid SoundTrigger::onServiceStateChange(const sp<IMemory>& eventMemory)
219df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent{
220df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    Mutex::Autolock _l(mLock);
221df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
222df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        return;
223df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
224df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
225df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    if (mCallback != 0) {
226df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        mCallback->onServiceStateChange(
227df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent                *((sound_trigger_service_state_t *)eventMemory->pointer()));
228df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
229df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent}
230b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
231b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent//IBinder::DeathRecipient
232b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentvoid SoundTrigger::binderDied(const wp<IBinder>& who __unused) {
233b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    Mutex::Autolock _l(mLock);
234b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ALOGW("SoundTrigger server binder Died ");
235b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    mISoundTrigger = 0;
236b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (mCallback != 0) {
237b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        mCallback->onServiceDied();
238b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
239b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
240b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
241b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::stringToGuid(const char *str, sound_trigger_uuid_t *guid)
242b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
243b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (str == NULL || guid == NULL) {
244b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return BAD_VALUE;
245b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
246b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
247b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    int tmp[10];
248b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
249b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
250b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
251b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return BAD_VALUE;
252b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
253b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->timeLow = (uint32_t)tmp[0];
254b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->timeMid = (uint16_t)tmp[1];
255b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->timeHiAndVersion = (uint16_t)tmp[2];
256b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->clockSeq = (uint16_t)tmp[3];
257b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[0] = (uint8_t)tmp[4];
258b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[1] = (uint8_t)tmp[5];
259b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[2] = (uint8_t)tmp[6];
260b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[3] = (uint8_t)tmp[7];
261b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[4] = (uint8_t)tmp[8];
262b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    guid->node[5] = (uint8_t)tmp[9];
263b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
264b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return NO_ERROR;
265b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
266b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
267b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t SoundTrigger::guidToString(const sound_trigger_uuid_t *guid, char *str, size_t maxLen)
268b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
269b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    if (guid == NULL || str == NULL) {
270b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return BAD_VALUE;
271b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
272b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
273b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
274b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->timeLow,
275b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->timeMid,
276b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->timeHiAndVersion,
277b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->clockSeq,
278b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[0],
279b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[1],
280b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[2],
281b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[3],
282b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[4],
283b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            guid->node[5]);
284b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
285b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    return NO_ERROR;
286b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
287b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
288b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android
289