blob: c9a0c24415a01150c2076d9d434554825b99ee7d [file] [log] [blame]
Eric Laurentb7a11d82014-04-18 17:40:41 -07001/*
2**
3** Copyright 2014, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "BpSoundTriggerHwService"
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Errors.h>
23
24#include <stdint.h>
25#include <sys/types.h>
26#include <binder/IMemory.h>
27#include <binder/Parcel.h>
28#include <binder/IPCThreadState.h>
29#include <binder/IServiceManager.h>
30
31#include <soundtrigger/ISoundTriggerHwService.h>
32#include <soundtrigger/ISoundTrigger.h>
33#include <soundtrigger/ISoundTriggerClient.h>
34
35namespace android {
36
37enum {
38 LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
39 ATTACH,
40};
41
42class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
43{
44public:
45 BpSoundTriggerHwService(const sp<IBinder>& impl)
46 : BpInterface<ISoundTriggerHwService>(impl)
47 {
48 }
49
50 virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
51 uint32_t *numModules)
52 {
53 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
54 return BAD_VALUE;
55 }
56 Parcel data, reply;
57 data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
58 unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
59 data.writeInt32(numModulesReq);
60 status_t status = remote()->transact(LIST_MODULES, data, &reply);
61 if (status == NO_ERROR) {
62 status = (status_t)reply.readInt32();
63 *numModules = (unsigned int)reply.readInt32();
64 }
65 ALOGV("listModules() status %d got *numModules %d", status, *numModules);
66 if (status == NO_ERROR) {
67 if (numModulesReq > *numModules) {
68 numModulesReq = *numModules;
69 }
70 if (numModulesReq > 0) {
71 reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
72 }
73 }
74 return status;
75 }
76
77 virtual status_t attach(const sound_trigger_module_handle_t handle,
78 const sp<ISoundTriggerClient>& client,
79 sp<ISoundTrigger>& module)
80 {
81 Parcel data, reply;
82 data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
83 data.write(&handle, sizeof(sound_trigger_module_handle_t));
84 data.writeStrongBinder(client->asBinder());
85 remote()->transact(ATTACH, data, &reply);
86 status_t status = reply.readInt32();
87 if (reply.readInt32() != 0) {
88 module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
89 }
90 return status;
91 }
92
93};
94
95IMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
96
97// ----------------------------------------------------------------------
98
99status_t BnSoundTriggerHwService::onTransact(
100 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
101{
102 switch(code) {
103 case LIST_MODULES: {
104 CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
105 unsigned int numModulesReq = data.readInt32();
106 unsigned int numModules = numModulesReq;
107 struct sound_trigger_module_descriptor *modules =
108 (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
109 sizeof(struct sound_trigger_module_descriptor));
110 status_t status = listModules(modules, &numModules);
111 reply->writeInt32(status);
112 reply->writeInt32(numModules);
113 ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
114
115 if (status == NO_ERROR) {
116 if (numModulesReq > numModules) {
117 numModulesReq = numModules;
118 }
119 reply->write(modules,
120 numModulesReq * sizeof(struct sound_trigger_module_descriptor));
121 }
122 free(modules);
123 return NO_ERROR;
124 }
125
126 case ATTACH: {
127 CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
128 sound_trigger_module_handle_t handle;
129 data.read(&handle, sizeof(sound_trigger_module_handle_t));
130 sp<ISoundTriggerClient> client =
131 interface_cast<ISoundTriggerClient>(data.readStrongBinder());
132 sp<ISoundTrigger> module;
133 status_t status = attach(handle, client, module);
134 reply->writeInt32(status);
135 if (module != 0) {
136 reply->writeInt32(1);
137 reply->writeStrongBinder(module->asBinder());
138 } else {
139 reply->writeInt32(0);
140 }
141 return NO_ERROR;
142 } break;
143 default:
144 return BBinder::onTransact(code, data, reply, flags);
145 }
146}
147
148// ----------------------------------------------------------------------------
149
150}; // namespace android