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
31#include <sensor/Sensor.h>
32#include <sensor/ISensorEventConnection.h>
33
34namespace android {
35// ----------------------------------------------------------------------------
36
37enum {
38    GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
39    CREATE_SENSOR_EVENT_CONNECTION,
40    ENABLE_DATA_INJECTION,
41    GET_DYNAMIC_SENSOR_LIST,
42    CREATE_SENSOR_DIRECT_CONNECTION,
43    SET_OPERATION_PARAMETER,
44};
45
46class BpSensorServer : public BpInterface<ISensorServer>
47{
48public:
49    explicit BpSensorServer(const sp<IBinder>& impl)
50        : BpInterface<ISensorServer>(impl)
51    {
52    }
53
54    virtual ~BpSensorServer();
55
56    virtual Vector<Sensor> getSensorList(const String16& opPackageName)
57    {
58        Parcel data, reply;
59        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
60        data.writeString16(opPackageName);
61        remote()->transact(GET_SENSOR_LIST, data, &reply);
62        Sensor s;
63        Vector<Sensor> v;
64        uint32_t n = reply.readUint32();
65        v.setCapacity(n);
66        while (n--) {
67            reply.read(s);
68            v.add(s);
69        }
70        return v;
71    }
72
73    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName)
74    {
75        Parcel data, reply;
76        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
77        data.writeString16(opPackageName);
78        remote()->transact(GET_DYNAMIC_SENSOR_LIST, data, &reply);
79        Sensor s;
80        Vector<Sensor> v;
81        uint32_t n = reply.readUint32();
82        v.setCapacity(n);
83        while (n--) {
84            reply.read(s);
85            v.add(s);
86        }
87        return v;
88    }
89
90    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
91             int mode, const String16& opPackageName)
92    {
93        Parcel data, reply;
94        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
95        data.writeString8(packageName);
96        data.writeInt32(mode);
97        data.writeString16(opPackageName);
98        remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
99        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
100    }
101
102    virtual int isDataInjectionEnabled() {
103        Parcel data, reply;
104        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
105        remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
106        return reply.readInt32();
107    }
108
109    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
110            uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) {
111        Parcel data, reply;
112        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
113        data.writeString16(opPackageName);
114        data.writeUint32(size);
115        data.writeInt32(type);
116        data.writeInt32(format);
117        data.writeNativeHandle(resource);
118        remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply);
119        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
120    }
121
122    virtual int setOperationParameter(
123            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
124        Parcel data, reply;
125        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
126        data.writeInt32(type);
127        data.writeUint32(static_cast<uint32_t>(floats.size()));
128        for (auto i : floats) {
129            data.writeFloat(i);
130        }
131        data.writeUint32(static_cast<uint32_t>(ints.size()));
132        for (auto i : ints) {
133            data.writeInt32(i);
134        }
135        remote()->transact(SET_OPERATION_PARAMETER, data, &reply);
136        return reply.readInt32();
137    }
138};
139
140// Out-of-line virtual method definition to trigger vtable emission in this
141// translation unit (see clang warning -Wweak-vtables)
142BpSensorServer::~BpSensorServer() {}
143
144IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
145
146// ----------------------------------------------------------------------
147
148status_t BnSensorServer::onTransact(
149    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
150{
151    switch(code) {
152        case GET_SENSOR_LIST: {
153            CHECK_INTERFACE(ISensorServer, data, reply);
154            const String16& opPackageName = data.readString16();
155            Vector<Sensor> v(getSensorList(opPackageName));
156            size_t n = v.size();
157            reply->writeUint32(static_cast<uint32_t>(n));
158            for (size_t i = 0; i < n; i++) {
159                reply->write(v[i]);
160            }
161            return NO_ERROR;
162        }
163        case CREATE_SENSOR_EVENT_CONNECTION: {
164            CHECK_INTERFACE(ISensorServer, data, reply);
165            String8 packageName = data.readString8();
166            int32_t mode = data.readInt32();
167            const String16& opPackageName = data.readString16();
168            sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode,
169                    opPackageName));
170            reply->writeStrongBinder(IInterface::asBinder(connection));
171            return NO_ERROR;
172        }
173        case ENABLE_DATA_INJECTION: {
174            CHECK_INTERFACE(ISensorServer, data, reply);
175            int32_t ret = isDataInjectionEnabled();
176            reply->writeInt32(static_cast<int32_t>(ret));
177            return NO_ERROR;
178        }
179        case GET_DYNAMIC_SENSOR_LIST: {
180            CHECK_INTERFACE(ISensorServer, data, reply);
181            const String16& opPackageName = data.readString16();
182            Vector<Sensor> v(getDynamicSensorList(opPackageName));
183            size_t n = v.size();
184            reply->writeUint32(static_cast<uint32_t>(n));
185            for (size_t i = 0; i < n; i++) {
186                reply->write(v[i]);
187            }
188            return NO_ERROR;
189        }
190        case CREATE_SENSOR_DIRECT_CONNECTION: {
191            CHECK_INTERFACE(ISensorServer, data, reply);
192            const String16& opPackageName = data.readString16();
193            uint32_t size = data.readUint32();
194            int32_t type = data.readInt32();
195            int32_t format = data.readInt32();
196            native_handle_t *resource = data.readNativeHandle();
197            sp<ISensorEventConnection> ch =
198                    createSensorDirectConnection(opPackageName, size, type, format, resource);
199            native_handle_close(resource);
200            native_handle_delete(resource);
201            reply->writeStrongBinder(IInterface::asBinder(ch));
202            return NO_ERROR;
203        }
204        case SET_OPERATION_PARAMETER: {
205            CHECK_INTERFACE(ISensorServer, data, reply);
206            int32_t type;
207            Vector<float> floats;
208            Vector<int32_t> ints;
209
210            type = data.readInt32();
211            floats.resize(data.readUint32());
212            for (auto &i : floats) {
213                i = data.readFloat();
214            }
215            ints.resize(data.readUint32());
216            for (auto &i : ints) {
217                i = data.readInt32();
218            }
219
220            int32_t ret = setOperationParameter(type, floats, ints);
221            reply->writeInt32(ret);
222            return NO_ERROR;
223        }
224    }
225    return BBinder::onTransact(code, data, reply, flags);
226}
227
228// ----------------------------------------------------------------------------
229}; // namespace android
230