Migrating Car service to new Vehicle HAL

- make car service work directly with Vehicle HAL
- getting rid of protobufs and dependencies on VNS
- get rid of CarTestManager / CarTestService and refactor
  tests accordingly
- reworked ICarImpl to pass dependencies rather than
  using singletons for better testing experience

Test: existing test should work, although some of the tests
      (esp. audio) are broken and we will fix them in follow up CLs

Bug: b/31971746
Change-Id: I229969af332304ba3b1718f130cdf22038e86fad
Tests: tests adjusted to new data structures
diff --git a/service/src/com/android/car/BootReceiver.java b/service/src/com/android/car/BootReceiver.java
index ea96ca6..10c6f2f 100644
--- a/service/src/com/android/car/BootReceiver.java
+++ b/service/src/com/android/car/BootReceiver.java
@@ -23,8 +23,6 @@
 import android.os.UserHandle;
 import android.util.Log;
 
-import com.android.car.hal.VehicleHal;
-
 
 /**
  *  When system boots up, start car service.
@@ -34,10 +32,9 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         Log.w(CarLog.TAG_SERVICE, "Starting...");
-        VehicleHal hal = VehicleHal.getInstance();
-        Intent carServiceintent = new Intent();
-        carServiceintent.setPackage(context.getPackageName());
-        carServiceintent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);
-        context.startServiceAsUser(carServiceintent, UserHandle.SYSTEM);
+        Intent carServiceIntent = new Intent();
+        carServiceIntent.setPackage(context.getPackageName());
+        carServiceIntent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);
+        context.startServiceAsUser(carServiceIntent, UserHandle.SYSTEM);
     }
 }
diff --git a/service/src/com/android/car/CarAudioService.java b/service/src/com/android/car/CarAudioService.java
index 17df7a0..e23ac93 100644
--- a/service/src/com/android/car/CarAudioService.java
+++ b/service/src/com/android/car/CarAudioService.java
@@ -171,8 +171,9 @@
             CarAudioAttributesUtil.getAudioAttributesForCarUsage(
                     CarAudioAttributesUtil.CAR_AUDIO_USAGE_CARSERVICE_CAR_PROXY);
 
-    public CarAudioService(Context context, CarInputService inputService) {
-        mAudioHal = VehicleHal.getInstance().getAudioHal();
+    public CarAudioService(Context context, AudioHalService audioHal,
+            CarInputService inputService) {
+        mAudioHal = audioHal;
         mContext = context;
         mFocusHandlerThread = new HandlerThread(CarLog.TAG_AUDIO);
         mSystemFocusListener = new SystemFocusListener();
@@ -221,10 +222,6 @@
         AudioPolicy audioPolicy = null;
         if (isFocusSupported || mUseDynamicRouting) {
             audioPolicy = builder.build();
-            int r = mAudioManager.registerAudioPolicy(audioPolicy);
-            if (r != 0) {
-                throw new RuntimeException("registerAudioPolicy failed " + r);
-            }
         }
         mAudioHal.setFocusListener(this);
         mAudioHal.setAudioRoutingPolicy(audioRoutingPolicy);
@@ -287,6 +284,12 @@
             Arrays.fill(mExternalRoutings, 0);
         }
         mVolumeService.init();
+
+        // Register audio policy only after this class is fully initialized.
+        int r = mAudioManager.registerAudioPolicy(audioPolicy);
+        if (r != 0) {
+            throw new RuntimeException("registerAudioPolicy failed " + r);
+        }
     }
 
     private void setupDynamicRouting(AudioRoutingPolicy audioRoutingPolicy,
diff --git a/service/src/com/android/car/CarCabinService.java b/service/src/com/android/car/CarCabinService.java
index 47aaa76..cdf8635 100644
--- a/service/src/com/android/car/CarCabinService.java
+++ b/service/src/com/android/car/CarCabinService.java
@@ -18,14 +18,13 @@
 
 import android.car.Car;
 import android.content.Context;
-import com.android.car.CarLog;
-import com.android.car.hal.VehicleHal;
+
+import com.android.car.hal.CabinHalService;
 
 public class CarCabinService extends CarPropertyServiceBase {
 	private final static boolean DBG = false;
 
-    public CarCabinService(Context context) {
-        super(context, VehicleHal.getInstance().getCabinHal(), Car.PERMISSION_CAR_CABIN, DBG,
-                CarLog.TAG_CABIN);
+    public CarCabinService(Context context, CabinHalService cabinHal) {
+        super(context, cabinHal, Car.PERMISSION_CAR_CABIN, DBG, CarLog.TAG_CABIN);
     }
 }
diff --git a/service/src/com/android/car/CarCameraService.java b/service/src/com/android/car/CarCameraService.java
index 7d2608b..c1a71c4 100644
--- a/service/src/com/android/car/CarCameraService.java
+++ b/service/src/com/android/car/CarCameraService.java
@@ -16,9 +16,9 @@
 
 package com.android.car;
 
-import android.content.Context;
 import android.car.hardware.camera.CarCameraState;
 import android.car.hardware.camera.ICarCamera;
+import android.content.Context;
 import android.graphics.Rect;
 import android.util.Log;
 
@@ -45,7 +45,11 @@
         if (DBG) {
             Log.d(TAG, "init called");
         }
-        mModule = nativeOpen();
+        try {
+            mModule = nativeOpen();
+        } catch (UnsatisfiedLinkError ex) {
+            Log.e(TAG, "Failed to open camera module: " + ex.getMessage());
+        }
 
         if (mModule != 0) {
             int[] cameraType = nativeGetSupportedCameras(mModule);
diff --git a/service/src/com/android/car/CarHvacService.java b/service/src/com/android/car/CarHvacService.java
index 99745ee..e22a38d 100644
--- a/service/src/com/android/car/CarHvacService.java
+++ b/service/src/com/android/car/CarHvacService.java
@@ -18,13 +18,13 @@
 
 import android.car.Car;
 import android.content.Context;
-import com.android.car.hal.VehicleHal;
+
+import com.android.car.hal.HvacHalService;
 
 public class CarHvacService extends CarPropertyServiceBase {
-	private final static boolean DBG = false;
+    private final static boolean DBG = false;
 
-    public CarHvacService(Context context) {
-        super(context, VehicleHal.getInstance().getHvacHal(), Car.PERMISSION_CAR_HVAC, DBG,
-                CarLog.TAG_HVAC);
+    public CarHvacService(Context context, HvacHalService hvacHal) {
+        super(context, hvacHal, Car.PERMISSION_CAR_HVAC, DBG, CarLog.TAG_HVAC);
     }
 }
diff --git a/service/src/com/android/car/CarInfoService.java b/service/src/com/android/car/CarInfoService.java
index c51ee15..9715325 100644
--- a/service/src/com/android/car/CarInfoService.java
+++ b/service/src/com/android/car/CarInfoService.java
@@ -17,26 +17,21 @@
 
 import android.car.CarInfoManager;
 import android.car.ICarInfo;
-import android.car.annotation.ValueTypeDef;
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.Settings;
 
 import com.android.car.hal.InfoHalService;
-import com.android.car.hal.VehicleHal;
 
 import java.io.PrintWriter;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
 
 public class CarInfoService extends ICarInfo.Stub implements CarServiceBase {
 
     private final InfoHalService mInfoHal;
     private final Context mContext;
 
-    public CarInfoService(Context context) {
-        mInfoHal = VehicleHal.getInstance().getInfoHal();
+    public CarInfoService(Context context, InfoHalService infoHal) {
+        mInfoHal = infoHal;
         mContext = context;
     }
 
diff --git a/service/src/com/android/car/CarInputService.java b/service/src/com/android/car/CarInputService.java
index 31c07d5..5ed9d49 100644
--- a/service/src/com/android/car/CarInputService.java
+++ b/service/src/com/android/car/CarInputService.java
@@ -60,6 +60,7 @@
     private static final boolean DBG = false;
 
     private final Context mContext;
+    private final InputHalService mInputHalService;
     private final TelecomManager mTelecomManager;
     private final InputManager mInputManager;
 
@@ -125,8 +126,9 @@
         }
     };
 
-    public CarInputService(Context context) {
+    public CarInputService(Context context, InputHalService inputHalService) {
         mContext = context;
+        mInputHalService = inputHalService;
         mTelecomManager = context.getSystemService(TelecomManager.class);
         mInputManager = context.getSystemService(InputManager.class);
     }
@@ -181,14 +183,13 @@
 
     @Override
     public void init() {
-        InputHalService hal = VehicleHal.getInstance().getInputHal();
-        if (!hal.isKeyInputSupported()) {
+        if (!mInputHalService.isKeyInputSupported()) {
             Log.w(CarLog.TAG_INPUT, "Hal does not support key input.");
             return;
         }
 
 
-        hal.setInputListener(this);
+        mInputHalService.setInputListener(this);
         mCarInputListenerBound = bindCarInputService();
     }
 
diff --git a/service/src/com/android/car/CarNightService.java b/service/src/com/android/car/CarNightService.java
index 0d3af67..497f77c 100644
--- a/service/src/com/android/car/CarNightService.java
+++ b/service/src/com/android/car/CarNightService.java
@@ -18,12 +18,10 @@
 
 import android.annotation.IntDef;
 import android.app.UiModeManager;
-import android.car.Car;
 import android.car.hardware.CarSensorEvent;
 import android.car.hardware.CarSensorManager;
 import android.car.hardware.ICarSensorEventListener;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.util.Log;
 
 import java.io.PrintWriter;
@@ -104,8 +102,9 @@
         return mUiModeManager.getNightMode();
     }
 
-    CarNightService(Context context) {
+    CarNightService(Context context, CarSensorService sensorService) {
         mContext = context;
+        mCarSensorService = sensorService;
         mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
         if (mUiModeManager == null) {
             Log.w(CarLog.TAG_SENSOR,"Failed to get UI_MODE_SERVICE");
@@ -117,8 +116,6 @@
         if (DBG) {
             Log.d(CarLog.TAG_SENSOR,"CAR dayNight init.");
         }
-        mCarSensorService = (CarSensorService) ICarImpl.getInstance(mContext).getCarService(
-                Car.SENSOR_SERVICE);
         mCarSensorService.registerOrUpdateSensorListener(CarSensorManager.SENSOR_TYPE_NIGHT,
                 CarSensorManager.SENSOR_RATE_NORMAL, mICarSensorEventListener);
         CarSensorEvent currentState = mCarSensorService.getLatestSensorEvent(
diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java
index 34a67fa..22f8b09 100644
--- a/service/src/com/android/car/CarPowerManagementService.java
+++ b/service/src/com/android/car/CarPowerManagementService.java
@@ -15,23 +15,15 @@
  */
 package com.android.car;
 
-import android.annotation.NonNull;
-import android.car.Car;
-import android.content.Context;
-import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
 import android.os.SystemClock;
 import android.util.Log;
-import android.view.Display;
 
 import com.android.car.hal.PowerHalService;
 import com.android.car.hal.PowerHalService.PowerState;
-import com.android.car.hal.VehicleHal;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -95,23 +87,8 @@
         int getWakeupTime();
     }
 
-    /** Interface to abstract all system interaction. Separated for testing. */
-    public interface SystemInteface {
-        void setDisplayState(boolean on);
-        void releaseAllWakeLocks();
-        void shutdown();
-        void enterDeepSleep(int wakeupTimeSec);
-        void switchToPartialWakeLock();
-        void switchToFullWakeLock();
-        void startDisplayStateMonitoring(CarPowerManagementService service);
-        void stopDisplayStateMonitoring();
-        boolean isSystemSupportingDeepSleep();
-        boolean isWakeupCausedByTimer();
-    }
-
-    private final Context mContext;
     private final PowerHalService mHal;
-    private final SystemInteface mSystemInterface;
+    private final SystemInterface mSystemInterface;
     private final HandlerThread mHandlerThread;
     private final PowerHandler mHandler;
 
@@ -131,23 +108,10 @@
     @GuardedBy("this")
     private final LinkedList<PowerState> mPendingPowerStates = new LinkedList<>();
 
-    private final int SHUTDOWN_POLLING_INTERVAL_MS = 2000;
-    private final int SHUTDOWN_EXTEND_MAX_MS = 5000;
+    private final static int SHUTDOWN_POLLING_INTERVAL_MS = 2000;
+    private final static int SHUTDOWN_EXTEND_MAX_MS = 5000;
 
-    /**
-     * Constructor for full functionality.
-     */
-    public CarPowerManagementService(@NonNull Context context) {
-        this(context, VehicleHal.getInstance().getPowerHal(),
-                new SystemIntefaceImpl(context));
-    }
-
-    /**
-     * Constructor for full functionality. Can inject external interfaces
-     */
-    public CarPowerManagementService(@NonNull Context context, @NonNull PowerHalService powerHal,
-            @NonNull SystemInteface systemInterface) {
-        mContext = context;
+    public CarPowerManagementService(PowerHalService powerHal, SystemInterface systemInterface) {
         mHal = powerHal;
         mSystemInterface = systemInterface;
         mHandlerThread = new HandlerThread(CarLog.TAG_POWER);
@@ -161,7 +125,6 @@
      */
     @VisibleForTesting
     protected CarPowerManagementService() {
-        mContext = null;
         mHal = null;
         mSystemInterface = null;
         mHandlerThread = null;
@@ -174,7 +137,12 @@
         if (mHal.isPowerStateSupported()) {
             mHal.sendBootComplete();
             PowerState currentState = mHal.getCurrentPowerState();
-            onApPowerStateChange(currentState);
+            if (currentState != null) {
+                onApPowerStateChange(currentState);
+            } else {
+                Log.w(CarLog.TAG_POWER, "Unable to get get current power state during "
+                        + "initialization");
+            }
         } else {
             Log.w(CarLog.TAG_POWER, "Vehicle hal does not support power state yet.");
             onApPowerStateChange(new PowerState(PowerHalService.STATE_ON_FULL, 0));
@@ -246,7 +214,7 @@
             if (mCurrentState == null) {
                 return;
             }
-            if (mCurrentState.state != PowerHalService.STATE_SHUTDOWN_PREPARE) {
+            if (mCurrentState.mState != PowerHalService.STATE_SHUTDOWN_PREPARE) {
                 return;
             }
             if (mCurrentState.canEnterDeepSleep()) {
@@ -300,7 +268,7 @@
         }
 
         Log.i(CarLog.TAG_POWER, "Power state change:" + state);
-        switch (state.state) {
+        switch (state.mState) {
             case PowerHalService.STATE_ON_DISP_OFF:
                 handleDisplayOff(state);
                 notifyPowerOn(false);
@@ -415,9 +383,7 @@
         synchronized (this) {
             mLastSleepEntryTime = SystemClock.elapsedRealtime();
         }
-        if (!shouldDoFakeShutdown()) { // if it is mocked, do not enter sleep.
-            mSystemInterface.enterDeepSleep(wakeupTimeSec);
-        }
+        mSystemInterface.enterDeepSleep(wakeupTimeSec);
         mHal.sendSleepExit();
         for (PowerServiceEventListener listener : mListeners) {
             listener.onSleepExit();
@@ -426,7 +392,7 @@
             doHandlePreprocessing(false /*shuttingDown*/);
         } else {
             PowerState currentState = mHal.getCurrentPowerState();
-            if (needPowerStateChange(currentState)) {
+            if (currentState != null && needPowerStateChange(currentState)) {
                 onApPowerStateChange(currentState);
             } else { // power controller woke-up but no power state change. Just shutdown.
                 Log.w(CarLog.TAG_POWER, "external sleep wake up, but no power state change:" +
@@ -439,7 +405,7 @@
     private void doHandleNotifyPowerOn() {
         boolean displayOn = false;
         synchronized (this) {
-            if (mCurrentState != null && mCurrentState.state == PowerHalService.STATE_ON_FULL) {
+            if (mCurrentState != null && mCurrentState.mState == PowerHalService.STATE_ON_FULL) {
                 displayOn = true;
             }
         }
@@ -468,9 +434,7 @@
             wakeupTimeSec = getWakeupTime();
         }
         mHal.sendShutdownStart(wakeupTimeSec);
-        if (!shouldDoFakeShutdown()) {
-            mSystemInterface.shutdown();
-        }
+        mSystemInterface.shutdown();
     }
 
     private int getWakeupTime() {
@@ -517,15 +481,6 @@
         //TODO bug: 32065231
     }
 
-    private boolean shouldDoFakeShutdown() {
-        ICarImpl carImpl = ICarImpl.getInstance(mContext);
-        if (!carImpl.isInMocking()) {
-            return false;
-        }
-        CarTestService testService = (CarTestService) carImpl.getCarService(Car.TEST_SERVICE);
-        return !testService.shouldDoRealShutdownInMocking();
-    }
-
     public void handleMainDisplayChanged(boolean on) {
         mHandler.handleMainDisplayStateChange(on);
     }
@@ -611,151 +566,6 @@
         }
     }
 
-    private static class SystemIntefaceImpl implements SystemInteface {
-
-        private final PowerManager mPowerManager;
-        private final DisplayManager mDisplayManager;
-        private final WakeLock mFullWakeLock;
-        private final WakeLock mPartialWakeLock;
-        private final DisplayStateListener mDisplayListener;
-        private CarPowerManagementService mService;
-        private boolean mDisplayStateSet;
-
-        private SystemIntefaceImpl(Context context) {
-            mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
-            mFullWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, CarLog.TAG_POWER);
-            mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                    CarLog.TAG_POWER);
-            mDisplayListener = new DisplayStateListener();
-        }
-
-        @Override
-        public void startDisplayStateMonitoring(CarPowerManagementService service) {
-            synchronized (this) {
-                mService = service;
-                mDisplayStateSet = isMainDisplayOn();
-            }
-            mDisplayManager.registerDisplayListener(mDisplayListener, service.getHandler());
-        }
-
-        @Override
-        public void stopDisplayStateMonitoring() {
-            mDisplayManager.unregisterDisplayListener(mDisplayListener);
-        }
-
-        @Override
-        public void setDisplayState(boolean on) {
-            synchronized (this) {
-                mDisplayStateSet = on;
-            }
-            if (on) {
-                switchToFullWakeLock();
-                Log.i(CarLog.TAG_POWER, "on display");
-                mPowerManager.wakeUp(SystemClock.uptimeMillis());
-            } else {
-                switchToPartialWakeLock();
-                Log.i(CarLog.TAG_POWER, "off display");
-                mPowerManager.goToSleep(SystemClock.uptimeMillis());
-            }
-        }
-
-        private boolean isMainDisplayOn() {
-            Display disp = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
-            return disp.getState() == Display.STATE_ON;
-        }
-
-        @Override
-        public void shutdown() {
-            mPowerManager.shutdown(false /* no confirm*/, null, true /* true */);
-        }
-
-        @Override
-        public void enterDeepSleep(int wakeupTimeSec) {
-            //TODO set wake up time, bug: 32061842
-            mPowerManager.goToSleep(SystemClock.uptimeMillis(),
-                    PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN,
-                    PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
-        }
-
-        @Override
-        public boolean isSystemSupportingDeepSleep() {
-            //TODO should return by checking some kernel suspend control sysfs, bug: 32061842
-            return false;
-        }
-
-        @Override
-        public void switchToPartialWakeLock() {
-            if (!mPartialWakeLock.isHeld()) {
-                mPartialWakeLock.acquire();
-            }
-            if (mFullWakeLock.isHeld()) {
-                mFullWakeLock.release();
-            }
-        }
-
-        @Override
-        public void switchToFullWakeLock() {
-            if (!mFullWakeLock.isHeld()) {
-                mFullWakeLock.acquire();
-            }
-            if (mPartialWakeLock.isHeld()) {
-                mPartialWakeLock.release();
-            }
-        }
-
-        @Override
-        public void releaseAllWakeLocks() {
-            if (mPartialWakeLock.isHeld()) {
-                mPartialWakeLock.release();
-            }
-            if (mFullWakeLock.isHeld()) {
-                mFullWakeLock.release();
-            }
-        }
-
-        @Override
-        public boolean isWakeupCausedByTimer() {
-            //TODO bug: 32061842, check wake up reason and do necessary operation information should
-            // come from kernel. it can be either power on or wake up for maintenance
-            // power on will involve GPIO trigger from power controller
-            // its own wakeup will involve timer expiration.
-            return false;
-        }
-
-        private void handleMainDisplayChanged() {
-            boolean isOn = isMainDisplayOn();
-            CarPowerManagementService service;
-            synchronized (this) {
-                if (mDisplayStateSet == isOn) { // same as what is set
-                    return;
-                }
-                service = mService;
-            }
-            service.handleMainDisplayChanged(isOn);
-        }
-
-        private class DisplayStateListener implements DisplayManager.DisplayListener {
-
-            @Override
-            public void onDisplayAdded(int displayId) {
-                //ignore
-            }
-
-            @Override
-            public void onDisplayChanged(int displayId) {
-                if (displayId == Display.DEFAULT_DISPLAY) {
-                    handleMainDisplayChanged();
-                }
-            }
-
-            @Override
-            public void onDisplayRemoved(int displayId) {
-                //ignore
-            }
-        }
-    }
-
     private class ShutdownProcessingTimerTask extends TimerTask {
         private final boolean mShutdownWhenCompleted;
         private final int mExpirationCount;
diff --git a/service/src/com/android/car/CarRadioService.java b/service/src/com/android/car/CarRadioService.java
index c59983c..d12c9ae 100644
--- a/service/src/com/android/car/CarRadioService.java
+++ b/service/src/com/android/car/CarRadioService.java
@@ -28,7 +28,6 @@
 import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.car.hal.VehicleHal;
 import com.android.car.hal.RadioHalService;
 
 import java.io.PrintWriter;
@@ -46,8 +45,8 @@
         new HashMap<IBinder, RadioDeathRecipient>();
     private final Context mContext;
 
-    public CarRadioService(Context context) {
-        mRadioHal = VehicleHal.getInstance().getRadioHal();
+    public CarRadioService(Context context, RadioHalService radioHal) {
+        mRadioHal = radioHal;
         mContext = context;
     }
 
diff --git a/service/src/com/android/car/CarSensorService.java b/service/src/com/android/car/CarSensorService.java
index 748d3c2..e9ab453 100644
--- a/service/src/com/android/car/CarSensorService.java
+++ b/service/src/com/android/car/CarSensorService.java
@@ -32,11 +32,13 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
-import com.android.car.hal.VehicleHal;
+import com.google.android.collect.Lists;
+
 import com.android.car.hal.SensorHalService;
 import com.android.car.hal.SensorHalServiceBase;
 import com.android.internal.annotations.GuardedBy;
@@ -81,9 +83,8 @@
     private final ReentrantLock mSensorLock = new ReentrantLock();
     /** hold clients callback  */
     @GuardedBy("mSensorLock")
-    private final LinkedList<SensorClient> mClients = new LinkedList<SensorClient>();
-    /** should be used only as temp data for event dispatching */
-    private final LinkedList<SensorClient> mClientDispatchList = new LinkedList<>();
+    private final LinkedList<SensorClient> mClients = new LinkedList<>();
+
     /** key: sensor type. */
     @GuardedBy("mSensorLock")
     private final SparseArray<SensorListeners> mSensorListeners = new SparseArray<>();
@@ -106,7 +107,7 @@
     private final HandlerThread mHandlerThread;
     private final SensorDispatchHandler mSensorDispatchHandler;
 
-    public CarSensorService(Context context) {
+    public CarSensorService(Context context, SensorHalService sensorHal) {
         mContext = context;
         if (ENABLE_DISPATCHING_LIMIT) {
             mHandlerThread = new HandlerThread("SENSOR", Process.THREAD_PRIORITY_AUDIO);
@@ -117,8 +118,8 @@
             mSensorDispatchHandler = null;
         }
         // This triggers sensor hal init as well.
-        mSensorHal = VehicleHal.getInstance().getSensorHal();
-        mDrivingStatePolicy = new DrivingStatePolicy(context);
+        mSensorHal = sensorHal;
+        mDrivingStatePolicy = new DrivingStatePolicy(context, this);
         mDayNightModePolicy = new DayNightModePolicy(context);
     }
 
@@ -154,8 +155,8 @@
                 mDayNightModePolicy.registerSensorListener(this);
             } else {
                 event = mSensorHal.getCurrentSensorValue(CarSensorManager.SENSOR_TYPE_NIGHT);
-                Log.i(CarLog.TAG_SENSOR, "initial daynight:" + ((event == null)?
-                        "not ready" : + event.intValues[0]));
+                Log.i(CarLog.TAG_SENSOR, "initial daynight: "
+                        + ((event == null) ? "not ready" : + event.intValues[0]));
             }
             if (event == null) {
                 event = DayNightModePolicy.getDefaultValue(CarSensorManager.SENSOR_TYPE_NIGHT);
@@ -226,6 +227,8 @@
     }
 
     private void processSensorData(List<CarSensorEvent> events) {
+        ArrayMap<SensorClient, List<CarSensorEvent>> eventsByClient = new ArrayMap<>();
+
         mSensorLock.lock();
         for (CarSensorEvent event: events) {
             SensorRecord record = mSensorRecords.get(event.sensorType);
@@ -239,24 +242,35 @@
                     //TODO recycle new event, bug: 32094595
                     continue;
                 }
+
                 SensorListeners listeners = mSensorListeners.get(event.sensorType);
-                if (listeners != null) {
-                    listeners.queueSensorEvent(event);
+                if (listeners == null) {
+                    continue;
+                }
+
+                for (SensorClientWithRate clientWithRate : listeners.mSensorClients) {
+                    SensorClient client = clientWithRate.getSensorClient();
+                    List<CarSensorEvent> clientEvents = eventsByClient.get(client);
+                    if (clientEvents == null) {
+                        clientEvents = new LinkedList<>();
+                        eventsByClient.put(client, clientEvents);
+                    }
+                    clientEvents.add(event);
                 }
             }
         }
-        mClientDispatchList.addAll(mClients);
         mSensorLock.unlock();
-        for (SensorClient client: mClientDispatchList) {
-            client.dispatchSensorUpdate();
+
+        for (ArrayMap.Entry<SensorClient, List<CarSensorEvent>> entry : eventsByClient.entrySet()) {
+            SensorClient client = entry.getKey();
+            List<CarSensorEvent> clientEvents = entry.getValue();
+
+            client.dispatchSensorUpdate(clientEvents);
         }
-        mClientDispatchList.clear();
     }
 
     /**
      * Received sensor data from car.
-     *
-     * @param event
      */
     @Override
     public void onSensorEvents(List<CarSensorEvent> events) {
@@ -325,15 +339,14 @@
             // If we have a cached event for this sensor, send the event.
             SensorRecord record = mSensorRecords.get(sensorType);
             if (record != null && record.lastEvent != null) {
-                sensorClient.queueSensorEvent(record.lastEvent);
-                sensorClient.dispatchSensorUpdate();
+                sensorClient.dispatchSensorUpdate(Lists.newArrayList(record.lastEvent));
             }
             if (sensorListeners == null) {
                 sensorListeners = new SensorListeners(rate);
                 mSensorListeners.put(sensorType, sensorListeners);
                 shouldStartSensors = true;
             } else {
-                oldRate = Integer.valueOf(sensorListeners.getRate());
+                oldRate = sensorListeners.getRate();
                 sensorClientWithRate = sensorListeners.findSensorClientWithRate(sensorClient);
             }
             if (sensorClientWithRate == null) {
@@ -635,7 +648,7 @@
     private SensorClient findSensorClientLocked(ICarSensorEventListener listener) {
         IBinder binder = listener.asBinder();
         for (SensorClient sensorClient : mClients) {
-            if (sensorClient.isHoldingListernerBinder(binder)) {
+            if (sensorClient.isHoldingListenerBinder(binder)) {
                 return sensorClient;
             }
         }
@@ -738,8 +751,6 @@
         /** callback for sensor events */
         private final ICarSensorEventListener mListener;
         private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
-        private final LinkedList<CarSensorEvent> mSensorsToDispatch =
-                new LinkedList<CarSensorEvent>();
 
         /** when false, it is already released */
         private volatile boolean mActive = true;
@@ -757,7 +768,7 @@
             return false;
         }
 
-        boolean isHoldingListernerBinder(IBinder listenerBinder) {
+        boolean isHoldingListenerBinder(IBinder listenerBinder) {
             return mListener.asBinder() == listenerBinder;
         }
 
@@ -794,17 +805,13 @@
             removeClient(this);
         }
 
-        void queueSensorEvent(CarSensorEvent event) {
-            mSensorsToDispatch.add(event);
-        }
-
-        void dispatchSensorUpdate() {
-            if (mSensorsToDispatch.size() == 0) {
+        void dispatchSensorUpdate(List<CarSensorEvent> events) {
+            if (events.size() == 0) {
                 return;
             }
             if (mActive) {
                 try {
-                    mListener.onSensorChanged(mSensorsToDispatch);
+                    mListener.onSensorChanged(events);
                 } catch (RemoteException e) {
                     //ignore. crash will be handled by death handler
                 }
@@ -813,14 +820,12 @@
                     Log.d(CarLog.TAG_SENSOR, "sensor update while client is already released");
                 }
             }
-            mSensorsToDispatch.clear();
         }
 
         void release() {
             if (mActive) {
                 mListener.asBinder().unlinkToDeath(this, 0);
                 mActiveSensors.clear();
-                mSensorsToDispatch.clear();
                 mActive = false;
             }
         }
@@ -920,12 +925,6 @@
             return null;
         }
 
-        void queueSensorEvent(CarSensorEvent event) {
-            for (SensorClientWithRate clientWithRate: mSensorClients) {
-                clientWithRate.getSensorClient().queueSensorEvent(event);
-            }
-        }
-
         void release() {
             for (SensorClientWithRate clientWithRate: mSensorClients) {
                 clientWithRate.mSensorClient.release();
diff --git a/service/src/com/android/car/CarService.java b/service/src/com/android/car/CarService.java
index 475d4de..37df29d 100644
--- a/service/src/com/android/car/CarService.java
+++ b/service/src/com/android/car/CarService.java
@@ -15,28 +15,40 @@
  */
 package com.android.car;
 
+import static android.os.SystemClock.elapsedRealtime;
+
+import android.annotation.Nullable;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.hardware.vehicle.V2_0.IVehicle;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.Log;
 
-import com.android.car.hal.VehicleHal;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 public class CarService extends Service {
 
-    // main thread only
+    /** Default vehicle HAL service name. */
+    private static final String VEHICLE_SERVICE_NAME = "Vehicle";
+
+    private static final long WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS = 10_000;
+
     private ICarImpl mICarImpl;
 
     @Override
     public void onCreate() {
         Log.i(CarLog.TAG_SERVICE, "Service onCreate");
-        mICarImpl = ICarImpl.getInstance(this);
+        IVehicle vehicle = getVehicle(WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS);
+        if (vehicle == null) {
+            throw new IllegalStateException("Vehicle HAL service is not available.");
+        }
+
+        mICarImpl = new ICarImpl(this, vehicle, SystemInterface.getDefault(this));
+        mICarImpl.init();
         SystemProperties.set("boot.car_service_created", "1");
         super.onCreate();
     }
@@ -44,7 +56,7 @@
     @Override
     public void onDestroy() {
         Log.i(CarLog.TAG_SERVICE, "Service onDestroy");
-        ICarImpl.releaseInstance();
+        mICarImpl.release();
         super.onDestroy();
     }
 
@@ -70,12 +82,30 @@
         }
         if (args == null || args.length == 0) {
             writer.println("*dump car service*");
-            writer.println("*dump HAL*");
-            VehicleHal.getInstance().dump(writer);
-            writer.println("*dump services*");
-            ICarImpl.getInstance(this).dump(writer);
+            mICarImpl.dump(writer);
         } else {
-            ICarImpl.getInstance(this).execShellCmd(args, writer);
+            mICarImpl.execShellCmd(args, writer);
         }
     }
+
+    @Nullable
+    private IVehicle getVehicle(long waitMilliseconds) {
+        IVehicle vehicle = getVehicle();
+        long start = elapsedRealtime();
+        while (vehicle == null && (start + waitMilliseconds) > elapsedRealtime()) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Sleep was interrupted", e);
+            }
+
+            vehicle = getVehicle();
+        }
+        return vehicle;
+    }
+
+    @Nullable
+    private IVehicle getVehicle() {
+        return IVehicle.getService(VEHICLE_SERVICE_NAME);
+    }
 }
\ No newline at end of file
diff --git a/service/src/com/android/car/CarServiceUtils.java b/service/src/com/android/car/CarServiceUtils.java
index b47e22c..5467401 100644
--- a/service/src/com/android/car/CarServiceUtils.java
+++ b/service/src/com/android/car/CarServiceUtils.java
@@ -16,17 +16,16 @@
 
 package com.android.car;
 
-import java.util.List;
-
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
 
+import java.util.List;
+
 /** Utility class */
 public final class CarServiceUtils {
 
@@ -158,4 +157,13 @@
         }
         return array;
     }
+
+    public static byte[] toByteArray(List<Byte> list) {
+        final int size = list.size();
+        final byte[] array = new byte[size];
+        for (int i = 0; i < size; ++i) {
+            array[i] = list.get(i);
+        }
+        return array;
+    }
 }
diff --git a/service/src/com/android/car/CarTestService.java b/service/src/com/android/car/CarTestService.java
index 9541af1..ec1606c 100644
--- a/service/src/com/android/car/CarTestService.java
+++ b/service/src/com/android/car/CarTestService.java
@@ -15,41 +15,35 @@
  */
 package com.android.car;
 
-import android.car.test.CarTestManager;
+import android.car.Car;
 import android.car.test.ICarTest;
 import android.content.Context;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.car.hal.VehicleHal;
-import com.android.car.vehiclenetwork.IVehicleNetworkHalMock;
-import com.android.car.vehiclenetwork.VehicleNetwork;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
-import com.android.car.vehiclenetwork.VehiclePropValueParcelable;
-
 import java.io.PrintWriter;
-import java.util.NoSuchElementException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Service to allow testing / mocking vehicle HAL.
  * This service uses Vehicle HAL APIs directly (one exception) as vehicle HAL mocking anyway
  * requires accessing that level directly.
  */
-public class CarTestService extends ICarTest.Stub implements CarServiceBase {
+class CarTestService extends ICarTest.Stub implements CarServiceBase {
+
+    private static final String TAG = CarTestService.class.getSimpleName();
 
     private final Context mContext;
-    private final VehicleNetwork mVehicleNetwork;
     private final ICarImpl mICarImpl;
-    private boolean mInMocking = false;
-    private int mMockingFlags = 0;
-    private Exception mException = null;
-    private IVehicleNetworkHalMock mMock = null;
-    private final MockDeathRecipient mDeathRecipient = new MockDeathRecipient();
 
-    public CarTestService(Context context, ICarImpl carImpl) {
+    private final Map<IBinder, TokenDeathRecipient> mTokens = new HashMap<>();
+
+    CarTestService(Context context, ICarImpl carImpl) {
         mContext = context;
         mICarImpl = carImpl;
-        mVehicleNetwork = VehicleHal.getInstance().getVehicleNetwork();
     }
 
     @Override
@@ -67,124 +61,59 @@
     @Override
     public void dump(PrintWriter writer) {
         writer.println("*CarTestService*");
-        writer.println(" mInMocking:" + mInMocking);
+        writer.println(" mTokens:" + Arrays.toString(mTokens.entrySet().toArray()));
     }
 
     @Override
-    public void injectEvent(VehiclePropValueParcelable value) {
-        ICarImpl.assertVehicleHalMockPermission(mContext);
-        mVehicleNetwork.injectEvent(value.value);
-    }
+    public void stopCarService(IBinder token) throws RemoteException {
+        Log.d(TAG, "stopCarService, token: " + token);
+        ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
 
-    @Override
-    public void startMocking(final IVehicleNetworkHalMock mock, final int flags) {
-        ICarImpl.assertVehicleHalMockPermission(mContext);
-        CarServiceUtils.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    synchronized (this) {
-                        mInMocking = true;
-                        mMockingFlags = flags;
-                        mException = null;
-                        if (mMock != null) {
-                            Log.w(CarLog.TAG_TEST,
-                                    "New mocking started while previous one is not stopped");
-                            try {
-                                mMock.asBinder().unlinkToDeath(mDeathRecipient, 0);
-                            } catch (NoSuchElementException e) {
-                                //ignore
-                            }
-                        }
-                        mMock = mock;
-                    }
-                    mock.asBinder().linkToDeath(mDeathRecipient, 0);
-                    mVehicleNetwork.startMocking(mock);
-                    mICarImpl.startMocking();
-                } catch (Exception e) {
-                    Log.w(CarLog.TAG_TEST, "startMocking failed", e);
-                    synchronized (this) {
-                        mException = e;
-                        mInMocking = false;
-                        mMockingFlags = 0;
-                    }
-                }
-                Log.i(CarLog.TAG_TEST, "start vehicle HAL mocking, flags:0x" +
-                        Integer.toHexString(flags));
-            }
-        });
         synchronized (this) {
-            if (mException != null) {
-                throw new IllegalStateException(mException);
+            if (mTokens.containsKey(token)) {
+                Log.w(TAG, "Calling stopCarService twice with the same token.");
+                return;
+            }
+
+            TokenDeathRecipient deathRecipient = new TokenDeathRecipient(token);
+            mTokens.put(token, deathRecipient);
+            token.linkToDeath(deathRecipient, 0);
+
+            if (mTokens.size() == 1) {
+                mICarImpl.release();
             }
         }
     }
 
     @Override
-    public void stopMocking(final IVehicleNetworkHalMock mock) {
-        ICarImpl.assertVehicleHalMockPermission(mContext);
-        CarServiceUtils.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    synchronized (this) {
-                        if (!mInMocking) {
-                            throw new IllegalStateException("not in mocking");
-                        }
-                        if (mMock.asBinder() != mock.asBinder()) {
-                            throw new IllegalArgumentException("Try to stop mocking not owned");
-                        }
-                        try {
-                            mMock.asBinder().unlinkToDeath(mDeathRecipient, 0);
-                        } catch (NoSuchElementException e) {
-                            //ignore
-                        }
-                    }
-                    mVehicleNetwork.stopMocking(mock);
-                    mICarImpl.stopMocking();
-                    synchronized (this) {
-                        mInMocking = false;
-                        mMockingFlags = 0;
-                        mException = null;
-                        mMock = null;
-                    }
-                    Log.i(CarLog.TAG_TEST, "stop vehicle HAL mocking");
-                } catch (Exception e) {
-                    Log.w(CarLog.TAG_TEST, "stopMocking failed", e);
-                }
-            }
-        });
+    public void startCarService(IBinder token) throws RemoteException {
+        Log.d(TAG, "startCarService, token: " + token);
+        ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
+        releaseToken(token);
     }
 
-    @Override
-    public boolean isPropertySupported(int property) {
-        VehiclePropConfigs configs = VehicleHal.getInstance().getVehicleNetwork().listProperties(
-                property);
-        return configs != null;
+    private synchronized void releaseToken(IBinder token) {
+        Log.d(TAG, "releaseToken, token: " + token);
+        DeathRecipient deathRecipient = mTokens.remove(token);
+        if (deathRecipient != null) {
+            token.unlinkToDeath(deathRecipient, 0);
+        }
+
+        if (mTokens.size() == 0) {
+            mICarImpl.init();
+        }
     }
 
-    public synchronized boolean isInMocking() {
-        return mInMocking;
-    }
+    private class TokenDeathRecipient implements DeathRecipient {
+        private final IBinder mToken;
 
-    public synchronized boolean shouldDoRealShutdownInMocking() {
-        return (mMockingFlags & CarTestManager.FLAG_MOCKING_REAL_SHUTDOWN) != 0;
-    }
+        TokenDeathRecipient(IBinder token) throws RemoteException {
+            mToken = token;
+        }
 
-    private class MockDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
-            CarServiceUtils.runOnMainSync(() -> {
-               try {
-                   IVehicleNetworkHalMock mock;
-                   synchronized (this) {
-                       mock = mMock;
-                   }
-                   stopMocking(mock);
-               } catch (Exception e) {
-                   //ignore
-               }
-            });
+            releaseToken(mToken);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/service/src/com/android/car/CarVendorExtensionService.java b/service/src/com/android/car/CarVendorExtensionService.java
index 3808684..2e2d074 100644
--- a/service/src/com/android/car/CarVendorExtensionService.java
+++ b/service/src/com/android/car/CarVendorExtensionService.java
@@ -19,7 +19,7 @@
 import android.car.Car;
 import android.content.Context;
 
-import com.android.car.hal.VehicleHal;
+import com.android.car.hal.VendorExtensionHalService;
 
 /**
  * Service responsible for handling custom properties that were defined in vehicle HAL by OEMs.
@@ -28,8 +28,7 @@
 
     private final static boolean DEBUG = false;
 
-    public CarVendorExtensionService(Context context) {
-        super(context, VehicleHal.getInstance().getVendorExtensionHal(),
-                Car.PERMISSION_VENDOR_EXTENSION, DEBUG, CarLog.TAG_VENDOR_EXT);
+    public CarVendorExtensionService(Context context, VendorExtensionHalService vendorHal) {
+        super(context, vendorHal, Car.PERMISSION_VENDOR_EXTENSION, DEBUG, CarLog.TAG_VENDOR_EXT);
     }
 }
diff --git a/service/src/com/android/car/CarVolumeControllerFactory.java b/service/src/com/android/car/CarVolumeControllerFactory.java
index 79ada5a..ae7dc1b 100644
--- a/service/src/com/android/car/CarVolumeControllerFactory.java
+++ b/service/src/com/android/car/CarVolumeControllerFactory.java
@@ -30,7 +30,6 @@
 import android.telecom.TelecomManager;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Pair;
 import android.util.SparseArray;
 import android.view.KeyEvent;
 
@@ -229,9 +228,6 @@
                 new SparseArray<>(VolumeUtils.CAR_AUDIO_CONTEXT.length);
         // stream volume limit, the key is car audio context type
         @GuardedBy("this")
-        private final SparseArray<Integer> mCarContextVolumeMin =
-                new SparseArray<>(VolumeUtils.CAR_AUDIO_CONTEXT.length);
-        @GuardedBy("this")
         private final RemoteCallbackList<IVolumeController> mVolumeControllers =
                 new RemoteCallbackList<>();
         @GuardedBy("this")
@@ -374,19 +370,13 @@
         private void initVolumeLimitLocked() {
             for (int i : VolumeUtils.CAR_AUDIO_CONTEXT) {
                 int carStream = carContextToCarStream(i);
-                Pair<Integer, Integer> volumeMinMax = mHal.getStreamVolumeLimit(carStream);
-                int max;
-                int min;
-                if (volumeMinMax == null) {
+                Integer volumeMax = mHal.getStreamMaxVolume(carStream);
+                int max = volumeMax == null ? 0 : volumeMax;
+                if (max < 0) {
                     max = 0;
-                    min = 0;
-                } else {
-                    max = volumeMinMax.second >= 0 ? volumeMinMax.second : 0;
-                    min = volumeMinMax.first >=0 ? volumeMinMax.first : 0;
                 }
                 // get default stream volume limit first.
                 mCarContextVolumeMax.put(i, max);
-                mCarContextVolumeMin.put(i, min);
             }
         }
 
@@ -574,13 +564,7 @@
 
         @Override
         public int getStreamMinVolume(int stream) {
-            synchronized (this) {
-                if (VolumeUtils.carContextToAndroidStream(mCurrentContext) == stream) {
-                    return mCarContextVolumeMin.get(mCurrentContext);
-                } else {
-                    return mCarContextVolumeMin.get(VolumeUtils.androidStreamToCarContext(stream));
-                }
-            }
+            return 0;  // Min value is always zero.
         }
 
         @Override
@@ -669,8 +653,6 @@
                 dumpVolumes(writer, mCurrentCarContextVolume);
                 writer.println("mCarContextVolumeMax:");
                 dumpVolumes(writer, mCarContextVolumeMax);
-                writer.println("mCarContextVolumeMin:");
-                dumpVolumes(writer, mCarContextVolumeMin);
                 writer.println("Number of volume controllers:" +
                         mVolumeControllers.getRegisteredCallbackCount());
             }
diff --git a/service/src/com/android/car/CarVolumeService.java b/service/src/com/android/car/CarVolumeService.java
index 74e7071..786c791 100644
--- a/service/src/com/android/car/CarVolumeService.java
+++ b/service/src/com/android/car/CarVolumeService.java
@@ -17,12 +17,11 @@
 package com.android.car;
 
 import android.content.Context;
+import android.hardware.vehicle.V2_0.VehicleAudioContextFlag;
 import android.media.AudioAttributes;
 import android.media.IVolumeController;
-import android.view.KeyEvent;
 
 import com.android.car.hal.AudioHalService;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioContextFlag;
 
 import java.io.PrintWriter;
 
@@ -38,7 +37,7 @@
     private static final String TAG = "CarVolumeService";
 
     public static int DEFAULT_CAR_AUDIO_CONTEXT =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG;
+            VehicleAudioContextFlag.MUSIC_FLAG;
     private final Context mContext;
     private final AudioHalService mAudioHal;
     private final CarAudioService mAudioService;
diff --git a/service/src/com/android/car/DrivingStatePolicy.java b/service/src/com/android/car/DrivingStatePolicy.java
index 4716c1e..2da7021 100644
--- a/service/src/com/android/car/DrivingStatePolicy.java
+++ b/service/src/com/android/car/DrivingStatePolicy.java
@@ -16,7 +16,6 @@
 
 package com.android.car;
 
-import android.car.Car;
 import android.car.hardware.CarSensorEvent;
 import android.car.hardware.CarSensorManager;
 import android.car.hardware.ICarSensorEventListener;
@@ -37,7 +36,7 @@
 
     private final Context mContext;
     private CarSensorService mSensorService;
-    private int mDringState = CarSensorEvent.DRIVE_STATUS_FULLY_RESTRICTED;
+    private int mDrivingState = CarSensorEvent.DRIVE_STATUS_FULLY_RESTRICTED;
     private SensorListener mSensorListener;
     private boolean mIsReady = false;
     private boolean mStarted = false;
@@ -54,8 +53,9 @@
         }
     };
 
-    public DrivingStatePolicy(Context context) {
+    public DrivingStatePolicy(Context context, CarSensorService sensorService) {
         mContext = context;
+        mSensorService = sensorService;
     }
 
     @Override
@@ -65,8 +65,6 @@
 
     @Override
     public synchronized void onSensorServiceReady() {
-        mSensorService =
-                (CarSensorService) ICarImpl.getInstance(mContext).getCarService(Car.SENSOR_SERVICE);
         int sensorList[] = mSensorService.getSupportedSensors();
         boolean hasSpeed = subscribeIfSupportedLocked(sensorList,
                 CarSensorManager.SENSOR_TYPE_CAR_SPEED, CarSensorManager.SENSOR_RATE_FASTEST);
@@ -118,7 +116,7 @@
     @Override
     public synchronized boolean requestSensorStart(int sensorType, int rate) {
         mStarted = true;
-        dispatchCarSensorEvent(mSensorListener, createEvent(mDringState));
+        dispatchCarSensorEvent(mSensorListener, createEvent(mDrivingState));
         return true;
     }
 
@@ -146,9 +144,9 @@
             case CarSensorManager.SENSOR_TYPE_GEAR:
             case CarSensorManager.SENSOR_TYPE_CAR_SPEED:
                 int drivingState = recalcDrivingStateLocked();
-                if (drivingState != mDringState && mSensorListener != null) {
-                    mDringState = drivingState;
-                    dispatchCarSensorEvent(mSensorListener, createEvent(mDringState));
+                if (drivingState != mDrivingState && mSensorListener != null) {
+                    mDrivingState = drivingState;
+                    dispatchCarSensorEvent(mSensorListener, createEvent(mDrivingState));
                 }
                 break;
             default:
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index b6386af..e05efaa 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -22,6 +22,7 @@
 import android.car.cluster.renderer.IInstrumentClusterNavigation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.hardware.vehicle.V2_0.IVehicle;
 import android.os.IBinder;
 import android.util.Log;
 
@@ -40,14 +41,16 @@
 
     // load jni for all services here
     static {
-        System.loadLibrary("jni_car_service");
+        try {
+            System.loadLibrary("jni_car_service");
+        } catch (UnsatisfiedLinkError ex) {
+            // Unable to load native library when loaded from the testing framework.
+            Log.e(CarLog.TAG_SERVICE, "Failed to load jni_car_service library: " + ex.getMessage());
+        }
     }
 
-    @GuardedBy("ICarImpl.class")
-    private static ICarImpl sInstance = null;
-
     private final Context mContext;
-    private final VehicleHal mHal;
+    private VehicleHal mHal;
 
     private final SystemActivityMonitoringService mSystemActivityMonitoringService;
     private final CarPowerManagementService mCarPowerManagementService;
@@ -68,54 +71,42 @@
     private final SystemStateControllerService mSystemStateControllerService;
     private final CarVendorExtensionService mCarVendorExtensionService;
 
+    private final CarServiceBase[] mAllServices;
+
     /** Test only service. Populate it only when necessary. */
     @GuardedBy("this")
     private CarTestService mCarTestService;
-    private final CarServiceBase[] mAllServices;
 
-    public synchronized static ICarImpl getInstance(Context serviceContext) {
-        if (sInstance == null) {
-            sInstance = new ICarImpl(serviceContext);
-            sInstance.init();
-        }
-        return sInstance;
-    }
-
-    public synchronized static void releaseInstance() {
-        if (sInstance == null) {
-            return;
-        }
-        sInstance.release();
-        sInstance = null;
-    }
-
-    public ICarImpl(Context serviceContext) {
+    public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface) {
         mContext = serviceContext;
-        mHal = VehicleHal.getInstance();
+        mHal = new VehicleHal(vehicle);
         mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
-        mCarPowerManagementService = new CarPowerManagementService(serviceContext);
-        mCarSensorService = new CarSensorService(serviceContext);
+        mCarPowerManagementService = new CarPowerManagementService(
+                mHal.getPowerHal(), systemInterface);
+        mCarSensorService = new CarSensorService(serviceContext, mHal.getSensorHal());
         mCarPackageManagerService = new CarPackageManagerService(serviceContext, mCarSensorService,
                 mSystemActivityMonitoringService);
-        mCarInputService = new CarInputService(serviceContext);
+        mCarInputService = new CarInputService(serviceContext, mHal.getInputHal());
         mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
         mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
-        mCarInfoService = new CarInfoService(serviceContext);
+        mCarInfoService = new CarInfoService(serviceContext, mHal.getInfoHal());
         mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
-        mCarAudioService = new CarAudioService(serviceContext, mCarInputService);
-        mCarCabinService = new CarCabinService(serviceContext);
-        mCarHvacService = new CarHvacService(serviceContext);
-        mCarRadioService = new CarRadioService(serviceContext);
+        mCarAudioService = new CarAudioService(serviceContext, mHal.getAudioHal(),
+                mCarInputService);
+        mCarCabinService = new CarCabinService(serviceContext, mHal.getCabinHal());
+        mCarHvacService = new CarHvacService(serviceContext, mHal.getHvacHal());
+        mCarRadioService = new CarRadioService(serviceContext, mHal.getRadioHal());
         mCarCameraService = new CarCameraService(serviceContext);
-        mCarNightService = new CarNightService(serviceContext);
+        mCarNightService = new CarNightService(serviceContext, mCarSensorService);
         mInstrumentClusterService = new InstrumentClusterService(serviceContext,
                 mAppFocusService, mCarInputService);
         mSystemStateControllerService = new SystemStateControllerService(serviceContext,
                 mCarPowerManagementService, mCarAudioService, this);
-        mCarVendorExtensionService = new CarVendorExtensionService(serviceContext);
+        mCarVendorExtensionService = new CarVendorExtensionService(serviceContext,
+                mHal.getVendorExtensionHal());
 
         // Be careful with order. Service depending on other service should be inited later.
-        mAllServices = new CarServiceBase[] {
+        mAllServices = new CarServiceBase[]{
                 mSystemActivityMonitoringService,
                 mCarPowerManagementService,
                 mCarSensorService,
@@ -134,43 +125,22 @@
                 mCarProjectionService,
                 mSystemStateControllerService,
                 mCarVendorExtensionService
-                };
+        };
     }
 
-    private void init() {
+    public void init() {
+        mHal.init();
         for (CarServiceBase service: mAllServices) {
             service.init();
         }
     }
 
-    private void release() {
+    public void release() {
         // release done in opposite order from init
         for (int i = mAllServices.length - 1; i >= 0; i--) {
             mAllServices[i].release();
         }
-        VehicleHal.releaseInstance();
-    }
-
-    /** Only for CarTestService */
-    void startMocking() {
-        reinitServices();
-    }
-
-    /** Only for CarTestService */
-    void stopMocking() {
-        reinitServices();
-    }
-
-    /** Reset all services when starting / stopping vehicle hal mocking */
-    private void reinitServices() {
-        for (int i = mAllServices.length - 1; i >= 0; i--) {
-            mAllServices[i].release();
-        }
-        VehicleHal.getInstance().release();
-        VehicleHal.getInstance().init();
-        for (CarServiceBase service: mAllServices) {
-            service.init();
-        }
+        mHal.release();
     }
 
     @Override
@@ -210,7 +180,7 @@
                 assertVendorExtensionPermission(mContext);
                 return mCarVendorExtensionService;
             case Car.TEST_SERVICE: {
-                assertVehicleHalMockPermission(mContext);
+                assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
                 synchronized (this) {
                     if (mCarTestService == null) {
                         mCarTestService = new CarTestService(mContext, this);
@@ -226,11 +196,7 @@
 
     @Override
     public int getCarConnectionType() {
-        if (!isInMocking()) {
-            return Car.CONNECTION_TYPE_EMBEDDED;
-        } else {
-            return Car.CONNECTION_TYPE_EMBEDDED_MOCKING;
-        }
+        return Car.CONNECTION_TYPE_EMBEDDED;
     }
 
     public CarServiceBase getCarInternalService(String serviceName) {
@@ -246,17 +212,6 @@
         }
     }
 
-    /**
-     * Whether mocking underlying HAL or not.
-     * @return
-     */
-    public synchronized boolean isInMocking() {
-        if (mCarTestService == null) {
-            return false;
-        }
-        return mCarTestService.isInMocking();
-    }
-
     public static void assertVehicleHalMockPermission(Context context) {
         assertPermission(context, Car.PERMISSION_MOCK_VEHICLE_HAL);
     }
@@ -300,10 +255,11 @@
         for (CarServiceBase service: mAllServices) {
             service.dump(writer);
         }
-        CarTestService testService = mCarTestService;
-        if (testService != null) {
-            testService.dump(writer);
+        if (mCarTestService != null) {
+            mCarTestService.dump(writer);
         }
+        writer.println("*Dump Vehicle HAL*");
+        mHal.dump(writer);
     }
 
     void execShellCmd(String[] args, PrintWriter writer) {
diff --git a/service/src/com/android/car/SystemInterface.java b/service/src/com/android/car/SystemInterface.java
new file mode 100644
index 0000000..6311d80
--- /dev/null
+++ b/service/src/com/android/car/SystemInterface.java
@@ -0,0 +1,191 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.Display;
+
+/**
+ * Interface to abstract all system interaction.
+ */
+public abstract class SystemInterface {
+    public abstract void setDisplayState(boolean on);
+    public abstract void releaseAllWakeLocks();
+    public abstract void shutdown();
+    public abstract void enterDeepSleep(int wakeupTimeSec);
+    public abstract void switchToPartialWakeLock();
+    public abstract void switchToFullWakeLock();
+    public abstract void startDisplayStateMonitoring(CarPowerManagementService service);
+    public abstract void stopDisplayStateMonitoring();
+    public abstract boolean isSystemSupportingDeepSleep();
+    public abstract boolean isWakeupCausedByTimer();
+
+
+    public static SystemInterface getDefault(Context context) {
+        return new SystemInterfaceImpl(context);
+    }
+
+    private static class SystemInterfaceImpl extends SystemInterface {
+        private final PowerManager mPowerManager;
+        private final DisplayManager mDisplayManager;
+        private final WakeLock mFullWakeLock;
+        private final WakeLock mPartialWakeLock;
+        private final DisplayStateListener mDisplayListener;
+        private CarPowerManagementService mService;
+        private boolean mDisplayStateSet;
+
+        private SystemInterfaceImpl(Context context) {
+            mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+            mFullWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK,
+                    CarLog.TAG_POWER);
+            mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    CarLog.TAG_POWER);
+            mDisplayListener = new DisplayStateListener();
+        }
+
+        @Override
+        public void startDisplayStateMonitoring(CarPowerManagementService service) {
+            synchronized (this) {
+                mService = service;
+                mDisplayStateSet = isMainDisplayOn();
+            }
+            mDisplayManager.registerDisplayListener(mDisplayListener, service.getHandler());
+        }
+
+        @Override
+        public void stopDisplayStateMonitoring() {
+            mDisplayManager.unregisterDisplayListener(mDisplayListener);
+        }
+
+        @Override
+        public void setDisplayState(boolean on) {
+            synchronized (this) {
+                mDisplayStateSet = on;
+            }
+            if (on) {
+                switchToFullWakeLock();
+                Log.i(CarLog.TAG_POWER, "on display");
+                mPowerManager.wakeUp(SystemClock.uptimeMillis());
+            } else {
+                switchToPartialWakeLock();
+                Log.i(CarLog.TAG_POWER, "off display");
+                mPowerManager.goToSleep(SystemClock.uptimeMillis());
+            }
+        }
+
+        private boolean isMainDisplayOn() {
+            Display disp = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            return disp.getState() == Display.STATE_ON;
+        }
+
+        @Override
+        public void shutdown() {
+            mPowerManager.shutdown(false /* no confirm*/, null, true /* true */);
+        }
+
+        @Override
+        public void enterDeepSleep(int wakeupTimeSec) {
+            //TODO set wake up time, bug: 32061842
+            mPowerManager.goToSleep(SystemClock.uptimeMillis(),
+                    PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN,
+                    PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+        }
+
+        @Override
+        public boolean isSystemSupportingDeepSleep() {
+            //TODO should return by checking some kernel suspend control sysfs, bug: 32061842
+            return false;
+        }
+
+        @Override
+        public void switchToPartialWakeLock() {
+            if (!mPartialWakeLock.isHeld()) {
+                mPartialWakeLock.acquire();
+            }
+            if (mFullWakeLock.isHeld()) {
+                mFullWakeLock.release();
+            }
+        }
+
+        @Override
+        public void switchToFullWakeLock() {
+            if (!mFullWakeLock.isHeld()) {
+                mFullWakeLock.acquire();
+            }
+            if (mPartialWakeLock.isHeld()) {
+                mPartialWakeLock.release();
+            }
+        }
+
+        @Override
+        public void releaseAllWakeLocks() {
+            if (mPartialWakeLock.isHeld()) {
+                mPartialWakeLock.release();
+            }
+            if (mFullWakeLock.isHeld()) {
+                mFullWakeLock.release();
+            }
+        }
+
+        @Override
+        public boolean isWakeupCausedByTimer() {
+            //TODO bug: 32061842, check wake up reason and do necessary operation information should
+            // come from kernel. it can be either power on or wake up for maintenance
+            // power on will involve GPIO trigger from power controller
+            // its own wakeup will involve timer expiration.
+            return false;
+        }
+
+        private void handleMainDisplayChanged() {
+            boolean isOn = isMainDisplayOn();
+            CarPowerManagementService service;
+            synchronized (this) {
+                if (mDisplayStateSet == isOn) { // same as what is set
+                    return;
+                }
+                service = mService;
+            }
+            service.handleMainDisplayChanged(isOn);
+        }
+
+        private class DisplayStateListener implements DisplayManager.DisplayListener {
+
+            @Override
+            public void onDisplayAdded(int displayId) {
+                //ignore
+            }
+
+            @Override
+            public void onDisplayChanged(int displayId) {
+                if (displayId == Display.DEFAULT_DISPLAY) {
+                    handleMainDisplayChanged();
+                }
+            }
+
+            @Override
+            public void onDisplayRemoved(int displayId) {
+                //ignore
+            }
+        }
+    }
+}
diff --git a/service/src/com/android/car/SystemStateControllerService.java b/service/src/com/android/car/SystemStateControllerService.java
index 5746300..63821c5 100644
--- a/service/src/com/android/car/SystemStateControllerService.java
+++ b/service/src/com/android/car/SystemStateControllerService.java
@@ -33,9 +33,9 @@
     private final boolean mLockWhenMuting;
 
     public SystemStateControllerService(Context context,
-            CarPowerManagementService carPowerManagementSercvice,
+            CarPowerManagementService carPowerManagementService,
             CarAudioService carAudioService, ICarImpl carImpl) {
-        mCarPowerManagementService = carPowerManagementSercvice;
+        mCarPowerManagementService = carPowerManagementService;
         mCarAudioService = carAudioService;
         mICarImpl = carImpl;
         Resources res = context.getResources();
@@ -51,16 +51,12 @@
     @Override
     public void onPowerOn(boolean displayOn) {
         if (displayOn) {
-            if (!mICarImpl.isInMocking()) {
-                Log.i(CarLog.TAG_SYS, "Media unmute");
-                mCarAudioService.unMuteMedia();
-            }
+            Log.i(CarLog.TAG_SYS, "Media unmute");
+            mCarAudioService.unMuteMedia();
         } else {
-            if (!mICarImpl.isInMocking()) { // do not do this in mocking as it can affect test.
-                Log.i(CarLog.TAG_SYS, "Media mute");
-                mCarAudioService.muteMediaWithLock(mLockWhenMuting);
-                //TODO store last context and resume or silence radio on display on. bug: 32096079
-            }
+            Log.i(CarLog.TAG_SYS, "Media mute");
+            mCarAudioService.muteMediaWithLock(mLockWhenMuting);
+            //TODO store last context and resume or silence radio on display on. bug: 32096079
         }
     }
 
diff --git a/service/src/com/android/car/VolumeUtils.java b/service/src/com/android/car/VolumeUtils.java
index fac3350..c2a1a7a 100644
--- a/service/src/com/android/car/VolumeUtils.java
+++ b/service/src/com/android/car/VolumeUtils.java
@@ -17,16 +17,13 @@
 package com.android.car;
 
 import android.car.settings.CarSettings;
+import android.hardware.vehicle.V2_0.VehicleAudioContextFlag;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioContextFlag;
-
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 public class VolumeUtils {
     private static final String TAG = "VolumeUtils";
@@ -42,50 +39,50 @@
     };
 
     public static final int[] CAR_AUDIO_CONTEXT = {
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CD_ROM_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_AUX_AUDIO_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG,
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG
+            VehicleAudioContextFlag.MUSIC_FLAG,
+            VehicleAudioContextFlag.NAVIGATION_FLAG,
+            VehicleAudioContextFlag.VOICE_COMMAND_FLAG,
+            VehicleAudioContextFlag.CALL_FLAG,
+            VehicleAudioContextFlag.ALARM_FLAG,
+            VehicleAudioContextFlag.NOTIFICATION_FLAG,
+            VehicleAudioContextFlag.UNKNOWN_FLAG,
+            VehicleAudioContextFlag.SAFETY_ALERT_FLAG,
+            VehicleAudioContextFlag.CD_ROM_FLAG,
+            VehicleAudioContextFlag.AUX_AUDIO_FLAG,
+            VehicleAudioContextFlag.SYSTEM_SOUND_FLAG,
+            VehicleAudioContextFlag.RADIO_FLAG
     };
 
     public static final SparseArray<String> CAR_AUDIO_CONTEXT_SETTINGS = new SparseArray<>();
     static {
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.UNKNOWN_FLAG,
                 CarSettings.Global.KEY_VOLUME_MUSIC);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.MUSIC_FLAG,
                 CarSettings.Global.KEY_VOLUME_MUSIC);
         CAR_AUDIO_CONTEXT_SETTINGS.put(
-                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG,
+                VehicleAudioContextFlag.NAVIGATION_FLAG,
                 CarSettings.Global.KEY_VOLUME_NAVIGATION);
         CAR_AUDIO_CONTEXT_SETTINGS.put(
-                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG,
+                VehicleAudioContextFlag.VOICE_COMMAND_FLAG,
                 CarSettings.Global.KEY_VOLUME_VOICE_COMMAND);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.CALL_FLAG,
                 CarSettings.Global.KEY_VOLUME_CALL);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.ALARM_FLAG,
                 CarSettings.Global.KEY_VOLUME_ALARM);
         CAR_AUDIO_CONTEXT_SETTINGS.put(
-                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG,
+                VehicleAudioContextFlag.NOTIFICATION_FLAG,
                 CarSettings.Global.KEY_VOLUME_NOTIFICATION);
         CAR_AUDIO_CONTEXT_SETTINGS.put(
-                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG,
+                VehicleAudioContextFlag.SAFETY_ALERT_FLAG,
                 CarSettings.Global.KEY_VOLUME_SAFETY_ALERT);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CD_ROM_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.CD_ROM_FLAG,
                 CarSettings.Global.KEY_VOLUME_CD_ROM);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_AUX_AUDIO_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.AUX_AUDIO_FLAG,
                 CarSettings.Global.KEY_VOLUME_AUX);
         CAR_AUDIO_CONTEXT_SETTINGS.put(
-                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG,
+                VehicleAudioContextFlag.SYSTEM_SOUND_FLAG,
                 CarSettings.Global.KEY_VOLUME_SYSTEM_SOUND);
-        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG,
+        CAR_AUDIO_CONTEXT_SETTINGS.put(VehicleAudioContextFlag.RADIO_FLAG,
                 CarSettings.Global.KEY_VOLUME_RADIO);
     }
 
@@ -105,35 +102,35 @@
     public static int androidStreamToCarContext(int logicalAndroidStream) {
         switch (logicalAndroidStream) {
             case AudioManager.STREAM_VOICE_CALL:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG;
+                return VehicleAudioContextFlag.CALL_FLAG;
             case AudioManager.STREAM_SYSTEM:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG;
+                return VehicleAudioContextFlag.SYSTEM_SOUND_FLAG;
             case AudioManager.STREAM_RING:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG;
+                return VehicleAudioContextFlag.NOTIFICATION_FLAG;
             case AudioManager.STREAM_MUSIC:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG;
+                return VehicleAudioContextFlag.MUSIC_FLAG;
             case AudioManager.STREAM_ALARM:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG;
+                return VehicleAudioContextFlag.ALARM_FLAG;
             case AudioManager.STREAM_NOTIFICATION:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG;
+                return VehicleAudioContextFlag.NOTIFICATION_FLAG;
             case AudioManager.STREAM_DTMF:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG;
+                return VehicleAudioContextFlag.SYSTEM_SOUND_FLAG;
             default:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG;
+                return VehicleAudioContextFlag.UNKNOWN_FLAG;
         }
     }
 
     public static int carContextToAndroidStream(int carContext) {
         switch (carContext) {
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG:
+            case VehicleAudioContextFlag.CALL_FLAG:
                 return AudioManager.STREAM_VOICE_CALL;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG:
+            case VehicleAudioContextFlag.SYSTEM_SOUND_FLAG:
                 return AudioManager.STREAM_SYSTEM;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG:
+            case VehicleAudioContextFlag.NOTIFICATION_FLAG:
                 return AudioManager.STREAM_NOTIFICATION;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG:
+            case VehicleAudioContextFlag.MUSIC_FLAG:
                 return AudioManager.STREAM_MUSIC;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG:
+            case VehicleAudioContextFlag.ALARM_FLAG:
                 return AudioManager.STREAM_ALARM;
             default:
                 return AudioManager.STREAM_MUSIC;
diff --git a/service/src/com/android/car/hal/AudioHalService.java b/service/src/com/android/car/hal/AudioHalService.java
index cb73454..b3f8880 100644
--- a/service/src/com/android/car/hal/AudioHalService.java
+++ b/service/src/com/android/car/hal/AudioHalService.java
@@ -15,95 +15,89 @@
  */
 package com.android.car.hal;
 
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_EXT_ROUTING_HINT;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_HW_VARIANT;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_ROUTING_POLICY;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_VOLUME;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AUDIO_VOLUME_LIMIT;
+import static com.android.car.CarServiceUtils.toIntArray;
+import static java.lang.Integer.toHexString;
+
+import android.annotation.Nullable;
 import android.car.VehicleZoneUtil;
 import android.car.media.CarAudioManager;
-import android.os.ServiceSpecificException;
+import android.hardware.vehicle.V2_0.VehicleAudioContextFlag;
+import android.hardware.vehicle.V2_0.VehicleAudioExtFocusFlag;
+import android.hardware.vehicle.V2_0.VehicleAudioFocusIndex;
+import android.hardware.vehicle.V2_0.VehicleAudioFocusRequest;
+import android.hardware.vehicle.V2_0.VehicleAudioFocusState;
+import android.hardware.vehicle.V2_0.VehicleAudioHwVariantConfigFlag;
+import android.hardware.vehicle.V2_0.VehicleAudioRoutingPolicyIndex;
+import android.hardware.vehicle.V2_0.VehicleAudioVolumeCapabilityFlag;
+import android.hardware.vehicle.V2_0.VehicleAudioVolumeIndex;
+import android.hardware.vehicle.V2_0.VehicleAudioVolumeLimitIndex;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehicleProperty;
+import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 
 import com.android.car.AudioRoutingPolicy;
 import com.android.car.CarAudioAttributesUtil;
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetwork;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioContextFlag;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioExtFocusFlag;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusRequest;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusState;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioHwVariantConfigFlag;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioRoutingPolicyIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioStreamState;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioStreamStateIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioVolumeCapabilityFlag;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioVolumeIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioVolumeLimitIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
-import com.android.car.vehiclenetwork.VehiclePropValueUtil;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 public class AudioHalService extends HalServiceBase {
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_INVALID = -1;
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_GAIN =
-            VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN;
+            VehicleAudioFocusRequest.REQUEST_GAIN;
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT =
-            VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT;
+            VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT;
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK =
-            VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK;
+            VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK;
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_NO_DUCK =
-            VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_NO_DUCK;
+            VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_NO_DUCK;
     public static final int VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE =
-            VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE;
-
-    public static String audioFocusRequestToString(int request) {
-        return VehicleAudioFocusRequest.enumToString(request);
-    }
+            VehicleAudioFocusRequest.REQUEST_RELEASE;
 
     public static final int VEHICLE_AUDIO_FOCUS_STATE_INVALID = -1;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_GAIN =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN;
+            VehicleAudioFocusState.STATE_GAIN;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT;
+            VehicleAudioFocusState.STATE_GAIN_TRANSIENT;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_CAN_DUCK =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_CAN_DUCK;
+            VehicleAudioFocusState.STATE_LOSS_TRANSIENT_CAN_DUCK;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT;
+            VehicleAudioFocusState.STATE_LOSS_TRANSIENT;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_LOSS =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS;
+            VehicleAudioFocusState.STATE_LOSS;
     public static final int VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_EXLCUSIVE =
-            VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_EXLCUSIVE;
+            VehicleAudioFocusState.STATE_LOSS_TRANSIENT_EXLCUSIVE;
 
-    public static String audioFocusStateToString(int state) {
-        return VehicleAudioFocusState.enumToString(state);
-    }
-
-    public static final int VEHICLE_AUDIO_STREAM_STATE_STOPPED =
-            VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STOPPED;
-    public static final int VEHICLE_AUDIO_STREAM_STATE_STARTED =
-            VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STARTED;
-
-    public static String audioStreamStateToString(int state) {
-        return VehicleAudioStreamState.enumToString(state);
-    }
+    // TODO(pavelm): we don't have internal properties anymore
+//    public static final int VEHICLE_AUDIO_STREAM_STATE_STOPPED =
+//            VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STOPPED;
+//    public static final int VEHICLE_AUDIO_STREAM_STATE_STARTED =
+//            VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STARTED;
 
     public static final int VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG =
-            VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG;
+            VehicleAudioExtFocusFlag.NONE_FLAG;
     public static final int VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG =
-            VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG;
+            VehicleAudioExtFocusFlag.PERMANENT_FLAG;
     public static final int VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT_FLAG =
-            VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT_FLAG;
+            VehicleAudioExtFocusFlag.TRANSIENT_FLAG;
     public static final int VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG =
-            VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG;
+            VehicleAudioExtFocusFlag.PLAY_ONLY_FLAG;
     public static final int VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG =
-            VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG;
+            VehicleAudioExtFocusFlag.MUTE_MEDIA_FLAG;
 
     public static final int STREAM_NUM_DEFAULT = 0;
 
@@ -112,31 +106,31 @@
     public static final int FOCUS_STATE_ARRAY_INDEX_EXTERNAL_FOCUS = 2;
 
     public static final int AUDIO_CONTEXT_MUSIC_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG;
+            VehicleAudioContextFlag.MUSIC_FLAG;
     public static final int AUDIO_CONTEXT_NAVIGATION_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG;
+            VehicleAudioContextFlag.NAVIGATION_FLAG;
     public static final int AUDIO_CONTEXT_VOICE_COMMAND_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG;
+            VehicleAudioContextFlag.VOICE_COMMAND_FLAG;
     public static final int AUDIO_CONTEXT_CALL_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG;
+            VehicleAudioContextFlag.CALL_FLAG;
     public static final int AUDIO_CONTEXT_ALARM_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG;
+            VehicleAudioContextFlag.ALARM_FLAG;
     public static final int AUDIO_CONTEXT_NOTIFICATION_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG;
+            VehicleAudioContextFlag.NOTIFICATION_FLAG;
     public static final int AUDIO_CONTEXT_UNKNOWN_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG;
+            VehicleAudioContextFlag.UNKNOWN_FLAG;
     public static final int AUDIO_CONTEXT_SAFETY_ALERT_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG;
+            VehicleAudioContextFlag.SAFETY_ALERT_FLAG;
     public static final int AUDIO_CONTEXT_RADIO_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG;
+            VehicleAudioContextFlag.RADIO_FLAG;
     public static final int AUDIO_CONTEXT_CD_ROM_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CD_ROM_FLAG;
+            VehicleAudioContextFlag.CD_ROM_FLAG;
     public static final int AUDIO_CONTEXT_AUX_AUDIO_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_AUX_AUDIO_FLAG;
+            VehicleAudioContextFlag.AUX_AUDIO_FLAG;
     public static final int AUDIO_CONTEXT_SYSTEM_SOUND_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG;
+            VehicleAudioContextFlag.SYSTEM_SOUND_FLAG;
     public static final int AUDIO_CONTEXT_EXT_SOURCE_FLAG =
-            VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_EXT_SOURCE_FLAG;
+            VehicleAudioContextFlag.EXT_SOURCE_FLAG;
 
     public interface AudioHalFocusListener {
         /**
@@ -193,60 +187,54 @@
     }
 
     public void setAudioRoutingPolicy(AudioRoutingPolicy policy) {
-        VehicleNetwork vn = mVehicleHal.getVehicleNetwork();
-        VehiclePropConfigs configs = vn.listProperties(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY);
-        if (configs == null) {
+        if (!mVehicleHal.isPropertySupported(VehicleProperty.AUDIO_ROUTING_POLICY)) {
             Log.w(CarLog.TAG_AUDIO,
-                    "Vehicle HAL did not implement VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY");
+                    "Vehicle HAL did not implement VehicleProperty.AUDIO_ROUTING_POLICY");
             return;
         }
         int[] policyToSet = new int[2];
         for (int i = 0; i < policy.getPhysicalStreamsCount(); i++) {
-            policyToSet[VehicleAudioRoutingPolicyIndex.VEHICLE_AUDIO_ROUTING_POLICY_INDEX_STREAM] =
-                    i;
+            policyToSet[VehicleAudioRoutingPolicyIndex.STREAM] = i;
             int contexts = 0;
             for (int logicalStream : policy.getLogicalStreamsForPhysicalStream(i)) {
                 contexts |= logicalStreamToHalContextType(logicalStream);
             }
-            policyToSet[VehicleAudioRoutingPolicyIndex.VEHICLE_AUDIO_ROUTING_POLICY_INDEX_CONTEXTS]
-                    = contexts;
+            policyToSet[VehicleAudioRoutingPolicyIndex.CONTEXTS] = contexts;
             try {
-                vn.setIntVectorProperty(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY,
-                        policyToSet);
-            } catch (ServiceSpecificException e) {
-                Log.e(CarLog.TAG_AUDIO, "Cannot write to VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY", e);
+                mVehicleHal.set(AUDIO_ROUTING_POLICY).to(policyToSet);
+            } catch (PropertyTimeoutException e) {
+                Log.e(CarLog.TAG_AUDIO, "Cannot write to VehicleProperty.AUDIO_ROUTING_POLICY", e);
             }
         }
     }
 
     /**
-     * Returns the volume limits of a stream in the form <min, max>.
+     * Returns the volume limits of a stream. Returns null if max value wasn't defined for
+     * AUDIO_VOLUME property.
      */
-    public synchronized Pair<Integer, Integer> getStreamVolumeLimit(int stream) {
-        if (!isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME)) {
-            throw new IllegalStateException("VEHICLE_PROPERTY_AUDIO_VOLUME not supported");
+    @Nullable
+    public synchronized Integer getStreamMaxVolume(int stream) {
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AUDIO_VOLUME);
+        if (config == null) {
+            throw new IllegalStateException("VehicleProperty.AUDIO_VOLUME not supported");
         }
         int supportedContext = getSupportedAudioVolumeContexts();
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME);
-        List<Integer> maxs = config.getInt32MaxsList();
-        List<Integer> mins = config.getInt32MinsList();
 
-        if (maxs.size() != mins.size()) {
-            Log.e(CarLog.TAG_AUDIO, "Invalid volume prop config");
-            return null;
+        int MAX_VALUES_FIRST_ELEMENT_INDEX = 4;
+        ArrayList<Integer> maxValues = new ArrayList<>();
+        for (int i = MAX_VALUES_FIRST_ELEMENT_INDEX; i < config.configArray.size(); i++) {
+            maxValues.add(config.configArray.get(i));
         }
 
-        Pair<Integer, Integer> result = null;
+        Integer result = null;
         if (supportedContext != 0) {
             int index = VehicleZoneUtil.zoneToIndex(supportedContext, stream);
-            if (index < maxs.size()) {
-                result = new Pair<>(mins.get(index), maxs.get(index));
+            if (index < maxValues.size()) {
+                result = maxValues.get(index);
             }
         } else {
-            if (stream < maxs.size()) {
-                result = new Pair<>(mins.get(stream), maxs.get(stream));
+            if (stream < maxValues.size()) {
+                result = maxValues.get(stream);
             }
         }
 
@@ -268,25 +256,25 @@
     public static int logicalStreamWithExtTypeToHalContextType(int logicalStream, String extType) {
         switch (logicalStream) {
             case CarAudioManager.CAR_AUDIO_USAGE_RADIO:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG;
+                return VehicleAudioContextFlag.RADIO_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG;
+                return VehicleAudioContextFlag.CALL_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_MUSIC:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG;
+                return VehicleAudioContextFlag.MUSIC_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG;
+                return VehicleAudioContextFlag.NAVIGATION_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG;
+                return VehicleAudioContextFlag.VOICE_COMMAND_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_ALARM:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG;
+                return VehicleAudioContextFlag.ALARM_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG;
+                return VehicleAudioContextFlag.NOTIFICATION_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG;
+                return VehicleAudioContextFlag.SAFETY_ALERT_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG;
+                return VehicleAudioContextFlag.SYSTEM_SOUND_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_DEFAULT:
-                return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG;
+                return VehicleAudioContextFlag.UNKNOWN_FLAG;
             case CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE:
                 if (extType != null) {
                     switch (extType) {
@@ -297,13 +285,13 @@
                         return AudioHalService.AUDIO_CONTEXT_AUX_AUDIO_FLAG;
                     default:
                         if (extType.startsWith("RADIO_")) {
-                            return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG;
+                            return VehicleAudioContextFlag.RADIO_FLAG;
                         } else {
                             return AudioHalService.AUDIO_CONTEXT_EXT_SOURCE_FLAG;
                         }
                     }
                 } else { // no external source specified. fall back to radio
-                    return VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG;
+                    return VehicleAudioContextFlag.RADIO_FLAG;
                 }
             case CarAudioAttributesUtil.CAR_AUDIO_USAGE_CARSERVICE_BOTTOM:
             case CarAudioAttributesUtil.CAR_AUDIO_USAGE_CARSERVICE_CAR_PROXY:
@@ -321,31 +309,31 @@
      */
     public static int carContextToCarUsage(int carContext) {
         switch (carContext) {
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG:
+            case VehicleAudioContextFlag.MUSIC_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_MUSIC;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG:
+            case VehicleAudioContextFlag.NAVIGATION_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG:
+            case VehicleAudioContextFlag.ALARM_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_ALARM;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG:
+            case VehicleAudioContextFlag.VOICE_COMMAND_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_AUX_AUDIO_FLAG:
+            case VehicleAudioContextFlag.AUX_AUDIO_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CALL_FLAG:
+            case VehicleAudioContextFlag.CALL_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_CD_ROM_FLAG:
+            case VehicleAudioContextFlag.CD_ROM_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG:
+            case VehicleAudioContextFlag.NOTIFICATION_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_RADIO_FLAG:
+            case VehicleAudioContextFlag.RADIO_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_RADIO;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG:
+            case VehicleAudioContextFlag.SAFETY_ALERT_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG:
+            case VehicleAudioContextFlag.SYSTEM_SOUND_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG:
+            case VehicleAudioContextFlag.UNKNOWN_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_DEFAULT;
-            case VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_EXT_SOURCE_FLAG:
+            case VehicleAudioContextFlag.EXT_SOURCE_FLAG:
                 return CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE;
             default:
                 Log.w(CarLog.TAG_AUDIO, "Unknown car context:" + carContext);
@@ -360,10 +348,9 @@
     public void requestAudioFocusChange(int request, int streams, int extFocus, int audioContexts) {
         int[] payload = { request, streams, extFocus, audioContexts };
         try {
-            mVehicleHal.getVehicleNetwork().setIntVectorProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, payload);
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "Cannot write to VEHICLE_PROPERTY_AUDIO_FOCUS", e);
+            mVehicleHal.set(AUDIO_FOCUS).to(payload);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "Cannot write to VehicleProperty.AUDIO_FOCUS", e);
             // focus timeout will reset it anyway
         }
     }
@@ -371,36 +358,35 @@
     public void setStreamVolume(int streamType, int index) {
         int[] payload = {streamType, index, 0};
         try {
-            mVehicleHal.getVehicleNetwork().setIntVectorProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME, payload);
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "Cannot write to VEHICLE_PROPERTY_AUDIO_VOLUME", e);
+            mVehicleHal.set(VehicleProperty.AUDIO_VOLUME).to(payload);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "Cannot write to VehicleProperty.AUDIO_VOLUME", e);
             //TODO should reset volume, bug: 32096870
         }
     }
 
     public int getStreamVolume(int stream) {
         int[] volume = {stream, 0, 0};
-        VehiclePropValue streamVolume =
-                VehiclePropValueUtil.createIntVectorValue(
-                        VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME, volume, 0);
-        VehiclePropValue value;
+        VehiclePropValue requestedStreamVolume = new VehiclePropValue();
+        requestedStreamVolume.prop = VehicleProperty.AUDIO_VOLUME;
+        requestedStreamVolume.value.int32Values.addAll(Arrays.asList(stream, 0 , 0));
+        VehiclePropValue propValue;
         try {
-            value = mVehicleHal.getVehicleNetwork().getProperty(streamVolume);
-        }  catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "AUDIO_VOLUME not ready", e);
+            propValue = mVehicleHal.get(requestedStreamVolume);
+        }  catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "VehicleProperty.AUDIO_VOLUME not ready", e);
             return 0;
         }
 
-        if (value.getInt32ValuesCount() != 3) {
+        if (propValue.value.int32Values.size() != 3) {
             Log.e(CarLog.TAG_AUDIO, "returned value not valid");
             throw new IllegalStateException("Invalid preset returned from service: "
-                    + value.getInt32ValuesList());
+                    + Arrays.toString(propValue.value.int32Values.toArray()));
         }
 
-        int retStreamNum = value.getInt32Values(0);
-        int retVolume = value.getInt32Values(1);
-        int retVolumeState = value.getInt32Values(2);
+        int retStreamNum = propValue.value.int32Values.get(0);
+        int retVolume = propValue.value.int32Values.get(1);
+        int retVolumeState = propValue.value.int32Values.get(2);
 
         if (retStreamNum != stream) {
             Log.e(CarLog.TAG_AUDIO, "Stream number is not the same: "
@@ -415,31 +401,28 @@
     }
 
     public synchronized boolean isRadioExternal() {
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_HW_VARIANT);
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AUDIO_HW_VARIANT);
         if (config == null) {
             return true;
         }
-        return (config.getConfigArray(0) &
-                VehicleAudioHwVariantConfigFlag.VEHICLE_AUDIO_HW_VARIANT_FLAG_INTERNAL_RADIO_FLAG)
-                == 0;
+        return (config.configArray.get(0)
+                & VehicleAudioHwVariantConfigFlag.INTERNAL_RADIO_FLAG) == 0;
     }
 
     public synchronized boolean isFocusSupported() {
-        return isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS);
+        return isPropertySupportedLocked(AUDIO_FOCUS);
     }
 
     public synchronized boolean isAudioVolumeSupported() {
-        return isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME);
+        return isPropertySupportedLocked(VehicleProperty.AUDIO_VOLUME);
     }
 
     public synchronized int getSupportedAudioVolumeContexts() {
-        if (!isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME)) {
-            throw new IllegalStateException("VEHICLE_PROPERTY_AUDIO_VOLUME not supported");
+        if (!isPropertySupportedLocked(VehicleProperty.AUDIO_VOLUME)) {
+            throw new IllegalStateException("VehicleProperty.AUDIO_VOLUME not supported");
         }
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME);
-        return config.getConfigArray(0);
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AUDIO_VOLUME);
+        return config.configArray.get(0);
     }
 
     /**
@@ -447,34 +430,32 @@
      * @return
      */
     public synchronized boolean isExternalAudioVolumePersistent() {
-        if (!isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME)) {
-            throw new IllegalStateException("VEHICLE_PROPERTY_AUDIO_VOLUME not supported");
+        if (!isPropertySupportedLocked(VehicleProperty.AUDIO_VOLUME)) {
+            throw new IllegalStateException("VehicleProperty.AUDIO_VOLUME not supported");
         }
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME);
-        if (config.getConfigArray(0) == 0) { // physical streams only
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AUDIO_VOLUME);
+        if (config.configArray.get(0) == 0) { // physical streams only
             return false;
         }
-        if ((config.getConfigArray(1) &
-                VehicleAudioVolumeCapabilityFlag.VEHICLE_AUDIO_VOLUME_CAPABILITY_PERSISTENT_STORAGE)
-                != 0) {
+        if ((config.configArray.get(1)
+                & VehicleAudioVolumeCapabilityFlag.PERSISTENT_STORAGE) != 0) {
             return true;
         }
         return false;
     }
 
     public synchronized boolean isAudioVolumeLimitSupported() {
-        return isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT);
+        return isPropertySupportedLocked(AUDIO_VOLUME_LIMIT);
     }
 
     public synchronized boolean isAudioVolumeMasterOnly() {
-        if (!isPropertySupportedLocked(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME)) {
-            throw new IllegalStateException("VEHICLE_PROPERTY_AUDIO_VOLUME not supported");
+        if (!isPropertySupportedLocked(VehicleProperty.AUDIO_VOLUME)) {
+            throw new IllegalStateException("VehicleProperty.AUDIO_VOLUME not supported");
         }
         VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME);
-        if ((config.getConfigArray(1) &
-                VehicleAudioVolumeCapabilityFlag.VEHICLE_AUDIO_VOLUME_CAPABILITY_MASTER_VOLUME_ONLY)
+                AUDIO_VOLUME);
+        if ((config.configArray.get(1) &
+                VehicleAudioVolumeCapabilityFlag.MASTER_VOLUME_ONLY)
                 != 0) {
             return true;
         }
@@ -490,10 +471,10 @@
             return new int[] { VEHICLE_AUDIO_FOCUS_STATE_GAIN, 0xffffffff, 0};
         }
         try {
-            return mVehicleHal.getVehicleNetwork().getIntVectorProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS);
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "VEHICLE_PROPERTY_AUDIO_HW_VARIANT not ready", e);
+            VehiclePropValue propValue = mVehicleHal.get(VehicleProperty.AUDIO_FOCUS);
+            return toIntArray(propValue.value.int32Values);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "VehicleProperty.AUDIO_HW_VARIANT not ready", e);
             return new int[] { VEHICLE_AUDIO_FOCUS_STATE_LOSS, 0x0, 0};
         }
     }
@@ -518,7 +499,7 @@
 
         @Override
         public String toString() {
-            return "[bitPosition=" + bitPosition + ", physycalStreamNumber="
+            return "[bitPosition=" + bitPosition + ", physicalStreamNumber="
                     + physicalStreamNumber + "]";
         }
     }
@@ -531,21 +512,22 @@
     public Map<String, ExtRoutingSourceInfo> getExternalAudioRoutingTypes() {
         VehiclePropConfig config;
         synchronized (this) {
-            if (!isPropertySupportedLocked(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT)) {
+            if (!isPropertySupportedLocked(AUDIO_EXT_ROUTING_HINT)) {
+                if (DBG) {
+                    Log.i(CarLog.TAG_AUDIO, "AUDIO_EXT_ROUTING_HINT is not supported");
+                }
                 return null;
             }
-            config = mProperties.get(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT);
+            config = mProperties.get(AUDIO_EXT_ROUTING_HINT);
         }
-        if (!config.hasConfigString()) {
-            Log.w(CarLog.TAG_HAL, "AUDIO_EXT_ROUTING_HINT with empty config string");
+        if (TextUtils.isEmpty(config.configString)) {
+            Log.w(CarLog.TAG_AUDIO, "AUDIO_EXT_ROUTING_HINT with empty config string");
             return null;
         }
         Map<String, ExtRoutingSourceInfo> routingTypes = new HashMap<>();
-        String configString = config.getConfigString();
+        String configString = config.configString;
         if (DBG) {
-            Log.i(CarLog.TAG_HAL, "AUDIO_EXT_ROUTING_HINT config string:" + configString);
+            Log.i(CarLog.TAG_AUDIO, "AUDIO_EXT_ROUTING_HINT config string:" + configString);
         }
         String[] routes = configString.split(",");
         for (String routeString : routes) {
@@ -561,7 +543,7 @@
                 name = tokens[1];
                 physicalStreamNumber = Integer.parseInt(tokens[2]);
             } else {
-                Log.w(CarLog.TAG_AUDIO, "VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT has wrong entry:" +
+                Log.w(CarLog.TAG_AUDIO, "AUDIO_EXT_ROUTING_HINT has wrong entry:" +
                         routeString);
                 continue;
             }
@@ -572,10 +554,9 @@
 
     public void setExternalRoutingSource(int[] externalRoutings) {
         try {
-            mVehicleHal.getVehicleNetwork().setIntVectorProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT, externalRoutings);
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "Cannot write to VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT", e);
+            mVehicleHal.set(AUDIO_EXT_ROUTING_HINT).to(externalRoutings);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "Cannot write to VehicleProperty.AUDIO_EXT_ROUTING_HINT", e);
         }
     }
 
@@ -588,17 +569,16 @@
     public synchronized void init() {
         for (VehiclePropConfig config : mProperties.values()) {
             if (VehicleHal.isPropertySubscribable(config)) {
-                mVehicleHal.subscribeProperty(this, config.getProp(), 0);
+                mVehicleHal.subscribeProperty(this, config.prop, 0);
             }
         }
         try {
-            mVariant = mVehicleHal.getVehicleNetwork().getIntProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_HW_VARIANT);
+            mVariant = mVehicleHal.get(int.class, AUDIO_HW_VARIANT);
         } catch (IllegalArgumentException e) {
             // no variant. Set to default, 0.
             mVariant = 0;
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_AUDIO, "VEHICLE_PROPERTY_AUDIO_HW_VARIANT not ready", e);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_AUDIO, "VehicleProperty.AUDIO_HW_VARIANT not ready", e);
             mVariant = 0;
         }
     }
@@ -607,34 +587,35 @@
     public synchronized void release() {
         for (VehiclePropConfig config : mProperties.values()) {
             if (VehicleHal.isPropertySubscribable(config)) {
-                mVehicleHal.unsubscribeProperty(this, config.getProp());
+                mVehicleHal.unsubscribeProperty(this, config.prop);
             }
         }
         mProperties.clear();
     }
 
     @Override
-    public synchronized List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
+    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
         for (VehiclePropConfig p : allProperties) {
-            switch (p.getProp()) {
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_HW_VARIANT:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE:
-                    mProperties.put(p.getProp(), p);
+            switch (p.prop) {
+                case VehicleProperty.AUDIO_FOCUS:
+                case VehicleProperty.AUDIO_VOLUME:
+                case VehicleProperty.AUDIO_VOLUME_LIMIT:
+                case VehicleProperty.AUDIO_HW_VARIANT:
+                case VehicleProperty.AUDIO_EXT_ROUTING_HINT:
+                    // TODO(pavelm): we don't have internal properties anymore.
+//                case VehicleProperty.INTERNAL_AUDIO_STREAM_STATE:
+                    mProperties.put(p.prop, p);
                     break;
             }
         }
-        return new LinkedList<VehiclePropConfig>(mProperties.values());
+        return new ArrayList<>(mProperties.values());
     }
 
     @Override
     public void handleHalEvents(List<VehiclePropValue> values) {
-        AudioHalFocusListener focusListener = null;
-        AudioHalVolumeListener volumeListener = null;
+        AudioHalFocusListener focusListener;
+        AudioHalVolumeListener volumeListener;
         synchronized (this) {
             focusListener = mFocusListener;
             volumeListener = mVolumeListener;
@@ -646,44 +627,38 @@
             AudioHalVolumeListener volumeListener,
             List<VehiclePropValue> values) {
         for (VehiclePropValue v : values) {
-            switch (v.getProp()) {
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS: {
-                    int focusState = v.getInt32Values(
-                            VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_FOCUS);
-                    int streams = v.getInt32Values(
-                            VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_STREAMS);
-                    int externalFocus = v.getInt32Values(
-                            VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_EXTERNAL_FOCUS_STATE);
+            ArrayList<Integer> vec = v.value.int32Values;
+            switch (v.prop) {
+                case VehicleProperty.AUDIO_FOCUS: {
+                    int focusState = vec.get(VehicleAudioFocusIndex.FOCUS);
+                    int streams = vec.get(VehicleAudioFocusIndex.STREAMS);
+                    int externalFocus = vec.get(VehicleAudioFocusIndex.EXTERNAL_FOCUS_STATE);
                     if (focusListener != null) {
                         focusListener.onFocusChange(focusState, streams, externalFocus);
                     }
                 } break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE: {
-                    int state = v.getInt32Values(
-                            VehicleAudioStreamStateIndex.VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE);
-                    int streamNum = v.getInt32Values(
-                            VehicleAudioStreamStateIndex.VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM);
-                    if (focusListener != null) {
-                        focusListener.onStreamStatusChange(streamNum, state ==
-                                VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STARTED);
-                    }
-                } break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME: {
-                    int volume = v.getInt32Values(
-                            VehicleAudioVolumeIndex.VEHICLE_AUDIO_VOLUME_INDEX_VOLUME);
-                    int streamNum = v.getInt32Values(
-                            VehicleAudioVolumeIndex.VEHICLE_AUDIO_VOLUME_INDEX_STREAM);
-                    int volumeState = v.getInt32Values(
-                            VehicleAudioVolumeIndex.VEHICLE_AUDIO_VOLUME_INDEX_STATE);
+                // TODO(pavelm): we don't have internal properties anymore
+//                case INTERNAL_AUDIO_STREAM_STATE: {
+//                    int state = v.getInt32Values(
+//                            VehicleAudioStreamStateIndex.VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE);
+//                    int streamNum = v.getInt32Values(
+//                            VehicleAudioStreamStateIndex.VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM);
+//                    if (focusListener != null) {
+//                        focusListener.onStreamStatusChange(streamNum, state ==
+//                                VehicleAudioStreamState.VEHICLE_AUDIO_STREAM_STATE_STARTED);
+//                    }
+//                } break;
+                case AUDIO_VOLUME: {
+                    int volume = vec.get(VehicleAudioVolumeIndex.INDEX_VOLUME);
+                    int streamNum = vec.get(VehicleAudioVolumeIndex.INDEX_STREAM);
+                    int volumeState = vec.get(VehicleAudioVolumeIndex.INDEX_STATE);
                     if (volumeListener != null) {
                         volumeListener.onVolumeChange(streamNum, volume, volumeState);
                     }
                 } break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT: {
-                    int stream = v.getInt32Values(
-                            VehicleAudioVolumeLimitIndex.VEHICLE_AUDIO_VOLUME_LIMIT_INDEX_STREAM);
-                    int maxVolume = v.getInt32Values(
-                            VehicleAudioVolumeLimitIndex.VEHICLE_AUDIO_VOLUME_LIMIT_INDEX_MAX_VOLUME);
+                case AUDIO_VOLUME_LIMIT: {
+                    int stream = vec.get(VehicleAudioVolumeLimitIndex.STREAM);
+                    int maxVolume = vec.get(VehicleAudioVolumeLimitIndex.MAX_VOLUME);
                     if (volumeListener != null) {
                         volumeListener.onVolumeLimitChange(stream, maxVolume);
                     }
diff --git a/service/src/com/android/car/hal/CabinHalService.java b/service/src/com/android/car/hal/CabinHalService.java
index 213f458..b0e5e21 100644
--- a/service/src/com/android/car/hal/CabinHalService.java
+++ b/service/src/com/android/car/hal/CabinHalService.java
@@ -16,8 +16,7 @@
 package com.android.car.hal;
 
 import android.car.hardware.cabin.CarCabinManager;
-
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
+import android.hardware.vehicle.V2_0.VehicleProperty;
 
 public class CabinHalService extends PropertyHalServiceBase {
     private static final boolean DBG = false;
@@ -25,127 +24,127 @@
 
     private final ManagerToHalPropIdMap mMgrHalPropIdMap = ManagerToHalPropIdMap.create(new int[] {
             CarCabinManager.ID_DOOR_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_DOOR_POS,
+            VehicleProperty.DOOR_POS,
 
             CarCabinManager.ID_DOOR_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_DOOR_MOVE,
+            VehicleProperty.DOOR_MOVE,
 
             CarCabinManager.ID_DOOR_LOCK,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_DOOR_LOCK,
+            VehicleProperty.DOOR_LOCK,
 
             CarCabinManager.ID_MIRROR_Z_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_Z_POS,
+            VehicleProperty.MIRROR_Z_POS,
 
             CarCabinManager.ID_MIRROR_Z_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_Z_MOVE,
+            VehicleProperty.MIRROR_Z_MOVE,
 
             CarCabinManager.ID_MIRROR_Y_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_Y_POS,
+            VehicleProperty.MIRROR_Y_POS,
 
             CarCabinManager.ID_MIRROR_Y_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_Y_MOVE,
+            VehicleProperty.MIRROR_Y_MOVE,
 
             CarCabinManager.ID_MIRROR_LOCK,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_LOCK,
+            VehicleProperty.MIRROR_LOCK,
 
             CarCabinManager.ID_MIRROR_FOLD,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_MIRROR_FOLD,
+            VehicleProperty.MIRROR_FOLD,
 
             CarCabinManager.ID_SEAT_MEMORY_SELECT,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_MEMORY_SELECT,
+            VehicleProperty.SEAT_MEMORY_SELECT,
 
             CarCabinManager.ID_SEAT_MEMORY_SET,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_MEMORY_SET,
+            VehicleProperty.SEAT_MEMORY_SET,
 
             CarCabinManager.ID_SEAT_BELT_BUCKLED,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BELT_BUCKLED,
+            VehicleProperty.SEAT_BELT_BUCKLED,
 
             CarCabinManager.ID_SEAT_BELT_HEIGHT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_POS,
+            VehicleProperty.SEAT_BELT_HEIGHT_POS,
 
             CarCabinManager.ID_SEAT_BELT_HEIGHT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_MOVE,
+            VehicleProperty.SEAT_BELT_HEIGHT_MOVE,
 
             CarCabinManager.ID_SEAT_FORE_AFT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_FORE_AFT_POS,
+            VehicleProperty.SEAT_FORE_AFT_POS,
 
             CarCabinManager.ID_SEAT_FORE_AFT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_FORE_AFT_MOVE,
+            VehicleProperty.SEAT_FORE_AFT_MOVE,
 
             CarCabinManager.ID_SEAT_BACKREST_ANGLE_1_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_POS,
+            VehicleProperty.SEAT_BACKREST_ANGLE_1_POS,
 
             CarCabinManager.ID_SEAT_BACKREST_ANGLE_1_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_MOVE,
+            VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE,
 
             CarCabinManager.ID_SEAT_BACKREST_ANGLE_2_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_POS,
+            VehicleProperty.SEAT_BACKREST_ANGLE_2_POS,
 
             CarCabinManager.ID_SEAT_BACKREST_ANGLE_2_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_MOVE,
+            VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE,
 
             CarCabinManager.ID_SEAT_HEIGHT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEIGHT_POS,
+            VehicleProperty.SEAT_HEIGHT_POS,
 
             CarCabinManager.ID_SEAT_HEIGHT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEIGHT_MOVE,
+            VehicleProperty.SEAT_HEIGHT_MOVE,
 
             CarCabinManager.ID_SEAT_DEPTH_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_DEPTH_POS,
+            VehicleProperty.SEAT_DEPTH_POS,
 
             CarCabinManager.ID_SEAT_DEPTH_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_DEPTH_MOVE,
+            VehicleProperty.SEAT_DEPTH_MOVE,
 
             CarCabinManager.ID_SEAT_TILT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_TILT_POS,
+            VehicleProperty.SEAT_TILT_POS,
 
             CarCabinManager.ID_SEAT_TILT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_TILT_MOVE,
+            VehicleProperty.SEAT_TILT_MOVE,
 
             CarCabinManager.ID_SEAT_LUMBAR_FORE_AFT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_POS,
+            VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS,
 
             CarCabinManager.ID_SEAT_LUMBAR_FORE_AFT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_MOVE,
+            VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE,
 
             CarCabinManager.ID_SEAT_LUMBAR_SIDE_SUPPORT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_POS,
+            VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS,
 
             CarCabinManager.ID_SEAT_LUMBAR_SIDE_SUPPORT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_MOVE,
+            VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE,
 
             CarCabinManager.ID_SEAT_HEADREST_HEIGHT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_POS,
+            VehicleProperty.SEAT_HEADREST_HEIGHT_POS,
 
             CarCabinManager.ID_SEAT_HEADREST_HEIGHT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_MOVE,
+            VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE,
 
             CarCabinManager.ID_SEAT_HEADREST_ANGLE_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_POS,
+            VehicleProperty.SEAT_HEADREST_ANGLE_POS,
 
             CarCabinManager.ID_SEAT_HEADREST_ANGLE_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_MOVE,
+            VehicleProperty.SEAT_HEADREST_ANGLE_MOVE,
 
             CarCabinManager.ID_SEAT_HEADREST_FORE_AFT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_POS,
+            VehicleProperty.SEAT_HEADREST_FORE_AFT_POS,
 
             CarCabinManager.ID_SEAT_HEADREST_FORE_AFT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_MOVE,
+            VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE,
 
             CarCabinManager.ID_WINDOW_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_WINDOW_POS,
+            VehicleProperty.WINDOW_POS,
 
             CarCabinManager.ID_WINDOW_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_WINDOW_MOVE,
+            VehicleProperty.WINDOW_MOVE,
 
             CarCabinManager.ID_WINDOW_VENT_POS,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_WINDOW_VENT_POS,
+            VehicleProperty.WINDOW_VENT_POS,
 
             CarCabinManager.ID_WINDOW_VENT_MOVE,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_WINDOW_VENT_MOVE,
+            VehicleProperty.WINDOW_VENT_MOVE,
 
             CarCabinManager.ID_WINDOW_LOCK,
-            VehicleNetworkConsts.VEHICLE_PROPERTY_WINDOW_LOCK
+            VehicleProperty.WINDOW_LOCK
     });
 
     public CabinHalService(VehicleHal vehicleHal) {
diff --git a/service/src/com/android/car/hal/CarPropertyUtils.java b/service/src/com/android/car/hal/CarPropertyUtils.java
index c584f31..00cde28 100644
--- a/service/src/com/android/car/hal/CarPropertyUtils.java
+++ b/service/src/com/android/car/hal/CarPropertyUtils.java
@@ -15,46 +15,20 @@
  */
 package com.android.car.hal;
 
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_BYTES;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_STRING;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_NONE;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_ZONE;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_SEAT;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_DOOR;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_WINDOW;
-import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_MIRROR;
-import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorValueType;
+import static com.android.car.CarServiceUtils.toByteArray;
 import static java.lang.Integer.toHexString;
 
 import android.car.VehicleAreaType;
 import android.car.VehicleZoneUtil;
 import android.car.hardware.CarPropertyConfig;
 import android.car.hardware.CarPropertyValue;
+import android.hardware.vehicle.V2_0.VehicleArea;
+import android.hardware.vehicle.V2_0.VehicleAreaConfig;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehiclePropertyType;
 
-import com.google.protobuf.ByteString;
-
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
-
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -68,168 +42,136 @@
     /** Converts {@link VehiclePropValue} to {@link CarPropertyValue} */
     static CarPropertyValue<?> toCarPropertyValue(
             VehiclePropValue halValue, int propertyId) {
-        Class<?> clazz = getJavaClass(halValue.getValueType());
-        int areaId = halValue.getZone();
+        Class<?> clazz = getJavaClass(halValue.prop & VehiclePropertyType.MASK);
+        int areaId = halValue.areaId;
+        VehiclePropValue.RawValue v = halValue.value;
+
         if (Boolean.class == clazz) {
-            return new CarPropertyValue<>(propertyId, areaId, halValue.getInt32Values(0) == 1);
+            return new CarPropertyValue<>(propertyId, areaId, v.int32Values.get(0) == 1);
         } else if (String.class == clazz) {
-            return new CarPropertyValue<>(propertyId, areaId, halValue.getStringValue());
+            return new CarPropertyValue<>(propertyId, areaId, v.stringValue);
         } else if (Long.class == clazz) {
-            return new CarPropertyValue<>(propertyId, areaId, halValue.getInt64Value());
+            return new CarPropertyValue<>(propertyId, areaId, v.int64Values.get(0));
         } else if (byte[].class == clazz) {
-            byte[] halData = halValue.getBytesValue().toByteArray();
+            byte[] halData = toByteArray(v.bytes);
             return new CarPropertyValue<>(propertyId, areaId, halData);
         } else /* All list properties */ {
-            Object[] values = getRawValueList(clazz, halValue).toArray();
+            Object[] values = getRawValueList(clazz, v).toArray();
             return new CarPropertyValue<>(propertyId, areaId,
                     values.length == 1 ? values[0] : values);
         }
     }
 
     /** Converts {@link CarPropertyValue} to {@link VehiclePropValue} */
-    static VehiclePropValue toVehiclePropValue(CarPropertyValue hvacProp, int halPropId) {
-        VehiclePropValue.Builder builder = VehiclePropValue.newBuilder();
-        builder.setProp(halPropId);
+    static VehiclePropValue toVehiclePropValue(CarPropertyValue carProp, int halPropId) {
+        VehiclePropValue vehicleProp = new VehiclePropValue();
+        vehicleProp.prop = halPropId;
+        vehicleProp.areaId = carProp.getAreaId();
+        VehiclePropValue.RawValue v = vehicleProp.value;
 
-        if (hvacProp.getAreaId() != 0) {
-            builder.setZone(hvacProp.getAreaId());
-        }
+        Object o = carProp.getValue();
 
-        Object o = hvacProp.getValue();
-
-        boolean hasArea = hvacProp.getAreaId() != 0;
-        int vectorLength = (o instanceof Object[] ? ((Object[]) o).length : 0);
-        int halType;
         if (o instanceof Boolean) {
-            halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_BOOLEAN : VEHICLE_VALUE_TYPE_BOOLEAN;
-            builder.addInt32Values(((Boolean )o) ? 1 : 0);
+            v.int32Values.add(((Boolean )o) ? 1 : 0);
         } else if (o instanceof Integer) {
-            halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_INT32;
-            builder.addInt32Values((Integer) o);
+            v.int32Values.add((Integer) o);
         } else if (o instanceof Float) {
-            halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_FLOAT;
-            builder.addFloatValues((Float) o);
+            v.floatValues.add((Float) o);
         } else if (o instanceof Integer[]) {
-            halType = getVectorValueType(
-                    hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_ZONED_INT32,
-                    vectorLength);
-            for (Integer i : (Integer[]) o) {
-                builder.addInt32Values(i);
-            }
+            Collections.addAll(v.int32Values, (Integer[]) o);
         } else if (o instanceof Float[]) {
-            halType = getVectorValueType(
-                    hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_ZONED_FLOAT,
-                    vectorLength);
-            for (Float f : (Float[]) o) {
-                builder.addFloatValues(f);
-            }
+            Collections.addAll(v.floatValues, (Float[]) o);
         } else if (o instanceof String) {
-            halType = VEHICLE_VALUE_TYPE_STRING;
-            builder.setStringValue((String) o);
+            v.stringValue = (String) o;
         } else if (o instanceof byte[]) {
-            halType = VEHICLE_VALUE_TYPE_BYTES;  // We don't have zoned type in vehicle.h
-            builder.setBytesValue(ByteString.copyFrom((byte[]) o));
+            for (byte b : (byte[]) o) {
+                v.bytes.add(b);
+            }
         } else {
-            throw new IllegalArgumentException("Unexpected type in: " + hvacProp);
+            throw new IllegalArgumentException("Unexpected type in: " + carProp);
         }
-        builder.setValueType(halType);
-        return builder.build();
+
+        return vehicleProp;
     }
 
     /**
      * Converts {@link VehiclePropConfig} to {@link CarPropertyConfig}.
      */
     static CarPropertyConfig<?> toCarPropertyConfig(VehiclePropConfig p, int propertyId) {
-        int[] areas = VehicleZoneUtil.listAllZones(p.getZones());
+        int[] areas = VehicleZoneUtil.listAllZones(p.supportedAreas);
 
-        int areaType = getVehicleAreaType(VehicleNetworkConsts.getVehicleZoneType(p.getProp()));
+        int areaType = getVehicleAreaType(p.prop & VehicleArea.MASK);
 
-        Class<?> clazz = getJavaClass(p.getValueType());
+        Class<?> clazz = getJavaClass(p.prop & VehiclePropertyType.MASK);
         if (clazz == Boolean.class || clazz == byte[].class || clazz == String.class) {
             return CarPropertyConfig
                     .newBuilder(clazz, propertyId, areaType, /* capacity */ 1)
                     .addAreas(areas)
                     .build();
         } else {
-            List mins;
-            List maxs;
-            if (classMatched(Integer.class, clazz)) {
-                mins = p.getInt32MinsList();
-                maxs = p.getInt32MaxsList();
-            } else if (classMatched(Float.class, clazz)) {
-                mins = p.getFloatMinsList();
-                maxs = p.getFloatMaxsList();
-            } else {
-                throw new IllegalArgumentException("Unexpected type: " + clazz);
-            }
             CarPropertyConfig.Builder builder = CarPropertyConfig
-                    .newBuilder(clazz, propertyId, areaType, /* capacity */ mins.size());
-            for (int i = 0; i < mins.size(); i++) {
-                int areaId = areas.length == 0 ? 0 : areas[i];
-                builder.addAreaConfig(areaId, mins.get(i), maxs.get(i));
+                    .newBuilder(clazz, propertyId, areaType, /* capacity */  p.areaConfigs.size());
+
+            for (VehicleAreaConfig area : p.areaConfigs) {
+                if (classMatched(Integer.class, clazz)) {
+                    builder.addAreaConfig(area.areaId, area.minInt32Value, area.maxInt32Value);
+                } else if (classMatched(Float.class, clazz)) {
+                    builder.addAreaConfig(area.areaId, area.minFloatValue, area.maxFloatValue);
+                } else if (classMatched(Long.class, clazz)) {
+                    builder.addAreaConfig(area.areaId, area.minInt64Value, area.maxInt64Value);
+                } else {
+                    throw new IllegalArgumentException("Unexpected type: " + clazz);
+                }
             }
             return builder.build();
         }
     }
 
-    private static @VehicleAreaType.VehicleAreaTypeValue int getVehicleAreaType(int zoneType) {
-        switch (zoneType) {
-            case VEHICLE_ZONE_TYPE_NONE:
+    private static @VehicleAreaType.VehicleAreaTypeValue int getVehicleAreaType(int halArea) {
+        switch (halArea) {
+            case VehicleArea.GLOBAL:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_NONE;
-            case VEHICLE_ZONE_TYPE_ZONE:
+            case VehicleArea.ZONE:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_ZONE;
-            case VEHICLE_ZONE_TYPE_SEAT:
+            case VehicleArea.SEAT:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_SEAT;
-            case VEHICLE_ZONE_TYPE_DOOR:
+            case VehicleArea.DOOR:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_DOOR;
-            case VEHICLE_ZONE_TYPE_WINDOW:
+            case VehicleArea.WINDOW:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_WINDOW;
-            case VEHICLE_ZONE_TYPE_MIRROR:
+            case VehicleArea.MIRROR:
                 return VehicleAreaType.VEHICLE_AREA_TYPE_MIRROR;
             default:
-                throw new RuntimeException("Unsupported zone type " + zoneType);
+                throw new RuntimeException("Unsupported area type " + halArea);
         }
     }
 
     private static Class<?> getJavaClass(int halType) {
         switch (halType) {
-            case VEHICLE_VALUE_TYPE_BOOLEAN:
-            case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
+            case VehiclePropertyType.BOOLEAN:
                 return Boolean.class;
-            case VEHICLE_VALUE_TYPE_FLOAT:
-            case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
+            case VehiclePropertyType.FLOAT:
                 return Float.class;
-            case VEHICLE_VALUE_TYPE_INT32:
-            case VEHICLE_VALUE_TYPE_ZONED_INT32:
+            case VehiclePropertyType.INT32:
                 return Integer.class;
-            case VEHICLE_VALUE_TYPE_INT32_VEC2:
-            case VEHICLE_VALUE_TYPE_INT32_VEC3:
-            case VEHICLE_VALUE_TYPE_INT32_VEC4:
-            case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
-            case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
-            case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
+            case VehiclePropertyType.INT32_VEC:
                 return Integer[].class;
-            case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
-            case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
-            case VEHICLE_VALUE_TYPE_FLOAT_VEC4:
-            case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
-            case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
-            case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
+            case VehiclePropertyType.FLOAT_VEC:
                 return Float[].class;
-            case VEHICLE_VALUE_TYPE_STRING:
+            case VehiclePropertyType.STRING:
                 return String.class;
-            case VEHICLE_VALUE_TYPE_BYTES:
+            case VehiclePropertyType.BYTES:
                 return byte[].class;
             default:
                 throw new IllegalArgumentException("Unexpected type: " + toHexString(halType));
         }
     }
 
-    private static List getRawValueList(Class<?> clazz, VehiclePropValue vehiclePropValue) {
+    private static List getRawValueList(Class<?> clazz, VehiclePropValue.RawValue value) {
         if (classMatched(Float.class, clazz)) {
-            return vehiclePropValue.getFloatValuesList();
+            return value.floatValues;
         } else if (classMatched(Integer.class, clazz)) {
-            return vehiclePropValue.getInt32ValuesList();
+            return value.int32Values;
         } else {
             throw new IllegalArgumentException("Unexpected type: " + clazz);
         }
diff --git a/service/src/com/android/car/hal/HalClient.java b/service/src/com/android/car/hal/HalClient.java
new file mode 100644
index 0000000..ee5e593
--- /dev/null
+++ b/service/src/com/android/car/hal/HalClient.java
@@ -0,0 +1,261 @@
+/*
+ * 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.hal;
+
+import static android.os.SystemClock.elapsedRealtime;
+
+import android.hardware.vehicle.V2_0.IVehicle;
+import android.hardware.vehicle.V2_0.IVehicle.getCallback;
+import android.hardware.vehicle.V2_0.IVehicleCallback;
+import android.hardware.vehicle.V2_0.StatusCode;
+import android.hardware.vehicle.V2_0.SubscribeFlags;
+import android.hardware.vehicle.V2_0.SubscribeOptions;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.os.Handler;
+import android.os.IHwBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.car.CarLog;
+
+import java.util.ArrayList;
+
+/**
+ * Vehicle HAL client. Interacts directly with Vehicle HAL interface {@link IVehicle}. Contains
+ * some logic for retriable properties, redirects Vehicle notifications into given looper thread.
+ */
+class  HalClient {
+    /**
+     * If call to vehicle HAL returns StatusCode.TRY_AGAIN, than {@link HalClient} will retry to
+     * invoke that method again for this amount of milliseconds.
+     */
+    private static final int WAIT_CAP_FOR_RETRIABLE_RESULT_MS = 2000;
+
+    private static final int SLEEP_BETWEEN_RETRIABLE_INVOKES_MS = 50;
+
+    private final IVehicle mVehicle;
+
+    private final IVehicleCallback mInternalCallback;
+
+    /**
+     * Create HalClient object
+     *
+     * @param vehicle interface to the vehicle HAL
+     * @param looper looper that will be used to propagate notifications from vehicle HAL
+     * @param callback to propagate notifications from Vehicle HAL in the provided looper thread
+     */
+    HalClient(IVehicle vehicle, Looper looper, IVehicleCallback callback) {
+        mVehicle = vehicle;
+        Handler handler = new CallbackHandler(looper, callback);
+        mInternalCallback = new VehicleCallback(handler);
+    }
+
+    ArrayList<VehiclePropConfig> getAllPropConfigs() {
+        return mVehicle.getAllPropConfigs();
+    }
+
+    public void subscribe(int prop, float sampleRateHz) {
+        SubscribeOptions opt = new SubscribeOptions();
+        opt.propId = prop;
+        opt.sampleRate = sampleRateHz;
+        opt.flags = SubscribeFlags.HAL_EVENT;
+        ArrayList<SubscribeOptions> options = new ArrayList<>(1);
+        options.add(opt);
+        mVehicle.subscribe(mInternalCallback, options);
+    }
+
+    public void unsubscribe(int prop) {
+        mVehicle.unsubscribe(mInternalCallback, prop);
+    }
+
+    public void setValue(VehiclePropValue propValue) throws PropertyTimeoutException {
+        int status = invokeRetriable(() -> mVehicle.set(propValue),
+                WAIT_CAP_FOR_RETRIABLE_RESULT_MS, SLEEP_BETWEEN_RETRIABLE_INVOKES_MS);
+
+        if (StatusCode.INVALID_ARG == status) {
+            throw new IllegalArgumentException(
+                    String.format("Failed to set value for: 0x%x, areaId: 0x%x",
+                            propValue.prop, propValue.areaId));
+        }
+
+        if (StatusCode.TRY_AGAIN == status) {
+            throw new PropertyTimeoutException(propValue.prop);
+        }
+
+        if (StatusCode.OK != status) {
+            throw new IllegalStateException(
+                    String.format("Failed to set property: 0x%x, areaId: 0x%x, "
+                            + "code: %d", propValue.prop, propValue.areaId, status));
+        }
+    }
+
+    VehiclePropValue getValue(VehiclePropValue requestedPropValue) throws PropertyTimeoutException {
+        final ObjectWrapper<VehiclePropValue> valueWrapper = new ObjectWrapper<>();
+        int status = invokeRetriable(() -> {
+            ValueResult res = internalGet(requestedPropValue);
+            valueWrapper.object = res.propValue;
+            return res.status;
+        }, WAIT_CAP_FOR_RETRIABLE_RESULT_MS, SLEEP_BETWEEN_RETRIABLE_INVOKES_MS);
+
+        int propId = requestedPropValue.prop;
+        int areaId = requestedPropValue.areaId;
+        if (StatusCode.INVALID_ARG == status) {
+            throw new IllegalArgumentException(
+                    String.format("Failed to get value for: 0x%x, areaId: 0x%x", propId, areaId));
+        }
+
+        if (StatusCode.TRY_AGAIN == status) {
+            throw new PropertyTimeoutException(propId);
+        }
+
+        if (StatusCode.OK != status || valueWrapper.object == null) {
+            throw new IllegalStateException(
+                    String.format("Failed to get property: 0x%x, areaId: 0x%x, "
+                            + "code: %d", propId, areaId, status));
+        }
+
+        return valueWrapper.object;
+    }
+
+    private ValueResult internalGet(VehiclePropValue requestedPropValue) {
+        final ValueResult result = new ValueResult();
+        mVehicle.get(requestedPropValue,
+                new getCallback() {
+                    @Override
+                    public void onValues(int status, VehiclePropValue propValue) {
+                        result.status = status;
+                        result.propValue = propValue;
+                    }
+                });
+
+        return result;
+    }
+
+    interface RetriableCallback {
+        /** Returns {@link StatusCode} */
+        int action();
+    }
+
+    private static int invokeRetriable(RetriableCallback callback, long timeoutMs, long sleepMs) {
+        int status = callback.action();
+        long startTime = elapsedRealtime();
+        while (StatusCode.TRY_AGAIN == status && (elapsedRealtime() - startTime) < timeoutMs) {
+            try {
+                Thread.sleep(sleepMs);
+            } catch (InterruptedException e) {
+                Log.e(CarLog.TAG_HAL, "Thread was interrupted while waiting for vehicle HAL.", e);
+                break;
+            }
+
+            status = callback.action();
+        }
+        return status;
+    }
+
+    private static class ObjectWrapper<T> {
+        T object;
+    }
+
+    private static class ValueResult {
+        int status;
+        VehiclePropValue propValue;
+    }
+
+    private static class PropertySetError {
+        final int errorCode;
+        final int propId;
+        final int areaId;
+
+        PropertySetError(int errorCode, int propId, int areaId) {
+            this.errorCode = errorCode;
+            this.propId = propId;
+            this.areaId = areaId;
+        }
+    }
+
+    private static class CallbackHandler extends Handler {
+        private static final int MSG_ON_PROPERTY_SET = 1;
+        private static final int MSG_ON_PROPERTY_EVENT = 2;
+        private static final int MSG_ON_SET_ERROR = 3;
+
+        private final IVehicleCallback mCallback;
+
+        CallbackHandler(Looper looper, IVehicleCallback callback) {
+            super(looper);
+            mCallback = callback;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+
+            switch (msg.what) {
+                case MSG_ON_PROPERTY_EVENT:
+                    mCallback.onPropertyEvent((ArrayList<VehiclePropValue>) msg.obj);
+                    break;
+                case MSG_ON_PROPERTY_SET:
+                    mCallback.onPropertySet((VehiclePropValue) msg.obj);
+                    break;
+                case MSG_ON_SET_ERROR:
+                    PropertySetError obj = (PropertySetError) msg.obj;
+                    mCallback.onPropertySetError(obj.errorCode, obj.propId, obj.areaId);
+                    break;
+                default:
+                        Log.e(CarLog.TAG_HAL, "Unexpected message: " + msg.what);
+            }
+        }
+    }
+
+    private static class VehicleCallback implements IVehicleCallback {
+        private Handler mHandler;
+
+        VehicleCallback(Handler handler) {
+            mHandler = handler;
+        }
+
+        @Override
+        public IHwBinder asBinder() {
+            return null;
+        }
+
+        @Override
+        public void onPropertyEvent(ArrayList<VehiclePropValue> propValues) {
+            mHandler.sendMessage(Message.obtain(
+                    mHandler, CallbackHandler.MSG_ON_PROPERTY_EVENT, propValues));
+        }
+
+        @Override
+        public void onPropertySet(VehiclePropValue propValue) {
+            mHandler.sendMessage(Message.obtain(
+                    mHandler, CallbackHandler.MSG_ON_PROPERTY_SET, propValue));
+        }
+
+        @Override
+        public void onPropertySetError(int errorCode, int propId, int areaId) {
+            mHandler.sendMessage(Message.obtain(
+                    mHandler, CallbackHandler.MSG_ON_SET_ERROR,
+                    new PropertySetError(errorCode, propId, areaId)));
+        }
+
+        @Override
+        public ArrayList<String> interfaceChain() {
+            return null;
+        }
+    }
+}
diff --git a/service/src/com/android/car/hal/HalServiceBase.java b/service/src/com/android/car/hal/HalServiceBase.java
index 3a801fd..30115ae 100644
--- a/service/src/com/android/car/hal/HalServiceBase.java
+++ b/service/src/com/android/car/hal/HalServiceBase.java
@@ -16,10 +16,13 @@
 
 package com.android.car.hal;
 
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
+
+import android.annotation.Nullable;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
 
 import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -51,8 +54,11 @@
      * @param allProperties
      * @return null if no properties are supported.
      */
-    public abstract List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties);
+    @Nullable
+    public Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
+        return null;
+    }
 
     public abstract void handleHalEvents(List<VehiclePropValue> values);
 
diff --git a/service/src/com/android/car/hal/HvacHalService.java b/service/src/com/android/car/hal/HvacHalService.java
index b6996bf..77b5364 100644
--- a/service/src/com/android/car/hal/HvacHalService.java
+++ b/service/src/com/android/car/hal/HvacHalService.java
@@ -16,70 +16,51 @@
 package com.android.car.hal;
 
 import android.car.hardware.hvac.CarHvacManager;
-
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
+import android.hardware.vehicle.V2_0.VehicleProperty;
 
 public class HvacHalService extends PropertyHalServiceBase {
     private static final boolean DBG = false;
     private static final String TAG = "HvacHalService";
 
     private final ManagerToHalPropIdMap mMgrHalPropIdMap = ManagerToHalPropIdMap.create(new int[] {
-           CarHvacManager.ID_MIRROR_DEFROSTER_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_SIDE_MIRROR_HEAT,
+           CarHvacManager.ID_MIRROR_DEFROSTER_ON, VehicleProperty.HVAC_SIDE_MIRROR_HEAT,
 
-           CarHvacManager.ID_STEERING_WHEEL_TEMP,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_STEERING_WHEEL_TEMP,
+           CarHvacManager.ID_STEERING_WHEEL_TEMP, VehicleProperty.HVAC_STEERING_WHEEL_TEMP,
 
-           CarHvacManager.ID_OUTSIDE_AIR_TEMP,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE,
+           CarHvacManager.ID_OUTSIDE_AIR_TEMP, VehicleProperty.ENV_OUTSIDE_TEMPERATURE,
 
-           CarHvacManager.ID_TEMPERATURE_UNITS,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_UNITS,
+           CarHvacManager.ID_TEMPERATURE_UNITS, VehicleProperty.HVAC_TEMPERATURE_UNITS,
 
-           CarHvacManager.ID_ZONED_TEMP_SETPOINT,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET,
+           CarHvacManager.ID_ZONED_TEMP_SETPOINT, VehicleProperty.HVAC_TEMPERATURE_SET,
 
-           CarHvacManager.ID_ZONED_TEMP_ACTUAL,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT,
+           CarHvacManager.ID_ZONED_TEMP_ACTUAL, VehicleProperty.HVAC_TEMPERATURE_CURRENT,
 
-           CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_SPEED,
+           CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT, VehicleProperty.HVAC_FAN_SPEED,
 
-           CarHvacManager.ID_ZONED_FAN_SPEED_RPM,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_ACTUAL_FAN_SPEED_RPM,
+           CarHvacManager.ID_ZONED_FAN_SPEED_RPM, VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM,
 
            CarHvacManager.ID_ZONED_FAN_POSITION_AVAILABLE,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_DIRECTION_AVAILABLE,
+           VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE,
 
-           CarHvacManager.ID_ZONED_FAN_POSITION,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_DIRECTION,
+           CarHvacManager.ID_ZONED_FAN_POSITION, VehicleProperty.HVAC_FAN_DIRECTION,
 
-           CarHvacManager.ID_ZONED_SEAT_TEMP,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_SEAT_TEMPERATURE,
+           CarHvacManager.ID_ZONED_SEAT_TEMP, VehicleProperty.HVAC_SEAT_TEMPERATURE,
 
-           CarHvacManager.ID_ZONED_AC_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_AC_ON,
+           CarHvacManager.ID_ZONED_AC_ON, VehicleProperty.HVAC_AC_ON,
 
-           CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_AUTO_ON,
+           CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON, VehicleProperty.HVAC_AUTO_ON,
 
-           CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_RECIRC_ON,
+           CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON,VehicleProperty.HVAC_RECIRC_ON,
 
-           CarHvacManager.ID_ZONED_MAX_AC_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_MAX_AC_ON,
+           CarHvacManager.ID_ZONED_MAX_AC_ON, VehicleProperty.HVAC_MAX_AC_ON,
 
-           CarHvacManager.ID_ZONED_DUAL_ZONE_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_DUAL_ON,
+           CarHvacManager.ID_ZONED_DUAL_ZONE_ON, VehicleProperty.HVAC_DUAL_ON,
 
-           CarHvacManager.ID_ZONED_MAX_DEFROST_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_MAX_DEFROST_ON,
+           CarHvacManager.ID_ZONED_MAX_DEFROST_ON, VehicleProperty.HVAC_MAX_DEFROST_ON,
 
-           CarHvacManager.ID_ZONED_HVAC_POWER_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_POWER_ON,
+           CarHvacManager.ID_ZONED_HVAC_POWER_ON, VehicleProperty.HVAC_POWER_ON,
 
-           CarHvacManager.ID_WINDOW_DEFROSTER_ON,
-           VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_DEFROSTER
+           CarHvacManager.ID_WINDOW_DEFROSTER_ON, VehicleProperty.HVAC_DEFROSTER
     });
 
     public HvacHalService(VehicleHal vehicleHal) {
diff --git a/service/src/com/android/car/hal/InfoHalService.java b/service/src/com/android/car/hal/InfoHalService.java
index 490779b..56e3b08 100644
--- a/service/src/com/android/car/hal/InfoHalService.java
+++ b/service/src/com/android/car/hal/InfoHalService.java
@@ -16,17 +16,16 @@
 package com.android.car.hal;
 
 import android.car.CarInfoManager;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehicleProperty;
 import android.os.Bundle;
 import android.util.Log;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetwork;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 
 import java.io.PrintWriter;
-import java.util.HashMap;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -50,23 +49,19 @@
     }
 
     @Override
-    public synchronized List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
-        VehicleNetwork vn = mHal.getVehicleNetwork();
-        List<VehiclePropConfig> supported = new LinkedList<VehiclePropConfig>();
+    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
+        List<VehiclePropConfig> supported = new LinkedList<>();
         for (VehiclePropConfig p: allProperties) {
-            switch (p.getProp()) {
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_INFO_MAKE:
-                    mBasicInfo.putString(CarInfoManager.BASIC_INFO_KEY_MANUFACTURER,
-                            vn.getStringProperty(p.getProp()));
+            switch (p.prop) {
+                case VehicleProperty.INFO_MAKE:
+                    readPropertyToBundle(p.prop, CarInfoManager.BASIC_INFO_KEY_MANUFACTURER);
                     break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_INFO_MODEL:
-                    mBasicInfo.putString(CarInfoManager.BASIC_INFO_KEY_MODEL,
-                            vn.getStringProperty(p.getProp()));
+                case VehicleProperty.INFO_MODEL:
+                    readPropertyToBundle(p.prop, CarInfoManager.BASIC_INFO_KEY_MODEL);
                     break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_INFO_MODEL_YEAR:
-                    mBasicInfo.putString(CarInfoManager.BASIC_INFO_KEY_MODEL_YEAR,
-                            vn.getStringProperty(p.getProp()));
+                case VehicleProperty.INFO_MODEL_YEAR:
+                    readPropertyToBundle(p.prop, CarInfoManager.BASIC_INFO_KEY_MODEL_YEAR);
                     break;
                 default: // not supported
                     break;
@@ -75,10 +70,20 @@
         return supported;
     }
 
+    private void readPropertyToBundle(int prop, String key) {
+        String value = "";
+        try {
+            value = mHal.get(String.class, prop);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_INFO, "Unable to read property", e);
+        }
+        mBasicInfo.putString(key, value);
+    }
+
     @Override
     public void handleHalEvents(List<VehiclePropValue> values) {
         for (VehiclePropValue v : values) {
-            logUnexpectedEvent(v.getProp());
+            logUnexpectedEvent(v.prop);
         }
     }
 
diff --git a/service/src/com/android/car/hal/InputHalService.java b/service/src/com/android/car/hal/InputHalService.java
index 41a4b87..6d6521f 100644
--- a/service/src/com/android/car/hal/InputHalService.java
+++ b/service/src/com/android/car/hal/InputHalService.java
@@ -15,6 +15,12 @@
  */
 package com.android.car.hal;
 
+import static android.hardware.vehicle.V2_0.VehicleProperty.HW_KEY_INPUT;
+
+import android.hardware.vehicle.V2_0.VehicleDisplay;
+import android.hardware.vehicle.V2_0.VehicleHwKeyInputAction;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseLongArray;
@@ -22,21 +28,17 @@
 import android.view.KeyEvent;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleDisplay;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleHwKeyInputAction;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 
 import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
 public class InputHalService extends HalServiceBase {
 
-    public static final int DISPLAY_MAIN = VehicleDisplay.VEHICLE_DISPLAY_MAIN;
-    public static final int DISPLAY_INSTRUMENT_CLUSTER =
-            VehicleDisplay.VEHICLE_DISPLAY_INSTRUMENT_CLUSTER;
+    public static final int DISPLAY_MAIN = VehicleDisplay.MAIN;
+    public static final int DISPLAY_INSTRUMENT_CLUSTER = VehicleDisplay.INSTRUMENT_CLUSTER;
+    private final VehicleHal mHal;
 
     public interface InputListener {
         void onKeyEvent(KeyEvent event, int targetDisplay);
@@ -48,6 +50,10 @@
     private InputListener mListener;
     private final SparseLongArray mKeyDownTimes = new SparseLongArray();
 
+    public InputHalService(VehicleHal hal) {
+        mHal = hal;
+    }
+
     public void setInputListener(InputListener listener) {
         synchronized (this) {
             if (!mKeyInputSupported) {
@@ -56,8 +62,7 @@
             }
             mListener = listener;
         }
-        VehicleHal.getInstance().subscribeProperty(this,
-                VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT, 0);
+        mHal.subscribeProperty(this, HW_KEY_INPUT, 0);
     }
 
     public synchronized boolean isKeyInputSupported() {
@@ -77,10 +82,11 @@
     }
 
     @Override
-    public List<VehiclePropConfig> takeSupportedProperties(List<VehiclePropConfig> allProperties) {
-        List<VehiclePropConfig> supported = new LinkedList<VehiclePropConfig>();
+    public Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
+        List<VehiclePropConfig> supported = new LinkedList<>();
         for (VehiclePropConfig p: allProperties) {
-            if (p.getProp() == VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT) {
+            if (p.prop == HW_KEY_INPUT) {
                 supported.add(p);
                 synchronized (this) {
                     mKeyInputSupported = true;
@@ -92,7 +98,7 @@
 
     @Override
     public void handleHalEvents(List<VehiclePropValue> values) {
-        InputListener listener = null;
+        InputListener listener;
         synchronized (this) {
             listener = mListener;
         }
@@ -101,19 +107,18 @@
             return;
         }
         for (VehiclePropValue v : values) {
-            if (v.getProp() != VehicleNetworkConsts.VEHICLE_PROPERTY_HW_KEY_INPUT) {
+            if (v.prop != HW_KEY_INPUT) {
                 Log.e(CarLog.TAG_INPUT, "Wrong event dispatched, prop:0x" +
-                        Integer.toHexString(v.getProp()));
+                        Integer.toHexString(v.prop));
                 continue;
             }
-            int action = (v.getInt32Values(0) ==
-                    VehicleHwKeyInputAction.VEHICLE_HW_KEY_INPUT_ACTION_DOWN) ?
+            int action = (v.value.int32Values.get(0) == VehicleHwKeyInputAction.ACTION_DOWN) ?
                             KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
-            int code = v.getInt32Values(1);
-            int display = v.getInt32Values(2);
+            int code = v.value.int32Values.get(1);
+            int display = v.value.int32Values.get(2);
             if (DBG) {
-                Log.i(CarLog.TAG_INPUT, "hal event code:" + code + ",action:" + action +
-                        ",display:" + display);
+                Log.i(CarLog.TAG_INPUT, "hal event code:" + code + ", action:" + action +
+                        ", display:" + display);
             }
 
             dispatchKeyEvent(listener, action, code, display);
diff --git a/service/src/com/android/car/hal/PowerHalService.java b/service/src/com/android/car/hal/PowerHalService.java
index 580e7a7..ff43cfc 100644
--- a/service/src/com/android/car/hal/PowerHalService.java
+++ b/service/src/com/android/car/hal/PowerHalService.java
@@ -15,69 +15,64 @@
  */
 package com.android.car.hal;
 
-import android.os.ServiceSpecificException;
+import static android.hardware.vehicle.V2_0.VehicleProperty.AP_POWER_STATE;
+import static android.hardware.vehicle.V2_0.VehicleProperty.DISPLAY_BRIGHTNESS;
+
+import android.annotation.Nullable;
+import android.hardware.vehicle.V2_0.VehicleApPowerSetState;
+import android.hardware.vehicle.V2_0.VehicleApPowerState;
+import android.hardware.vehicle.V2_0.VehicleApPowerStateConfigFlag;
+import android.hardware.vehicle.V2_0.VehicleApPowerStateIndex;
+import android.hardware.vehicle.V2_0.VehicleApPowerStateShutdownParam;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehicleProperty;
 import android.util.Log;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleApPowerSetState;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleApPowerState;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleApPowerStateConfigFlag;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleApPowerStateIndex;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleApPowerStateShutdownParam;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 
 public class PowerHalService extends HalServiceBase {
 
-    public static final int STATE_OFF = VehicleApPowerState.VEHICLE_AP_POWER_STATE_OFF;
-    public static final int STATE_DEEP_SLEEP =
-            VehicleApPowerState.VEHICLE_AP_POWER_STATE_DEEP_SLEEP;
-    public static final int STATE_ON_DISP_OFF =
-            VehicleApPowerState.VEHICLE_AP_POWER_STATE_ON_DISP_OFF;
-    public static final int STATE_ON_FULL = VehicleApPowerState.VEHICLE_AP_POWER_STATE_ON_FULL;
-    public static final int STATE_SHUTDOWN_PREPARE =
-            VehicleApPowerState.VEHICLE_AP_POWER_STATE_SHUTDOWN_PREPARE;
+    public static final int STATE_OFF = VehicleApPowerState.OFF;
+    public static final int STATE_DEEP_SLEEP = VehicleApPowerState.DEEP_SLEEP;
+    public static final int STATE_ON_DISP_OFF = VehicleApPowerState.ON_DISP_OFF;
+    public static final int STATE_ON_FULL = VehicleApPowerState.ON_FULL;
+    public static final int STATE_SHUTDOWN_PREPARE = VehicleApPowerState.SHUTDOWN_PREPARE;
 
     @VisibleForTesting
-    public static final int SET_BOOT_COMPLETE =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_BOOT_COMPLETE;
+    public static final int SET_BOOT_COMPLETE = VehicleApPowerSetState.BOOT_COMPLETE;
     @VisibleForTesting
-    public static final int SET_DEEP_SLEEP_ENTRY =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DEEP_SLEEP_ENTRY;
+    public static final int SET_DEEP_SLEEP_ENTRY = VehicleApPowerSetState.DEEP_SLEEP_ENTRY;
     @VisibleForTesting
-    public static final int SET_DEEP_SLEEP_EXIT =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DEEP_SLEEP_EXIT;
+    public static final int SET_DEEP_SLEEP_EXIT = VehicleApPowerSetState.DEEP_SLEEP_EXIT;
     @VisibleForTesting
-    public static final int SET_SHUTDOWN_POSTPONE =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_SHUTDOWN_POSTPONE;
+    public static final int SET_SHUTDOWN_POSTPONE = VehicleApPowerSetState.SHUTDOWN_POSTPONE;
     @VisibleForTesting
-    public static final int SET_SHUTDOWN_START =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_SHUTDOWN_START;
+    public static final int SET_SHUTDOWN_START = VehicleApPowerSetState.SHUTDOWN_START;
     @VisibleForTesting
-    public static final int SET_DISPLAY_ON = VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DISPLAY_ON;
+    public static final int SET_DISPLAY_ON = VehicleApPowerSetState.DISPLAY_ON;
     @VisibleForTesting
     public static final int SET_DISPLAY_OFF =
-            VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DISPLAY_OFF;
+            VehicleApPowerSetState.DISPLAY_OFF;
 
     @VisibleForTesting
     public static final int FLAG_SHUTDOWN_PARAM_CAN_SLEEP =
-            VehicleApPowerStateShutdownParam.VEHICLE_AP_POWER_SHUTDOWN_PARAM_CAN_SLEEP;
+            VehicleApPowerStateShutdownParam.CAN_SLEEP;
     @VisibleForTesting
     public static final int FLAG_SHUTDOWN_IMMEDIATELY =
-            VehicleApPowerStateShutdownParam.VEHICLE_AP_POWER_SHUTDOWN_PARAM_SHUTDOWN_IMMEDIATELY;
+            VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY;
 
     public interface PowerEventListener {
         /**
          * Received power state change event.
          * @param state One of STATE_*
-         * @param param
          */
         void onApPowerStateChange(PowerState state);
         /**
@@ -91,12 +86,12 @@
         /**
          * One of STATE_*
          */
-        public final int state;
-        public final int param;
+        public final int mState;
+        public final int mParam;
 
         public PowerState(int state, int param) {
-            this.state = state;
-            this.param = param;
+            this.mState = state;
+            this.mParam = param;
         }
 
         /**
@@ -106,12 +101,10 @@
          * @throws IllegalStateException
          */
         public boolean canEnterDeepSleep() {
-            if (state != STATE_SHUTDOWN_PREPARE) {
+            if (mState != STATE_SHUTDOWN_PREPARE) {
                 throw new IllegalStateException("wrong state");
             }
-            return (param &
-                    VehicleApPowerStateShutdownParam.VEHICLE_AP_POWER_SHUTDOWN_PARAM_CAN_SLEEP) !=
-                    0;
+            return (mParam & VehicleApPowerStateShutdownParam.CAN_SLEEP) != 0;
         }
 
         /**
@@ -121,12 +114,10 @@
          * @throws IllegalStateException
          */
         public boolean canPostponeShutdown() {
-            if (state != STATE_SHUTDOWN_PREPARE) {
+            if (mState != STATE_SHUTDOWN_PREPARE) {
                 throw new IllegalStateException("wrong state");
             }
-            return (param &
-                    VehicleApPowerStateShutdownParam.VEHICLE_AP_POWER_SHUTDOWN_PARAM_SHUTDOWN_IMMEDIATELY)
-                    == 0;
+            return (mParam & VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY) == 0;
         }
 
         @Override
@@ -138,12 +129,12 @@
                 return false;
             }
             PowerState that = (PowerState) o;
-            return this.state == that.state && this.param == that.param;
+            return this.mState == that.mState && this.mParam == that.mParam;
         }
 
         @Override
         public String toString() {
-            return "PowerState state:" + state + ",param:" + param;
+            return "PowerState state:" + mState + ", param:" + mParam;
         }
     }
 
@@ -174,98 +165,99 @@
 
     public void sendBootComplete() {
         Log.i(CarLog.TAG_POWER, "send boot complete");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_BOOT_COMPLETE, 0);
+        setPowerState(VehicleApPowerSetState.BOOT_COMPLETE, 0);
     }
 
     public void sendSleepEntry() {
         Log.i(CarLog.TAG_POWER, "send sleep entry");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DEEP_SLEEP_ENTRY, 0);
+        setPowerState(VehicleApPowerSetState.DEEP_SLEEP_ENTRY, 0);
     }
 
     public void sendSleepExit() {
         Log.i(CarLog.TAG_POWER, "send sleep exit");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DEEP_SLEEP_EXIT, 0);
+        setPowerState(VehicleApPowerSetState.DEEP_SLEEP_EXIT, 0);
     }
 
     public void sendShutdownPostpone(int postponeTimeMs) {
         Log.i(CarLog.TAG_POWER, "send shutdown postpone, time:" + postponeTimeMs);
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_SHUTDOWN_POSTPONE,
+        setPowerState(VehicleApPowerSetState.SHUTDOWN_POSTPONE,
                 postponeTimeMs);
     }
 
     public void sendShutdownStart(int wakeupTimeSec) {
         Log.i(CarLog.TAG_POWER, "send shutdown start");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_SHUTDOWN_START, 0);
+        setPowerState(VehicleApPowerSetState.SHUTDOWN_START, 0);
     }
 
     public void sendDisplayOn() {
         Log.i(CarLog.TAG_POWER, "send display on");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DISPLAY_ON, 0);
+        setPowerState(VehicleApPowerSetState.DISPLAY_ON, 0);
     }
 
     public void sendDisplayOff() {
         Log.i(CarLog.TAG_POWER, "send display off");
-        setPowerState(VehicleApPowerSetState.VEHICLE_AP_POWER_SET_DISPLAY_OFF, 0);
+        setPowerState(VehicleApPowerSetState.DISPLAY_OFF, 0);
     }
 
     private void setPowerState(int state, int additionalParam) {
         int[] values = { state, additionalParam };
         try {
-            mHal.getVehicleNetwork().setIntVectorProperty(
-                    VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE, values);
-        } catch (ServiceSpecificException e) {
+            mHal.set(VehicleProperty.AP_POWER_STATE).to(values);
+        } catch (PropertyTimeoutException e) {
             Log.e(CarLog.TAG_POWER, "cannot set to AP_POWER_STATE", e);
         }
     }
 
+    @Nullable
     public PowerState getCurrentPowerState() {
-        int[] state = mHal.getVehicleNetwork().getIntVectorProperty(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE);
-        return new PowerState(state[VehicleApPowerStateIndex.VEHICLE_AP_POWER_STATE_INDEX_STATE],
-                state[VehicleApPowerStateIndex.VEHICLE_AP_POWER_STATE_INDEX_ADDITIONAL]);
+        int[] state;
+        try {
+            state = mHal.get(int[].class, VehicleProperty.AP_POWER_STATE);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_POWER, "Cannot get AP_POWER_STATE", e);
+            return null;
+        }
+        return new PowerState(state[VehicleApPowerStateIndex.STATE],
+                state[VehicleApPowerStateIndex.ADDITIONAL]);
     }
 
     public synchronized boolean isPowerStateSupported() {
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE);
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AP_POWER_STATE);
         return config != null;
     }
 
     public synchronized boolean isDeepSleepAllowed() {
-        VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE);
+        VehiclePropConfig config = mProperties.get(VehicleProperty.AP_POWER_STATE);
         if (config == null) {
             return false;
         }
-        return (config.getConfigArray(0) &
-                VehicleApPowerStateConfigFlag.VEHICLE_AP_POWER_STATE_CONFIG_ENABLE_DEEP_SLEEP_FLAG)
-                != 0;
+        return (config.configArray.get(0)
+                & VehicleApPowerStateConfigFlag.ENABLE_DEEP_SLEEP_FLAG) != 0;
     }
 
     public synchronized boolean isTimedWakeupAllowed() {
         VehiclePropConfig config = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE);
+                AP_POWER_STATE);
         if (config == null) {
             return false;
         }
-        return (config.getConfigArray(0) &
-                VehicleApPowerStateConfigFlag.VEHICLE_AP_POWER_STATE_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG)
-                != 0;
+        return (config.configArray.get(0)
+                & VehicleApPowerStateConfigFlag.CONFIG_SUPPORT_TIMER_POWER_ON_FLAG) != 0;
     }
 
     @Override
     public synchronized void init() {
         for (VehiclePropConfig config : mProperties.values()) {
             if (VehicleHal.isPropertySubscribable(config)) {
-                mHal.subscribeProperty(this, config.getProp(), 0);
+                mHal.subscribeProperty(this, config.prop, 0);
             }
         }
-        VehiclePropConfig brightnessProperty = mProperties.get(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS);
+        VehiclePropConfig brightnessProperty = mProperties.get(DISPLAY_BRIGHTNESS);
         if (brightnessProperty != null) {
-            mMaxDisplayBrightness = brightnessProperty.getInt32Maxs(0);
+            mMaxDisplayBrightness = brightnessProperty.areaConfigs.size() > 0
+                    ? brightnessProperty.areaConfigs.get(0).maxInt32Value : 0;
             if (mMaxDisplayBrightness <= 0) {
-                Log.w(CarLog.TAG_POWER, "Max display brightness from vehicle HAL is invald:" +
+                Log.w(CarLog.TAG_POWER, "Max display brightness from vehicle HAL is invalid:" +
                         mMaxDisplayBrightness);
                 mMaxDisplayBrightness = 1;
             }
@@ -278,17 +270,17 @@
     }
 
     @Override
-    public synchronized List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
+    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
         for (VehiclePropConfig config : allProperties) {
-            switch (config.getProp()) {
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE:
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS:
-                    mProperties.put(config.getProp(), config);
+            switch (config.prop) {
+                case AP_POWER_STATE:
+                case DISPLAY_BRIGHTNESS:
+                    mProperties.put(config.prop, config);
                     break;
             }
         }
-        return new LinkedList<VehiclePropConfig>(mProperties.values());
+        return new LinkedList<>(mProperties.values());
     }
 
     @Override
@@ -297,7 +289,7 @@
         synchronized (this) {
             if (mListener == null) {
                 if (mQueuedEvents == null) {
-                    mQueuedEvents = new LinkedList<VehiclePropValue>();
+                    mQueuedEvents = new LinkedList<>();
                 }
                 mQueuedEvents.addAll(values);
                 return;
@@ -309,20 +301,19 @@
 
     private void dispatchEvents(List<VehiclePropValue> values, PowerEventListener listener) {
         for (VehiclePropValue v : values) {
-            switch (v.getProp()) {
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_AP_POWER_STATE:
-                    listener.onApPowerStateChange(new PowerState(
-                            v.getInt32Values(
-                                VehicleApPowerStateIndex.VEHICLE_AP_POWER_STATE_INDEX_STATE),
-                            v.getInt32Values(
-                                VehicleApPowerStateIndex.VEHICLE_AP_POWER_STATE_INDEX_ADDITIONAL)));
+            switch (v.prop) {
+                case AP_POWER_STATE:
+                    int state = v.value.int32Values.get(VehicleApPowerStateIndex.STATE);
+                    int param = v.value.int32Values.get(VehicleApPowerStateIndex.ADDITIONAL);
+                    listener.onApPowerStateChange(new PowerState(state, param));
                     break;
-                case VehicleNetworkConsts.VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS:
+                case DISPLAY_BRIGHTNESS:
                     int maxBrightness;
                     synchronized (this) {
                         maxBrightness = mMaxDisplayBrightness;
                     }
-                    listener.onDisplayBrightnessChange(v.getInt32Values(0) * 100 / maxBrightness);
+                    listener.onDisplayBrightnessChange(
+                            (v.value.int32Values.get(0) * 100) / maxBrightness);
                     break;
             }
         }
diff --git a/service/src/com/android/car/hal/PropertyHalServiceBase.java b/service/src/com/android/car/hal/PropertyHalServiceBase.java
index 79fd626..28dd4c6 100644
--- a/service/src/com/android/car/hal/PropertyHalServiceBase.java
+++ b/service/src/com/android/car/hal/PropertyHalServiceBase.java
@@ -19,20 +19,21 @@
 import static com.android.car.hal.CarPropertyUtils.toVehiclePropValue;
 import static java.lang.Integer.toHexString;
 
+import android.annotation.Nullable;
 import android.car.hardware.CarPropertyConfig;
 import android.car.hardware.CarPropertyValue;
 import android.car.hardware.property.CarPropertyEvent;
-import android.os.ServiceSpecificException;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
 import android.util.Log;
 import android.util.SparseIntArray;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
@@ -44,7 +45,6 @@
  */
 public abstract class PropertyHalServiceBase extends HalServiceBase {
     private final boolean mDbg;
-    private final SparseIntArray mHalPropToValueType = new SparseIntArray();
     private final ConcurrentHashMap<Integer, CarPropertyConfig<?>> mProps =
             new ConcurrentHashMap<>();
     private final String mTag;
@@ -81,6 +81,10 @@
         return new ArrayList<>(mProps.values());
     }
 
+    /**
+     * Returns property or null if property is not ready yet.
+     */
+    @Nullable
     public CarPropertyValue getProperty(int mgrPropId, int areaId) {
         int halPropId = managerToHalPropId(mgrPropId);
         if (halPropId == NOT_SUPPORTED_PROPERTY) {
@@ -89,14 +93,8 @@
 
         VehiclePropValue value = null;
         try {
-            VehiclePropValue valueRequest = VehiclePropValue.newBuilder()
-                    .setProp(halPropId)
-                    .setZone(areaId)
-                    .setValueType(mHalPropToValueType.get(halPropId))
-                    .build();
-
-            value = mVehicleHal.getVehicleNetwork().getProperty(valueRequest);
-        } catch (ServiceSpecificException e) {
+            value = mVehicleHal.get(halPropId, areaId);
+        } catch (PropertyTimeoutException e) {
             Log.e(CarLog.TAG_PROPERTY, "get, property not ready 0x" + toHexString(halPropId), e);
         }
 
@@ -111,8 +109,8 @@
         }
         VehiclePropValue halProp = toVehiclePropValue(prop, halPropId);
         try {
-            mVehicleHal.getVehicleNetwork().setProperty(halProp);
-        } catch (ServiceSpecificException e) {
+            mVehicleHal.set(halProp);
+        } catch (PropertyTimeoutException e) {
             Log.e(CarLog.TAG_PROPERTY, "set, property not ready 0x" + toHexString(halPropId), e);
             throw new RuntimeException(e);
         }
@@ -148,12 +146,12 @@
     }
 
     @Override
-    public List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
+    public Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
         List<VehiclePropConfig> taken = new LinkedList<>();
 
         for (VehiclePropConfig p : allProperties) {
-            int mgrPropId = halToManagerPropId(p.getProp());
+            int mgrPropId = halToManagerPropId(p.prop);
 
             if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
                 continue;  // The property is not handled by this HAL.
@@ -162,11 +160,10 @@
             CarPropertyConfig config = CarPropertyUtils.toCarPropertyConfig(p, mgrPropId);
 
             taken.add(p);
-            mProps.put(p.getProp(), config);
-            mHalPropToValueType.put(p.getProp(), p.getValueType());
+            mProps.put(p.prop, config);
 
             if (mDbg) {
-                Log.d(mTag, "takeSupportedProperties: " + toHexString(p.getProp()));
+                Log.d(mTag, "takeSupportedProperties: " + toHexString(p.prop));
             }
         }
         return taken;
@@ -180,7 +177,7 @@
         }
         if (listener != null) {
             for (VehiclePropValue v : values) {
-                int prop = v.getProp();
+                int prop = v.prop;
                 int mgrPropId = halToManagerPropId(prop);
 
                 if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
diff --git a/service/src/com/android/car/hal/PropertyTimeoutException.java b/service/src/com/android/car/hal/PropertyTimeoutException.java
new file mode 100644
index 0000000..2d6120d
--- /dev/null
+++ b/service/src/com/android/car/hal/PropertyTimeoutException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.hal;
+
+import static java.lang.Integer.toHexString;
+
+/**
+ * This exception is raised when IVehicle#get or IVehicle#set returns StatusCode.TRY_AGAIN. This
+ * usually happens during boot-up meaning that Vehicle HAL is not ready to get or set that property.
+ */
+class PropertyTimeoutException extends Exception {
+    PropertyTimeoutException(int property) {
+        super("Property 0x" + toHexString(property) + " is not ready yet.");
+    }
+}
diff --git a/service/src/com/android/car/hal/RadioHalService.java b/service/src/com/android/car/hal/RadioHalService.java
index 68423d0..8cd8687 100644
--- a/service/src/com/android/car/hal/RadioHalService.java
+++ b/service/src/com/android/car/hal/RadioHalService.java
@@ -16,22 +16,23 @@
 
 package com.android.car.hal;
 
+import android.annotation.Nullable;
 import android.car.hardware.radio.CarRadioEvent;
 import android.car.hardware.radio.CarRadioPreset;
-import android.os.ServiceSpecificException;
-import android.util.Log;
 import android.hardware.radio.RadioManager;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehicleProperty;
+import android.hardware.vehicle.V2_0.VehicleRadioConstants;
+import android.util.Log;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
-import com.android.car.vehiclenetwork.VehiclePropValueUtil;
 
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
-import java.io.PrintWriter;
 
 /**
  * This class exposes the Radio related features in the HAL layer.
@@ -48,7 +49,7 @@
     private RadioListener mListener;
 
     public interface RadioListener {
-        public void onEvent(CarRadioEvent event);
+        void onEvent(CarRadioEvent event);
     }
 
     public RadioHalService(VehicleHal hal) {
@@ -65,9 +66,9 @@
     }
 
     @Override
-    public synchronized List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
-        List<VehiclePropConfig> supported = new LinkedList<VehiclePropConfig>();
+    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
+        Collection<VehiclePropConfig> supported = new LinkedList<>();
         for (VehiclePropConfig p : allProperties) {
             if (handleRadioProperty(p)) {
                 supported.add(p);
@@ -81,7 +82,7 @@
         if (DBG) {
             Log.d(TAG, "handleHalEvents");
         }
-        RadioHalService.RadioListener radioListener = null;
+        RadioHalService.RadioListener radioListener;
         synchronized (this) {
             radioListener = mListener;
         }
@@ -108,7 +109,7 @@
     public void dump(PrintWriter writer) {
         writer.println("*RadioHal*");
         writer.println("**Supported properties**");
-        writer.println(VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET);
+        writer.println(VehicleProperty.RADIO_PRESET);
         if (mListener != null) {
             writer.println("Hal service registered.");
         }
@@ -121,7 +122,7 @@
         mListener = listener;
 
         // Subscribe to all radio properties.
-        mHal.subscribeProperty(this, VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET, 0);
+        mHal.subscribeProperty(this, VehicleProperty.RADIO_PRESET, 0);
     }
 
     public synchronized void unregisterListener() {
@@ -130,8 +131,8 @@
         }
         mListener = null;
 
-        // Unsubscribe from all propreties.
-        mHal.unsubscribeProperty(this, VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET);
+        // Unsubscribe from all properties.
+        mHal.unsubscribeProperty(this, VehicleProperty.RADIO_PRESET);
     }
 
     public synchronized int getPresetCount() {
@@ -139,6 +140,7 @@
         return mPresetCount;
     }
 
+    @Nullable
     public CarRadioPreset getRadioPreset(int presetNumber) {
         // Check if the preset number is out of range. We should return NULL if that is the case.
         if (DBG) {
@@ -148,30 +150,30 @@
             throw new IllegalArgumentException("Preset number not valid: " + presetNumber);
         }
 
-        int[] presetArray = {presetNumber, 0, 0, 0};
-        VehiclePropValue presetNumberValue =
-            VehiclePropValueUtil.createIntVectorValue(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET, presetArray, 0);
+        VehiclePropValue presetNumberValue = new VehiclePropValue();
+        presetNumberValue.prop = VehicleProperty.RADIO_PRESET;
+        presetNumberValue.value.int32Values.addAll(Arrays.asList(presetNumber, 0, 0, 0));
 
         VehiclePropValue presetConfig;
         try {
-            presetConfig = mHal.getVehicleNetwork().getProperty(presetNumberValue);
-        } catch (ServiceSpecificException e) {
-            Log.e(TAG, "property VEHICLE_PROPERTY_RADIO_PRESET not ready");
+            presetConfig = mHal.get(presetNumberValue);
+        } catch (PropertyTimeoutException e) {
+            Log.e(TAG, "property VehicleProperty.RADIO_PRESET not ready", e);
             return null;
         }
         // Sanity check the output from HAL.
-        if (presetConfig.getInt32ValuesCount() != 4) {
+        if (presetConfig.value.int32Values.size() != 4) {
             Log.e(TAG, "Return value does not have 4 elements: " +
-                presetConfig.getInt32ValuesList());
+                Arrays.toString(presetConfig.value.int32Values.toArray()));
             throw new IllegalStateException(
-                "Invalid preset returned from service: " + presetConfig.getInt32ValuesList());
+                "Invalid preset returned from service: "
+                        + Arrays.toString(presetConfig.value.int32Values.toArray()));
         }
 
-        int retPresetNumber = presetConfig.getInt32Values(0);
-        int retBand = presetConfig.getInt32Values(1);
-        int retChannel = presetConfig.getInt32Values(2);
-        int retSubChannel = presetConfig.getInt32Values(3);
+        int retPresetNumber = presetConfig.value.int32Values.get(0);
+        int retBand = presetConfig.value.int32Values.get(1);
+        int retChannel = presetConfig.value.int32Values.get(2);
+        int retSubChannel = presetConfig.value.int32Values.get(3);
         if (retPresetNumber != presetNumber) {
             Log.e(TAG, "Preset number is not the same: " + presetNumber + " vs " + retPresetNumber);
             return null;
@@ -197,18 +199,13 @@
             return false;
         }
 
-        VehiclePropValue setPresetValue =
-            VehiclePropValueUtil.createBuilder(
-                VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET,
-                VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4, 0)
-            .addInt32Values(preset.getPresetNumber())
-            .addInt32Values(preset.getBand())
-            .addInt32Values(preset.getChannel())
-            .addInt32Values(preset.getSubChannel())
-            .build();
         try {
-            mHal.getVehicleNetwork().setProperty(setPresetValue);
-        } catch (ServiceSpecificException e) {
+            mHal.set(VehicleProperty.RADIO_PRESET).to(new int[] {
+                    preset.getPresetNumber(),
+                    preset.getBand(),
+                    preset.getChannel(),
+                    preset.getSubChannel()});
+        } catch (PropertyTimeoutException e) {
             Log.e(CarLog.TAG_POWER, "cannot set to RADIO_PRESET", e);
             return false;
         }
@@ -217,7 +214,7 @@
 
     private boolean isValidPresetNumber(int presetNumber) {
         // Check for preset number.
-        if (presetNumber < VehicleNetworkConsts.VehicleRadioConsts.VEHICLE_RADIO_PRESET_MIN_VALUE
+        if (presetNumber < VehicleRadioConstants.VEHICLE_RADIO_PRESET_MIN_VALUE
             || presetNumber > mPresetCount) {
             Log.e(TAG, "Preset number not in range (1, " + mPresetCount + ") - " + presetNumber);
             return false;
@@ -238,10 +235,10 @@
     }
 
     private boolean handleRadioProperty(VehiclePropConfig property) {
-        switch (property.getProp()) {
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET:
+        switch (property.prop) {
+            case VehicleProperty.RADIO_PRESET:
                 // Extract the count of presets.
-                mPresetCount = property.getConfigArray(0);
+                mPresetCount = property.configArray.get(0);
                 Log.d(TAG, "Read presets count: " + mPresetCount);
                 return true;
             default:
@@ -251,15 +248,16 @@
     }
 
     private CarRadioEvent createCarRadioEvent(VehiclePropValue v) {
-        switch (v.getProp()) {
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_RADIO_PRESET:
-                if (v.getInt32ValuesCount() != 4) {
-                    Log.e(TAG, "Returned a wrong array size: " + v.getInt32ValuesCount());
+        switch (v.prop) {
+            case VehicleProperty.RADIO_PRESET:
+                int vecSize = v.value.int32Values.size();
+                if (vecSize != 4) {
+                    Log.e(TAG, "Returned a wrong array size: " + vecSize);
                     return null;
                 }
 
                 Integer intValues[] = new Integer[4];
-                v.getInt32ValuesList().toArray(intValues);
+                v.value.int32Values.toArray(intValues);
 
                 // Verify the correctness of the values.
                 if (!isValidPresetNumber(intValues[0]) && !isValidBand(intValues[1])) {
diff --git a/service/src/com/android/car/hal/SensorHalService.java b/service/src/com/android/car/hal/SensorHalService.java
index c21bddd..d2c2714 100644
--- a/service/src/com/android/car/hal/SensorHalService.java
+++ b/service/src/com/android/car/hal/SensorHalService.java
@@ -16,21 +16,30 @@
 
 package com.android.car.hal;
 
+import static android.hardware.vehicle.V2_0.VehicleProperty.DRIVING_STATUS;
+import static android.hardware.vehicle.V2_0.VehicleProperty.FUEL_LEVEL_LOW;
+import static android.hardware.vehicle.V2_0.VehicleProperty.GEAR_SELECTION;
+import static android.hardware.vehicle.V2_0.VehicleProperty.NIGHT_MODE;
+import static android.hardware.vehicle.V2_0.VehicleProperty.PARKING_BRAKE_ON;
+import static android.hardware.vehicle.V2_0.VehicleProperty.PERF_VEHICLE_SPEED;
+import static java.lang.Integer.toHexString;
+
+import android.annotation.Nullable;
 import android.car.hardware.CarSensorEvent;
 import android.car.hardware.CarSensorManager;
-import android.os.ServiceSpecificException;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehicleProperty;
+import android.hardware.vehicle.V2_0.VehiclePropertyAccess;
+import android.hardware.vehicle.V2_0.VehiclePropertyChangeMode;
 import android.util.Log;
 import android.util.SparseArray;
 
 import com.android.car.CarLog;
 import com.android.car.CarSensorEventFactory;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropChangeMode;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
 
 import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -41,13 +50,12 @@
 
     private static final boolean DBG_EVENTS = false;
 
-    private static final int SENSOR_TYPE_INVALD = -1;
+    private static final int SENSOR_TYPE_INVALID = -1;
 
     private final VehicleHal mHal;
     private boolean mIsReady = false;
     private SensorHalServiceBase.SensorListener mSensorListener;
-    private final SparseArray<VehiclePropConfig> mSensorToHalProperty =
-            new SparseArray<VehiclePropConfig>();
+    private final SparseArray<VehiclePropConfig> mSensorToHalProperty = new SparseArray<>();
 
     public SensorHalService(VehicleHal hal) {
         mHal = hal;
@@ -59,17 +67,14 @@
     }
 
     @Override
-    public synchronized List<VehiclePropConfig> takeSupportedProperties(
-            List<VehiclePropConfig> allProperties) {
-        LinkedList<VehiclePropConfig> supportedProperties = new LinkedList<VehiclePropConfig>();
+    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
+            Collection<VehiclePropConfig> allProperties) {
+        LinkedList<VehiclePropConfig> supportedProperties = new LinkedList<>();
         for (VehiclePropConfig halProperty : allProperties) {
-            int sensor = getSensorTypeFromHalProperty(halProperty.getProp());
-            if (sensor != SENSOR_TYPE_INVALD &&
-                halProperty.getChangeMode() !=
-                    VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_STATIC &&
-                (halProperty.getAccess() == VehiclePropAccess.VEHICLE_PROP_ACCESS_READ
-                    || halProperty.getAccess() ==
-                    VehiclePropAccess.VEHICLE_PROP_ACCESS_WRITE)) {
+            int sensor = getSensorTypeFromHalProperty(halProperty.prop);
+            if (sensor != SENSOR_TYPE_INVALID
+                    && halProperty.changeMode != VehiclePropertyChangeMode.STATIC
+                    && ((halProperty.access & VehiclePropertyAccess.READ) != 0)) {
                 supportedProperties.add(halProperty);
                 mSensorToHalProperty.append(sensor, halProperty);
             }
@@ -83,8 +88,8 @@
         mIsReady = false;
     }
 
-    // should be used only insidehandleHalEvents.
-    private final LinkedList<CarSensorEvent> mEventsToDispatch = new LinkedList<CarSensorEvent>();
+    // Should be used only inside handleHalEvents method.
+    private final LinkedList<CarSensorEvent> mEventsToDispatch = new LinkedList<>();
     @Override
     public void handleHalEvents(List<VehiclePropValue> values) {
         for (VehiclePropValue v : values) {
@@ -104,42 +109,42 @@
     }
 
     private CarSensorEvent createCarSensorEvent(VehiclePropValue v) {
-        int property = v.getProp();
+        int property = v.prop;
         int sensorType = getSensorTypeFromHalProperty(property);
-        if (sensorType == SENSOR_TYPE_INVALD) {
+        if (sensorType == SENSOR_TYPE_INVALID) {
             throw new RuntimeException("handleBooleanHalEvent no sensor defined for property " +
                     property);
         }
         switch (property) {
             // boolean
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE:
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_PARKING_BRAKE_ON:
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_FUEL_LEVEL_LOW: {
+            case VehicleProperty.NIGHT_MODE:
+            case VehicleProperty.PARKING_BRAKE_ON:
+            case VehicleProperty.FUEL_LEVEL_LOW: {
                 if (DBG_EVENTS) {
                     Log.i(CarLog.TAG_SENSOR, "boolean event, property:" +
-                            Integer.toHexString(property) + " value:" + v.getInt32Values(0));
+                            toHexString(property) + " value:" + v.value.int32Values.get(0));
                 }
-                return CarSensorEventFactory.createBooleanEvent(sensorType, v.getTimestamp(),
-                        v.getInt32Values(0) == 1);
+                return CarSensorEventFactory.createBooleanEvent(sensorType, v.timestamp,
+                        v.value.int32Values.get(0) == 1);
             }
             // int
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_GEAR_SELECTION:
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_DRIVING_STATUS: {
+            case VehicleProperty.GEAR_SELECTION:
+            case VehicleProperty.DRIVING_STATUS: {
                 if (DBG_EVENTS) {
                     Log.i(CarLog.TAG_SENSOR, "int event, property:" +
-                            Integer.toHexString(property) + " value:" + v.getInt32Values(0));
+                            toHexString(property) + " value:" + v.value.int32Values.get(0));
                 }
-                return CarSensorEventFactory.createIntEvent(sensorType, v.getTimestamp(),
-                        v.getInt32Values(0));
+                return CarSensorEventFactory.createIntEvent(sensorType, v.timestamp,
+                        v.value.int32Values.get(0));
             }
             // float
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_PERF_VEHICLE_SPEED: {
+            case VehicleProperty.PERF_VEHICLE_SPEED: {
                 if (DBG_EVENTS) {
                     Log.i(CarLog.TAG_SENSOR, "float event, property:" +
-                            Integer.toHexString(property) + " value:" + v.getFloatValues(0));
+                            toHexString(property) + " value:" + v.value.floatValues.get(0));
                 }
-                return CarSensorEventFactory.createFloatEvent(sensorType, v.getTimestamp(),
-                        v.getFloatValues(0));
+                return CarSensorEventFactory.createFloatEvent(sensorType, v.timestamp,
+                        v.value.floatValues.get(0));
             }
         }
         return null;
@@ -171,10 +176,11 @@
             return false;
         }
         //TODO calculate sampling rate properly, bug: 32095903
-        mHal.subscribeProperty(this, config.getProp(), fixSamplingRateForProperty(config, rate));
+        mHal.subscribeProperty(this, config.prop, fixSamplingRateForProperty(config, rate));
         return true;
     }
 
+    @Nullable
     public CarSensorEvent getCurrentSensorValue(int sensorType) {
         VehiclePropConfig config;
         synchronized (this) {
@@ -182,23 +188,22 @@
         }
         if (config == null) {
             Log.e(CarLog.TAG_SENSOR, "sensor type not available 0x" +
-                    Integer.toHexString(sensorType));
+                    toHexString(sensorType));
             return null;
         }
         try {
-            VehiclePropValue value = mHal.getVehicleNetwork().getProperty(config.getProp());
+            VehiclePropValue value = mHal.get(config.prop);
             return createCarSensorEvent(value);
-        } catch (ServiceSpecificException e) {
-            Log.e(CarLog.TAG_SENSOR, "property not ready 0x" +
-                    Integer.toHexString(config.getProp()), e);
+        } catch (PropertyTimeoutException e) {
+            Log.e(CarLog.TAG_SENSOR, "property not ready 0x" + toHexString(config.prop), e);
             return null;
         }
     }
 
     private float fixSamplingRateForProperty(VehiclePropConfig prop, int carSensorManagerRate) {
-        switch (prop.getChangeMode()) {
-            case VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE:
-            case VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_SET:
+        switch (prop.changeMode) {
+            case VehiclePropertyChangeMode.ON_CHANGE:
+            case VehiclePropertyChangeMode.ON_SET:
                 return 0;
         }
         float rate = 1.0f;
@@ -213,11 +218,11 @@
             default: // fall back to default.
                 break;
         }
-        if (rate > prop.getSampleRateMax()) {
-            rate = prop.getSampleRateMax();
+        if (rate > prop.maxSampleRate) {
+            rate = prop.maxSampleRate;
         }
-        if (rate < prop.getSampleRateMin()) {
-            rate = prop.getSampleRateMin();
+        if (rate < prop.minSampleRate) {
+            rate = prop.minSampleRate;
         }
         return rate;
     }
@@ -228,7 +233,7 @@
         if (config == null) {
             return;
         }
-        mHal.unsubscribeProperty(this, config.getProp());
+        mHal.unsubscribeProperty(this, config.prop);
     }
 
     /**
@@ -239,20 +244,20 @@
      */
     static int getSensorTypeFromHalProperty(int halPropertyType) {
         switch (halPropertyType) {
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_PERF_VEHICLE_SPEED:
+            case PERF_VEHICLE_SPEED:
                 return CarSensorManager.SENSOR_TYPE_CAR_SPEED;
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_GEAR_SELECTION:
+            case GEAR_SELECTION:
                 return CarSensorManager.SENSOR_TYPE_GEAR;
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE:
+            case NIGHT_MODE:
                 return CarSensorManager.SENSOR_TYPE_NIGHT;
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_PARKING_BRAKE_ON:
+            case PARKING_BRAKE_ON:
                 return CarSensorManager.SENSOR_TYPE_PARKING_BRAKE;
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_DRIVING_STATUS:
+            case DRIVING_STATUS:
                 return CarSensorManager.SENSOR_TYPE_DRIVING_STATUS;
-            case VehicleNetworkConsts.VEHICLE_PROPERTY_FUEL_LEVEL_LOW:
+            case FUEL_LEVEL_LOW:
                 return CarSensorManager.SENSOR_TYPE_FUEL_LEVEL;
             default:
-                return SENSOR_TYPE_INVALD;
+                return SENSOR_TYPE_INVALID;
         }
     }
 
diff --git a/service/src/com/android/car/hal/SensorHalServiceBase.java b/service/src/com/android/car/hal/SensorHalServiceBase.java
index ab4dd6a..bf47f7b 100644
--- a/service/src/com/android/car/hal/SensorHalServiceBase.java
+++ b/service/src/com/android/car/hal/SensorHalServiceBase.java
@@ -17,11 +17,10 @@
 package com.android.car.hal;
 
 import android.car.hardware.CarSensorEvent;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
 
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
-
-import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -44,7 +43,7 @@
         void onSensorEvents(List<CarSensorEvent> events);
     }
 
-    private final LinkedList<CarSensorEvent> mDispatchQ = new LinkedList<CarSensorEvent>();
+    private final LinkedList<CarSensorEvent> mDispatchQ = new LinkedList<>();
 
     public abstract void registerSensorListener(SensorListener listener);
 
@@ -83,9 +82,4 @@
         // sensor provider.
         throw new RuntimeException("should not be called");
     }
-
-    @Override
-    public List<VehiclePropConfig> takeSupportedProperties(List<VehiclePropConfig> allProperties) {
-        return null;
-    }
 }
diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java
index 7c8d7be..182583d 100644
--- a/service/src/com/android/car/hal/VehicleHal.java
+++ b/service/src/com/android/car/hal/VehicleHal.java
@@ -16,6 +16,19 @@
 
 package com.android.car.hal;
 
+import static com.android.car.CarServiceUtils.toByteArray;
+import static com.android.car.CarServiceUtils.toFloatArray;
+import static com.android.car.CarServiceUtils.toIntArray;
+import static java.lang.Integer.toHexString;
+
+import android.annotation.CheckResult;
+import android.hardware.vehicle.V2_0.IVehicle;
+import android.hardware.vehicle.V2_0.IVehicleCallback;
+import android.hardware.vehicle.V2_0.VehicleAreaConfig;
+import android.hardware.vehicle.V2_0.VehiclePropConfig;
+import android.hardware.vehicle.V2_0.VehiclePropValue;
+import android.hardware.vehicle.V2_0.VehiclePropertyAccess;
+import android.hardware.vehicle.V2_0.VehiclePropertyChangeMode;
 import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -23,23 +36,17 @@
 import android.util.SparseArray;
 
 import com.android.car.CarLog;
-import com.android.car.vehiclenetwork.VehicleNetwork;
-import com.android.car.vehiclenetwork.VehicleNetwork.VehicleNetworkListener;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess;
-import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropChangeMode;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
-import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.LinkedList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Abstraction for vehicle HAL. This class handles interface with native HAL and do basic parsing
@@ -47,39 +54,13 @@
  * implementation. It is responsibility of {@link HalServiceBase} to convert data to corresponding
  * Car*Service for Car*Manager API.
  */
-public class VehicleHal implements VehicleNetworkListener {
+public class VehicleHal extends IVehicleCallback.Stub {
 
     private static final boolean DBG = false;
 
-    static {
-        createInstance();
-    }
-
-    private static VehicleHal sInstance;
-
-    public static synchronized VehicleHal getInstance() {
-        if (sInstance == null) {
-            createInstance();
-        }
-        return sInstance;
-    }
-
-    private static synchronized void createInstance() {
-        sInstance = new VehicleHal();
-        // init is handled in a separate thread to prevent blocking the calling thread for too
-        // long.
-        sInstance.init();
-    }
-
-    public static synchronized void releaseInstance() {
-        if (sInstance != null) {
-            sInstance.release();
-            sInstance = null;
-        }
-    }
+    private static final int NO_AREA = -1;
 
     private final HandlerThread mHandlerThread;
-    private final VehicleNetwork mVehicleNetwork;
     private final SensorHalService mSensorHal;
     private final InfoHalService mInfoHal;
     private final AudioHalService mAudioHal;
@@ -89,16 +70,17 @@
     private final HvacHalService mHvacHal;
     private final InputHalService mInputHal;
     private final VendorExtensionHalService mVendorExtensionHal;
+    private final HalClient mHalClient;
 
     /** stores handler for each HAL property. Property events are sent to handler. */
-    private final SparseArray<HalServiceBase> mPropertyHandlers = new SparseArray<HalServiceBase>();
+    private final SparseArray<HalServiceBase> mPropertyHandlers = new SparseArray<>();
     /** This is for iterating all HalServices with fixed order. */
     private final HalServiceBase[] mAllServices;
-    private final ArraySet<Integer> mSubscribedProperties = new ArraySet<Integer>();
+    private final ArraySet<Integer> mSubscribedProperties = new ArraySet<>();
     private final HashMap<Integer, VehiclePropConfig> mAllProperties = new HashMap<>();
     private final HashMap<Integer, VehiclePropertyEventInfo> mEventLog = new HashMap<>();
 
-    private VehicleHal() {
+    public VehicleHal(IVehicle vehicle) {
         mHandlerThread = new HandlerThread("VEHICLE-HAL");
         mHandlerThread.start();
         // passing this should be safe as long as it is just kept and not used in constructor
@@ -109,7 +91,7 @@
         mCabinHal = new CabinHalService(this);
         mRadioHal = new RadioHalService(this);
         mHvacHal = new HvacHalService(this);
-        mInputHal = new InputHalService();
+        mInputHal = new InputHalService(this);
         mVendorExtensionHal = new VendorExtensionHalService(this);
         mAllServices = new HalServiceBase[] {
                 mPowerHal,
@@ -122,14 +104,15 @@
                 mInputHal,
                 mVendorExtensionHal
                 };
-        mVehicleNetwork = VehicleNetwork.createVehicleNetwork(this, mHandlerThread.getLooper());
+
+        mHalClient = new HalClient(vehicle, mHandlerThread.getLooper(), this /*IVehicleCallback*/);
     }
 
     /** Dummy version only for testing */
     @VisibleForTesting
     public VehicleHal(PowerHalService powerHal, SensorHalService sensorHal, InfoHalService infoHal,
             AudioHalService audioHal, CabinHalService cabinHal, RadioHalService radioHal,
-            HvacHalService hvacHal, VehicleNetwork vehicleNetwork) {
+            HvacHalService hvacHal, HalClient halClient) {
         mHandlerThread = null;
         mPowerHal = powerHal;
         mSensorHal = sensorHal;
@@ -141,24 +124,21 @@
         mInputHal = null;
         mVendorExtensionHal = null;
         mAllServices = null;
-        mVehicleNetwork = vehicleNetwork;
+        mHalClient = halClient;
     }
 
     public void init() {
-        VehiclePropConfigs properties = mVehicleNetwork.listProperties();
-        // needs copy as getConfigsList gives unmodifiable one.
-        List<VehiclePropConfig> propertiesList =
-                new LinkedList<VehiclePropConfig>(properties.getConfigsList());
+        Set<VehiclePropConfig> properties = new HashSet<>(mHalClient.getAllPropConfigs());
 
         synchronized (this) {
             // Create map of all properties
-            for (VehiclePropConfig p : propertiesList) {
-                mAllProperties.put(p.getProp(), p);
+            for (VehiclePropConfig p : properties) {
+                mAllProperties.put(p.prop, p);
             }
         }
 
         for (HalServiceBase service: mAllServices) {
-            List<VehiclePropConfig> taken = service.takeSupportedProperties(propertiesList);
+            Collection<VehiclePropConfig> taken = service.takeSupportedProperties(properties);
             if (taken == null) {
                 continue;
             }
@@ -167,10 +147,10 @@
             }
             synchronized (this) {
                 for (VehiclePropConfig p: taken) {
-                    mPropertyHandlers.append(p.getProp(), service);
+                    mPropertyHandlers.append(p.prop, service);
                 }
             }
-            propertiesList.removeAll(taken);
+            properties.removeAll(taken);
             service.init();
         }
     }
@@ -182,7 +162,7 @@
         }
         synchronized (this) {
             for (int p : mSubscribedProperties) {
-                mVehicleNetwork.unsubscribe(p);
+                mHalClient.unsubscribe(p);
             }
             mSubscribedProperties.clear();
             mAllProperties.clear();
@@ -228,19 +208,20 @@
 
     private void assertServiceOwnerLocked(HalServiceBase service, int property) {
         if (service != mPropertyHandlers.get(property)) {
-            throw new IllegalArgumentException("Property 0x" + Integer.toHexString(property)
+            throw new IllegalArgumentException("Property 0x" + toHexString(property)
                     + " is not owned by service: " + service);
         }
     }
 
     /**
      * Subscribe given property. Only Hal service owning the property can subscribe it.
-     * @param service
-     * @param property
-     * @param samplingRateHz
      */
     public void subscribeProperty(HalServiceBase service, int property,
             float samplingRateHz) throws IllegalArgumentException {
+        if (DBG) {
+            Log.i(CarLog.TAG_HAL, "subscribeProperty, service:" + service
+                    + ", property: 0x" + toHexString(property));
+        }
         VehiclePropConfig config;
         synchronized (this) {
             config = mAllProperties.get(property);
@@ -254,13 +235,17 @@
                 assertServiceOwnerLocked(service, property);
                 mSubscribedProperties.add(property);
             }
-            mVehicleNetwork.subscribe(property, samplingRateHz);
+            mHalClient.subscribe(property, samplingRateHz);
         } else {
             Log.e(CarLog.TAG_HAL, "Cannot subscribe to property: " + property);
         }
     }
 
     public void unsubscribeProperty(HalServiceBase service, int property) {
+        if (DBG) {
+            Log.i(CarLog.TAG_HAL, "unsubscribeProperty, service:" + service
+                    + ", property: 0x" + toHexString(property));
+        }
         VehiclePropConfig config;
         synchronized (this) {
             config = mAllProperties.get(property);
@@ -273,45 +258,116 @@
                 assertServiceOwnerLocked(service, property);
                 mSubscribedProperties.remove(property);
             }
-            mVehicleNetwork.unsubscribe(property);
+            mHalClient.unsubscribe(property);
         } else {
             Log.e(CarLog.TAG_HAL, "Cannot unsubscribe property: " + property);
         }
     }
 
-    public VehicleNetwork getVehicleNetwork() {
-        return mVehicleNetwork;
+    public boolean isPropertySupported(int propertyId) {
+        return mAllProperties.containsKey(propertyId);
     }
 
-    public static boolean isPropertySubscribable(VehiclePropConfig config) {
-        if ((config.getAccess() & VehiclePropAccess.VEHICLE_PROP_ACCESS_READ) == 0 ||
-                (config.getChangeMode() ==
-                VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_STATIC)) {
+    public Collection<VehiclePropConfig> getAllPropConfigs() {
+        return mAllProperties.values();
+    }
+
+    public VehiclePropValue get(int propertyId) throws PropertyTimeoutException {
+        return get(propertyId, NO_AREA);
+    }
+
+    public VehiclePropValue get(int propertyId, int areaId) throws PropertyTimeoutException {
+        Log.i(CarLog.TAG_HAL, "get, property: 0x" + toHexString(propertyId)
+                + ", areaId: 0x" + toHexString(areaId));
+        VehiclePropValue propValue = new VehiclePropValue();
+        propValue.prop = propertyId;
+        propValue.areaId = areaId;
+        return mHalClient.getValue(propValue);
+    }
+
+    public <T> T get(Class clazz, int propertyId) throws PropertyTimeoutException {
+        return get(clazz, createPropValue(propertyId, NO_AREA));
+    }
+
+    public <T> T get(Class clazz, int propertyId, int areaId) throws PropertyTimeoutException {
+        return get(clazz, createPropValue(propertyId, areaId));
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T get(Class clazz, VehiclePropValue requestedPropValue)
+            throws PropertyTimeoutException {
+        VehiclePropValue propValue = mHalClient.getValue(requestedPropValue);
+        if (clazz == Integer.class || clazz == int.class) {
+            return (T) propValue.value.int32Values.get(0);
+        } else if (clazz == Boolean.class || clazz == boolean.class) {
+            return (T) Boolean.valueOf(propValue.value.int32Values.get(0) == 1);
+        } else if (clazz == Float.class || clazz == float.class) {
+            return (T) propValue.value.floatValues.get(0);
+        } else if (clazz == Integer[].class) {
+            Integer[] intArray = new Integer[propValue.value.int32Values.size()];
+            return (T) propValue.value.int32Values.toArray(intArray);
+        } else if (clazz == Float[].class) {
+            Float[] floatArray = new Float[propValue.value.floatValues.size()];
+            return (T) propValue.value.floatValues.toArray(floatArray);
+        } else if (clazz == int[].class) {
+            return (T) toIntArray(propValue.value.int32Values);
+        } else if (clazz == float[].class) {
+            return (T) toFloatArray(propValue.value.floatValues);
+        } else if (clazz == byte[].class) {
+            return (T) toByteArray(propValue.value.bytes);
+        } else if (clazz == String.class) {
+            return (T) propValue.value.stringValue;
+        } else {
+            throw new IllegalArgumentException("Unexpected type: " + clazz);
+        }
+    }
+
+    public VehiclePropValue get(VehiclePropValue requestedPropValue)
+            throws PropertyTimeoutException {
+        return mHalClient.getValue(requestedPropValue);
+    }
+
+    void set(VehiclePropValue propValue) throws PropertyTimeoutException {
+        mHalClient.setValue(propValue);
+    }
+
+    @CheckResult
+    VehiclePropValueSetter set(int propId) {
+        return new VehiclePropValueSetter(mHalClient, propId, NO_AREA);
+    }
+
+    @CheckResult
+    VehiclePropValueSetter set(int propId, int areaId) {
+        return new VehiclePropValueSetter(mHalClient, propId, areaId);
+    }
+
+    static boolean isPropertySubscribable(VehiclePropConfig config) {
+        if ((config.access & VehiclePropertyAccess.READ) == 0 ||
+                (config.changeMode == VehiclePropertyChangeMode.STATIC)) {
             return false;
         }
         return true;
     }
 
-    public static void dumpProperties(PrintWriter writer, Collection<VehiclePropConfig> configs) {
+    static void dumpProperties(PrintWriter writer, Collection<VehiclePropConfig> configs) {
         for (VehiclePropConfig config : configs) {
-            writer.println("property " +
-                    VehicleNetworkConsts.getVehiclePropertyName(config.getProp()));
+            writer.println(String.format("property 0x%x", config.prop));
         }
     }
 
-    private final ArraySet<HalServiceBase> mServicesToDispatch = new ArraySet<HalServiceBase>();
+    private final ArraySet<HalServiceBase> mServicesToDispatch = new ArraySet<>();
 
     @Override
-    public void onVehicleNetworkEvents(VehiclePropValues values) {
+    public void onPropertyEvent(ArrayList<VehiclePropValue> propValues) {
         synchronized (this) {
-            for (VehiclePropValue v : values.getValuesList()) {
-                HalServiceBase service = mPropertyHandlers.get(v.getProp());
+            for (VehiclePropValue v : propValues) {
+                HalServiceBase service = mPropertyHandlers.get(v.prop);
                 service.getDispatchList().add(v);
                 mServicesToDispatch.add(service);
-                VehiclePropertyEventInfo info = mEventLog.get(v.getProp());
+                VehiclePropertyEventInfo info = mEventLog.get(v.prop);
                 if (info == null) {
                     info = new VehiclePropertyEventInfo(v);
-                    mEventLog.put(v.getProp(), info);
+                    mEventLog.put(v.prop, info);
                 } else {
                     info.addNewEvent(v);
                 }
@@ -330,19 +386,12 @@
     }
 
     @Override
-    public void onHalError(int errorCode, int property, int operation) {
-        Log.e(CarLog.TAG_HAL, "onHalError, errorCode:" + errorCode +
-                " property:0x" + Integer.toHexString(property) +
-                " operation:" + operation);
+    public void onPropertySetError(int errorCode, int propId, int areaId) {
+        Log.e(CarLog.TAG_HAL, String.format("onPropertySetError, errorCode: %d, prop: 0x%x, "
+                + "area: 0x%x", errorCode, propId, areaId));
         // TODO propagate per property error to HAL services and handle global error, bug:32068464
     }
 
-    @Override
-    public void onHalRestart(boolean inMocking) {
-        Log.e(CarLog.TAG_HAL, "onHalRestart, inMocking:" + inMocking);
-        // TODO restart things as other components started mocking. For now, ignore., bug:32068464
-    }
-
     public void dump(PrintWriter writer) {
         writer.println("**dump HAL services**");
         for (HalServiceBase service: mAllServices) {
@@ -354,30 +403,26 @@
             configList = new ArrayList<>(mAllProperties.values());
         }
 
+
         writer.println("**All properties**");
         for (VehiclePropConfig config : configList) {
-            StringBuilder builder = new StringBuilder();
-            builder.append("Property:0x").append(Integer.toHexString(config.getProp()));
-            builder.append(",access:0x" + Integer.toHexString(config.getAccess()));
-            builder.append(",changeMode:0x" + Integer.toHexString(config.getChangeMode()));
-            builder.append(",valueType:0x" + Integer.toHexString(config.getValueType()));
-            builder.append(",permission:0x" + Integer.toHexString(config.getPermissionModel()));
-            builder.append(",zone:0x" + Integer.toHexString(
-                config.hasZones() ? config.getZones() : 0));
-            builder.append(",config:0x" + Integer.toHexString(config.getConfigArray(0)));
-            builder.append(",fs min:" + config.getSampleRateMin());
-            builder.append(",fs max:").append(config.getSampleRateMax());
-            for (int i = 0; i < config.getFloatMaxsCount(); i++) {
-                builder.append(",v min:" + config.getFloatMins(i));
-                builder.append(",v max:" + config.getFloatMaxs(i));
-            }
-            for (int i = 0; i < config.getInt32MaxsCount(); i++) {
-                builder.append(",v min:" + config.getInt32Mins(i));
-                builder.append(",v max:" + config.getInt32Maxs(i));
-            }
-            for (int i = 0; i < config.getInt64MaxsCount(); i++) {
-                builder.append(",v min:" + config.getInt64Mins(i));
-                builder.append(",v max:" + config.getInt64Maxs(i));
+            StringBuilder builder = new StringBuilder()
+                    .append("Property:0x").append(toHexString(config.prop))
+                    .append(",access:0x").append(toHexString(config.access))
+                    .append(",changeMode:0x").append(toHexString(config.changeMode))
+                    .append(",permission:0x").append(toHexString(config.permissionModel))
+                    .append(",areas:0x").append(toHexString(config.supportedAreas))
+                    .append(",config:0x").append(Arrays.toString(config.configArray.toArray()))
+                    .append(",fs min:").append(config.minSampleRate)
+                    .append(",fs max:").append(config.maxSampleRate);
+            for (VehicleAreaConfig area : config.areaConfigs) {
+                builder.append(",areaId :").append(toHexString(area.areaId))
+                        .append(",f min:").append(area.minFloatValue)
+                        .append(",f max:").append(area.maxFloatValue)
+                        .append(",i min:").append(area.minInt32Value)
+                        .append(",i max:").append(area.maxInt32Value)
+                        .append(",i64 min:").append(area.minInt64Value)
+                        .append(",i64 max:").append(area.maxInt64Value);
             }
             writer.println(builder.toString());
         }
@@ -396,35 +441,6 @@
         }
     }
 
-    public static String dumpVehiclePropValue(VehiclePropValue value) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Property:0x" + Integer.toHexString(value.getProp()));
-        sb.append(",timestamp:" + value.getTimestamp());
-        sb.append(",value type:0x" + Integer.toHexString(value.getValueType()));
-        sb.append(",zone:0x" + Integer.toHexString(value.getZone()));
-        if (value.getInt32ValuesCount() > 0) {
-            sb.append(",int32 values:");
-            for (int i = 0; i < value.getInt32ValuesCount(); i++) {
-                sb.append("," + value.getInt32Values(i));
-            }
-        }
-        if (value.hasInt64Value()) {
-            sb.append(",int64 value:" + value.getInt64Value());
-        }
-        if (value.getFloatValuesCount() > 0) {
-            sb.append(",float values:");
-            for (int i = 0; i < value.getFloatValuesCount(); i++) {
-                sb.append("," + value.getFloatValues(i));
-            }
-        }
-        if (value.hasStringValue()) {
-            sb.append(",string value:" + value.getStringValue());
-        }
-        if (value.hasBytesValue()) {
-            sb.append(",bytes value:" + value.getBytesValue());
-        }
-        return sb.toString();
-    }
     private static class VehiclePropertyEventInfo {
         private int eventCount;
         private VehiclePropValue lastEvent;
@@ -439,4 +455,76 @@
             lastEvent = event;
         }
     }
+
+    final class VehiclePropValueSetter {
+        final WeakReference<HalClient> mClient;
+        final VehiclePropValue mPropValue;
+
+        private VehiclePropValueSetter(HalClient client, int propId, int areaId) {
+            mClient = new WeakReference<>(client);
+            mPropValue = new VehiclePropValue();
+            mPropValue.prop = propId;
+            mPropValue.areaId = areaId;
+        }
+
+        void to(boolean value) throws PropertyTimeoutException {
+            to(value ? 1 : 0);
+        }
+
+        void to(int value) throws PropertyTimeoutException {
+            mPropValue.value.int32Values.add(value);
+            submit();
+        }
+
+        void to(int[] values) throws PropertyTimeoutException {
+            for (int value : values) {
+                mPropValue.value.int32Values.add(value);
+            }
+            submit();
+        }
+
+        void to(Collection<Integer> values) throws PropertyTimeoutException {
+            mPropValue.value.int32Values.addAll(values);
+            submit();
+        }
+
+        void submit() throws PropertyTimeoutException {
+            HalClient client =  mClient.get();
+            if (client != null) {
+                Log.i(CarLog.TAG_HAL, "set, property: 0x" + toHexString(mPropValue.prop)
+                        + ", areaId: 0x" + toHexString(mPropValue.areaId));
+                client.setValue(mPropValue);
+            }
+        }
+    }
+
+    private static String dumpVehiclePropValue(VehiclePropValue value) {
+        final int MAX_BYTE_SIZE = 20;
+
+        StringBuilder sb = new StringBuilder()
+                .append("Property:0x").append(toHexString(value.prop))
+                .append(",timestamp:").append(value.timestamp)
+                .append(",zone:0x").append(toHexString(value.areaId))
+                .append(",floatValues: ").append(Arrays.toString(value.value.floatValues.toArray()))
+                .append(",int32Values: ").append(Arrays.toString(value.value.int32Values.toArray()))
+                .append(",int64Values: ")
+                .append(Arrays.toString(value.value.int64Values.toArray()));
+
+        if (value.value.bytes.size() > MAX_BYTE_SIZE) {
+            Object[] bytes = Arrays.copyOf(value.value.bytes.toArray(), MAX_BYTE_SIZE);
+            sb.append(",bytes: ").append(Arrays.toString(bytes));
+        } else {
+            sb.append(",bytes: ").append(Arrays.toString(value.value.bytes.toArray()));
+        }
+        sb.append(",string: ").append(value.value.stringValue);
+
+        return sb.toString();
+    }
+
+    private static VehiclePropValue createPropValue(int propId, int areaId) {
+        VehiclePropValue propValue = new VehiclePropValue();
+        propValue.prop = propId;
+        propValue.areaId = areaId;
+        return propValue;
+    }
 }
diff --git a/service/src/com/android/car/hal/VendorExtensionHalService.java b/service/src/com/android/car/hal/VendorExtensionHalService.java
index adcc754..0630bae 100644
--- a/service/src/com/android/car/hal/VendorExtensionHalService.java
+++ b/service/src/com/android/car/hal/VendorExtensionHalService.java
@@ -16,13 +16,13 @@
 
 package com.android.car.hal;
 
-import com.android.car.vehiclenetwork.VehiclePropValueUtil;
+import android.hardware.vehicle.V2_0.VehiclePropertyGroup;
 
 /**
  * Implementation of {@link HalServiceBase} that responsible for custom properties that were defined
  * by OEMs.
  */
-/*package*/ class VendorExtensionHalService extends PropertyHalServiceBase {
+public class VendorExtensionHalService extends PropertyHalServiceBase {
 
     private final static String TAG = VendorExtensionHalService.class.getSimpleName();
     private final static boolean DEBUG = false;
@@ -33,13 +33,15 @@
 
     @Override
     protected int managerToHalPropId(int managerPropId) {
-        return VehiclePropValueUtil.isCustomProperty(managerPropId)
-                ? managerPropId : NOT_SUPPORTED_PROPERTY;
+        return isVendorProperty(managerPropId) ? managerPropId : NOT_SUPPORTED_PROPERTY;
     }
 
     @Override
     protected int halToManagerPropId(int halPropId) {
-        return VehiclePropValueUtil.isCustomProperty(halPropId)
-                ? halPropId : NOT_SUPPORTED_PROPERTY;
+        return isVendorProperty(halPropId) ? halPropId : NOT_SUPPORTED_PROPERTY;
+    }
+
+    private static boolean isVendorProperty(int property) {
+        return (property & VehiclePropertyGroup.MASK) == VehiclePropertyGroup.VENDOR;
     }
 }
\ No newline at end of file
diff --git a/service/src/com/android/car/pm/CarPackageManagerService.java b/service/src/com/android/car/pm/CarPackageManagerService.java
index 9f73b61..8a3bd94 100644
--- a/service/src/com/android/car/pm/CarPackageManagerService.java
+++ b/service/src/com/android/car/pm/CarPackageManagerService.java
@@ -31,8 +31,8 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
 import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.content.pm.Signature;
 import android.content.res.Resources;
 import android.os.Handler;
@@ -54,7 +54,6 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;