1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <sensor/ISensorServer.h>
18
19 #include <stdint.h>
20 #include <sys/types.h>
21
22 #include <cutils/native_handle.h>
23 #include <utils/Errors.h>
24 #include <utils/RefBase.h>
25 #include <utils/Vector.h>
26 #include <utils/Timers.h>
27
28 #include <binder/Parcel.h>
29 #include <binder/IInterface.h>
30 #include <binder/IResultReceiver.h>
31
32 #include <sensor/Sensor.h>
33 #include <sensor/ISensorEventConnection.h>
34
35 namespace android {
36 // ----------------------------------------------------------------------------
37
38 enum {
39 GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
40 CREATE_SENSOR_EVENT_CONNECTION,
41 ENABLE_DATA_INJECTION,
42 GET_DYNAMIC_SENSOR_LIST,
43 CREATE_SENSOR_DIRECT_CONNECTION,
44 SET_OPERATION_PARAMETER,
45 };
46
47 class BpSensorServer : public BpInterface<ISensorServer>
48 {
49 public:
BpSensorServer(const sp<IBinder> & impl)50 explicit BpSensorServer(const sp<IBinder>& impl)
51 : BpInterface<ISensorServer>(impl)
52 {
53 }
54
55 virtual ~BpSensorServer();
56
getSensorList(const String16 & opPackageName)57 virtual Vector<Sensor> getSensorList(const String16& opPackageName)
58 {
59 Parcel data, reply;
60 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
61 data.writeString16(opPackageName);
62 remote()->transact(GET_SENSOR_LIST, data, &reply);
63 Sensor s;
64 Vector<Sensor> v;
65 uint32_t n = reply.readUint32();
66 v.setCapacity(n);
67 while (n) {
68 n--;
69 reply.read(s);
70 v.add(s);
71 }
72 return v;
73 }
74
getDynamicSensorList(const String16 & opPackageName)75 virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName)
76 {
77 Parcel data, reply;
78 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
79 data.writeString16(opPackageName);
80 remote()->transact(GET_DYNAMIC_SENSOR_LIST, data, &reply);
81 Sensor s;
82 Vector<Sensor> v;
83 uint32_t n = reply.readUint32();
84 v.setCapacity(n);
85 while (n) {
86 n--;
87 reply.read(s);
88 v.add(s);
89 }
90 return v;
91 }
92
createSensorEventConnection(const String8 & packageName,int mode,const String16 & opPackageName,const String16 & attributionTag)93 virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
94 int mode, const String16& opPackageName, const String16& attributionTag)
95 {
96 Parcel data, reply;
97 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
98 data.writeString8(packageName);
99 data.writeInt32(mode);
100 data.writeString16(opPackageName);
101 data.writeString16(attributionTag);
102 remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
103 return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
104 }
105
isDataInjectionEnabled()106 virtual int isDataInjectionEnabled() {
107 Parcel data, reply;
108 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
109 remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
110 return reply.readInt32();
111 }
112
createSensorDirectConnection(const String16 & opPackageName,uint32_t size,int32_t type,int32_t format,const native_handle_t * resource)113 virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
114 uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) {
115 Parcel data, reply;
116 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
117 data.writeString16(opPackageName);
118 data.writeUint32(size);
119 data.writeInt32(type);
120 data.writeInt32(format);
121 data.writeNativeHandle(resource);
122 remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply);
123 return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
124 }
125
setOperationParameter(int32_t handle,int32_t type,const Vector<float> & floats,const Vector<int32_t> & ints)126 virtual int setOperationParameter(int32_t handle, int32_t type,
127 const Vector<float> &floats,
128 const Vector<int32_t> &ints) {
129 Parcel data, reply;
130 data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
131 data.writeInt32(handle);
132 data.writeInt32(type);
133 data.writeUint32(static_cast<uint32_t>(floats.size()));
134 for (auto i : floats) {
135 data.writeFloat(i);
136 }
137 data.writeUint32(static_cast<uint32_t>(ints.size()));
138 for (auto i : ints) {
139 data.writeInt32(i);
140 }
141 remote()->transact(SET_OPERATION_PARAMETER, data, &reply);
142 return reply.readInt32();
143 }
144 };
145
146 // Out-of-line virtual method definition to trigger vtable emission in this
147 // translation unit (see clang warning -Wweak-vtables)
~BpSensorServer()148 BpSensorServer::~BpSensorServer() {}
149
150 IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
151
152 // ----------------------------------------------------------------------
153
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)154 status_t BnSensorServer::onTransact(
155 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
156 {
157 switch(code) {
158 case GET_SENSOR_LIST: {
159 CHECK_INTERFACE(ISensorServer, data, reply);
160 const String16& opPackageName = data.readString16();
161 Vector<Sensor> v(getSensorList(opPackageName));
162 size_t n = v.size();
163 reply->writeUint32(static_cast<uint32_t>(n));
164 for (size_t i = 0; i < n; i++) {
165 reply->write(v[i]);
166 }
167 return NO_ERROR;
168 }
169 case CREATE_SENSOR_EVENT_CONNECTION: {
170 CHECK_INTERFACE(ISensorServer, data, reply);
171 String8 packageName = data.readString8();
172 int32_t mode = data.readInt32();
173 const String16& opPackageName = data.readString16();
174 const String16& attributionTag = data.readString16();
175 sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode,
176 opPackageName, attributionTag));
177 reply->writeStrongBinder(IInterface::asBinder(connection));
178 return NO_ERROR;
179 }
180 case ENABLE_DATA_INJECTION: {
181 CHECK_INTERFACE(ISensorServer, data, reply);
182 int32_t ret = isDataInjectionEnabled();
183 reply->writeInt32(static_cast<int32_t>(ret));
184 return NO_ERROR;
185 }
186 case GET_DYNAMIC_SENSOR_LIST: {
187 CHECK_INTERFACE(ISensorServer, data, reply);
188 const String16& opPackageName = data.readString16();
189 Vector<Sensor> v(getDynamicSensorList(opPackageName));
190 size_t n = v.size();
191 reply->writeUint32(static_cast<uint32_t>(n));
192 for (size_t i = 0; i < n; i++) {
193 reply->write(v[i]);
194 }
195 return NO_ERROR;
196 }
197 case CREATE_SENSOR_DIRECT_CONNECTION: {
198 CHECK_INTERFACE(ISensorServer, data, reply);
199 const String16& opPackageName = data.readString16();
200 uint32_t size = data.readUint32();
201 int32_t type = data.readInt32();
202 int32_t format = data.readInt32();
203 native_handle_t *resource = data.readNativeHandle();
204 // Avoid a crash in native_handle_close if resource is nullptr
205 if (resource == nullptr) {
206 return BAD_VALUE;
207 }
208 sp<ISensorEventConnection> ch =
209 createSensorDirectConnection(opPackageName, size, type, format, resource);
210 native_handle_close(resource);
211 native_handle_delete(resource);
212 reply->writeStrongBinder(IInterface::asBinder(ch));
213 return NO_ERROR;
214 }
215 case SET_OPERATION_PARAMETER: {
216 CHECK_INTERFACE(ISensorServer, data, reply);
217 int32_t handle;
218 int32_t type;
219 Vector<float> floats;
220 Vector<int32_t> ints;
221 uint32_t count;
222
223 handle = data.readInt32();
224 type = data.readInt32();
225
226 count = data.readUint32();
227 if (count > (data.dataAvail() / sizeof(float))) {
228 return BAD_VALUE;
229 }
230 floats.resize(count);
231 for (auto &i : floats) {
232 i = data.readFloat();
233 }
234
235 count = data.readUint32();
236 if (count > (data.dataAvail() / sizeof(int32_t))) {
237 return BAD_VALUE;
238 }
239 ints.resize(count);
240 for (auto &i : ints) {
241 i = data.readInt32();
242 }
243
244 int32_t ret = setOperationParameter(handle, type, floats, ints);
245 reply->writeInt32(ret);
246 return NO_ERROR;
247 }
248 case SHELL_COMMAND_TRANSACTION: {
249 int in = data.readFileDescriptor();
250 int out = data.readFileDescriptor();
251 int err = data.readFileDescriptor();
252 int argc = data.readInt32();
253 Vector<String16> args;
254 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
255 args.add(data.readString16());
256 }
257 sp<IBinder> unusedCallback;
258 sp<IResultReceiver> resultReceiver;
259 status_t status;
260 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
261 return status;
262 }
263 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
264 return status;
265 }
266 status = shellCommand(in, out, err, args);
267 if (resultReceiver != nullptr) {
268 resultReceiver->send(status);
269 }
270 return NO_ERROR;
271 }
272 }
273 return BBinder::onTransact(code, data, reply, flags);
274 }
275
276 // ----------------------------------------------------------------------------
277 }; // namespace android
278