• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
35 namespace android {
36 
37 enum {
38     LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
39     ATTACH,
40     SET_CAPTURE_STATE,
41 };
42 
43 #define MAX_ITEMS_PER_LIST 1024
44 
45 class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
46 {
47 public:
BpSoundTriggerHwService(const sp<IBinder> & impl)48     explicit BpSoundTriggerHwService(const sp<IBinder>& impl)
49         : BpInterface<ISoundTriggerHwService>(impl)
50     {
51     }
52 
listModules(const String16 & opPackageName,struct sound_trigger_module_descriptor * modules,uint32_t * numModules)53     virtual status_t listModules(const String16& opPackageName,
54                                  struct sound_trigger_module_descriptor *modules,
55                                  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());
62         data.writeString16(opPackageName);
63         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 
attach(const String16 & opPackageName,const sound_trigger_module_handle_t handle,const sp<ISoundTriggerClient> & client,sp<ISoundTrigger> & module)82     virtual status_t attach(const String16& opPackageName,
83                             const sound_trigger_module_handle_t handle,
84                             const sp<ISoundTriggerClient>& client,
85                             sp<ISoundTrigger>& module)
86     {
87         Parcel data, reply;
88         data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
89         data.writeString16(opPackageName);
90         data.write(&handle, sizeof(sound_trigger_module_handle_t));
91         data.writeStrongBinder(IInterface::asBinder(client));
92         status_t status = remote()->transact(ATTACH, data, &reply);
93         if (status != NO_ERROR) {
94             return status;
95         }
96         status = reply.readInt32();
97         if (reply.readInt32() != 0) {
98             module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
99         }
100         return status;
101     }
102 
setCaptureState(bool active)103     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 
115 };
116 
117 IMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
118 
119 // ----------------------------------------------------------------------
120 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)121 status_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);
127             String16 opPackageName;
128             status_t status = data.readString16(&opPackageName);
129             if (status != NO_ERROR) {
130                 return status;
131             }
132             unsigned int numModulesReq = data.readInt32();
133             if (numModulesReq > MAX_ITEMS_PER_LIST) {
134                 numModulesReq = MAX_ITEMS_PER_LIST;
135             }
136             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));
140             if (modules == NULL) {
141                 reply->writeInt32(NO_MEMORY);
142                 reply->writeInt32(0);
143                 return NO_ERROR;
144             }
145             status = listModules(opPackageName, modules, &numModules);
146             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);
163             String16 opPackageName;
164             status_t status = data.readString16(&opPackageName);
165             if (status != NO_ERROR) {
166                 return status;
167             }
168             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;
173             status = attach(opPackageName, handle, client, module);
174             reply->writeInt32(status);
175             if (module != 0) {
176                 reply->writeInt32(1);
177                 reply->writeStrongBinder(IInterface::asBinder(module));
178             } else {
179                 reply->writeInt32(0);
180             }
181             return NO_ERROR;
182         } break;
183 
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 
190         default:
191             return BBinder::onTransact(code, data, reply, flags);
192     }
193 }
194 
195 // ----------------------------------------------------------------------------
196 
197 }; // namespace android
198