• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #include <string.h>
21 
22 #include <binder/IPCThreadState.h>
23 #include <binder/Status.h>
24 
25 #include <utils/Log.h>
26 
27 #include <IVehicleNetwork.h>
28 #include <VehicleNetworkProto.pb.h>
29 
30 #include "BinderUtil.h"
31 #include "VehicleNetworkProtoUtil.h"
32 
33 namespace android {
34 
35 enum {
36     LIST_PROPERTIES = IBinder::FIRST_CALL_TRANSACTION,
37     SET_PROPERTY,
38     GET_PROPERTY,
39     SUBSCRIBE,
40     UNSUBSCRIBE,
41     INJECT_EVENT,
42     START_MOCKING,
43     STOP_MOCKING,
44     INJECT_HAL_ERROR,
45     START_ERROR_LISTENING,
46     STOP_ERROR_LISTENING,
47     START_HAL_RESTART_MONITORING,
48     STOP_HAL_RESTART_MONITORING
49 };
50 
51 // ----------------------------------------------------------------------------
52 
53 const char IVehicleNetwork::SERVICE_NAME[] = "com.android.car.vehiclenetwork.IVehicleNetwork";
54 
55 // ----------------------------------------------------------------------------
56 
57 class BpVehicleNetwork : public BpInterface<IVehicleNetwork> {
58 public:
BpVehicleNetwork(const sp<IBinder> & impl)59     BpVehicleNetwork(const sp<IBinder> & impl)
60         : BpInterface<IVehicleNetwork>(impl) {
61     }
62 
listProperties(int32_t property)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) {
70             reply.readExceptionCode(); // for compatibility with java
71             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             }
94             holder = new VehiclePropertiesHolder();
95             ASSERT_OR_HANDLE_NO_MEMORY(holder.get(), return);
96             status = VehicleNetworkProtoUtil::fromVehiclePropConfigs(*configs.get(),
97                     holder->getList());
98             if (status != NO_ERROR) {
99                 ALOGE("listProperties, cannot convert VehiclePropConfigs %d", status);
100                 return holder;
101             }
102 
103         }
104         return holder;
105     }
106 
setProperty(const vehicle_prop_value_t & value)107     virtual status_t setProperty(const vehicle_prop_value_t& value) {
108         Parcel data, reply;
109         data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
110         status_t status = VehiclePropValueBinderUtil::writeToParcel(data, value);
111         if (status != NO_ERROR) {
112             return status;
113         }
114         status = remote()->transact(SET_PROPERTY, data, &reply);
115         return status;
116     }
117 
getProperty(vehicle_prop_value_t * value)118     virtual status_t getProperty(vehicle_prop_value_t* value) {
119         Parcel data, reply;
120         if (value == NULL) {
121             return BAD_VALUE;
122         }
123         data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
124         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);
130         if (status == NO_ERROR) {
131             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             }
138             status = VehiclePropValueBinderUtil::readFromParcel(reply, value);
139         }
140         return status;
141     }
142 
subscribe(const sp<IVehicleNetworkListener> & listener,int32_t property,float sampleRate,int32_t zones)143     virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
144                 float sampleRate, int32_t zones) {
145         Parcel data, reply;
146         data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor());
147         data.writeStrongBinder(IInterface::asBinder(listener));
148         data.writeInt32(property);
149         data.writeFloat(sampleRate);
150         data.writeInt32(zones);
151         status_t status = remote()->transact(SUBSCRIBE, data, &reply);
152         return status;
153     }
154 
unsubscribe(const sp<IVehicleNetworkListener> & listener,int32_t property)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     }
165 
injectEvent(const vehicle_prop_value_t & value)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 
startMocking(const sp<IVehicleNetworkHalMock> & mock)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 
stopMocking(const sp<IVehicleNetworkHalMock> & mock)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     }
200 
injectHalError(int32_t errorCode,int32_t property,int32_t operation)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 
startErrorListening(const sp<IVehicleNetworkListener> & listener)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 
stopErrorListening(const sp<IVehicleNetworkListener> & listener)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 
startHalRestartMonitoring(const sp<IVehicleNetworkListener> & listener)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 
stopHalRestartMonitoring(const sp<IVehicleNetworkListener> & listener)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     }
246 };
247 
248 IMPLEMENT_META_INTERFACE(VehicleNetwork, IVehicleNetwork::SERVICE_NAME);
249 
250 // ----------------------------------------------------------------------
251 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)252 status_t BnVehicleNetwork::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
253         uint32_t flags) {
254     status_t r;
255     switch (code) {
256         case LIST_PROPERTIES: {
257             CHECK_INTERFACE(IVehicleNetwork, data, reply);
258             if (!isOperationAllowed(0, false)) {
259                 return PERMISSION_DENIED;
260             }
261             int32_t property = data.readInt32();
262             sp<VehiclePropertiesHolder> holder = listProperties(property);
263             if (holder.get() == NULL) { // given property not found
264                 BinderUtil::fillObjectResultReply(reply, false /* isValid */);
265                 return NO_ERROR;
266             }
267             std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
268             ASSERT_OR_HANDLE_NO_MEMORY(configs.get(), return NO_MEMORY);
269             VehicleNetworkProtoUtil::toVehiclePropConfigs(holder->getList(), *configs.get());
270             int size = configs->ByteSize();
271             WritableBlobHolder blob(new Parcel::WritableBlob());
272             ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
273             BinderUtil::fillObjectResultReply(reply, true);
274             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);
281             ScopedVehiclePropValue value;
282             r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value,
283                     false /* deleteMembers */);
284             if (r != NO_ERROR) {
285                 return r;
286             }
287             if (!isOperationAllowed(value.value.prop, true)) {
288                 return PERMISSION_DENIED;
289             }
290             r = setProperty(value.value);
291             BinderUtil::fillNoResultReply(reply);
292             return r;
293         } break;
294         case GET_PROPERTY: {
295             CHECK_INTERFACE(IVehicleNetwork, data, reply);
296             vehicle_prop_value_t value;
297             memset(&value, 0, sizeof(value));
298             r = VehiclePropValueBinderUtil::readFromParcel(data, &value,
299                     false /* deleteMembers */, true /*canIgnoreNoData*/);
300             if (r != NO_ERROR) {
301                 ALOGE("getProperty cannot read %d", r);
302                 return r;
303             }
304             if (!isOperationAllowed(value.prop, false)) {
305                 return PERMISSION_DENIED;
306             }
307             r = getProperty(&value);
308             if (r == NO_ERROR) {
309                 reply->writeNoException();
310                 r = VehiclePropValueBinderUtil::writeToParcel(*reply, value);
311                 releaseMemoryFromGet(&value);
312             } 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;
316             }
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();
324             if (!isOperationAllowed(property, false)) {
325                 return PERMISSION_DENIED;
326             }
327             float sampleRate = data.readFloat();
328             int32_t zones = data.readInt32();
329             r = subscribe(listener, property, sampleRate, zones);
330             BinderUtil::fillNoResultReply(reply);
331             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();
338             if (!isOperationAllowed(property, false)) {
339                 return PERMISSION_DENIED;
340             }
341             unsubscribe(listener, property);
342             BinderUtil::fillNoResultReply(reply);
343             return NO_ERROR;
344         } break;
345         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             }
350             if (!isOperationAllowed(0, true)) {
351                 return PERMISSION_DENIED;
352             }
353             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: {
378             if (!isOperationAllowed(0, true)) {
379                 return PERMISSION_DENIED;
380             }
381             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: {
389             if (!isOperationAllowed(0, true)) {
390                 return PERMISSION_DENIED;
391             }
392             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;
399         case INJECT_HAL_ERROR: {
400             if (!isOperationAllowed(0, true)) {
401                 return PERMISSION_DENIED;
402             }
403             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: {
412             if (!isOperationAllowed(0, false)) {
413                 return PERMISSION_DENIED;
414             }
415             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: {
423             if (!isOperationAllowed(0, false)) {
424                 return PERMISSION_DENIED;
425             }
426             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: {
434             if (!isOperationAllowed(0, false)) {
435                 return PERMISSION_DENIED;
436             }
437             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: {
445             if (!isOperationAllowed(0, false)) {
446                 return PERMISSION_DENIED;
447             }
448             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;
455         default:
456             return BBinder::onTransact(code, data, reply, flags);
457     }
458 }
459 
460 }; // namespace android
461