11ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung/*
21ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * Copyright (C) 2015 The Android Open Source Project
31ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung *
41ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * Licensed under the Apache License, Version 2.0 (the "License");
51ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * you may not use this file except in compliance with the License.
61ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * You may obtain a copy of the License at
71ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung *
81ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung *      http://www.apache.org/licenses/LICENSE-2.0
91ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung *
101ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * Unless required by applicable law or agreed to in writing, software
111ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * distributed under the License is distributed on an "AS IS" BASIS,
121ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * See the License for the specific language governing permissions and
141ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung * limitations under the License.
151ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung */
161ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
171ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#define LOG_TAG "VehicleNetwork"
181ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
191ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <memory>
201ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
211ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <binder/IPCThreadState.h>
221ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <private/android_filesystem_config.h>
231ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
241ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <utils/Log.h>
251ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
261ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <IVehicleNetwork.h>
271ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <IVehicleNetworkHalMock.h>
281ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include <VehicleNetworkProto.pb.h>
291ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
301ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include "BinderUtil.h"
311ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung#include "VehicleNetworkProtoUtil.h"
321ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
331ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungnamespace android {
341ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
351ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungenum {
361ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    ON_LIST_PROPERTIES = IBinder::FIRST_CALL_TRANSACTION,
371ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    ON_PROPERTY_SET,
381ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    ON_PROPERTY_GET,
391ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    ON_SUBSCRIBE,
401ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    ON_UNSUBSCRIBE,
411ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung};
421ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
431ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung// ----------------------------------------------------------------------------
441ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
451ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungconst char IVehicleNetworkHalMock::SERVICE_NAME[] =
461ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        "com.android.car.vehiclenetwork.IVehicleNetworkHalMock";
471ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
481ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung// ----------------------------------------------------------------------------
491ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
501ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungclass BpVehicleNetworkHalMock : public BpInterface<IVehicleNetworkHalMock> {
511ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungpublic:
521ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    BpVehicleNetworkHalMock(const sp<IBinder> & impl)
531ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        : BpInterface<IVehicleNetworkHalMock>(impl) {
541ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
551ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
561ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    virtual sp<VehiclePropertiesHolder> onListProperties() {
571ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        sp<VehiclePropertiesHolder> holder;
581ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        Parcel data, reply;
591ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInterfaceToken(IVehicleNetworkHalMock::getInterfaceDescriptor());
601ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        status_t status = remote()->transact(ON_LIST_PROPERTIES, data, &reply);
611ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        if (status == NO_ERROR) {
621ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            reply.readExceptionCode(); // for compatibility with java
631ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (reply.readInt32() == 0) { // no result
641ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
651ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
661ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ReadableBlobHolder blob(new Parcel::ReadableBlob());
671ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (blob.blob == NULL) {
681ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("listProperties, no memory");
691ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
701ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
711ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            int32_t size = reply.readInt32();
721ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            status = reply.readBlob(size, blob.blob);
731ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (status != NO_ERROR) {
741ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("listProperties, cannot read blob %d", status);
751ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
761ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
771ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            //TODO make this more memory efficient
781ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
791ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (configs.get() == NULL) {
801ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
811ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
821ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if(!configs->ParseFromArray(blob.blob->data(), size)) {
831ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("listProperties, cannot parse reply");
841ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
851ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
861ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            holder = new VehiclePropertiesHolder();
871ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ASSERT_OR_HANDLE_NO_MEMORY(holder.get(), return);
881ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            status = VehicleNetworkProtoUtil::fromVehiclePropConfigs(*configs.get(),
891ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                    holder->getList());
901ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (status != NO_ERROR) {
911ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("listProperties, cannot convert VehiclePropConfigs %d", status);
921ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return holder;
931ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
941ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
951ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        }
961ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        return holder;
971ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
981ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
991ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    virtual status_t onPropertySet(const vehicle_prop_value_t& value) {
1001ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        Parcel data, reply;
1011ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInterfaceToken(IVehicleNetworkHalMock::getInterfaceDescriptor());
1027d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        status_t status = VehiclePropValueBinderUtil::writeToParcel(data, value);
1037d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        if (status != NO_ERROR) {
1047d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung            return status;
1057d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        }
1067d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        status = remote()->transact(ON_PROPERTY_SET, data, &reply);
1071ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        return status;
1081ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1091ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1101ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    virtual status_t onPropertyGet(vehicle_prop_value_t* value) {
1117d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        if (value == NULL) {
1127d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung            return BAD_VALUE;
1137d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        }
1141ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        Parcel data, reply;
1151ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInterfaceToken(IVehicleNetworkHalMock::getInterfaceDescriptor());
1167d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        status_t status = VehiclePropValueBinderUtil::writeToParcel(data, *value);
1177d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        if (status != NO_ERROR) {
1187d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung            return status;
1197d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        }
1207d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung        status = remote()->transact(ON_PROPERTY_GET, data, &reply);
1211ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        if (status == NO_ERROR) {
1221ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            reply.readExceptionCode(); // for compatibility with java
1237d74e6d9195f29d0eb50f7bcbe235334b02dba8ekeunyoung            status = VehiclePropValueBinderUtil::readFromParcel(reply, value);
1241ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        }
1251ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        return status;
1261ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1271ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1280727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park    virtual status_t onPropertySubscribe(int32_t property, float sampleRate, int32_t zones) {
1291ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        Parcel data, reply;
1301ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInterfaceToken(IVehicleNetworkHalMock::getInterfaceDescriptor());
1311ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInt32(property);
1321ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeFloat(sampleRate);
1330727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park        data.writeInt32(zones);
1341ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        status_t status = remote()->transact(ON_SUBSCRIBE, data, &reply);
1351ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        return status;
1361ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1371ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1381ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    virtual void onPropertyUnsubscribe(int32_t property) {
1391ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        Parcel data, reply;
1401ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInterfaceToken(IVehicleNetworkHalMock::getInterfaceDescriptor());
1411ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        data.writeInt32(property);
1421ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        status_t status = remote()->transact(ON_UNSUBSCRIBE, data, &reply);
1431ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        if (status != NO_ERROR) {
1441ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ALOGI("onPropertyUnsubscribe property %d failed %d", property, status);
1451ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        }
1461ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1471ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung};
1481ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1491ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungIMPLEMENT_META_INTERFACE(VehicleNetworkHalMock, IVehicleNetworkHalMock::SERVICE_NAME);
1501ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1511ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung// ----------------------------------------------------------------------
1521ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1531ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungstatic bool isSystemUser() {
1541ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    uid_t uid =  IPCThreadState::self()->getCallingUid();
1551ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    switch (uid) {
1561ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        // This list will be expanded. Only those UIDs are allowed to access vehicle network
1571ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        // for now. There can be per property based UID check built-in as well.
1581ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case AID_ROOT:
1591ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case AID_SYSTEM:
1601ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case AID_AUDIO: {
1611ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return true;
1621ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
1631ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        default: {
1641ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ALOGE("non-system user tried access, uid %d", uid);
1651ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
1661ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1671ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    return false;
1681ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung}
1691ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
1701ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoungstatus_t BnVehicleNetworkHalMock::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
1711ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        uint32_t flags) {
1721ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    if (!isSystemUser()) {
1731ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        return PERMISSION_DENIED;
1741ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
1751ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    status_t r;
1761ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    switch (code) {
1771ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case ON_LIST_PROPERTIES: {
1781ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            CHECK_INTERFACE(IVehicleNetworkHalMock, data, reply);
1791ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            sp<VehiclePropertiesHolder> holder = onListProperties();
1801ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (holder.get() == NULL) { // given property not found
1811ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                BinderUtil::fillObjectResultReply(reply, false /* isValid */);
1821ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return NO_ERROR;
1831ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
1841ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs());
1851ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ASSERT_OR_HANDLE_NO_MEMORY(configs.get(), return NO_MEMORY);
1861ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            VehicleNetworkProtoUtil::toVehiclePropConfigs(holder->getList(), *configs.get());
1871ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            int size = configs->ByteSize();
1881ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            WritableBlobHolder blob(new Parcel::WritableBlob());
1891ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
1901ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            BinderUtil::fillObjectResultReply(reply, true);
1911ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            reply->writeInt32(size);
1921ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            reply->writeBlob(size, false, blob.blob);
1931ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            configs->SerializeToArray(blob.blob->data(), size);
1941ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return NO_ERROR;
1951ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
1961ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case ON_PROPERTY_SET: {
1971ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            CHECK_INTERFACE(IVehicleNetworkHalMock, data, reply);
1981ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (data.readInt32() == 0) { // java side allows passing null with this.
1991ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return BAD_VALUE;
2001ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
2011ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ScopedVehiclePropValue value;
2021ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ReadableBlobHolder blob(new Parcel::ReadableBlob());
2031ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
2041ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            int32_t size = data.readInt32();
2051ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            r = data.readBlob(size, blob.blob);
2061ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (r != NO_ERROR) {
2071ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("setProperty:service, cannot read blob");
2081ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return r;
2091ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
2101ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
2111ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
2121ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (!v->ParseFromArray(blob.blob->data(), size)) {
2131ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("setProperty:service, cannot parse data");
2141ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return BAD_VALUE;
2151ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
2161ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            r = VehicleNetworkProtoUtil::fromVehiclePropValue(*v.get(), value.value);
2171ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (r != NO_ERROR) {
2181ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ALOGE("setProperty:service, cannot convert data");
2191ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                return BAD_VALUE;
2201ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
2211ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            r = onPropertySet(value.value);
2221ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            BinderUtil::fillNoResultReply(reply);
2231ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return r;
2241ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
2251ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case ON_PROPERTY_GET: {
2261ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            CHECK_INTERFACE(IVehicleNetworkHalMock, data, reply);
2271ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            ScopedVehiclePropValue value;
228aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value,
229aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                                false /* deleteMembers */, true /*canIgnoreNoData*/);
230aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            if (r != NO_ERROR) {
231aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                ALOGE("onPropertyGet cannot read %d", r);
232aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                return r;
233aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            }
2341ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            r = onPropertyGet(&(value.value));
2351ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            if (r == NO_ERROR) {
2361ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                BinderUtil::fillObjectResultReply(reply, true);
2371ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
2381ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
2391ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                VehicleNetworkProtoUtil::toVehiclePropValue(value.value, *v.get());
2401ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                int size = v->ByteSize();
2411ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                WritableBlobHolder blob(new Parcel::WritableBlob());
2421ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
2431ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                reply->writeInt32(size);
2441ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                reply->writeBlob(size, false, blob.blob);
2451ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung                v->SerializeToArray(blob.blob->data(), size);
2461ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            }
2471ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return r;
2481ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
2491ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case ON_SUBSCRIBE: {
2501ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            CHECK_INTERFACE(IVehicleNetworkHalMock, data, reply);
2511ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            int32_t property = data.readInt32();
2521ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            float sampleRate = data.readFloat();
2530727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park            int32_t zones = data.readInt32();
2540727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park            r = onPropertySubscribe(property, sampleRate, zones);
2551ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            BinderUtil::fillNoResultReply(reply);
2561ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return r;
2571ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
2581ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        case ON_UNSUBSCRIBE: {
2591ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            CHECK_INTERFACE(IVehicleNetworkHalMock, data, reply);
2601ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            int32_t property = data.readInt32();
2611ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            onPropertyUnsubscribe(property);
2621ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            BinderUtil::fillNoResultReply(reply);
2631ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return NO_ERROR;
2641ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        } break;
2651ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung        default:
2661ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung            return BBinder::onTransact(code, data, reply, flags);
2671ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung    }
2681ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung}
2691ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung
2701ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung}; // namespace android
271