diff --git a/car-support-lib/src/android/support/car/CarServiceLoaderEmbedded.java b/car-support-lib/src/android/support/car/CarServiceLoaderEmbedded.java
index 3ba3b49..7b96ae9 100644
--- a/car-support-lib/src/android/support/car/CarServiceLoaderEmbedded.java
+++ b/car-support-lib/src/android/support/car/CarServiceLoaderEmbedded.java
@@ -107,20 +107,20 @@
         }
         // For publicly available versions, return wrapper version.
         switch (serviceName) {
-        case Car.AUDIO_SERVICE:
-            return new CarAudioManagerEmbedded(manager);
-        case Car.SENSOR_SERVICE:
-            return new CarSensorManagerEmbedded(manager);
-        case Car.INFO_SERVICE:
-            return new CarInfoManagerEmbedded(manager);
-        case Car.APP_CONTEXT_SERVICE:
-            return new CarAppContextManagerEmbedded(manager);
-        case Car.PACKAGE_SERVICE:
-            return new CarPackageManagerEmbedded(manager);
-        case Car.CAR_NAVIGATION_SERVICE:
-            return new CarNavigationManagerEmbedded(manager);
-        default:
-            return manager;
+            case Car.AUDIO_SERVICE:
+                return new CarAudioManagerEmbedded(manager);
+            case Car.SENSOR_SERVICE:
+                return new CarSensorManagerEmbedded(manager, getContext());
+            case Car.INFO_SERVICE:
+                return new CarInfoManagerEmbedded(manager);
+            case Car.APP_CONTEXT_SERVICE:
+                return new CarAppContextManagerEmbedded(manager);
+            case Car.PACKAGE_SERVICE:
+                return new CarPackageManagerEmbedded(manager);
+            case Car.CAR_NAVIGATION_SERVICE:
+                return new CarNavigationManagerEmbedded(manager);
+            default:
+                return manager;
         }
     }
 
diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java
index 8b57147..2c00d3b 100644
--- a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java
+++ b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java
@@ -16,34 +16,71 @@
 
 package android.support.car.hardware;
 
+import android.content.Context;
 import android.support.car.CarNotConnectedException;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Arrays;
 import java.util.LinkedList;
+import java.util.Set;
+
 /**
  *  @hide
  */
 public class CarSensorManagerEmbedded extends CarSensorManager {
+    private static final String TAG = "CarSensorsProxy";
 
     private final android.car.hardware.CarSensorManager mManager;
+    private final CarSensorsProxy mCarSensorsProxy;
     private final LinkedList<CarSensorEventListenerProxy> mListeners = new LinkedList<>();
 
-    public CarSensorManagerEmbedded(Object manager) {
+    public CarSensorManagerEmbedded(Object manager, Context context) {
         mManager = (android.car.hardware.CarSensorManager) manager;
+        mCarSensorsProxy = new CarSensorsProxy(context);
     }
 
     @Override
     public int[] getSupportedSensors() throws CarNotConnectedException {
         try {
-            return mManager.getSupportedSensors();
+            Set<Integer> sensorsSet = new HashSet<Integer>();
+            for (Integer sensor : mManager.getSupportedSensors()) {
+                sensorsSet.add(sensor);
+            }
+            for (Integer proxySensor : mCarSensorsProxy.getSupportedSensors()) {
+                sensorsSet.add(proxySensor);
+            }
+            return toIntArray(sensorsSet);
         } catch (android.car.CarNotConnectedException e) {
             throw new CarNotConnectedException(e);
         }
     }
 
+    private static int[] toIntArray(Collection<Integer> collection) {
+        int len = collection.size();
+        int[] arr = new int[len];
+        int arrIndex = 0;
+        for (Integer item : collection) {
+            arr[arrIndex] = item;
+            arrIndex++;
+        }
+        return arr;
+    }
+
     @Override
     public boolean isSensorSupported(int sensorType) throws CarNotConnectedException {
         try {
-            return mManager.isSensorSupported(sensorType);
+            return mManager.isSensorSupported(sensorType)
+                    || mCarSensorsProxy.isSensorSupported(sensorType);
+        } catch (android.car.CarNotConnectedException e) {
+            throw new CarNotConnectedException(e);
+        }
+    }
+
+    private boolean isSensorProxied(int sensorType) throws CarNotConnectedException {
+        try {
+            return !mManager.isSensorSupported(sensorType)
+                    && mCarSensorsProxy.isSensorSupported(sensorType);
         } catch (android.car.CarNotConnectedException e) {
             throw new CarNotConnectedException(e);
         }
@@ -52,13 +89,17 @@
     @Override
     public boolean registerListener(CarSensorEventListener listener, int sensorType,
             int rate) throws CarNotConnectedException, IllegalArgumentException {
+        if (isSensorProxied(sensorType)) {
+            return mCarSensorsProxy.registerSensorListener(listener, sensorType, rate);
+        }
         CarSensorEventListenerProxy proxy = null;
         synchronized (this) {
             proxy = findListenerLocked(listener);
             if (proxy == null) {
                 proxy = new CarSensorEventListenerProxy(listener, sensorType);
+                mListeners.add(proxy);
             } else {
-                proxy.sensors |= sensorType;
+                proxy.sensors.add(sensorType);
             }
         }
         try {
@@ -70,6 +111,7 @@
 
     @Override
     public void unregisterListener(CarSensorEventListener listener) {
+        mCarSensorsProxy.unregisterSensorListener(listener);
         CarSensorEventListenerProxy proxy = null;
         synchronized (this) {
             proxy = findListenerLocked(listener);
@@ -83,14 +125,15 @@
 
     @Override
     public void unregisterListener(CarSensorEventListener listener, int sensorType) {
+        mCarSensorsProxy.unregisterSensorListener(listener, sensorType);
         CarSensorEventListenerProxy proxy = null;
         synchronized (this) {
             proxy = findListenerLocked(listener);
             if (proxy == null) {
                 return;
             }
-            proxy.sensors &= ~sensorType;
-            if (proxy.sensors == 0) {
+            proxy.sensors.remove(sensorType);
+            if (proxy.sensors.isEmpty()) {
                 mListeners.remove(proxy);
             }
         }
@@ -99,6 +142,9 @@
 
     @Override
     public CarSensorEvent getLatestSensorEvent(int type) throws CarNotConnectedException {
+        if (isSensorProxied(type)) {
+            return mCarSensorsProxy.getLatestSensorEvent(type);
+        }
         try {
             return convert(mManager.getLatestSensorEvent(type));
         } catch (android.car.CarNotConnectedException e) {
@@ -132,11 +178,11 @@
             android.car.hardware.CarSensorManager.CarSensorEventListener {
 
         public final CarSensorEventListener listener;
-        public int sensors;
+        public final Set<Integer> sensors = new HashSet<Integer>();
 
-        public CarSensorEventListenerProxy(CarSensorEventListener listener, int sensors) {
+        CarSensorEventListenerProxy(CarSensorEventListener listener, int sensor) {
             this.listener = listener;
-            this.sensors = sensors;
+            this.sensors.add(sensor);
         }
 
         @Override
diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java b/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java
new file mode 100644
index 0000000..6d5acc3
--- /dev/null
+++ b/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.car.hardware;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * CarSensorsProxy adds car sensors implementation for sensors that are not provided by vehicle HAL.
+ * @hide
+ */
+class CarSensorsProxy {
+    private static final String TAG = "CarSensorsProxy";
+    private static final int MSG_SENSORT_EVENT = 1;
+
+    // @GuardedBy("this")
+    private final Map<Integer, Set<CarSensorManager.CarSensorEventListener>> mListenersMultiMap;
+    private final LocationManager mLocationManager;
+    private final SensorManager mSensorManager;
+    private final Sensor mAccelerometerSensor;
+    private final Sensor mMagneticFieldSensor;
+    private final Sensor mGyroscopeSensor;
+    private final int[] mSupportedSensors;
+
+    // @GuardedBy("this")
+    private Location mLastLocation;
+    // @GuardedBy("this")
+    private GpsStatus mLastGpsStatus;
+    // @GuardedBy("this")
+    private float[] mLastAccelerometerData = new float[3];
+    // @GuardedBy("this")
+    private float[] mLastMagneticFieldData = new float[3];
+    // @GuardedBy("this")
+    private float[] mLastGyroscopeData = new float[3];
+    // @GuardedBy("this")
+    private float[] mR = new float[16];
+    // @GuardedBy("this")
+    private float[] mI = new float[16];
+    // @GuardedBy("this")
+    private float[] mOrientation = new float[3];
+    // @GuardedBy("this")
+    private long mLastLocationTime;
+    // @GuardedBy("this")
+    private long mLastGpsStatusTime;
+    // @GuardedBy("this")
+    private long mLastAccelerometerDataTime;
+    // @GuardedBy("this")
+    private long mLastMagneticFieldDataTime;
+    // @GuardedBy("this")
+    private long mLastGyroscopeDataTime;
+
+    private final GpsStatus.Listener mGpsStatusListener = new GpsStatus.Listener() {
+            @Override
+            public void onGpsStatusChanged(int event) {
+                if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
+                    synchronized (CarSensorsProxy.this) {
+                        mLastGpsStatus = mLocationManager.getGpsStatus(mLastGpsStatus);
+                        mLastGpsStatusTime = System.nanoTime();
+                    }
+                    pushSensorChanges(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE);
+                }
+            }
+        };
+
+    private final LocationListener mLocationListener = new LocationListener() {
+            @Override
+            public void onLocationChanged(Location location) {
+                synchronized (CarSensorsProxy.this) {
+                    mLastLocation = location;
+                    mLastLocationTime = System.nanoTime();
+                }
+                pushSensorChanges(CarSensorManager.SENSOR_TYPE_LOCATION);
+            }
+
+            @Override
+            public void onProviderEnabled(String provider) {
+            }
+
+            @Override
+            public void onProviderDisabled(String provider) {
+            }
+
+            @Override
+            public void onStatusChanged(String provider, int status, Bundle extras) {
+            }
+        };
+
+    private final SensorEventListener mSensorListener = new SensorEventListener() {
+            @Override
+            public void onSensorChanged(SensorEvent event) {
+                int type = event.sensor.getType();
+                synchronized (CarSensorsProxy.this) {
+                    switch (type) {
+                        case Sensor.TYPE_GYROSCOPE:
+                            System.arraycopy(event.values, 0, mLastGyroscopeData, 0, 3);
+                            mLastGyroscopeDataTime = System.nanoTime();
+                            pushSensorChanges(CarSensorManager.SENSOR_TYPE_GYROSCOPE);
+                            break;
+                        case Sensor.TYPE_MAGNETIC_FIELD:
+                            System.arraycopy(event.values, 0, mLastMagneticFieldData, 0, 3);
+                            mLastMagneticFieldDataTime = System.nanoTime();
+                            pushSensorChanges(CarSensorManager.SENSOR_TYPE_COMPASS);
+                            break;
+                        case Sensor.TYPE_ACCELEROMETER:
+                            System.arraycopy(event.values, 0, mLastAccelerometerData, 0, 3);
+                            mLastAccelerometerDataTime = System.nanoTime();
+                            pushSensorChanges(CarSensorManager.SENSOR_TYPE_ACCELEROMETER);
+                            pushSensorChanges(CarSensorManager.SENSOR_TYPE_COMPASS);
+                            break;
+                        default:
+                            Log.w(TAG, "Unexpected sensor event type: " + type);
+                            // Should never happen.
+                            return;
+                    }
+                }
+            }
+
+            @Override
+            public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+        };
+
+    private final Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_SENSORT_EVENT:
+                        int sensorType = msg.arg1;
+                        Collection<CarSensorManager.CarSensorEventListener> listenersCollection;
+                        synchronized (CarSensorsProxy.this) {
+                            listenersCollection = mListenersMultiMap.get(sensorType);
+                        }
+                        CarSensorEvent event = (CarSensorEvent) msg.obj;
+                        if (event != null) {
+                            for (CarSensorManager.CarSensorEventListener listener :
+                                         listenersCollection) {
+                                listener.onSensorChanged(event);
+                            }
+                        }
+                        break;
+                    default:
+                        Log.w(TAG, "Unexpected msg dispatched. msg: " + msg);
+                        super.handleMessage(msg);
+                }
+            }
+        };
+
+    CarSensorsProxy(Context context) {
+        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+        mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+        mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        mMagneticFieldSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+        mGyroscopeSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
+        mListenersMultiMap = new HashMap<Integer, Set<CarSensorManager.CarSensorEventListener>>();
+        mSupportedSensors = initSupportedSensors(context);
+
+    }
+
+    private int[] initSupportedSensors(Context context) {
+        Set<Integer> features = new HashSet<>();
+        PackageManager packageManager = context.getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)
+                && packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)) {
+            features.add(CarSensorManager.SENSOR_TYPE_COMPASS);
+        }
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)) {
+            features.add(CarSensorManager.SENSOR_TYPE_ACCELEROMETER);
+        }
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_GYROSCOPE)) {
+            features.add(CarSensorManager.SENSOR_TYPE_GYROSCOPE);
+        }
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION)) {
+            features.add(CarSensorManager.SENSOR_TYPE_LOCATION);
+            features.add(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE);
+        }
+        return toIntArray(features);
+    }
+
+    private static int[] toIntArray(Collection<Integer> collection) {
+        int len = collection.size();
+        int[] arr = new int[len];
+        int arrIndex = 0;
+        for (Integer item : collection) {
+            arr[arrIndex] = item;
+            arrIndex++;
+        }
+        return arr;
+    }
+
+
+    public boolean isSensorSupported(int sensorType) {
+        for (int sensor : mSupportedSensors) {
+            if (sensor == sensorType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public int[] getSupportedSensors() {
+        return mSupportedSensors;
+    }
+
+    public boolean registerSensorListener(CarSensorManager.CarSensorEventListener listener,
+            int sensorType, int rate) {
+        // current implementation ignores rate.
+        boolean sensorSetChanged = false;
+        synchronized (this) {
+            if (mListenersMultiMap.get(sensorType) == null) {
+                mListenersMultiMap.put(sensorType,
+                                       new HashSet<CarSensorManager.CarSensorEventListener>());
+                sensorSetChanged = true;
+            }
+            mListenersMultiMap.get(sensorType).add(listener);
+        }
+        if (sensorSetChanged) {
+            updateSensorListeners();
+        }
+        return true;
+    }
+
+    public void unregisterSensorListener(CarSensorManager.CarSensorEventListener listener,
+            int sensorType) {
+        if (listener == null) {
+            return;
+        }
+        boolean sensorSetChanged = false;
+        synchronized (this) {
+            Set<CarSensorManager.CarSensorEventListener> sensorTypeListeneres =
+                    mListenersMultiMap.get(sensorType);
+            if (sensorTypeListeneres != null) {
+                sensorTypeListeneres.remove(listener);
+                if (sensorTypeListeneres.isEmpty()) {
+                    mListenersMultiMap.remove(sensorType);
+                    sensorSetChanged = true;
+                }
+            }
+        }
+        if (sensorSetChanged) {
+            updateSensorListeners();
+        };
+    }
+
+    public void unregisterSensorListener(CarSensorManager.CarSensorEventListener listener) {
+        if (listener == null) {
+            return;
+        }
+        boolean sensorSetChanged = false;
+        synchronized (this) {
+            for (Map.Entry<Integer, Set<CarSensorManager.CarSensorEventListener>> entry :
+                         mListenersMultiMap.entrySet()) {
+                if (entry.getValue().contains(listener)) {
+                    entry.getValue().remove(listener);
+                }
+                if (entry.getValue().isEmpty()) {
+                    sensorSetChanged = true;
+                    mListenersMultiMap.remove(entry.getKey());
+                }
+            }
+        }
+        if (sensorSetChanged) {
+            updateSensorListeners();
+        };
+    }
+
+    public CarSensorEvent getLatestSensorEvent(int type) {
+        return getSensorEvent(type);
+    }
+
+    private void pushSensorChanges(int sensorType) {
+        CarSensorEvent event = getSensorEvent(sensorType);
+        if (event == null) {
+            return;
+        }
+        Message msg = mHandler.obtainMessage(MSG_SENSORT_EVENT, sensorType, 0, event);
+        mHandler.sendMessage(msg);
+    }
+
+    private CarSensorEvent getSensorEvent(int sensorType) {
+        CarSensorEvent event = null;
+        synchronized (this) {
+            switch (sensorType) {
+                case CarSensorManager.SENSOR_TYPE_COMPASS:
+                    if (mLastMagneticFieldDataTime != 0 && mLastAccelerometerDataTime != 0) {
+                        event = new CarSensorEvent(sensorType, Math.max(mLastMagneticFieldDataTime,
+                                mLastAccelerometerDataTime), 3, 0);
+                        SensorManager.getRotationMatrix(mR, mI, mLastAccelerometerData,
+                                mLastMagneticFieldData);
+                        SensorManager.getOrientation(mR, mOrientation);
+                        event.floatValues[CarSensorEvent.INDEX_COMPASS_BEARING] =
+                                (float) Math.toDegrees(mOrientation[0]);
+                        event.floatValues[CarSensorEvent.INDEX_COMPASS_PITCH] =
+                                (float) Math.toDegrees(mOrientation[1]);
+                        event.floatValues[CarSensorEvent.INDEX_COMPASS_ROLL] =
+                                (float) Math.toDegrees(mOrientation[2]);
+                    }
+                    break;
+                case CarSensorManager.SENSOR_TYPE_LOCATION:
+                    if (mLastLocationTime != 0) {
+                        event = new CarSensorEvent(sensorType, mLastLocationTime, 6, 3);
+                        populateLocationCarSensorEvent(event, mLastLocation);
+                    }
+                    break;
+                case CarSensorManager.SENSOR_TYPE_ACCELEROMETER:
+                    if (mLastAccelerometerDataTime != 0) {
+                        event = new CarSensorEvent(sensorType, mLastAccelerometerDataTime, 3, 0);
+                        event.floatValues[CarSensorEvent.INDEX_ACCELEROMETER_X] =
+                                mLastAccelerometerData[0];
+                        event.floatValues[CarSensorEvent.INDEX_ACCELEROMETER_Y] =
+                                mLastAccelerometerData[1];
+                        event.floatValues[CarSensorEvent.INDEX_ACCELEROMETER_Z] =
+                                mLastAccelerometerData[2];
+                    }
+                    break;
+                case CarSensorManager.SENSOR_TYPE_GPS_SATELLITE:
+                    if (mLastGpsStatusTime != 0) {
+                        event = createGpsStatusCarSensorEvent(mLastGpsStatus);
+                    }
+                    break;
+                case CarSensorManager.SENSOR_TYPE_GYROSCOPE:
+                    if (mLastGyroscopeDataTime != 0) {
+                        event = new CarSensorEvent(sensorType, mLastGyroscopeDataTime, 3, 0);
+                        event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_X] = mLastGyroscopeData[0];
+                        event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_Y] = mLastGyroscopeData[1];
+                        event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_Z] = mLastGyroscopeData[2];
+                    }
+                    break;
+                default:
+                    // Should not happen.
+                    Log.w(TAG, "[getSensorEvent]: Unsupported sensor type:" + sensorType);
+                    return null;
+            }
+        }
+        return event;
+    }
+
+    private void populateLocationCarSensorEvent(CarSensorEvent event, Location location) {
+        if (location == null) {
+            return;
+        }
+        int present = 0;
+        present |= (0x1 << CarSensorEvent.INDEX_LOCATION_LONGITUDE);
+        event.intValues[CarSensorEvent.INDEX_LOCATION_LATITUDE_INTS] =
+                (int) (location.getLongitude() * 1E7);
+
+        present |= (0x1 << CarSensorEvent.INDEX_LOCATION_LATITUDE);
+        event.intValues[CarSensorEvent.INDEX_LOCATION_LATITUDE_INTS] =
+                (int) (location.getLatitude() * 1E7);
+
+        if (location.hasAccuracy()) {
+            present |= (0x1 << CarSensorEvent.INDEX_LOCATION_ACCURACY);
+            event.floatValues[CarSensorEvent.INDEX_LOCATION_ACCURACY] = location.getAccuracy();
+        }
+
+        if (location.hasAltitude()) {
+            present |= (0x1 << CarSensorEvent.INDEX_LOCATION_ALTITUDE);
+            event.floatValues[CarSensorEvent.INDEX_LOCATION_ALTITUDE] =
+                    (float) location.getAltitude();
+        }
+
+        if (location.hasSpeed()) {
+            present |= (0x1 << CarSensorEvent.INDEX_LOCATION_SPEED);
+            event.floatValues[CarSensorEvent.INDEX_LOCATION_SPEED] = location.getSpeed();
+        }
+
+        if (location.hasBearing()) {
+            present |= (0x1 << CarSensorEvent.INDEX_LOCATION_BEARING);
+            event.floatValues[CarSensorEvent.INDEX_LOCATION_BEARING] = location.getBearing();
+        }
+
+        event.intValues[0] = present;
+    }
+
+    private CarSensorEvent createGpsStatusCarSensorEvent(GpsStatus gpsStatus) {
+        CarSensorEvent event = null;
+
+        if (gpsStatus == null) {
+            return event;
+        }
+
+        int numberInView = 0;
+        int numberInUse = 0;
+        for (GpsSatellite satellite : gpsStatus.getSatellites()) {
+            ++numberInView;
+            if (satellite.usedInFix()) {
+                ++numberInUse;
+            }
+        }
+        int floatValuesSize = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL * numberInView
+                + CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET;
+        int intValuesSize = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_INTERVAL * numberInView
+                + CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_OFFSET;
+        event = new CarSensorEvent(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE, mLastGpsStatusTime,
+                floatValuesSize, intValuesSize);
+        event.intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_USE] = numberInUse;
+        event.intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_VIEW] = numberInView;
+        int i = 0;
+        for (GpsSatellite satellite : gpsStatus.getSatellites()) {
+            int iInt = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_OFFSET
+                    + CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_INTERVAL * i;
+            int iFloat = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET
+                    + CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL * i;
+            event.floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_PRN_OFFSET] =
+                    satellite.getPrn();
+            event.floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_SNR_OFFSET] =
+                    satellite.getSnr();
+            event.floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_AZIMUTH_OFFSET] =
+                    satellite.getAzimuth();
+            event.floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_ELEVATION_OFFSET] =
+                    satellite.getElevation();
+            event.intValues[iInt] = satellite.usedInFix() ? 1 : 0;
+            i++;
+        }
+        return event;
+    }
+
+    private void updateSensorListeners() {
+        Set<Integer> activeSensors;
+        synchronized (this) {
+            activeSensors = mListenersMultiMap.keySet();
+        }
+        if (activeSensors.contains(CarSensorManager.SENSOR_TYPE_LOCATION)) {
+            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
+                    mLocationListener);
+        } else {
+            mLocationManager.removeUpdates(mLocationListener);
+        }
+
+        if (activeSensors.contains(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE)) {
+            mLocationManager.addGpsStatusListener(mGpsStatusListener);
+        } else {
+            mLocationManager.removeGpsStatusListener(mGpsStatusListener);
+        }
+
+        if (activeSensors.contains(CarSensorManager.SENSOR_TYPE_ACCELEROMETER)
+                || activeSensors.contains(CarSensorManager.SENSOR_TYPE_COMPASS)) {
+            mSensorManager.registerListener(mSensorListener, mAccelerometerSensor,
+                    SensorManager.SENSOR_DELAY_FASTEST);
+        } else {
+            mSensorManager.unregisterListener(mSensorListener, mAccelerometerSensor);
+        }
+
+        if (activeSensors.contains(CarSensorManager.SENSOR_TYPE_COMPASS)) {
+            mSensorManager.registerListener(mSensorListener, mMagneticFieldSensor,
+                    SensorManager.SENSOR_DELAY_FASTEST);
+        } else {
+            mSensorManager.unregisterListener(mSensorListener, mMagneticFieldSensor);
+        }
+
+        if (activeSensors.contains(CarSensorManager.SENSOR_TYPE_GYROSCOPE)) {
+            mSensorManager.registerListener(mSensorListener, mGyroscopeSensor,
+                    SensorManager.SENSOR_DELAY_FASTEST);
+        } else {
+            mSensorManager.unregisterListener(mSensorListener, mGyroscopeSensor);
+        }
+    }
+}
diff --git a/libvehiclenetwork/java/src/com/android/car/vehiclenetwork/VehicleNetworkProtoUtil.java b/libvehiclenetwork/java/src/com/android/car/vehiclenetwork/VehicleNetworkProtoUtil.java
index 5dc5a6f..ac2f393 100644
--- a/libvehiclenetwork/java/src/com/android/car/vehiclenetwork/VehicleNetworkProtoUtil.java
+++ b/libvehiclenetwork/java/src/com/android/car/vehiclenetwork/VehicleNetworkProtoUtil.java
@@ -18,6 +18,8 @@
 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 
+import java.util.Arrays;
+
 public class VehicleNetworkProtoUtil {
     public static String VehiclePropValueToString(VehiclePropValue value) {
         StringBuilder sb = new StringBuilder();
@@ -25,6 +27,8 @@
         sb.append(Integer.toHexString(value.getProp()));
         sb.append(" type:0x");
         sb.append(Integer.toHexString(value.getValueType()));
+        sb.append(" floatValues:" + Arrays.toString(value.getFloatValuesList().toArray()));
+        sb.append(" integerValues:" + Arrays.toString(value.getInt32ValuesList().toArray()));
         return sb.toString();
     }
 
diff --git a/tests/vehicle_hal_test/Android.mk b/tests/vehicle_hal_test/Android.mk
new file mode 100644
index 0000000..77bc6f8
--- /dev/null
+++ b/tests/vehicle_hal_test/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := AndroidVehicleHalTests
+
+# for system|priviledged permission.
+LOCAL_CERTIFICATE := platform
+
+LOCAL_MODULE_TAGS := tests
+
+# When built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := libvehiclenetwork-java
+
+LOCAL_JAVA_LIBRARIES := android.car android.test.runner
+
+include $(BUILD_PACKAGE)
diff --git a/tests/vehicle_hal_test/AndroidManifest.xml b/tests/vehicle_hal_test/AndroidManifest.xml
new file mode 100644
index 0000000..5fbb62d
--- /dev/null
+++ b/tests/vehicle_hal_test/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+        package="com.android.car.vehiclenetwork.haltest"
+        android:sharedUserId="android.uid.system" >
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+            android:targetPackage="com.android.car.vehiclenetwork.haltest"
+            android:label="Tests for vehicle hal using vehicle network service"/>
+
+    <application android:label="VehicleHalTest">
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".TestCarProxyActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/HvacVnsHalTest.java b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/HvacVnsHalTest.java
new file mode 100644
index 0000000..6111746
--- /dev/null
+++ b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/HvacVnsHalTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.vehiclenetwork.haltest;
+
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_AC_ON;
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_DEFROSTER;
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_DIRECTION;
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_SPEED;
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_MAX_AC_ON;
+import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_RECIRC_ON;
+
+import android.util.Log;
+
+import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleHvacFanDirection;
+import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess;
+import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
+import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
+
+/**
+ * Test HVAC vehicle HAL using vehicle network service.
+ */
+public class HvacVnsHalTest extends VnsHalBaseTestCase {
+
+    public void testAcProperty() throws Exception {
+        int propertyId = VEHICLE_PROPERTY_HVAC_AC_ON;
+        if (!isPropertyAvailable(propertyId)) {
+            return;
+        }
+
+        VehiclePropConfig config = mConfigsMap.get(propertyId);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        int zone = getFirstZoneForProperty(propertyId);
+        setPropertyAndVerify(propertyId, zone, false);
+
+        mVehicleNetwork.subscribe(propertyId, 0, 0);
+        mListener.reset();
+        mListener.addExpectedValues(propertyId, zone, true);
+        setPropertyAndVerify(propertyId, zone, true);
+        mListener.waitAndVerifyValues();
+    }
+
+    public void testRecirculateProperty() {
+        int propertyId = VEHICLE_PROPERTY_HVAC_RECIRC_ON;
+        if (!isPropertyAvailable(propertyId)) {
+            return;
+        }
+        VehiclePropConfig config = mConfigsMap.get(propertyId);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        // Verify subsequent calls ends-up with right value.
+        mVehicleNetwork.setBooleanProperty(propertyId, false);
+        mVehicleNetwork.setBooleanProperty(propertyId, true);
+        mVehicleNetwork.setBooleanProperty(propertyId, false);
+        mVehicleNetwork.setBooleanProperty(propertyId, true);
+        verifyValue(propertyId, true);
+
+        // Verify subsequent calls ends-up with right value.
+        mVehicleNetwork.setBooleanProperty(propertyId, false);
+        mVehicleNetwork.setBooleanProperty(propertyId, true);
+        mVehicleNetwork.setBooleanProperty(propertyId, false);
+        verifyValue(propertyId, false);
+
+        setPropertyAndVerify(propertyId, false);
+        setPropertyAndVerify(propertyId, true);
+        setPropertyAndVerify(propertyId, false);
+    }
+
+    public void testMaxAcProperty() throws Exception {
+        if (!isPropertyAvailable(
+                VEHICLE_PROPERTY_HVAC_MAX_AC_ON,
+                VEHICLE_PROPERTY_HVAC_AC_ON,
+                VEHICLE_PROPERTY_HVAC_RECIRC_ON)) {
+            return;
+        }
+        VehiclePropConfig config = mConfigsMap.get(VEHICLE_PROPERTY_HVAC_MAX_AC_ON);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        int acZone = getFirstZoneForProperty(VEHICLE_PROPERTY_HVAC_AC_ON);
+
+        // Turn off related properties.
+        setPropertyAndVerify(VEHICLE_PROPERTY_HVAC_MAX_AC_ON, false);
+        setPropertyAndVerify(VEHICLE_PROPERTY_HVAC_AC_ON, acZone, false);
+        setPropertyAndVerify(VEHICLE_PROPERTY_HVAC_RECIRC_ON, false);
+
+        // Now turning max A/C and verify that other related HVAC props turned on.
+        mVehicleNetwork.subscribe(VEHICLE_PROPERTY_HVAC_AC_ON, 0f, acZone);
+        mVehicleNetwork.subscribe(VEHICLE_PROPERTY_HVAC_RECIRC_ON, 0f);
+        mListener.reset();
+        mListener.addExpectedValues(VEHICLE_PROPERTY_HVAC_AC_ON, acZone, true);
+        mListener.addExpectedValues(VEHICLE_PROPERTY_HVAC_RECIRC_ON, 0, true);
+        setPropertyAndVerify(VEHICLE_PROPERTY_HVAC_MAX_AC_ON, true);
+        verifyValue(VEHICLE_PROPERTY_HVAC_AC_ON, acZone, true);
+        verifyValue(VEHICLE_PROPERTY_HVAC_RECIRC_ON, true);
+        mListener.waitAndVerifyValues();
+
+        // When max A/C turned off, A/C should remain to be turned on, but circulation should has
+        // the value it had before turning max A/C on, which if OFF in this case.
+        setPropertyAndVerify(VEHICLE_PROPERTY_HVAC_MAX_AC_ON, false);
+        verifyValue(VEHICLE_PROPERTY_HVAC_AC_ON, acZone, true);
+        verifyValue(VEHICLE_PROPERTY_HVAC_RECIRC_ON, false);
+    }
+
+    public void testDefroster() {
+        final int propertyId = VEHICLE_PROPERTY_HVAC_DEFROSTER;
+        if (!isPropertyAvailable(propertyId)) {
+            return;
+        }
+
+        VehiclePropConfig config = mConfigsMap.get(propertyId);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        iterateOnZones(config, (message, zone, minValue, maxValue) -> {
+            Log.i(TAG, "testDefroster, " + message);
+            setPropertyAndVerify(propertyId, zone, false);
+            setPropertyAndVerify(propertyId, zone, true);
+        });
+    }
+
+    public void testFanSpeed() throws Exception {
+        if (!isPropertyAvailable(VEHICLE_PROPERTY_HVAC_FAN_SPEED)) {
+            return;
+        }
+
+        VehiclePropConfig config = mConfigsMap.get(VEHICLE_PROPERTY_HVAC_FAN_SPEED);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        verifyIntZonedProperty(VEHICLE_PROPERTY_HVAC_FAN_SPEED);
+    }
+
+    public void testFanDirection() throws Exception {
+        final int propertyId = VEHICLE_PROPERTY_HVAC_FAN_DIRECTION;
+
+        if (!isPropertyAvailable(propertyId)) {
+            return;
+        }
+
+        VehiclePropConfig config = mConfigsMap.get(propertyId);
+        assertEquals(VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32, config.getValueType());
+        assertEquals(VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, config.getAccess());
+
+        // Assert setting edge-case values.
+        iterateOnZones(config, (message, zone, minValue, maxValue) -> {
+            setPropertyAndVerify(message, propertyId, zone, minValue);
+            setPropertyAndVerify(message, propertyId, zone, maxValue);
+        });
+
+        iterateOnZones(config, ((message, zone, minValue, maxValue)
+                -> setPropertyAndVerify(message, propertyId, zone,
+                        VehicleHvacFanDirection.VEHICLE_HVAC_FAN_DIRECTION_DEFROST_AND_FLOOR)));
+    }
+}
diff --git a/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/RecordingVehicleNetworkListener.java b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/RecordingVehicleNetworkListener.java
new file mode 100644
index 0000000..c10dbd0
--- /dev/null
+++ b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/RecordingVehicleNetworkListener.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.vehiclenetwork.haltest;
+
+import static java.lang.Integer.toHexString;
+import static junit.framework.Assert.assertTrue;
+
+import android.util.Log;
+
+import com.android.car.vehiclenetwork.VehicleNetwork.VehicleNetworkListener;
+import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
+import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
+import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
+import com.android.car.vehiclenetwork.VehicleNetworkProtoUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * This class must be used in testing environment only. Here's an example of usage:
+ * <ul>
+ *     <li>listener.reset();
+ *     <li>listener.addExpectedValues(myPropertyId, myZone, 10, 20, 30)
+ *     <li>... set values through VehicleNetworkService ...
+ *     <li>listener.waitAndVerifyValues()
+ *</ul>
+ *
+ */
+class RecordingVehicleNetworkListener implements VehicleNetworkListener {
+
+    private final static String TAG = VnsHalBaseTestCase.TAG;
+    private final static int EVENTS_WAIT_TIMEOUT_MS = 2000;
+
+    private final Set<NormalizedValue> mExpectedValues = new HashSet<>();
+    // Using Set here instead of List as we probably shouldn't assert the order event was received.
+    private final Set<NormalizedValue> mRecordedEvents = new HashSet<>();
+
+    synchronized void reset() {
+        mExpectedValues.clear();
+        mRecordedEvents.clear();
+    }
+
+    void addExpectedValues(int propertyId, int zone, Object... values) {
+        for (Object value : values) {
+            mExpectedValues.add(NormalizedValue.createFor(propertyId, zone, value));
+        }
+    }
+
+    /**
+     * Waits for events to come for #EVENTS_WAIT_TIMEOUT_MS milliseconds and asserts that recorded
+     * values match with expected.
+     * */
+    synchronized void waitAndVerifyValues() throws InterruptedException {
+        long currentTime = System.currentTimeMillis();
+        long deadline = currentTime + EVENTS_WAIT_TIMEOUT_MS;
+        while (currentTime < deadline && !isExpectedMatchedRecorded()) {
+            wait(deadline - currentTime);
+            currentTime = System.currentTimeMillis();
+        }
+        assertTrue("Expected values: " + Arrays.toString(mExpectedValues.toArray())
+                        + " doesn't match recorded: " + Arrays.toString(mRecordedEvents.toArray()),
+                isExpectedMatchedRecorded());
+    }
+
+    private boolean isExpectedMatchedRecorded() {
+        for (NormalizedValue expectedValue : mExpectedValues) {
+            if (!mRecordedEvents.contains(expectedValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void onVehicleNetworkEvents(VehiclePropValues values) {
+        for (VehiclePropValue value : values.getValuesList()) {
+            Log.d(TAG, "onVehicleNetworkEvents, value: "
+                    + VehicleNetworkProtoUtil.VehiclePropValueToString(value));
+
+            synchronized (this) {
+                mRecordedEvents.add(NormalizedValue.createFor(value));
+                notifyAll();
+            }
+        }
+    }
+
+    @Override
+    public void onHalError(int errorCode, int property, int operation) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void onHalRestart(boolean inMocking) {
+        // TODO Auto-generated method stub
+    }
+
+    // To be used to compare expected vs recorded values.
+    private static class NormalizedValue {
+        private final int propertyId;
+        private final int zone;
+        private final List<Object> value;
+
+        static NormalizedValue createFor(VehiclePropValue value) {
+            return new NormalizedValue(value.getProp(), value.getZone(), getObjectValue(value));
+        }
+
+        static NormalizedValue createFor(int propertyId, int zone, Object value) {
+            return new NormalizedValue(propertyId, zone, wrapSingleObjectToList(value));
+        }
+
+        // Do not call this ctor directly, use appropriate factory methods to create an object.
+        private NormalizedValue(int propertyId, int zone, List<Object> value) {
+            this.propertyId = propertyId;
+            this.zone = zone;
+            this.value = value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            NormalizedValue propValue = (NormalizedValue) o;
+            return propertyId == propValue.propertyId &&
+                    zone == propValue.zone &&
+                    Objects.equals(value, propValue.value);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(propertyId, zone, value);
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + " { "
+                    + "prop: 0x" + toHexString(propertyId)
+                    + ", zone: 0x" + toHexString(zone)
+                    + ", value: " + Arrays.toString(value.toArray())
+                    + " }";
+        }
+
+        private static List<Object> wrapSingleObjectToList(Object value) {
+            if (value instanceof Integer
+                    || value instanceof Float) {
+                List<Object> list = new ArrayList<>(1);
+                list.add(value);
+                return list;
+            } else if (value instanceof Boolean) {
+                List<Object> list = new ArrayList<>(1);
+                list.add((Boolean)value ? 1 : 0);
+                return list;
+            } else if (value instanceof Collection<?>) {
+                return new ArrayList<>((Collection<?>) value);
+            } else {
+                throw new IllegalArgumentException("Unexpected type: " + value);
+            }
+        }
+
+        // Converts any VehiclePropValue to either ArrayList<Integer> or ArrayList<Float>
+        private static List<Object> getObjectValue(VehiclePropValue val) {
+            switch (val.getValueType()) {
+                case VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_INT32:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
+                    return new ArrayList<>(val.getInt32ValuesList());
+                case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
+                case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
+                    return new ArrayList<>(val.getFloatValuesList());
+                default:
+                    throw new IllegalArgumentException("Unexpected type: " + val.getValueType());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/VnsHalBaseTestCase.java b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/VnsHalBaseTestCase.java
new file mode 100644
index 0000000..adcc336
--- /dev/null
+++ b/tests/vehicle_hal_test/src/com/android/car/vehiclenetwork/haltest/VnsHalBaseTestCase.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.vehiclenetwork.haltest;
+
+import static java.lang.Integer.toHexString;
+
+import android.car.VehicleZoneUtil;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.car.vehiclenetwork.VehicleNetwork;
+import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
+import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Base class for testing vehicle HAL using vehicle network service (VNS).
+ */
+public class VnsHalBaseTestCase extends AndroidTestCase {
+
+    protected static final String TAG = "VnsHalTest";
+
+    protected static final int PROP_TIMEOUT_MS = 5000;
+    protected static final int NO_ZONE = -1;
+
+    private final HandlerThread mHandlerThread =
+            new HandlerThread(VnsHalBaseTestCase.class.getSimpleName());
+    protected VehicleNetwork mVehicleNetwork;
+    protected RecordingVehicleNetworkListener mListener;
+
+    protected Map<Integer, VehiclePropConfig> mConfigsMap;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHandlerThread.start();
+        mListener = new RecordingVehicleNetworkListener();
+        mVehicleNetwork = VehicleNetwork.createVehicleNetwork(mListener,
+                mHandlerThread.getLooper());
+        setupConfigsMap();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mHandlerThread.quit();
+    }
+
+    private void setupConfigsMap() {
+        mConfigsMap = new HashMap<>();
+        for (VehiclePropConfig config : mVehicleNetwork.listProperties().getConfigsList()) {
+            mConfigsMap.put(config.getProp(), config);
+        }
+        assertTrue(mConfigsMap.size() > 0);
+    }
+
+    protected boolean isPropertyAvailable(int... properties) {
+        assertTrue(properties.length > 0);
+
+        for (int propertyId : properties) {
+            if (!mConfigsMap.containsKey(propertyId)) {
+                // Property is not supported by vehicle HAL, nothing to test.
+                Log.w(TAG, "Property: 0x" + Integer.toHexString(propertyId)
+                        + " is not available, ignoring...");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected void setPropertyAndVerify(int propertyId, boolean switchOn) {
+        setPropertyAndVerify(propertyId, NO_ZONE, switchOn);
+    }
+
+    protected void setPropertyAndVerify(int propertyId, int zone, boolean switchOn) {
+        int val = switchOn ? 1 : 0;
+
+        if (zone == NO_ZONE) {
+            mVehicleNetwork.setBooleanProperty(propertyId, switchOn);
+        } else {
+            mVehicleNetwork.setZonedBooleanProperty(propertyId, zone, switchOn);
+        }
+        verifyValue(propertyId, zone, val);
+    }
+
+    protected void setPropertyAndVerify(String message, int propertyId, int zone, int value) {
+        if (zone == NO_ZONE) {
+            mVehicleNetwork.setIntProperty(propertyId, value);
+        } else {
+            mVehicleNetwork.setZonedIntProperty(propertyId, zone, value);
+        }
+        verifyValue(message, propertyId, zone, value);
+    }
+
+    protected void verifyValue(int propertyId, boolean val) {
+        verifyValue(propertyId, NO_ZONE, val);
+    }
+
+    protected void verifyValue(int propertyId, int zone, boolean val) {
+        int intVal = val ? 1 : 0;
+        assertEquals(intVal, waitForIntValue(propertyId, zone, intVal));
+    }
+
+    protected void verifyValue(int propertyId, int zone, int val) {
+        assertEquals(val, waitForIntValue(propertyId, zone, val));
+    }
+
+    protected void verifyValue(String message, int propertyId, int zone, int val) {
+        assertEquals(message, val, waitForIntValue(propertyId, zone, val));
+    }
+
+    protected int getFirstZoneForProperty(int propertyId) {
+        return VehicleZoneUtil.getFirstZone(mConfigsMap.get(propertyId).getZones());
+    }
+
+    protected void verifyIntZonedProperty(int propertyId) throws InterruptedException {
+        if (!isPropertyAvailable(propertyId)) {
+            return;
+        }
+
+        VehiclePropConfig config = mConfigsMap.get(propertyId);
+
+        // Assert setting edge-case values.
+        iterateOnZones(config, (message, zone, minValue, maxValue) -> {
+            setPropertyAndVerify(message, propertyId, zone, minValue);
+            setPropertyAndVerify(message, propertyId, zone, maxValue);
+        });
+
+        // Setting out of the range values.
+        iterateOnZones(config, ((message, zone, minValue, maxValue) -> {
+            mVehicleNetwork.setZonedIntProperty(propertyId, zone, minValue - 1);
+            verifyValue(message, propertyId, zone, minValue);
+
+            mVehicleNetwork.setZonedIntProperty(propertyId, zone, maxValue + 20);
+            verifyValue(message, propertyId, zone, maxValue);
+        }));
+
+        // Verify that subsequent SET calls will result in correct value at the end.
+        mVehicleNetwork.subscribe(propertyId, 0f, config.getZones());
+        int zone = VehicleZoneUtil.getFirstZone(config.getZones());
+        int minValue = config.getInt32Mins(0);
+        int maxValue = config.getInt32Maxs(0);
+        int finalValue = (minValue + maxValue) / 2;
+        mListener.reset();
+        // We can only expect to see finalValue in the events as vehicle HAL may batch
+        // set commands and use only last value.
+        mListener.addExpectedValues(propertyId, zone, finalValue);
+        mVehicleNetwork.setZonedIntProperty(propertyId, zone, minValue);
+        mVehicleNetwork.setZonedIntProperty(propertyId, zone, maxValue);
+        mVehicleNetwork.setZonedIntProperty(propertyId, zone, finalValue);
+        verifyValue(propertyId, zone, finalValue);
+        mListener.waitAndVerifyValues();
+        mVehicleNetwork.unsubscribe(propertyId);
+    }
+
+    protected int waitForIntValue(int propertyId, int zone, int expectedValue) {
+        int actualValue = mVehicleNetwork.getZonedIntProperty(propertyId, zone);
+        long deadline = System.currentTimeMillis() + PROP_TIMEOUT_MS;
+
+        while (System.currentTimeMillis() <= deadline && actualValue != expectedValue) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException ex) {
+                throw new RuntimeException(ex);
+            }
+            actualValue = mVehicleNetwork.getZonedIntProperty(propertyId, zone);
+        }
+
+        return actualValue;
+    }
+
+    protected void iterateOnZones(VehiclePropConfig config, IntZonesFunctor f) {
+        int[] zones = VehicleZoneUtil.listAllZones(config.getZones());
+        int zoneIndex = 0;
+        boolean isBooleanType = config.getValueType() ==
+                VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN;
+
+        for (int zone : zones) {
+            int minValue = isBooleanType ? 0 : config.getInt32Mins(zoneIndex);
+            int maxValue = isBooleanType ? 1 : config.getInt32Maxs(zoneIndex);
+            String message = "PropertyId: 0x" + toHexString(config.getProp())
+                    + ", zone[" + zoneIndex + "]: 0x" + toHexString(zone);
+            f.func(message, zone, minValue, maxValue);
+            zoneIndex++;
+        }
+
+    }
+
+    protected interface IntZonesFunctor {
+        void func(String message, int zone, int minValue, int maxValue);
+    }
+
+
+}
