blob: bd107b4e87cff3fa0b8cd063c63e2c9d5fb7b819 [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,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070040 SET_CAPTURE_STATE,
Eric Laurentb7a11d82014-04-18 17:40:41 -070041};
42
Eric Laurentb9096dc2015-05-04 15:29:36 -070043#define MAX_ITEMS_PER_LIST 1024
44
Eric Laurentb7a11d82014-04-18 17:40:41 -070045class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
46{
47public:
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070048 explicit BpSoundTriggerHwService(const sp<IBinder>& impl)
Eric Laurentb7a11d82014-04-18 17:40:41 -070049 : BpInterface<ISoundTriggerHwService>(impl)
50 {
51 }
52
jiabin68e0df72019-03-18 17:55:35 -070053 virtual status_t listModules(const String16& opPackageName,
54 struct sound_trigger_module_descriptor *modules,
Eric Laurentb7a11d82014-04-18 17:40:41 -070055 uint32_t *numModules)
56 {
57 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
58 return BAD_VALUE;
59 }
60 Parcel data, reply;
61 data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
jiabin68e0df72019-03-18 17:55:35 -070062 data.writeString16(opPackageName);
Eric Laurentb7a11d82014-04-18 17:40:41 -070063 unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
64 data.writeInt32(numModulesReq);
65 status_t status = remote()->transact(LIST_MODULES, data, &reply);
66 if (status == NO_ERROR) {
67 status = (status_t)reply.readInt32();
68 *numModules = (unsigned int)reply.readInt32();
69 }
70 ALOGV("listModules() status %d got *numModules %d", status, *numModules);
71 if (status == NO_ERROR) {
72 if (numModulesReq > *numModules) {
73 numModulesReq = *numModules;
74 }
75 if (numModulesReq > 0) {
76 reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
77 }
78 }
79 return status;
80 }
81
jiabin68e0df72019-03-18 17:55:35 -070082 virtual status_t attach(const String16& opPackageName,
83 const sound_trigger_module_handle_t handle,
Eric Laurentb7a11d82014-04-18 17:40:41 -070084 const sp<ISoundTriggerClient>& client,
85 sp<ISoundTrigger>& module)
86 {
87 Parcel data, reply;
88 data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
jiabin68e0df72019-03-18 17:55:35 -070089 data.writeString16(opPackageName);
Eric Laurentb7a11d82014-04-18 17:40:41 -070090 data.write(&handle, sizeof(sound_trigger_module_handle_t));
Marco Nelissen06b46062014-11-14 07:58:25 -080091 data.writeStrongBinder(IInterface::asBinder(client));
Eric Laurent014620f2015-10-05 17:21:00 -070092 status_t status = remote()->transact(ATTACH, data, &reply);
93 if (status != NO_ERROR) {
94 return status;
95 }
96 status = reply.readInt32();
Eric Laurentb7a11d82014-04-18 17:40:41 -070097 if (reply.readInt32() != 0) {
98 module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
99 }
100 return status;
101 }
102
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700103 virtual status_t setCaptureState(bool active)
104 {
105 Parcel data, reply;
106 data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
107 data.writeInt32(active);
108 status_t status = remote()->transact(SET_CAPTURE_STATE, data, &reply);
109 if (status == NO_ERROR) {
110 status = reply.readInt32();
111 }
112 return status;
113 }
114
Eric Laurentb7a11d82014-04-18 17:40:41 -0700115};
116
117IMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
118
119// ----------------------------------------------------------------------
120
121status_t BnSoundTriggerHwService::onTransact(
122 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
123{
124 switch(code) {
125 case LIST_MODULES: {
126 CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
jiabin68e0df72019-03-18 17:55:35 -0700127 String16 opPackageName;
128 status_t status = data.readString16(&opPackageName);
129 if (status != NO_ERROR) {
130 return status;
131 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700132 unsigned int numModulesReq = data.readInt32();
Eric Laurentb9096dc2015-05-04 15:29:36 -0700133 if (numModulesReq > MAX_ITEMS_PER_LIST) {
134 numModulesReq = MAX_ITEMS_PER_LIST;
135 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700136 unsigned int numModules = numModulesReq;
137 struct sound_trigger_module_descriptor *modules =
138 (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
139 sizeof(struct sound_trigger_module_descriptor));
Eric Laurentb9096dc2015-05-04 15:29:36 -0700140 if (modules == NULL) {
141 reply->writeInt32(NO_MEMORY);
142 reply->writeInt32(0);
143 return NO_ERROR;
144 }
jiabin68e0df72019-03-18 17:55:35 -0700145 status = listModules(opPackageName, modules, &numModules);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700146 reply->writeInt32(status);
147 reply->writeInt32(numModules);
148 ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
149
150 if (status == NO_ERROR) {
151 if (numModulesReq > numModules) {
152 numModulesReq = numModules;
153 }
154 reply->write(modules,
155 numModulesReq * sizeof(struct sound_trigger_module_descriptor));
156 }
157 free(modules);
158 return NO_ERROR;
159 }
160
161 case ATTACH: {
162 CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
jiabin68e0df72019-03-18 17:55:35 -0700163 String16 opPackageName;
164 status_t status = data.readString16(&opPackageName);
165 if (status != NO_ERROR) {
166 return status;
167 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700168 sound_trigger_module_handle_t handle;
169 data.read(&handle, sizeof(sound_trigger_module_handle_t));
170 sp<ISoundTriggerClient> client =
171 interface_cast<ISoundTriggerClient>(data.readStrongBinder());
172 sp<ISoundTrigger> module;
jiabin68e0df72019-03-18 17:55:35 -0700173 status = attach(opPackageName, handle, client, module);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700174 reply->writeInt32(status);
175 if (module != 0) {
176 reply->writeInt32(1);
Marco Nelissen06b46062014-11-14 07:58:25 -0800177 reply->writeStrongBinder(IInterface::asBinder(module));
Eric Laurentb7a11d82014-04-18 17:40:41 -0700178 } else {
179 reply->writeInt32(0);
180 }
181 return NO_ERROR;
182 } break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700183
184 case SET_CAPTURE_STATE: {
185 CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
186 reply->writeInt32(setCaptureState((bool)data.readInt32()));
187 return NO_ERROR;
188 } break;
189
Eric Laurentb7a11d82014-04-18 17:40:41 -0700190 default:
191 return BBinder::onTransact(code, data, reply, flags);
192 }
193}
194
195// ----------------------------------------------------------------------------
196
197}; // namespace android