1/*
2 * Copyright (C) 2016 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#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_V2_0_IMPLEMENTATION_H
18#define ANDROID_HARDWARE_SOUNDTRIGGER_V2_0_IMPLEMENTATION_H
19
20#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
21#include <android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h>
22#include <hardware/sound_trigger.h>
23#include <hidl/Status.h>
24#include <stdatomic.h>
25#include <system/sound_trigger.h>
26#include <utils/KeyedVector.h>
27#include <utils/threads.h>
28
29namespace android {
30namespace hardware {
31namespace soundtrigger {
32namespace V2_0 {
33namespace implementation {
34
35using ::android::hardware::audio::common::V2_0::Uuid;
36using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
37
38class SoundTriggerHalImpl : public RefBase {
39   public:
40    SoundTriggerHalImpl();
41    ISoundTriggerHw* getInterface() { return new TrampolineSoundTriggerHw_2_0(this); }
42
43   protected:
44    class SoundModelClient : public RefBase {
45       public:
46        SoundModelClient(uint32_t id, ISoundTriggerHwCallback::CallbackCookie cookie)
47            : mId(id), mCookie(cookie) {}
48        virtual ~SoundModelClient() {}
49
50        uint32_t getId() const { return mId; }
51        sound_model_handle_t getHalHandle() const { return mHalHandle; }
52        void setHalHandle(sound_model_handle_t handle) { mHalHandle = handle; }
53
54        virtual void recognitionCallback(struct sound_trigger_recognition_event* halEvent) = 0;
55        virtual void soundModelCallback(struct sound_trigger_model_event* halEvent) = 0;
56
57       protected:
58        const uint32_t mId;
59        sound_model_handle_t mHalHandle;
60        ISoundTriggerHwCallback::CallbackCookie mCookie;
61    };
62
63    static void convertPhaseRecognitionEventFromHal(
64        ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
65        const struct sound_trigger_phrase_recognition_event* halEvent);
66    static void convertRecognitionEventFromHal(
67        ISoundTriggerHwCallback::RecognitionEvent* event,
68        const struct sound_trigger_recognition_event* halEvent);
69    static void convertSoundModelEventFromHal(ISoundTriggerHwCallback::ModelEvent* event,
70                                              const struct sound_trigger_model_event* halEvent);
71
72    virtual ~SoundTriggerHalImpl();
73
74    Return<void> getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb);
75    Return<void> loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
76                                const sp<ISoundTriggerHwCallback>& callback,
77                                ISoundTriggerHwCallback::CallbackCookie cookie,
78                                ISoundTriggerHw::loadSoundModel_cb _hidl_cb);
79    Return<void> loadPhraseSoundModel(const ISoundTriggerHw::PhraseSoundModel& soundModel,
80                                      const sp<ISoundTriggerHwCallback>& callback,
81                                      ISoundTriggerHwCallback::CallbackCookie cookie,
82                                      ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb);
83    Return<int32_t> unloadSoundModel(SoundModelHandle modelHandle);
84    Return<int32_t> startRecognition(SoundModelHandle modelHandle,
85                                     const ISoundTriggerHw::RecognitionConfig& config);
86    Return<int32_t> stopRecognition(SoundModelHandle modelHandle);
87    Return<int32_t> stopAllRecognitions();
88
89    uint32_t nextUniqueModelId();
90    int doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
91                         sp<SoundModelClient> client);
92
93    // RefBase
94    void onFirstRef() override;
95
96   private:
97    struct TrampolineSoundTriggerHw_2_0 : public ISoundTriggerHw {
98        explicit TrampolineSoundTriggerHw_2_0(sp<SoundTriggerHalImpl> impl) : mImpl(impl) {}
99
100        // Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow.
101        Return<void> getProperties(getProperties_cb _hidl_cb) override {
102            return mImpl->getProperties(_hidl_cb);
103        }
104        Return<void> loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
105                                    const sp<ISoundTriggerHwCallback>& callback,
106                                    ISoundTriggerHwCallback::CallbackCookie cookie,
107                                    loadSoundModel_cb _hidl_cb) override {
108            return mImpl->loadSoundModel(soundModel, callback, cookie, _hidl_cb);
109        }
110        Return<void> loadPhraseSoundModel(const ISoundTriggerHw::PhraseSoundModel& soundModel,
111                                          const sp<ISoundTriggerHwCallback>& callback,
112                                          ISoundTriggerHwCallback::CallbackCookie cookie,
113                                          loadPhraseSoundModel_cb _hidl_cb) override {
114            return mImpl->loadPhraseSoundModel(soundModel, callback, cookie, _hidl_cb);
115        }
116        Return<int32_t> unloadSoundModel(SoundModelHandle modelHandle) override {
117            return mImpl->unloadSoundModel(modelHandle);
118        }
119        Return<int32_t> startRecognition(
120            SoundModelHandle modelHandle, const ISoundTriggerHw::RecognitionConfig& config,
121            const sp<ISoundTriggerHwCallback>& /*callback*/,
122            ISoundTriggerHwCallback::CallbackCookie /*cookie*/) override {
123            return mImpl->startRecognition(modelHandle, config);
124        }
125        Return<int32_t> stopRecognition(SoundModelHandle modelHandle) override {
126            return mImpl->stopRecognition(modelHandle);
127        }
128        Return<int32_t> stopAllRecognitions() override { return mImpl->stopAllRecognitions(); }
129
130       private:
131        sp<SoundTriggerHalImpl> mImpl;
132    };
133
134    class SoundModelClient_2_0 : public SoundModelClient {
135       public:
136        SoundModelClient_2_0(uint32_t id, ISoundTriggerHwCallback::CallbackCookie cookie,
137                             sp<ISoundTriggerHwCallback> callback)
138            : SoundModelClient(id, cookie), mCallback(callback) {}
139
140        void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override;
141        void soundModelCallback(struct sound_trigger_model_event* halEvent) override;
142
143       private:
144        sp<ISoundTriggerHwCallback> mCallback;
145    };
146
147    void convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid);
148    void convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid);
149    void convertPropertiesFromHal(ISoundTriggerHw::Properties* properties,
150                                  const struct sound_trigger_properties* halProperties);
151    void convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
152                                   const ISoundTriggerHw::Phrase* triggerPhrase);
153    // returned HAL sound model must be freed by caller
154    struct sound_trigger_sound_model* convertSoundModelToHal(
155        const ISoundTriggerHw::SoundModel* soundModel);
156    void convertPhraseRecognitionExtraToHal(struct sound_trigger_phrase_recognition_extra* halExtra,
157                                            const PhraseRecognitionExtra* extra);
158    // returned recognition config must be freed by caller
159    struct sound_trigger_recognition_config* convertRecognitionConfigToHal(
160        const ISoundTriggerHw::RecognitionConfig* config);
161
162    static void convertPhraseRecognitionExtraFromHal(
163        PhraseRecognitionExtra* extra,
164        const struct sound_trigger_phrase_recognition_extra* halExtra);
165
166    static void soundModelCallback(struct sound_trigger_model_event* halEvent, void* cookie);
167    static void recognitionCallback(struct sound_trigger_recognition_event* halEvent, void* cookie);
168
169    const char* mModuleName;
170    struct sound_trigger_hw_device* mHwDevice;
171    volatile atomic_uint_fast32_t mNextModelId;
172    DefaultKeyedVector<int32_t, sp<SoundModelClient> > mClients;
173    Mutex mLock;
174};
175
176}  // namespace implementation
177}  // namespace V2_0
178}  // namespace soundtrigger
179}  // namespace hardware
180}  // namespace android
181
182#endif  // ANDROID_HARDWARE_SOUNDTRIGGER_V2_0_IMPLEMENTATION_H
183