1b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent/*
2b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent**
3b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent** Copyright 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 "BpSoundTriggerHwService"
19b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent//#define LOG_NDEBUG 0
20b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
21b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Log.h>
22b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <utils/Errors.h>
23b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
24b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <stdint.h>
25b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <sys/types.h>
26b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IMemory.h>
27b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/Parcel.h>
28b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IPCThreadState.h>
29b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <binder/IServiceManager.h>
30b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
31b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerHwService.h>
32b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTrigger.h>
33b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent#include <soundtrigger/ISoundTriggerClient.h>
34b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
35b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentnamespace android {
36b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
37b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentenum {
38b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
39b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    ATTACH,
40df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    SET_CAPTURE_STATE,
41b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
42b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
43b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent#define MAX_ITEMS_PER_LIST 1024
44b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent
45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentclass BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentpublic:
48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    BpSoundTriggerHwService(const sp<IBinder>& impl)
49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        : BpInterface<ISoundTriggerHwService>(impl)
50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                 uint32_t *numModules)
55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BAD_VALUE;
58b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInt32(numModulesReq);
63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(LIST_MODULES, data, &reply);
64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status == NO_ERROR) {
65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            *numModules = (unsigned int)reply.readInt32();
67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        ALOGV("listModules() status %d got *numModules %d", status, *numModules);
69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status == NO_ERROR) {
70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (numModulesReq > *numModules) {
71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                numModulesReq = *numModules;
72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (numModulesReq > 0) {
74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t attach(const sound_trigger_module_handle_t handle,
81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                            const sp<ISoundTriggerClient>& client,
82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                            sp<ISoundTrigger>& module)
83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_trigger_module_handle_t));
8706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(client));
88014620f143eda403795642dab116fb82bda54200Eric Laurent        status_t status = remote()->transact(ATTACH, data, &reply);
89014620f143eda403795642dab116fb82bda54200Eric Laurent        if (status != NO_ERROR) {
90014620f143eda403795642dab116fb82bda54200Eric Laurent            return status;
91014620f143eda403795642dab116fb82bda54200Eric Laurent        }
92014620f143eda403795642dab116fb82bda54200Eric Laurent        status = reply.readInt32();
93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (reply.readInt32() != 0) {
94b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
95b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
96b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
97b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
98b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
99df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    virtual status_t setCaptureState(bool active)
100df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    {
101df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        Parcel data, reply;
102df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
103df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        data.writeInt32(active);
104df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        status_t status = remote()->transact(SET_CAPTURE_STATE, data, &reply);
105df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        if (status == NO_ERROR) {
106df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            status = reply.readInt32();
107df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        }
108df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        return status;
109df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
110df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentIMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------
116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t BnSoundTriggerHwService::onTransact(
118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    switch(code) {
121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case LIST_MODULES: {
122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            unsigned int numModulesReq = data.readInt32();
124b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent            if (numModulesReq > MAX_ITEMS_PER_LIST) {
125b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent                numModulesReq = MAX_ITEMS_PER_LIST;
126b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent            }
127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            unsigned int numModules = numModulesReq;
128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            struct sound_trigger_module_descriptor *modules =
129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                                   sizeof(struct sound_trigger_module_descriptor));
131b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent            if (modules == NULL) {
132b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent                reply->writeInt32(NO_MEMORY);
133b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent                reply->writeInt32(0);
134b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent                return NO_ERROR;
135b9096dc829bd9ffd912f88853a87c972086c8796Eric Laurent            }
136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = listModules(modules, &numModules);
137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(numModules);
139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (status == NO_ERROR) {
142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                if (numModulesReq > numModules) {
143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    numModulesReq = numModules;
144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                }
145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->write(modules,
146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                             numModulesReq * sizeof(struct sound_trigger_module_descriptor));
147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            free(modules);
149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case ATTACH: {
153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_trigger_module_handle_t handle;
155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_trigger_module_handle_t));
156b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<ISoundTriggerClient> client =
157b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    interface_cast<ISoundTriggerClient>(data.readStrongBinder());
158b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<ISoundTrigger> module;
159b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = attach(handle, client, module);
160b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
161b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (module != 0) {
162b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->writeInt32(1);
16306b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen                reply->writeStrongBinder(IInterface::asBinder(module));
164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            } else {
165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->writeInt32(0);
166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } break;
169df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
170df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        case SET_CAPTURE_STATE: {
171df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
172df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            reply->writeInt32(setCaptureState((bool)data.readInt32()));
173df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            return NO_ERROR;
174df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        } break;
175df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
176b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        default:
177b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BBinder::onTransact(code, data, reply, flags);
178b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
179b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
180b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
181b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------------
182b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
183b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android
184