Home | History | Annotate | Download | only in native
      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:
     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) {
     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 
    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 
    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 
    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 
    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 
    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     }
    200 
    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     }
    246 };
    247 
    248 IMPLEMENT_META_INTERFACE(VehicleNetwork, IVehicleNetwork::SERVICE_NAME);
    249 
    250 // ----------------------------------------------------------------------
    251 
    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