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
43b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentclass BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
44b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
45b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentpublic:
46b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    BpSoundTriggerHwService(const sp<IBinder>& impl)
47b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        : BpInterface<ISoundTriggerHwService>(impl)
48b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
49b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
50b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
51b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
52b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                 uint32_t *numModules)
53b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
54b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
55b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BAD_VALUE;
56b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
57b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
58b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
59b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
60b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInt32(numModulesReq);
61b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = remote()->transact(LIST_MODULES, data, &reply);
62b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status == NO_ERROR) {
63b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status = (status_t)reply.readInt32();
64b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            *numModules = (unsigned int)reply.readInt32();
65b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
66b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        ALOGV("listModules() status %d got *numModules %d", status, *numModules);
67b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (status == NO_ERROR) {
68b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (numModulesReq > *numModules) {
69b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                numModulesReq = *numModules;
70b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
71b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (numModulesReq > 0) {
72b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
73b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
74b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
75b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
76b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
77b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
78b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    virtual status_t attach(const sound_trigger_module_handle_t handle,
79b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                            const sp<ISoundTriggerClient>& client,
80b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                            sp<ISoundTrigger>& module)
81b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    {
82b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        Parcel data, reply;
83b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
84b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.write(&handle, sizeof(sound_trigger_module_handle_t));
85b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        data.writeStrongBinder(client->asBinder());
86b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        remote()->transact(ATTACH, data, &reply);
87b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        status_t status = reply.readInt32();
88b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        if (reply.readInt32() != 0) {
89b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
90b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
91b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        return status;
92b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
93b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
94df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    virtual status_t setCaptureState(bool active)
95df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    {
96df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        Parcel data, reply;
97df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
98df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        data.writeInt32(active);
99df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        status_t status = remote()->transact(SET_CAPTURE_STATE, data, &reply);
100df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        if (status == NO_ERROR) {
101df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            status = reply.readInt32();
102df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        }
103df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        return status;
104df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent    }
105df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
106b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent};
107b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
108b7a11d83f749ad0200778c4815e907d011d4b5d3Eric LaurentIMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
109b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
110b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------
111b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
112b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurentstatus_t BnSoundTriggerHwService::onTransact(
113b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
114b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent{
115b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    switch(code) {
116b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case LIST_MODULES: {
117b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
118b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            unsigned int numModulesReq = data.readInt32();
119b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            unsigned int numModules = numModulesReq;
120b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            struct sound_trigger_module_descriptor *modules =
121b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
122b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                                                   sizeof(struct sound_trigger_module_descriptor));
123b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = listModules(modules, &numModules);
124b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
125b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(numModules);
126b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
127b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
128b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (status == NO_ERROR) {
129b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                if (numModulesReq > numModules) {
130b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    numModulesReq = numModules;
131b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                }
132b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->write(modules,
133b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                             numModulesReq * sizeof(struct sound_trigger_module_descriptor));
134b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
135b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            free(modules);
136b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
137b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        }
138b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
139b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        case ATTACH: {
140b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
141b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sound_trigger_module_handle_t handle;
142b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            data.read(&handle, sizeof(sound_trigger_module_handle_t));
143b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<ISoundTriggerClient> client =
144b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                    interface_cast<ISoundTriggerClient>(data.readStrongBinder());
145b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            sp<ISoundTrigger> module;
146b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            status_t status = attach(handle, client, module);
147b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            reply->writeInt32(status);
148b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            if (module != 0) {
149b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->writeInt32(1);
150b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->writeStrongBinder(module->asBinder());
151b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            } else {
152b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent                reply->writeInt32(0);
153b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            }
154b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return NO_ERROR;
155b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        } break;
156df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
157df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        case SET_CAPTURE_STATE: {
158df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
159df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            reply->writeInt32(setCaptureState((bool)data.readInt32()));
160df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent            return NO_ERROR;
161df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent        } break;
162df3dc7e2fe6c639529b70e3f3a7d2bf0f4c6e871Eric Laurent
163b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent        default:
164b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent            return BBinder::onTransact(code, data, reply, flags);
165b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent    }
166b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}
167b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
168b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent// ----------------------------------------------------------------------------
169b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent
170b7a11d83f749ad0200778c4815e907d011d4b5d3Eric Laurent}; // namespace android
171