OSDN Git Service

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