blob: c0b211903f07271b4fe8a054e365629c073504aa [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>
Keun-young Park71b2f5c2016-03-10 18:44:40 -080020#include <string.h>
keunyounge18e25d2015-08-28 15:57:19 -070021
22#include <binder/IPCThreadState.h>
Keun-young Parkba485482016-03-24 13:24:31 -070023#include <binder/Status.h>
keunyounge18e25d2015-08-28 15:57:19 -070024
25#include <utils/Log.h>
26
27#include <IVehicleNetwork.h>
28#include <VehicleNetworkProto.pb.h>
29
keunyoung15882e52015-09-16 16:57:58 -070030#include "BinderUtil.h"
keunyounge18e25d2015-08-28 15:57:19 -070031#include "VehicleNetworkProtoUtil.h"
32
33namespace android {
34
35enum {
36 LIST_PROPERTIES = IBinder::FIRST_CALL_TRANSACTION,
37 SET_PROPERTY,
38 GET_PROPERTY,
39 SUBSCRIBE,
40 UNSUBSCRIBE,
keunyoung1ab8e182015-09-24 09:25:22 -070041 INJECT_EVENT,
42 START_MOCKING,
43 STOP_MOCKING,
Keun-young Park28dd4702015-11-19 18:06:04 -080044 INJECT_HAL_ERROR,
45 START_ERROR_LISTENING,
46 STOP_ERROR_LISTENING,
47 START_HAL_RESTART_MONITORING,
48 STOP_HAL_RESTART_MONITORING
keunyounge18e25d2015-08-28 15:57:19 -070049};
50
51// ----------------------------------------------------------------------------
52
keunyoung15882e52015-09-16 16:57:58 -070053const char IVehicleNetwork::SERVICE_NAME[] = "com.android.car.vehiclenetwork.IVehicleNetwork";
keunyounge18e25d2015-08-28 15:57:19 -070054
55// ----------------------------------------------------------------------------
56
57class BpVehicleNetwork : public BpInterface<IVehicleNetwork> {
58public:
59 BpVehicleNetwork(const sp<IBinder> & impl)
60 : BpInterface<IVehicleNetwork>(impl) {
61 }
62
63 virtual sp<VehiclePropertiesHolder> listProperties(int32_t property) {
64 sp<VehiclePropertiesHolder> holder;
65 Parcel data, reply;
66 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
67 data.writeInt32(property);
68 status_t status = remote()->transact(LIST_PROPERTIES, data, &reply);
69 if (status == NO_ERROR) {
keunyoung15882e52015-09-16 16:57:58 -070070 reply.readExceptionCode(); // for compatibility with java
keunyounge18e25d2015-08-28 15:57:19 -070071 if (reply.readInt32() == 0) { // no result
72 return holder;
73 }
74 ReadableBlobHolder blob(new Parcel::ReadableBlob());
75 if (blob.blob == NULL) {
76 ALOGE("listProperties, no memory");
77 return holder;
78 }
79 int32_t size = reply.readInt32();
80 status = reply.readBlob(size, blob.blob);
81 if (status != NO_ERROR) {
82 ALOGE("listProperties, cannot read blob %d", status);
83 return holder;
84 }
85 //TODO make this more memory efficient
86 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
87 if (configs.get() == NULL) {
88 return holder;
89 }
90 if(!configs->ParseFromArray(blob.blob->data(), size)) {
91 ALOGE("listProperties, cannot parse reply");
92 return holder;
93 }
keunyoungd32f4e62015-09-21 11:33:06 -070094 holder = new VehiclePropertiesHolder();
95 ASSERT_OR_HANDLE_NO_MEMORY(holder.get(), return);
96 status = VehicleNetworkProtoUtil::fromVehiclePropConfigs(*configs.get(),
97 holder->getList());
keunyounge18e25d2015-08-28 15:57:19 -070098 if (status != NO_ERROR) {
99 ALOGE("listProperties, cannot convert VehiclePropConfigs %d", status);
100 return holder;
101 }
keunyoungd32f4e62015-09-21 11:33:06 -0700102
keunyounge18e25d2015-08-28 15:57:19 -0700103 }
104 return holder;
105 }
106
107 virtual status_t setProperty(const vehicle_prop_value_t& value) {
108 Parcel data, reply;
109 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
keunyoung7d74e6d2015-10-14 15:43:10 -0700110 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, value);
111 if (status != NO_ERROR) {
112 return status;
113 }
114 status = remote()->transact(SET_PROPERTY, data, &reply);
keunyounge18e25d2015-08-28 15:57:19 -0700115 return status;
116 }
117
118 virtual status_t getProperty(vehicle_prop_value_t* value) {
119 Parcel data, reply;
keunyoung7d74e6d2015-10-14 15:43:10 -0700120 if (value == NULL) {
121 return BAD_VALUE;
122 }
keunyounge18e25d2015-08-28 15:57:19 -0700123 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
keunyoung7d74e6d2015-10-14 15:43:10 -0700124 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, *value);
125 if (status != NO_ERROR) {
126 ALOGE("getProperty, cannot write");
127 return status;
128 }
129 status = remote()->transact(GET_PROPERTY, data, &reply);
keunyounge18e25d2015-08-28 15:57:19 -0700130 if (status == NO_ERROR) {
Keun-young Parkba485482016-03-24 13:24:31 -0700131 int32_t exceptionCode = reply.readExceptionCode();
132 if (exceptionCode != NO_ERROR) {
133 if (exceptionCode == binder::Status::EX_SERVICE_SPECIFIC) {
134 return -EAGAIN;
135 }
136 return exceptionCode;
137 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700138 status = VehiclePropValueBinderUtil::readFromParcel(reply, value);
keunyounge18e25d2015-08-28 15:57:19 -0700139 }
140 return status;
141 }
142
143 virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
Keun-young Park0727f952015-12-21 14:30:07 -0800144 float sampleRate, int32_t zones) {
keunyounge18e25d2015-08-28 15:57:19 -0700145 Parcel data, reply;
146 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
147 data.writeStrongBinder(IInterface::asBinder(listener));
148 data.writeInt32(property);
149 data.writeFloat(sampleRate);
Keun-young Park0727f952015-12-21 14:30:07 -0800150 data.writeInt32(zones);
keunyounge18e25d2015-08-28 15:57:19 -0700151 status_t status = remote()->transact(SUBSCRIBE, data, &reply);
152 return status;
153 }
154
155 virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property) {
156 Parcel data, reply;
157 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
158 data.writeStrongBinder(IInterface::asBinder(listener));
159 data.writeInt32(property);
160 status_t status = remote()->transact(UNSUBSCRIBE, data, &reply);
161 if (status != NO_ERROR) {
162 ALOGI("unsubscribing property %d failed %d", property, status);
163 }
164 }
keunyoung1ab8e182015-09-24 09:25:22 -0700165
166 virtual status_t injectEvent(const vehicle_prop_value_t& value) {
167 Parcel data, reply;
168 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
169 data.writeInt32(1); // 0 means no value. For compatibility with aidl based code.
170 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
171 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
172 VehicleNetworkProtoUtil::toVehiclePropValue(value, *v.get());
173 int size = v->ByteSize();
174 WritableBlobHolder blob(new Parcel::WritableBlob());
175 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
176 data.writeInt32(size);
177 data.writeBlob(size, false, blob.blob);
178 v->SerializeToArray(blob.blob->data(), size);
179 status_t status = remote()->transact(INJECT_EVENT, data, &reply);
180 return status;
181 }
182
183 virtual status_t startMocking(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(START_MOCKING, data, &reply);
188 return status;
189 }
190
191 virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock) {
192 Parcel data, reply;
193 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
194 data.writeStrongBinder(IInterface::asBinder(mock));
195 status_t status = remote()->transact(STOP_MOCKING, data, &reply);
196 if (status != NO_ERROR) {
197 ALOGI("stop mocking failed %d", status);
198 }
199 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800200
201 status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation) {
202 Parcel data, reply;
203 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
204 data.writeInt32(errorCode);
205 data.writeInt32(property);
206 data.writeInt32(operation);
207 status_t status = remote()->transact(INJECT_HAL_ERROR, data, &reply);
208 return status;
209 }
210
211 virtual status_t startErrorListening(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(START_ERROR_LISTENING, data, &reply);
216 return status;
217 }
218
219 virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener) {
220 Parcel data, reply;
221 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
222 data.writeStrongBinder(IInterface::asBinder(listener));
223 status_t status = remote()->transact(STOP_ERROR_LISTENING, data, &reply);
224 if (status != NO_ERROR) {
225 ALOGI("stopErrorListening %d", status);
226 }
227 }
228
229 virtual status_t startHalRestartMonitoring(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(START_HAL_RESTART_MONITORING, data, &reply);
234 return status;
235 }
236
237 virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener) {
238 Parcel data, reply;
239 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
240 data.writeStrongBinder(IInterface::asBinder(listener));
241 status_t status = remote()->transact(STOP_HAL_RESTART_MONITORING, data, &reply);
242 if (status != NO_ERROR) {
243 ALOGI("stopHalRestartMonitoring %d", status);
244 }
245 }
keunyounge18e25d2015-08-28 15:57:19 -0700246};
247
248IMPLEMENT_META_INTERFACE(VehicleNetwork, IVehicleNetwork::SERVICE_NAME);
249
250// ----------------------------------------------------------------------
251
keunyounge18e25d2015-08-28 15:57:19 -0700252status_t BnVehicleNetwork::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
253 uint32_t flags) {
keunyounge18e25d2015-08-28 15:57:19 -0700254 status_t r;
255 switch (code) {
256 case LIST_PROPERTIES: {
257 CHECK_INTERFACE(IVehicleNetwork, data, reply);
Keun-young Park737cdfb2016-02-12 15:11:39 -0800258 if (!isOperationAllowed(0, false)) {
259 return PERMISSION_DENIED;
260 }
keunyounge18e25d2015-08-28 15:57:19 -0700261 int32_t property = data.readInt32();
262 sp<VehiclePropertiesHolder> holder = listProperties(property);
263 if (holder.get() == NULL) { // given property not found
keunyoung15882e52015-09-16 16:57:58 -0700264 BinderUtil::fillObjectResultReply(reply, false /* isValid */);
265 return NO_ERROR;
keunyounge18e25d2015-08-28 15:57:19 -0700266 }
267 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
268 ASSERT_OR_HANDLE_NO_MEMORY(configs.get(), return NO_MEMORY);
keunyoungd32f4e62015-09-21 11:33:06 -0700269 VehicleNetworkProtoUtil::toVehiclePropConfigs(holder->getList(), *configs.get());
keunyounge18e25d2015-08-28 15:57:19 -0700270 int size = configs->ByteSize();
271 WritableBlobHolder blob(new Parcel::WritableBlob());
272 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
keunyoung15882e52015-09-16 16:57:58 -0700273 BinderUtil::fillObjectResultReply(reply, true);
keunyounge18e25d2015-08-28 15:57:19 -0700274 reply->writeInt32(size);
275 reply->writeBlob(size, false, blob.blob);
276 configs->SerializeToArray(blob.blob->data(), size);
277 return NO_ERROR;
278 } break;
279 case SET_PROPERTY: {
280 CHECK_INTERFACE(IVehicleNetwork, data, reply);
keunyounge18e25d2015-08-28 15:57:19 -0700281 ScopedVehiclePropValue value;
keunyoung7d74e6d2015-10-14 15:43:10 -0700282 r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value,
283 false /* deleteMembers */);
keunyounge18e25d2015-08-28 15:57:19 -0700284 if (r != NO_ERROR) {
keunyounge18e25d2015-08-28 15:57:19 -0700285 return r;
286 }
Keun-young Park737cdfb2016-02-12 15:11:39 -0800287 if (!isOperationAllowed(value.value.prop, true)) {
288 return PERMISSION_DENIED;
289 }
keunyounge18e25d2015-08-28 15:57:19 -0700290 r = setProperty(value.value);
keunyoung15882e52015-09-16 16:57:58 -0700291 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700292 return r;
293 } break;
294 case GET_PROPERTY: {
295 CHECK_INTERFACE(IVehicleNetwork, data, reply);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800296 vehicle_prop_value_t value;
297 memset(&value, 0, sizeof(value));
298 r = VehiclePropValueBinderUtil::readFromParcel(data, &value,
keunyoung7d74e6d2015-10-14 15:43:10 -0700299 false /* deleteMembers */, true /*canIgnoreNoData*/);
300 if (r != NO_ERROR) {
301 ALOGE("getProperty cannot read %d", r);
302 return r;
303 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800304 if (!isOperationAllowed(value.prop, false)) {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800305 return PERMISSION_DENIED;
306 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800307 r = getProperty(&value);
keunyounge18e25d2015-08-28 15:57:19 -0700308 if (r == NO_ERROR) {
keunyoung7d74e6d2015-10-14 15:43:10 -0700309 reply->writeNoException();
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800310 r = VehiclePropValueBinderUtil::writeToParcel(*reply, value);
311 releaseMemoryFromGet(&value);
Keun-young Parkba485482016-03-24 13:24:31 -0700312 } else if (r == -EAGAIN) {
313 // this should be handled specially to throw ServiceSpecificException in java.
314 reply->writeInt32(binder::Status::EX_SERVICE_SPECIFIC);
315 return NO_ERROR;
keunyounge18e25d2015-08-28 15:57:19 -0700316 }
317 return r;
318 } break;
319 case SUBSCRIBE: {
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 float sampleRate = data.readFloat();
Keun-young Park0727f952015-12-21 14:30:07 -0800328 int32_t zones = data.readInt32();
329 r = subscribe(listener, property, sampleRate, zones);
keunyoung15882e52015-09-16 16:57:58 -0700330 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700331 return r;
332 } break;
333 case UNSUBSCRIBE: {
334 CHECK_INTERFACE(IVehicleNetwork, data, reply);
335 sp<IVehicleNetworkListener> listener =
336 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
337 int32_t property = data.readInt32();
Keun-young Park737cdfb2016-02-12 15:11:39 -0800338 if (!isOperationAllowed(property, false)) {
339 return PERMISSION_DENIED;
340 }
keunyounge18e25d2015-08-28 15:57:19 -0700341 unsubscribe(listener, property);
keunyoung15882e52015-09-16 16:57:58 -0700342 BinderUtil::fillNoResultReply(reply);
keunyounge18e25d2015-08-28 15:57:19 -0700343 return NO_ERROR;
344 } break;
keunyoung1ab8e182015-09-24 09:25:22 -0700345 case INJECT_EVENT: {
346 CHECK_INTERFACE(IVehicleNetwork, data, reply);
347 if (data.readInt32() == 0) { // java side allows passing null with this.
348 return BAD_VALUE;
349 }
Keun-young Park737cdfb2016-02-12 15:11:39 -0800350 if (!isOperationAllowed(0, true)) {
351 return PERMISSION_DENIED;
352 }
keunyoung1ab8e182015-09-24 09:25:22 -0700353 ScopedVehiclePropValue value;
354 ReadableBlobHolder blob(new Parcel::ReadableBlob());
355 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
356 int32_t size = data.readInt32();
357 r = data.readBlob(size, blob.blob);
358 if (r != NO_ERROR) {
359 ALOGE("injectEvent:service, cannot read blob");
360 return r;
361 }
362 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
363 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
364 if (!v->ParseFromArray(blob.blob->data(), size)) {
365 ALOGE("injectEvent:service, cannot parse data");
366 return BAD_VALUE;
367 }
368 r = VehicleNetworkProtoUtil::fromVehiclePropValue(*v.get(), value.value);
369 if (r != NO_ERROR) {
370 ALOGE("injectEvent:service, cannot convert data");
371 return BAD_VALUE;
372 }
373 r = injectEvent(value.value);
374 BinderUtil::fillNoResultReply(reply);
375 return r;
376 } break;
377 case START_MOCKING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800378 if (!isOperationAllowed(0, true)) {
379 return PERMISSION_DENIED;
380 }
keunyoung1ab8e182015-09-24 09:25:22 -0700381 CHECK_INTERFACE(IVehicleNetwork, data, reply);
382 sp<IVehicleNetworkHalMock> mock =
383 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder());
384 r = startMocking(mock);
385 BinderUtil::fillNoResultReply(reply);
386 return r;
387 } break;
388 case STOP_MOCKING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800389 if (!isOperationAllowed(0, true)) {
390 return PERMISSION_DENIED;
391 }
keunyoung1ab8e182015-09-24 09:25:22 -0700392 CHECK_INTERFACE(IVehicleNetwork, data, reply);
393 sp<IVehicleNetworkHalMock> mock =
394 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder());
395 stopMocking(mock);
396 BinderUtil::fillNoResultReply(reply);
397 return NO_ERROR;
398 } break;
Keun-young Park28dd4702015-11-19 18:06:04 -0800399 case INJECT_HAL_ERROR: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800400 if (!isOperationAllowed(0, true)) {
401 return PERMISSION_DENIED;
402 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800403 CHECK_INTERFACE(IVehicleNetwork, data, reply);
404 int32_t errorCode = data.readInt32();
405 int32_t property = data.readInt32();
406 int32_t operation = data.readInt32();
407 r = injectHalError(errorCode, property, operation);
408 BinderUtil::fillNoResultReply(reply);
409 return r;
410 } break;
411 case START_ERROR_LISTENING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800412 if (!isOperationAllowed(0, false)) {
413 return PERMISSION_DENIED;
414 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800415 CHECK_INTERFACE(IVehicleNetwork, data, reply);
416 sp<IVehicleNetworkListener> listener =
417 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
418 r = startErrorListening(listener);
419 BinderUtil::fillNoResultReply(reply);
420 return r;
421 } break;
422 case STOP_ERROR_LISTENING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800423 if (!isOperationAllowed(0, false)) {
424 return PERMISSION_DENIED;
425 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800426 CHECK_INTERFACE(IVehicleNetwork, data, reply);
427 sp<IVehicleNetworkListener> listener =
428 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
429 stopErrorListening(listener);
430 BinderUtil::fillNoResultReply(reply);
431 return NO_ERROR;
432 } break;
433 case START_HAL_RESTART_MONITORING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800434 if (!isOperationAllowed(0, false)) {
435 return PERMISSION_DENIED;
436 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800437 CHECK_INTERFACE(IVehicleNetwork, data, reply);
438 sp<IVehicleNetworkListener> listener =
439 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
440 r = startHalRestartMonitoring(listener);
441 BinderUtil::fillNoResultReply(reply);
442 return r;
443 } break;
444 case STOP_HAL_RESTART_MONITORING: {
Keun-young Park737cdfb2016-02-12 15:11:39 -0800445 if (!isOperationAllowed(0, false)) {
446 return PERMISSION_DENIED;
447 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800448 CHECK_INTERFACE(IVehicleNetwork, data, reply);
449 sp<IVehicleNetworkListener> listener =
450 interface_cast<IVehicleNetworkListener>(data.readStrongBinder());
451 stopHalRestartMonitoring(listener);
452 BinderUtil::fillNoResultReply(reply);
453 return NO_ERROR;
454 } break;
keunyounge18e25d2015-08-28 15:57:19 -0700455 default:
456 return BBinder::onTransact(code, data, reply, flags);
457 }
458}
459
460}; // namespace android