blob: d70a69801dc486ac5196f53eb04d70f2531c7807 [file] [log] [blame]
keunyounge18e25d2015-08-28 15:57:19 -07001/*
2 * Copyright (C) 2015 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#define LOG_TAG "VehicleNetwork"
18
19#include <memory>
20
21#include <binder/IPCThreadState.h>
keunyounge18e25d2015-08-28 15:57:19 -070022
23#include <utils/Log.h>
24
25#include <IVehicleNetwork.h>
26#include <VehicleNetworkProto.pb.h>
27
keunyoung15882e52015-09-16 16:57:58 -070028#include "BinderUtil.h"
keunyounge18e25d2015-08-28 15:57:19 -070029#include "VehicleNetworkProtoUtil.h"
30
31namespace android {
32
33enum {
34 LIST_PROPERTIES = IBinder::FIRST_CALL_TRANSACTION,
35 SET_PROPERTY,
36 GET_PROPERTY,
37 SUBSCRIBE,
38 UNSUBSCRIBE,
keunyoung1ab8e182015-09-24 09:25:22 -070039 INJECT_EVENT,
40 START_MOCKING,
41 STOP_MOCKING,
Keun-young Park28dd4702015-11-19 18:06:04 -080042 INJECT_HAL_ERROR,
43 START_ERROR_LISTENING,
44 STOP_ERROR_LISTENING,
45 START_HAL_RESTART_MONITORING,
46 STOP_HAL_RESTART_MONITORING
keunyounge18e25d2015-08-28 15:57:19 -070047};
48
49// ----------------------------------------------------------------------------
50
keunyoung15882e52015-09-16 16:57:58 -070051const char IVehicleNetwork::SERVICE_NAME[] = "com.android.car.vehiclenetwork.IVehicleNetwork";
keunyounge18e25d2015-08-28 15:57:19 -070052
53// ----------------------------------------------------------------------------
54
55class BpVehicleNetwork : public BpInterface<IVehicleNetwork> {
56public:
57 BpVehicleNetwork(const sp<IBinder> & impl)
58 : BpInterface<IVehicleNetwork>(impl) {
59 }
60
61 virtual sp<VehiclePropertiesHolder> listProperties(int32_t property) {
62 sp<VehiclePropertiesHolder> holder;
63 Parcel data, reply;
64 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
65 data.writeInt32(property);
66 status_t status = remote()->transact(LIST_PROPERTIES, data, &reply);
67 if (status == NO_ERROR) {
keunyoung15882e52015-09-16 16:57:58 -070068 reply.readExceptionCode(); // for compatibility with java
keunyounge18e25d2015-08-28 15:57:19 -070069 if (reply.readInt32() == 0) { // no result
70 return holder;
71 }
72 ReadableBlobHolder blob(new Parcel::ReadableBlob());
73 if (blob.blob == NULL) {
74 ALOGE("listProperties, no memory");
75 return holder;
76 }
77 int32_t size = reply.readInt32();
78 status = reply.readBlob(size, blob.blob);
79 if (status != NO_ERROR) {
80 ALOGE("listProperties, cannot read blob %d", status);
81 return holder;
82 }
83 //TODO make this more memory efficient
84 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
85 if (configs.get() == NULL) {
86 return holder;
87 }
88 if(!configs->ParseFromArray(blob.blob->data(), size)) {
89 ALOGE("listProperties, cannot parse reply");
90 return holder;
91 }
keunyoungd32f4e62015-09-21 11:33:06 -070092 holder = new VehiclePropertiesHolder();
93 ASSERT_OR_HANDLE_NO_MEMORY(holder.get(), return);
94 status = VehicleNetworkProtoUtil::fromVehiclePropConfigs(*configs.get(),
95 holder->getList());
keunyounge18e25d2015-08-28 15:57:19 -070096 if (status != NO_ERROR) {
97 ALOGE("listProperties, cannot convert VehiclePropConfigs %d", status);
98 return holder;
99 }
keunyoungd32f4e62015-09-21 11:33:06 -0700100
keunyounge18e25d2015-08-28 15:57:19 -0700101 }
102 return holder;
103 }
104
105 virtual status_t setProperty(const vehicle_prop_value_t& value) {
106 Parcel data, reply;
107 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
keunyoung7d74e6d2015-10-14 15:43:10 -0700108 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, value);
109 if (status != NO_ERROR) {
110 return status;
111 }
112 status = remote()->transact(SET_PROPERTY, data, &reply);
keunyounge18e25d2015-08-28 15:57:19 -0700113 return status;
114 }
115
116 virtual status_t getProperty(vehicle_prop_value_t* value) {
117 Parcel data, reply;
keunyoung7d74e6d2015-10-14 15:43:10 -0700118 if (value == NULL) {
119 return BAD_VALUE;
120 }
keunyounge18e25d2015-08-28 15:57:19 -0700121 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
keunyoung7d74e6d2015-10-14 15:43:10 -0700122 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, *value);
123 if (status != NO_ERROR) {
124 ALOGE("getProperty, cannot write");
125 return status;
126 }
127 status = remote()->transact(GET_PROPERTY, data, &reply);
keunyounge18e25d2015-08-28 15:57:19 -0700128 if (status == NO_ERROR) {
keunyoung15882e52015-09-16 16:57:58 -0700129 reply.readExceptionCode(); // for compatibility with java
keunyoung7d74e6d2015-10-14 15:43:10 -0700130 status = VehiclePropValueBinderUtil::readFromParcel(reply, value);
keunyounge18e25d2015-08-28 15:57:19 -0700131 }
132 return status;
133 }
134
135 virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
Keun-young Park0727f952015-12-21 14:30:07 -0800136 float sampleRate, int32_t zones) {
keunyounge18e25d2015-08-28 15:57:19 -0700137 Parcel data, reply;
138 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
139 data.writeStrongBinder(IInterface::asBinder(listener));
140 data.writeInt32(property);
141 data.writeFloat(sampleRate);
Keun-young Park0727f952015-12-21 14:30:07 -0800142 data.writeInt32(zones);
keunyounge18e25d2015-08-28 15:57:19 -0700143 status_t status = remote()->transact(SUBSCRIBE, data, &reply);
144 return status;
145 }
146
147 virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property) {
148 Parcel data, reply;
149 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
150 data.writeStrongBinder(IInterface::asBinder(listener));
151 data.writeInt32(property);
152 status_t status = remote()->transact(UNSUBSCRIBE, data, &reply);
153 if (status != NO_ERROR) {
154 ALOGI("unsubscribing property %d failed %d", property, status);
155 }
156 }
keunyoung1ab8e182015-09-24 09:25:22 -0700157
158 virtual status_t injectEvent(const vehicle_prop_value_t& value) {
159 Parcel data, reply;
160 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
161 data.writeInt32(1); // 0 means no value. For compatibility with aidl based code.
162 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
163 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
164 VehicleNetworkProtoUtil::toVehiclePropValue(value, *v.get());
165 int size = v->ByteSize();
166 WritableBlobHolder blob(new Parcel::WritableBlob());
167 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
168 data.writeInt32(size);
169 data.writeBlob(size, false, blob.blob);
170 v->SerializeToArray(blob.blob->data(), size);
171 status_t status = remote()->transact(INJECT_EVENT, data, &reply);
172 return status;
173 }
174
175 virtual status_t startMocking(const sp<IVehicleNetworkHalMock>& mock) {
176 Parcel data, reply;
177 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
178 data.writeStrongBinder(IInterface::asBinder(mock));
179 status_t status = remote()->transact(START_MOCKING, data, &reply);
180 return status;
181 }
182
183 virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock) {
184 Parcel data, reply;
185 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
186 data.writeStrongBinder(IInterface::asBinder(mock));
187 status_t status = remote()->transact(STOP_MOCKING, data, &reply);
188 if (status != NO_ERROR) {
189 ALOGI("stop mocking failed %d", status);
190 }
191 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800192
193 status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation) {
194 Parcel data, reply;
195 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
196 data.writeInt32(errorCode);
197 data.writeInt32(property);
198 data.writeInt32(operation);
199 status_t status = remote()->transact(INJECT_HAL_ERROR, data, &reply);
200 return status;
201 }
202
203 virtual status_t startErrorListening(const sp<IVehicleNetworkListener> &listener) {
204 Parcel data, reply;
205 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
206 data.writeStrongBinder(IInterface::asBinder(listener));
207 status_t status = remote()->transact(START_ERROR_LISTENING, data, &reply);
208 return status;
209 }
210
211 virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener) {
212 Parcel data, reply;
213 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
214 data.writeStrongBinder(IInterface::asBinder(listener));
215 status_t status = remote()->transact(STOP_ERROR_LISTENING, data, &reply);
216 if (status != NO_ERROR) {
217 ALOGI("stopErrorListening %d", status);
218 }
219 }
220
221 virtual status_t startHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener) {
222 Parcel data, reply;
223 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
224 data.writeStrongBinder(IInterface::asBinder(listener));
225 status_t status = remote()->transact(START_HAL_RESTART_MONITORING, data, &reply);
226 return status;
227 }
228
229 virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener) {
230 Parcel data, reply;
231 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
232 data.writeStrongBinder(IInterface::asBinder(listener));
233 status_t status = remote()->transact(STOP_HAL_RESTART_MONITORING, data, &reply);
234 if (status != NO_ERROR) {
235 ALOGI("stopHalRestartMonitoring %d", status);
236 }
237 }
keunyounge18e25d2015-08-28 15:57:19 -0700238};
239
240IMPLEMENT_META_INTERFACE(VehicleNetwork, IVehicleNetwork::SERVICE_NAME);
241
242// ----------------------------------------------------------------------
243
keunyounge18e25d2015-08-28 15:57:19 -0700244status_t BnVehicleNetwork::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
245 uint32_t flags) {
keunyounge18e25d2015-08-28 15:57:19 -0700246 status_t r;
247 switch (code) {
248 case LIST_PROPERTIES: {
249 CHECK_INTERFACE(IVehicleNetwork, data, reply);
Keun-young Park737cdfb2016-02-12 15:11:39 -0800250 if (!isOperationAllowed(0, false)) {
251 return PERMISSION_DENIED;
252 }
keunyounge18e25d2015-08-28 15:57:19 -0700253 int32_t property = data.readInt32();
254 sp<VehiclePropertiesHolder> holder = listProperties(property);
255 if (holder.get() == NULL) { // given property not found
keunyoung15882e52015-09-16 16:57:58 -0700256 BinderUtil::fillObjectResultReply(reply, false /* isValid */);
257 return NO_ERROR;
keunyounge18e25d2015-08-28 15:57:19 -0700258 }
259 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
260 ASSERT_OR_HANDLE_NO_MEMORY(configs.get(), return NO_MEMORY);
keunyoungd32f4e62015-09-21 11:33:06 -0700261 VehicleNetworkProtoUtil::toVehiclePropConfigs(holder->getList(), *configs.get());
keunyounge18e25d2015-08-28 15:57:19 -0700262 int size = configs->ByteSize();
263 WritableBlobHolder blob(new Parcel::WritableBlob());
264 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
keunyoung15882e52015-09-16 16:57:58 -0700265 BinderUtil::fillObjectResultReply(reply, true);
keunyounge18e25d2015-08-28 15:57:19 -0700266 reply->writeInt32(size);
267 reply->writeBlob(size, false, blob.blob);
268 configs->SerializeToArray(blob.blob->data(), size);
269 return NO_ERROR;
270 } break;
271 case SET_PROPERTY: {
272 CHECK_INTERFACE(IVehicleNetwork, data, reply);
keunyounge18e25d2015-08-28 15:57:19 -0700273 ScopedVehiclePropValue value;
keunyoung7d74e6d2015-10-14 15:43:10 -0700274 r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value,
275 false /* deleteMembers */);
keunyounge18e25d2015-08-28 15:57:19 -0700276 if (r != NO_ERROR) {
keunyounge18e25d2015-08-28 15:57:19 -0700277 return r;
278 }
Keun-young Park737cdfb2016-02-12 15:11:39 -0800279 if (!isOperationAllowed(value.value.prop, true)) {
280 return PERMISSION_DENIED;
281 }
keunyounge18e25d2015-08-28 15:57:19 -0700282 r = setProperty(value.value);
keunyoung15882e52015-09-16 16:57:58 -0700283 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700284 return r;
285 } break;
286 case GET_PROPERTY: {
287 CHECK_INTERFACE(IVehicleNetwork, data, reply);
288 ScopedVehiclePropValue value;
keunyoung7d74e6d2015-10-14 15:43:10 -0700289 r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value,
290 false /* deleteMembers */, true /*canIgnoreNoData*/);
291 if (r != NO_ERROR) {
292 ALOGE("getProperty cannot read %d", r);
293 return r;
294 }
Keun-young Park737cdfb2016-02-12 15:11:39 -0800295 if (!isOperationAllowed(value.value.prop, false)) {
296 return PERMISSION_DENIED;
297 }
keunyounge18e25d2015-08-28 15:57:19 -0700298 r = getProperty(&(value.value));
299 if (r == NO_ERROR) {
keunyoung7d74e6d2015-10-14 15:43:10 -0700300 reply->writeNoException();
301 r = VehiclePropValueBinderUtil::writeToParcel(*reply, value.value);
keunyounge18e25d2015-08-28 15:57:19 -0700302 }
303 return r;
304 } break;
305 case SUBSCRIBE: {
306 CHECK_INTERFACE(IVehicleNetwork, data, reply);
307 sp<IVehicleNetworkListener> listener =
308 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
309 int32_t property = data.readInt32();
Keun-young Park737cdfb2016-02-12 15:11:39 -0800310 if (!isOperationAllowed(property, false)) {
311 return PERMISSION_DENIED;
312 }
keunyounge18e25d2015-08-28 15:57:19 -0700313 float sampleRate = data.readFloat();
Keun-young Park0727f952015-12-21 14:30:07 -0800314 int32_t zones = data.readInt32();
315 r = subscribe(listener, property, sampleRate, zones);
keunyoung15882e52015-09-16 16:57:58 -0700316 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700317 return r;
318 } break;
319 case UNSUBSCRIBE: {
320 CHECK_INTERFACE(IVehicleNetwork, data, reply);
321 sp<IVehicleNetworkListener> listener =
322 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
323 int32_t property = data.readInt32();
Keun-young Park737cdfb2016-02-12 15:11:39 -0800324 if (!isOperationAllowed(property, false)) {
325 return PERMISSION_DENIED;
326 }
keunyounge18e25d2015-08-28 15:57:19 -0700327 unsubscribe(listener, property);
keunyoung15882e52015-09-16 16:57:58 -0700328 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700329 return NO_ERROR;
330 } break;
keunyoung1ab8e182015-09-24 09:25:22 -0700331 case INJECT_EVENT: {
332 CHECK_INTERFACE(IVehicleNetwork, data, reply);
333 if (data.readInt32() == 0) { // java side allows passing null with this.
334 return BAD_VALUE;
335 }
Keun-young Park737cdfb2016-02-12 15:11:39 -0800336 if (!isOperationAllowed(0, true)) {
337 return PERMISSION_DENIED;
338 }
keunyoung1ab8e182015-09-24 09:25:22 -0700339 ScopedVehiclePropValue value;
340 ReadableBlobHolder blob(new Parcel::ReadableBlob());
341 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
342 int32_t size = data.readInt32();
343 r = data.readBlob(size, blob.blob);
344 if (r != NO_ERROR) {
345 ALOGE("injectEvent:service, cannot read blob");
346 return r;
347 }
348 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
349 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
350 if (!v->ParseFromArray(blob.blob->data(), size)) {
351 ALOGE("injectEvent:service, cannot parse data");
352 return BAD_VALUE;
353 }
354 r = VehicleNetworkProtoUtil::fromVehiclePropValue(*v.get(), value.value);
355 if (r != NO_ERROR) {
356 ALOGE("injectEvent:service, cannot convert data");
357 return BAD_VALUE;
358 }
359 r = injectEvent(value.value);
360 BinderUtil::fillNoResultReply(reply);
361 return r;
362 } break;
363 case START_MOCKING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800364 if (!isOperationAllowed(0, true)) {
365 return PERMISSION_DENIED;
366 }
keunyoung1ab8e182015-09-24 09:25:22 -0700367 CHECK_INTERFACE(IVehicleNetwork, data, reply);
368 sp<IVehicleNetworkHalMock> mock =
369 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder());
370 r = startMocking(mock);
371 BinderUtil::fillNoResultReply(reply);
372 return r;
373 } break;
374 case STOP_MOCKING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800375 if (!isOperationAllowed(0, true)) {
376 return PERMISSION_DENIED;
377 }
keunyoung1ab8e182015-09-24 09:25:22 -0700378 CHECK_INTERFACE(IVehicleNetwork, data, reply);
379 sp<IVehicleNetworkHalMock> mock =
380 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder());
381 stopMocking(mock);
382 BinderUtil::fillNoResultReply(reply);
383 return NO_ERROR;
384 } break;
Keun-young Park28dd4702015-11-19 18:06:04 -0800385 case INJECT_HAL_ERROR: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800386 if (!isOperationAllowed(0, true)) {
387 return PERMISSION_DENIED;
388 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800389 CHECK_INTERFACE(IVehicleNetwork, data, reply);
390 int32_t errorCode = data.readInt32();
391 int32_t property = data.readInt32();
392 int32_t operation = data.readInt32();
393 r = injectHalError(errorCode, property, operation);
394 BinderUtil::fillNoResultReply(reply);
395 return r;
396 } break;
397 case START_ERROR_LISTENING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800398 if (!isOperationAllowed(0, false)) {
399 return PERMISSION_DENIED;
400 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800401 CHECK_INTERFACE(IVehicleNetwork, data, reply);
402 sp<IVehicleNetworkListener> listener =
403 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
404 r = startErrorListening(listener);
405 BinderUtil::fillNoResultReply(reply);
406 return r;
407 } break;
408 case STOP_ERROR_LISTENING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800409 if (!isOperationAllowed(0, false)) {
410 return PERMISSION_DENIED;
411 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800412 CHECK_INTERFACE(IVehicleNetwork, data, reply);
413 sp<IVehicleNetworkListener> listener =
414 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
415 stopErrorListening(listener);
416 BinderUtil::fillNoResultReply(reply);
417 return NO_ERROR;
418 } break;
419 case START_HAL_RESTART_MONITORING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800420 if (!isOperationAllowed(0, false)) {
421 return PERMISSION_DENIED;
422 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800423 CHECK_INTERFACE(IVehicleNetwork, data, reply);
424 sp<IVehicleNetworkListener> listener =
425 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
426 r = startHalRestartMonitoring(listener);
427 BinderUtil::fillNoResultReply(reply);
428 return r;
429 } break;
430 case STOP_HAL_RESTART_MONITORING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800431 if (!isOperationAllowed(0, false)) {
432 return PERMISSION_DENIED;
433 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800434 CHECK_INTERFACE(IVehicleNetwork, data, reply);
435 sp<IVehicleNetworkListener> listener =
436 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
437 stopHalRestartMonitoring(listener);
438 BinderUtil::fillNoResultReply(reply);
439 return NO_ERROR;
440 } break;
keunyounge18e25d2015-08-28 15:57:19 -0700441 default:
442 return BBinder::onTransact(code, data, reply, flags);
443 }
444}
445
446}; // namespace android