Home | History | Annotate | Download | only in vehiclenetwork
      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 package com.android.car.vehiclenetwork;
     17 
     18 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorLength;
     19 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.isCustomProperty;
     20 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toFloatArray;
     21 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toIntArray;
     22 
     23 import android.os.Handler;
     24 import android.os.Looper;
     25 import android.os.Message;
     26 import android.os.RemoteException;
     27 import android.os.ServiceManager;
     28 import android.os.ServiceSpecificException;
     29 import android.util.Log;
     30 
     31 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
     32 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
     33 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
     34 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
     35 import com.android.internal.annotations.GuardedBy;
     36 
     37 import java.lang.ref.WeakReference;
     38 
     39 /**
     40  * System API to access Vehicle network. This is only for system services and applications should
     41  * not use this. All APIs will fail with security error if normal app tries this.
     42  */
     43 public class VehicleNetwork {
     44     /**
     45      * Listener for VNS events.
     46      */
     47     public interface VehicleNetworkListener {
     48         /**
     49          * Notify HAL events. This requires subscribing the property
     50          */
     51         void onVehicleNetworkEvents(VehiclePropValues values);
     52         void onHalError(int errorCode, int property, int operation);
     53         void onHalRestart(boolean inMocking);
     54     }
     55 
     56     public interface VehicleNetworkHalMock {
     57         VehiclePropConfigs onListProperties();
     58         void onPropertySet(VehiclePropValue value);
     59         VehiclePropValue onPropertyGet(VehiclePropValue value);
     60         void onPropertySubscribe(int property, float sampleRate, int zones);
     61         void onPropertyUnsubscribe(int property);
     62     }
     63 
     64     private static final String TAG = VehicleNetwork.class.getSimpleName();
     65 
     66     private final IVehicleNetwork mService;
     67     private final VehicleNetworkListener mListener;
     68     private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
     69     private final EventHandler mEventHandler;
     70 
     71     @GuardedBy("this")
     72     private VehicleNetworkHalMock mHalMock;
     73     private IVehicleNetworkHalMock mHalMockImpl;
     74 
     75     private static final int VNS_CONNECT_MAX_RETRY = 10;
     76     private static final long VNS_RETRY_WAIT_TIME_MS = 1000;
     77     private static final int NO_ZONE = -1;
     78 
     79     /**
     80      * Factory method to create VehicleNetwork
     81      *
     82      * @param listener listener for listening events
     83      * @param looper Looper to dispatch listener events
     84      */
     85     public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
     86             Looper looper) {
     87         int retryCount = 0;
     88         IVehicleNetwork service = null;
     89         while (service == null) {
     90             service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
     91                     IVehicleNetwork.class.getCanonicalName()));
     92             retryCount++;
     93             if (retryCount > VNS_CONNECT_MAX_RETRY) {
     94                 break;
     95             }
     96             try {
     97                 Thread.sleep(VNS_RETRY_WAIT_TIME_MS);
     98             } catch (InterruptedException e) {
     99                 //ignore
    100             }
    101         }
    102         if (service == null) {
    103             throw new RuntimeException("Vehicle network service not available:" +
    104                     IVehicleNetwork.class.getCanonicalName());
    105         }
    106         return new VehicleNetwork(service, listener, looper);
    107     }
    108 
    109     private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
    110             Looper looper) {
    111         mService = service;
    112         mListener = listener;
    113         mEventHandler = new EventHandler(looper);
    114         mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
    115     }
    116 
    117     /**
    118      * List all properties from vehicle HAL
    119      *
    120      * @return all properties
    121      */
    122     public VehiclePropConfigs listProperties() {
    123         return listProperties(0 /* all */);
    124     }
    125 
    126     /**
    127      * Return configuration information of single property
    128      *
    129      * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has
    130      * special meaning of list all properties.
    131      * @return null if given property does not exist.
    132      */
    133     public VehiclePropConfigs listProperties(int property) {
    134         try {
    135             VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
    136             if (parcelable != null) {
    137                 return parcelable.configs;
    138             }
    139         } catch (RemoteException e) {
    140             handleRemoteException(e);
    141         }
    142         return null;
    143     }
    144 
    145     /**
    146      * Set property which will lead into writing the value to vehicle HAL.
    147      *
    148      * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong
    149      * data, and etc.
    150      */
    151     public void setProperty(VehiclePropValue value) throws IllegalArgumentException {
    152         VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
    153         try {
    154             mService.setProperty(parcelable);
    155         } catch (RemoteException e) {
    156             handleRemoteException(e);
    157         }
    158     }
    159 
    160     /**
    161      * Set integer type property
    162      *
    163      * @throws IllegalArgumentException For type mismatch (=the property is not int type)
    164      */
    165     public void setIntProperty(int property, int value) throws IllegalArgumentException {
    166         VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
    167         setProperty(v);
    168     }
    169 
    170     /**
    171      * Set int vector type property. Length of passed values should match with vector length.
    172      */
    173     public void setIntVectorProperty(int property, int[] values) throws IllegalArgumentException {
    174         VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
    175         setProperty(v);
    176     }
    177 
    178     /**
    179      * Set long type property.
    180      */
    181     public void setLongProperty(int property, long value) throws IllegalArgumentException {
    182         VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
    183         setProperty(v);
    184     }
    185 
    186     /**
    187      * Set float type property.
    188      */
    189     public void setFloatProperty(int property, float value) throws IllegalArgumentException {
    190         VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
    191         setProperty(v);
    192     }
    193 
    194     /**
    195      * Set float vector type property. Length of values should match with vector length.
    196      */
    197     public void setFloatVectorProperty(int property, float[] values)
    198             throws IllegalArgumentException {
    199         VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
    200         setProperty(v);
    201     }
    202 
    203     /**
    204      * Set zoned boolean type property
    205      *
    206      * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
    207      */
    208     public void setBooleanProperty(int property, boolean value)
    209             throws IllegalArgumentException {
    210         VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
    211         setProperty(v);
    212     }
    213 
    214     /**
    215      * Set zoned boolean type property
    216      *
    217      * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
    218      */
    219     public void setZonedBooleanProperty(int property, int zone, boolean value)
    220             throws IllegalArgumentException {
    221         VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
    222         setProperty(v);
    223     }
    224 
    225     /**
    226      * Set zoned float type property
    227      *
    228      * @throws IllegalArgumentException For type mismatch (=the property is not float type)
    229      */
    230     public void setZonedFloatProperty(int property, int zone, float value)
    231             throws IllegalArgumentException {
    232         VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
    233         setProperty(v);
    234     }
    235 
    236     /**
    237      * Set zoned integer type property
    238      *
    239      * @throws IllegalArgumentException For type mismatch (=the property is not int type)
    240      */
    241     public void setZonedIntProperty(int property, int zone, int value)
    242             throws IllegalArgumentException {
    243         VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
    244         setProperty(v);
    245     }
    246 
    247     /**
    248      * Set zoned int vector type property. Length of passed values should match with vector length.
    249      */
    250     public void setZonedIntVectorProperty(int property, int zone, int[] values)
    251             throws IllegalArgumentException {
    252         VehiclePropValue v = VehiclePropValueUtil
    253                 .createZonedIntVectorValue(property, zone, values, 0);
    254         setProperty(v);
    255     }
    256 
    257     /**
    258      * Set zoned float vector type property. Length of passed values should match with vector
    259      * length.
    260      */
    261     public void setZonedFloatVectorProperty(int property, int zone, float[] values)
    262             throws IllegalArgumentException {
    263         VehiclePropValue v = VehiclePropValueUtil
    264                 .createZonedFloatVectorValue(property, zone, values, 0);
    265         setProperty(v);
    266     }
    267 
    268     /**
    269      * Get property. This can be used for a property which does not require any other data.
    270      */
    271     public VehiclePropValue getProperty(int property) throws IllegalArgumentException,
    272             ServiceSpecificException {
    273         int valueType = VehicleNetworkConsts.getVehicleValueType(property);
    274         if (valueType == 0) {
    275             throw new IllegalArgumentException("Data type is unknown for property: " + property);
    276         }
    277         VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
    278         return getProperty(value);
    279     }
    280 
    281     /**
    282      * Generic get method for any type of property. Some property may require setting data portion
    283      * as get may return different result depending on the data set.
    284      */
    285     public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException,
    286             ServiceSpecificException {
    287         VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
    288         try {
    289             VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
    290             if (resParcelable != null) {
    291                 return resParcelable.value;
    292             }
    293         } catch (RemoteException e) {
    294             handleRemoteException(e);
    295         }
    296         return null;
    297     }
    298 
    299     /**
    300      * Get int type property.
    301      */
    302     public int getIntProperty(int property) throws IllegalArgumentException,
    303             ServiceSpecificException {
    304         VehiclePropValue v = getProperty(
    305                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
    306         if (v.getInt32ValuesCount() != 1) {
    307             throw new IllegalStateException();
    308         }
    309         return v.getInt32Values(0);
    310     }
    311 
    312     /**
    313      * Get zoned int type property.
    314      */
    315     public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException,
    316             ServiceSpecificException {
    317         VehiclePropValue v = getProperty(
    318                 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
    319         if (v.getInt32ValuesCount() != 1) {
    320             throw new IllegalStateException();
    321         }
    322         return v.getInt32Values(0);
    323     }
    324 
    325     /**
    326      * Get int vector type property. Length of values should match vector length.
    327      */
    328     public int[] getIntVectorProperty(int property) throws IllegalArgumentException,
    329             ServiceSpecificException {
    330         VehiclePropValue v = getProperty(
    331                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
    332         assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
    333         return toIntArray(v.getInt32ValuesList());
    334     }
    335 
    336     /**
    337      * Get zoned int vector type property. Length of values should match vector length.
    338      */
    339     public int[] getZonedIntVectorProperty(int property, int zone)
    340             throws IllegalArgumentException, ServiceSpecificException {
    341         VehiclePropValue v = getProperty(
    342                 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
    343         assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
    344         return toIntArray(v.getInt32ValuesList());
    345     }
    346 
    347     /**
    348      * Get float type property.
    349      */
    350     public float getFloatProperty(int property) throws IllegalArgumentException,
    351             ServiceSpecificException {
    352         VehiclePropValue v = getProperty(
    353                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
    354         if (v.getFloatValuesCount() != 1) {
    355             throw new IllegalStateException();
    356         }
    357         return v.getFloatValues(0);
    358     }
    359 
    360     /**
    361      * Get float vector type property. Length of values should match vector's length.
    362      */
    363     public float[] getFloatVectorProperty(int property) throws IllegalArgumentException,
    364             ServiceSpecificException {
    365         VehiclePropValue v = getProperty(
    366                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
    367         assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
    368         return toFloatArray(v.getFloatValuesList());
    369     }
    370 
    371     /**
    372      * Get zoned float vector type property. Length of values should match vector's length.
    373      */
    374     public float[] getZonedFloatVectorProperty(int property, int zone)
    375             throws IllegalArgumentException, ServiceSpecificException {
    376         VehiclePropValue v = getProperty(property, zone,
    377                 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
    378         assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
    379         return toFloatArray(v.getFloatValuesList());
    380     }
    381 
    382     /**
    383      * Get long type property.
    384      */
    385     public long getLongProperty(int property) throws IllegalArgumentException,
    386             ServiceSpecificException {
    387         VehiclePropValue v = getProperty(
    388                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
    389         return v.getInt64Value();
    390     }
    391 
    392     /**
    393      * Get string type property.
    394      */
    395     //TODO check UTF8 to java string conversion
    396     public String getStringProperty(int property) throws IllegalArgumentException,
    397             ServiceSpecificException {
    398         VehiclePropValue v = getProperty(
    399                 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
    400         return v.getStringValue();
    401     }
    402 
    403     /**
    404      * Subscribe given property with given sample rate.
    405      */
    406     public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
    407         subscribe(property, sampleRate, 0);
    408     }
    409 
    410     /**
    411      * Subscribe given property with given sample rate.
    412      */
    413     public void subscribe(int property, float sampleRate, int zones)
    414             throws IllegalArgumentException {
    415         try {
    416             mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones);
    417         } catch (RemoteException e) {
    418             handleRemoteException(e);
    419         }
    420     }
    421 
    422     /**
    423      * Stop subscribing the property.
    424      */
    425     public void unsubscribe(int property) {
    426         try {
    427             mService.unsubscribe(mVehicleNetworkListener, property);
    428         } catch (RemoteException e) {
    429             handleRemoteException(e);
    430         }
    431     }
    432 
    433     /**
    434      * Inject given value to all clients subscribing the property. This is for testing.
    435      */
    436     public synchronized void injectEvent(VehiclePropValue value) {
    437         try {
    438             mService.injectEvent(new VehiclePropValueParcelable(value));
    439         } catch (RemoteException e) {
    440             handleRemoteException(e);
    441         }
    442     }
    443 
    444     /**
    445      * Start mocking of vehicle HAL. For testing only.
    446      */
    447     public synchronized void startMocking(VehicleNetworkHalMock mock) {
    448         mHalMock = mock;
    449         mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
    450         try {
    451             mService.startMocking(mHalMockImpl);
    452         } catch (RemoteException e) {
    453             handleRemoteException(e);
    454         }
    455     }
    456 
    457     /**
    458      * Stop mocking of vehicle HAL. For testing only.
    459      */
    460     public synchronized void stopMocking() {
    461         if (mHalMockImpl == null) {
    462             return;
    463         }
    464         try {
    465             mService.stopMocking(mHalMockImpl);
    466         } catch (RemoteException e) {
    467             handleRemoteException(e);
    468         } finally {
    469             mHalMock = null;
    470             mHalMockImpl = null;
    471         }
    472     }
    473 
    474     /**
    475      * Start mocking of vehicle HAL. For testing only.
    476      */
    477     public synchronized void startMocking(IVehicleNetworkHalMock mock) {
    478         mHalMock = null;
    479         mHalMockImpl = mock;
    480         try {
    481             mService.startMocking(mHalMockImpl);
    482         } catch (RemoteException e) {
    483             handleRemoteException(e);
    484         }
    485     }
    486 
    487     /**
    488      * Stop mocking of vehicle HAL. For testing only.
    489      */
    490     public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
    491         if (mock.asBinder() != mHalMockImpl.asBinder()) {
    492             return;
    493         }
    494         try {
    495             mService.stopMocking(mHalMockImpl);
    496         } catch (RemoteException e) {
    497             handleRemoteException(e);
    498         } finally {
    499             mHalMock = null;
    500             mHalMockImpl = null;
    501         }
    502     }
    503 
    504     public synchronized void injectHalError(int errorCode, int property, int operation) {
    505         try {
    506             mService.injectHalError(errorCode, property, operation);
    507         } catch (RemoteException e) {
    508             handleRemoteException(e);
    509         }
    510     }
    511 
    512     public synchronized void startErrorListening() {
    513         try {
    514             mService.startErrorListening(mVehicleNetworkListener);
    515         } catch (RemoteException e) {
    516             handleRemoteException(e);
    517         }
    518     }
    519 
    520     public synchronized void stopErrorListening() {
    521         try {
    522             mService.stopErrorListening(mVehicleNetworkListener);
    523         } catch (RemoteException e) {
    524             handleRemoteException(e);
    525         }
    526     }
    527 
    528     public synchronized void startHalRestartMonitoring() {
    529         try {
    530             mService.startHalRestartMonitoring(mVehicleNetworkListener);
    531         } catch (RemoteException e) {
    532             handleRemoteException(e);
    533         }
    534     }
    535 
    536     public synchronized void stopHalRestartMonitoring() {
    537         try {
    538             mService.stopHalRestartMonitoring(mVehicleNetworkListener);
    539         } catch (RemoteException e) {
    540             handleRemoteException(e);
    541         }
    542     }
    543 
    544     private synchronized VehicleNetworkHalMock getHalMock() {
    545         return mHalMock;
    546     }
    547 
    548     private void handleRemoteException(RemoteException e) {
    549         throw new RuntimeException("Vehicle network service not working ", e);
    550     }
    551 
    552     private void handleVehicleNetworkEvents(VehiclePropValues values) {
    553         mListener.onVehicleNetworkEvents(values);
    554     }
    555 
    556     private void handleHalError(int errorCode, int property, int operation) {
    557         mListener.onHalError(errorCode, property, operation);
    558     }
    559 
    560     private void handleHalRestart(boolean inMocking) {
    561         mListener.onHalRestart(inMocking);
    562     }
    563 
    564     private class EventHandler extends Handler {
    565 
    566         private static final int MSG_EVENTS = 0;
    567         private static final int MSG_HAL_ERROR = 1;
    568         private static final int MSG_HAL_RESTART = 2;
    569 
    570         private EventHandler(Looper looper) {
    571             super(looper);
    572         }
    573 
    574         private void notifyEvents(VehiclePropValues values) {
    575             Message msg = obtainMessage(MSG_EVENTS, values);
    576             sendMessage(msg);
    577         }
    578 
    579         private void notifyHalError(int errorCode, int property, int operation) {
    580             Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
    581             sendMessage(msg);
    582         }
    583 
    584         private void notifyHalRestart(boolean inMocking) {
    585             Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
    586             sendMessage(msg);
    587         }
    588 
    589         @Override
    590         public void handleMessage(Message msg) {
    591             switch (msg.what) {
    592                 case MSG_EVENTS:
    593                     handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
    594                     break;
    595                 case MSG_HAL_ERROR:
    596                     handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
    597                     break;
    598                 case MSG_HAL_RESTART:
    599                     handleHalRestart(msg.arg1 == 1);
    600                     break;
    601                 default:
    602                     Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
    603                     break;
    604             }
    605         }
    606     }
    607 
    608     private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
    609 
    610         private final WeakReference<VehicleNetwork> mVehicleNetwork;
    611 
    612         private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
    613             mVehicleNetwork = new WeakReference<>(vehicleNewotk);
    614         }
    615 
    616         @Override
    617         public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
    618             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    619             if (vehicleNetwork != null) {
    620                 vehicleNetwork.mEventHandler.notifyEvents(values.values);
    621             }
    622         }
    623 
    624         @Override
    625         public void onHalError(int errorCode, int property, int operation) {
    626             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    627             if (vehicleNetwork != null) {
    628                 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
    629             }
    630         }
    631 
    632         @Override
    633         public void onHalRestart(boolean inMocking) {
    634             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    635             if (vehicleNetwork != null) {
    636                 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
    637             }
    638         }
    639     }
    640 
    641     private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
    642         private final WeakReference<VehicleNetwork> mVehicleNetwork;
    643 
    644         private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
    645             mVehicleNetwork = new WeakReference<>(vehicleNewotk);
    646         }
    647 
    648         @Override
    649         public VehiclePropConfigsParcelable onListProperties() {
    650             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    651             if (vehicleNetwork == null) {
    652                 return null;
    653             }
    654             VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
    655             return new VehiclePropConfigsParcelable(configs);
    656         }
    657 
    658         @Override
    659         public void onPropertySet(VehiclePropValueParcelable value) {
    660             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    661             if (vehicleNetwork == null) {
    662                 return;
    663             }
    664             vehicleNetwork.getHalMock().onPropertySet(value.value);
    665         }
    666 
    667         @Override
    668         public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
    669             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    670             if (vehicleNetwork == null) {
    671                 return null;
    672             }
    673             VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
    674             return new VehiclePropValueParcelable(resValue);
    675         }
    676 
    677         @Override
    678         public void onPropertySubscribe(int property, float sampleRate, int zones) {
    679             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    680             if (vehicleNetwork == null) {
    681                 return;
    682             }
    683             vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
    684         }
    685 
    686         @Override
    687         public void onPropertyUnsubscribe(int property) {
    688             VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
    689             if (vehicleNetwork == null) {
    690                 return;
    691             }
    692             vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
    693         }
    694     }
    695 
    696     private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
    697         boolean isCustom = isCustomProperty(property);
    698         int valueType = isCustom
    699                 ? customPropetyDataType
    700                 : VehicleNetworkConsts.getVehicleValueType(property);
    701 
    702         VehiclePropValue.Builder valuePrototypeBuilder =
    703                 VehiclePropValueUtil.createBuilder(property, valueType, 0);
    704 
    705         if (zone != NO_ZONE) {
    706             valuePrototypeBuilder.setZone(zone);
    707         }
    708 
    709         VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
    710         if (v == null) {
    711             // if property is invalid, IllegalArgumentException should have been thrown
    712             // from getProperty.
    713             throw new IllegalStateException();
    714         }
    715 
    716         if (!isCustom && v.getValueType() != valueType) {
    717             throw new IllegalArgumentException(
    718                     "Unexpected type for property 0x" + Integer.toHexString(property) +
    719                     " got:0x" + Integer.toHexString(v.getValueType())
    720                     + ", expecting:0x" + Integer.toHexString(valueType));
    721         }
    722         return v;
    723     }
    724 
    725     private void assertVectorLength(int actual, int property, int valueType) {
    726         int expectedLen = getVectorLength(valueType);
    727         if (expectedLen != actual) {
    728             throw new IllegalStateException("Invalid array size for property: " + property
    729                     + ". Expected: " + expectedLen
    730                     + ", actual: " + actual);
    731         }
    732     }
    733 }
    734