Merge "graphics: rework IComposer"
diff --git a/audio/common/2.0/types.hal b/audio/common/2.0/types.hal
index d1674e4..13fd19b 100644
--- a/audio/common/2.0/types.hal
+++ b/audio/common/2.0/types.hal
@@ -665,6 +665,7 @@
                              // data bursts, not PCM.
     DIRECT_PCM = 0x2000,     // Audio stream containing PCM data that needs
                              // to pass through compress path for DSP post proc.
+    MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode.
 };
 
 /*
@@ -680,6 +681,7 @@
     HW_HOTWORD = 0x2,  // prefer an input that captures from hw hotword source
     RAW        = 0x4,  // minimize signal processing
     SYNC       = 0x8,  // synchronize I/O streams
+    MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode.
 };
 
 @export(name="audio_usage_t", value_prefix="AUDIO_USAGE_")
diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp
index d67972f..4eb728d 100644
--- a/boot/1.0/Android.bp
+++ b/boot/1.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.boot.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.boot@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+    srcs: [
+        "types.hal",
+        "IBootControl.hal",
+    ],
+    out: [
+        "android/hardware/boot/1.0/types.vts.cpp",
+        "android/hardware/boot/1.0/BootControl.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.boot.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.boot@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+    srcs: [
+        "types.hal",
+        "IBootControl.hal",
+    ],
+    out: [
+        "android/hardware/boot/1.0/types.vts.h",
+        "android/hardware/boot/1.0/BootControl.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.boot.vts.driver@1.0",
+    generated_sources: ["android.hardware.boot.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.boot.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.boot.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.boot@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/boot/1.0/vts/Android.mk b/boot/1.0/vts/Android.mk
index 9b30ef1..d3a3851 100644
--- a/boot/1.0/vts/Android.mk
+++ b/boot/1.0/vts/Android.mk
@@ -16,36 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Boot Control v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_boot@1.0
-
-LOCAL_SRC_FILES := \
-  BootControl.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.boot@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for boot.
 include $(CLEAR_VARS)
 
diff --git a/evs/1.0/Android.bp b/evs/1.0/Android.bp
new file mode 100644
index 0000000..86e9c1c
--- /dev/null
+++ b/evs/1.0/Android.bp
@@ -0,0 +1,80 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.evs@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.evs@1.0",
+    srcs: [
+        "types.hal",
+        "IEvsCamera.hal",
+        "IEvsCameraStream.hal",
+        "IEvsDisplay.hal",
+        "IEvsEnumerator.hal",
+    ],
+    out: [
+        "android/hardware/evs/1.0/types.cpp",
+        "android/hardware/evs/1.0/EvsCameraAll.cpp",
+        "android/hardware/evs/1.0/EvsCameraStreamAll.cpp",
+        "android/hardware/evs/1.0/EvsDisplayAll.cpp",
+        "android/hardware/evs/1.0/EvsEnumeratorAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.evs@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.evs@1.0",
+    srcs: [
+        "types.hal",
+        "IEvsCamera.hal",
+        "IEvsCameraStream.hal",
+        "IEvsDisplay.hal",
+        "IEvsEnumerator.hal",
+    ],
+    out: [
+        "android/hardware/evs/1.0/types.h",
+        "android/hardware/evs/1.0/IEvsCamera.h",
+        "android/hardware/evs/1.0/IHwEvsCamera.h",
+        "android/hardware/evs/1.0/BnEvsCamera.h",
+        "android/hardware/evs/1.0/BpEvsCamera.h",
+        "android/hardware/evs/1.0/BsEvsCamera.h",
+        "android/hardware/evs/1.0/IEvsCameraStream.h",
+        "android/hardware/evs/1.0/IHwEvsCameraStream.h",
+        "android/hardware/evs/1.0/BnEvsCameraStream.h",
+        "android/hardware/evs/1.0/BpEvsCameraStream.h",
+        "android/hardware/evs/1.0/BsEvsCameraStream.h",
+        "android/hardware/evs/1.0/IEvsDisplay.h",
+        "android/hardware/evs/1.0/IHwEvsDisplay.h",
+        "android/hardware/evs/1.0/BnEvsDisplay.h",
+        "android/hardware/evs/1.0/BpEvsDisplay.h",
+        "android/hardware/evs/1.0/BsEvsDisplay.h",
+        "android/hardware/evs/1.0/IEvsEnumerator.h",
+        "android/hardware/evs/1.0/IHwEvsEnumerator.h",
+        "android/hardware/evs/1.0/BnEvsEnumerator.h",
+        "android/hardware/evs/1.0/BpEvsEnumerator.h",
+        "android/hardware/evs/1.0/BsEvsEnumerator.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.evs@1.0",
+    generated_sources: ["android.hardware.evs@1.0_genc++"],
+    generated_headers: ["android.hardware.evs@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.evs@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/evs/1.0/IEvsCamera.hal b/evs/1.0/IEvsCamera.hal
new file mode 100644
index 0000000..a2fc565
--- /dev/null
+++ b/evs/1.0/IEvsCamera.hal
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.evs@1.0;
+
+import types;
+import IEvsCameraStream;
+
+
+/**
+ * Represents a single camera and is the primary interface for capturing images.
+ */
+interface IEvsCamera {
+
+    /**
+     * Returns the ID of this camera.
+     *
+     * Returns the string id of this camera. This must be the same value as reported in
+     * the camera_id field of the CameraDesc structure by EvsEnumerator::getCamerList().
+     */
+    getId() generates (string cameraId);
+
+    /**
+     * Specifies the depth of the buffer chain the camera is asked to support.
+     *
+     * Up to this many frames may be held concurrently by the client of IEvsCamera.
+     * If this many frames have been delivered to the receiver without being returned
+     * by doneWithFrame, the stream must skip frames until a buffer is returned for reuse.
+     * It is legal for this call to come at any time, even while streams are already running,
+     * in which case buffers should be added or removed from the chain as appropriate.
+     * If no call is made to this entry point, the IEvsCamera must support at least one
+     * frame by default. More is acceptable.
+     * BUFFER_NOT_AVAILABLE is returned if the implementation cannot support the
+     * requested number of concurrent frames.
+     */
+    setMaxFramesInFlight(uint32_t bufferCount) generates (EvsResult result);
+
+    /**
+     * Request delivery of EVS camera frames from this camera.
+     *
+     * The IEvsCameraStream must begin receiving periodic calls with new image
+     * frames until stopVideoStream() is called.
+     */
+    startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
+
+    /**
+     * Return a frame that was delivered by to the IEvsCameraStream.
+     *
+     * When done consuming a frame delivered to the IEvsCameraStream
+     * interface, it must be returned to the IEvsCamera for reuse.
+     * A small, finite number of buffers are available (possibly as small
+     * as one), and if the supply is exhausted, no further frames may be
+     * delivered until a buffer is returned.
+     */
+    doneWithFrame(uint32_t frameId, handle bufferHandle) generates (EvsResult result);
+
+    /**
+     * Stop the delivery of EVS camera frames.
+     *
+     * Because delivery is asynchronous, frames may continue to arrive for
+     * some time after this call returns. Each must be returned until the
+     * closure of the stream is signaled to the IEvsCameraStream.
+     * This function cannot fail and is simply ignored if the stream isn't running.
+     */
+    stopVideoStream();
+
+    /**
+     * Request driver specific information from the HAL implementation.
+     *
+     * The values allowed for opaqueIdentifier are driver specific,
+     * but no value passed in may crash the driver. The driver should
+     * return 0 for any unrecognized opaqueIdentifier.
+     */
+    getExtendedInfo(uint32_t opaqueIdentifier) generates (int32_t value);
+
+    /**
+     * Send a driver specific value to the HAL implementation.
+     *
+     * This extension is provided to facilitate car specific
+     * extensions, but no HAL implementation may require this call
+     * in order to function in a default state.
+     * INVALID_ARG is returned if the opaqueValue is not meaningful to
+     * the driver implementation.
+     */
+    setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue) generates (EvsResult result);
+};
diff --git a/evs/1.0/IEvsCameraStream.hal b/evs/1.0/IEvsCameraStream.hal
new file mode 100644
index 0000000..ef5460f
--- /dev/null
+++ b/evs/1.0/IEvsCameraStream.hal
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.evs@1.0;
+
+
+/**
+ * Implemented on client side to receive asynchronous video frame deliveries.
+ */
+interface IEvsCameraStream {
+
+    /**
+     * Receives calls from the HAL each time a video frame is ready for inspection.
+     * Buffer handles received by this method must be returned via calls to
+     * IEvsCamera::doneWithFrame(). When the video stream is stopped via a call
+     * to IEvsCamera::stopVideoStream(), this callback may continue to happen for
+     * some time as the pipeline drains. Each frame must still be returned.
+     * When the last frame in the stream has been delivered, a NULL bufferHandle
+     * must be delivered, signifying the end of the stream. No further frame
+     * deliveries may happen thereafter.
+     */
+    oneway deliverFrame(uint32_t frameId, handle bufferHandle);
+};
diff --git a/evs/1.0/IEvsDisplay.hal b/evs/1.0/IEvsDisplay.hal
new file mode 100644
index 0000000..a473872
--- /dev/null
+++ b/evs/1.0/IEvsDisplay.hal
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.evs@1.0;
+
+import types;
+
+
+/**
+ * Represents a single camera and is the primary interface for capturing images.
+ */
+interface IEvsDisplay {
+
+    /**
+     * Returns basic information about the EVS display provided by the system.
+     *
+     * See the description of the DisplayDesc structure below for details.
+     */
+     getDisplayInfo() generates (DisplayDesc info);
+
+
+    /**
+     * Clients may set the display state to express their desired state.
+     *
+     * The HAL implementation must gracefully accept a request for any state while in
+     * any other state, although the response may be to defer or ignore the request. The display
+     * is defined to start in the NOT_VISIBLE state upon initialization. The client is
+     * then expected to request the VISIBLE_ON_NEXT_FRAME state, and then begin providing
+     * video. When the display is no longer required, the client is expected to request
+     * the NOT_VISIBLE state after passing the last video frame.
+     * Returns INVALID_ARG if the requested state is not a recognized value.
+     */
+     setDisplayState(DisplayState state) generates (EvsResult result);
+
+
+    /**
+     * This call requests the current state of the display
+     *
+     * The HAL implementation should report the actual current state, which might
+     * transiently differ from the most recently requested state. Note, however, that
+     * the logic responsible for changing display states should generally live above
+     * the device layer, making it undesirable for the HAL implementation to spontaneously
+     * change display states.
+     */
+     getDisplayState() generates (DisplayState state);
+
+
+    /**
+     * This call returns a handle to a frame buffer associated with the display.
+     *
+     * The returned buffer may be locked and written to by software and/or GL. This buffer
+     * must be returned via a call to returnTargetBufferForDisplay() even if the
+     * display is no longer visible.
+     */
+     getTargetBuffer() generates (handle bufferHandle);
+
+
+    /**
+     * This call tells the display that the buffer is ready for display.
+     *
+     * The buffer is no longer valid for use by the client after this call.
+     * There is no maximum time the caller may hold onto the buffer before making this
+     * call. The buffer may be returned at any time and in any DisplayState, but all
+     * buffers are expected to be returned before the IEvsDisplay interface is destroyed.
+     */
+    returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);
+};
diff --git a/evs/1.0/IEvsEnumerator.hal b/evs/1.0/IEvsEnumerator.hal
new file mode 100644
index 0000000..e3a1382
--- /dev/null
+++ b/evs/1.0/IEvsEnumerator.hal
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.evs@1.0;
+
+import types;
+import IEvsCamera;
+import IEvsDisplay;
+
+
+/**
+ * Provides the mechanism for EVS camera discovery
+ */
+interface IEvsEnumerator {
+
+    /**
+     * Returns a list of all EVS cameras available to the system
+     */
+    getCameraList() generates (vec<CameraDesc> cameras);
+
+
+    /**
+     * Get the IEvsCamera associated with a cameraId from a CameraDesc
+     *
+     * Given a camera's unique cameraId from ca CameraDesc, returns
+     * the ICamera interface assocaited with the specified camera.
+     * When done using the camera, it must be returned by calling
+     * closeCamera on the ICamera interface.
+     */
+    openCamera(string cameraId) generates (IEvsCamera carCamera);
+
+    /**
+     * Return the specified IEvsCamera interface as no longer in use
+     *
+     * When the IEvsCamera object is no longer required, it must be released.
+     * NOTE: Video streaming must be cleanly stopped before making this call.
+     */
+    closeCamera(IEvsCamera carCamera);
+
+
+    /**
+     * Get exclusive access to IEvsDisplay for the system
+     *
+     * There can be at most one EVS display object for the system and this function
+     * requests access to it. If the EVS display is not available or is already in use,
+     * a null pointer is returned.
+     */
+    openDisplay() generates (IEvsDisplay display);
+
+    /**
+     * Return the specified IEvsDisplay interface as no longer in use
+     *
+     * When the IEvsDisplay object is no longer required, it must be released.
+     * NOTE: All buffer must have been returned to the display before making this call.
+     */
+    closeDisplay(IEvsDisplay display);
+};
+
diff --git a/evs/1.0/default/Android.bp b/evs/1.0/default/Android.bp
new file mode 100644
index 0000000..3bda250
--- /dev/null
+++ b/evs/1.0/default/Android.bp
@@ -0,0 +1,26 @@
+cc_binary {
+    name: "android.hardware.evs@1.0-service",
+    relative_install_path: "hw",
+    srcs: [
+        "service.cpp",
+        "EvsCamera.cpp",
+        "EvsEnumerator.cpp",
+        "EvsDisplay.cpp"
+    ],
+    init_rc: ["android.hardware.evs@1.0-service.rc"],
+
+    shared_libs: [
+        "android.hardware.evs@1.0",
+        "android.hardware.graphics.allocator@2.0",
+        "libui",
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/evs/1.0/default/EvsCamera.cpp b/evs/1.0/default/EvsCamera.cpp
new file mode 100644
index 0000000..32d4ed7
--- /dev/null
+++ b/evs/1.0/default/EvsCamera.cpp
@@ -0,0 +1,305 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.evs@1.0-service"
+
+#include "EvsCamera.h"
+
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+
+// These are the special camera names for which we'll initialize custom test data
+const char EvsCamera::kCameraName_Backup[]    = "backup";
+const char EvsCamera::kCameraName_RightTurn[] = "Right Turn";
+
+
+// TODO(b/31632518):  Need to get notification when our client dies so we can close the camera.
+// As it stands, if the client dies suddently, the buffer may be stranded.
+// As possible work around would be to give the client a HIDL object to exclusively hold
+// and use it's destructor to perform some work in the server side.
+
+EvsCamera::EvsCamera(const char *id) {
+    ALOGD("EvsCamera instantiated");
+
+    mDescription.cameraId = id;
+    mFrameBusy = false;
+    mStreamState = STOPPED;
+
+    // Set up dummy data for testing
+    if (mDescription.cameraId == kCameraName_Backup) {
+        mDescription.hints                  = UsageHint::USAGE_HINT_REVERSE;
+        mDescription.vendorFlags            = 0xFFFFFFFF;   // Arbitrary value
+        mDescription.defaultHorResolution   = 320;          // 1/2 NTSC/VGA
+        mDescription.defaultVerResolution   = 240;          // 1/2 NTSC/VGA
+    }
+    else if (mDescription.cameraId == kCameraName_RightTurn) {
+        // Nothing but the name and the usage hint
+        mDescription.hints                  = UsageHint::USAGE_HINT_RIGHT_TURN;
+    }
+    else {
+        // Leave empty for a minimalist camera description without even a hint
+    }
+}
+
+EvsCamera::~EvsCamera() {
+    ALOGD("EvsCamera being destroyed");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // Make sure our output stream is cleaned up
+    // (It really should be already)
+    stopVideoStream();
+
+    // Drop the graphics buffer we've been using
+    if (mBuffer) {
+        // Drop the graphics buffer we've been using
+        GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+        alloc.free(mBuffer);
+    }
+
+    ALOGD("EvsCamera destroyed");
+}
+
+
+// Methods from ::android::hardware::evs::V1_0::IEvsCamera follow.
+Return<void> EvsCamera::getId(getId_cb id_cb) {
+    ALOGD("getId");
+
+    id_cb(mDescription.cameraId);
+
+    return Void();
+}
+
+
+Return<EvsResult> EvsCamera::setMaxFramesInFlight(uint32_t bufferCount) {
+    ALOGD("setMaxFramesInFlight");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // TODO:  Update our stored value
+
+    // TODO:  Adjust our buffer count right now if we can.  Otherwise, it'll adjust in doneWithFrame
+
+    // For now we support only one!
+    if (bufferCount != 1) {
+        return EvsResult::BUFFER_NOT_AVAILABLE;
+    }
+
+    return EvsResult::OK;
+}
+
+Return<EvsResult> EvsCamera::startVideoStream(const ::android::sp<IEvsCameraStream>& stream)  {
+    ALOGD("startVideoStream");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // We only support a single stream at a time
+    if (mStreamState != STOPPED) {
+        ALOGE("ignoring startVideoStream call when a stream is already running.");
+        return EvsResult::STREAM_ALREADY_RUNNING;
+    }
+
+    // Record the user's callback for use when we have a frame ready
+    mStream = stream;
+
+    // Allocate a graphics buffer into which we'll put our test images
+    if (!mBuffer) {
+        mWidth  = (mDescription.defaultHorResolution) ? mDescription.defaultHorResolution : 640;
+        mHeight = (mDescription.defaultVerResolution) ? mDescription.defaultVerResolution : 480;
+        // TODO:  What about stride?  Assume no padding for now...
+        mStride = 4* mWidth;    // Special cased to assume 4 byte pixels with no padding for now
+
+        ALOGD("Allocating buffer for camera frame");
+        GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
+        status_t result = alloc.allocate(mWidth, mHeight,
+                                         HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_HW_TEXTURE,
+                                         &mBuffer, &mStride, 0, "EvsCamera");
+        if (result != NO_ERROR) {
+            ALOGE("Error %d allocating %d x %d graphics buffer", result, mWidth, mHeight);
+            return EvsResult::BUFFER_NOT_AVAILABLE;
+        }
+        if (!mBuffer) {
+            ALOGE("We didn't get a buffer handle back from the allocator");
+            return EvsResult::BUFFER_NOT_AVAILABLE;
+        }
+    }
+
+    // Start the frame generation thread
+    mStreamState = RUNNING;
+    mCaptureThread = std::thread([this](){GenerateFrames();});
+
+    return EvsResult::OK;
+}
+
+Return<EvsResult> EvsCamera::doneWithFrame(uint32_t frameId, const hidl_handle& bufferHandle)  {
+    ALOGD("doneWithFrame");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    if (!bufferHandle)
+    {
+        ALOGE("ignoring doneWithFrame called with invalid handle");
+        return EvsResult::INVALID_ARG;
+    }
+
+    // TODO:  Track which frames we've delivered and validate this is one of them
+
+    // Mark the frame buffer as available for a new frame
+    mFrameBusy = false;
+
+    // TODO:  If we currently have too many buffers, drop this one
+
+    return EvsResult::OK;
+}
+
+Return<void> EvsCamera::stopVideoStream()  {
+    ALOGD("stopVideoStream");
+
+    bool waitForJoin = false;
+    // Lock scope
+    {
+        std::lock_guard <std::mutex> lock(mAccessLock);
+
+        if (mStreamState == RUNNING) {
+            // Tell the GenerateFrames loop we want it to stop
+            mStreamState = STOPPING;
+
+            // Note that we asked the thread to stop and should wait for it do so
+            waitForJoin = true;
+        }
+    }
+
+    if (waitForJoin) {
+        // Block outside the mutex until the "stop" flag has been acknowledged
+        // NOTE:  We won't send any more frames, but the client might still get one already in flight
+        ALOGD("Waiting for stream thread to end...");
+        mCaptureThread.join();
+
+        // Lock scope
+        {
+            std::lock_guard <std::mutex> lock(mAccessLock);
+            mStreamState = STOPPED;
+        }
+    }
+
+    return Void();
+}
+
+Return<int32_t> EvsCamera::getExtendedInfo(uint32_t opaqueIdentifier)  {
+    ALOGD("getExtendedInfo");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // For any single digit value, return the index itself as a test value
+    if (opaqueIdentifier <= 9) {
+        return opaqueIdentifier;
+    }
+
+    // Return zero by default as required by the spec
+    return 0;
+}
+
+Return<EvsResult> EvsCamera::setExtendedInfo(uint32_t /*opaqueIdentifier*/, int32_t /*opaqueValue*/)  {
+    ALOGD("setExtendedInfo");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // We don't store any device specific information in this implementation
+    return EvsResult::INVALID_ARG;
+}
+
+
+void EvsCamera::GenerateFrames() {
+    ALOGD("Frame generate loop started");
+
+    uint32_t frameNumber;
+
+    while (true) {
+        bool timeForFrame = false;
+        // Lock scope
+        {
+            std::lock_guard<std::mutex> lock(mAccessLock);
+
+            // Tick the frame counter -- rollover is tolerated
+            frameNumber = mFrameId++;
+
+            if (mStreamState != RUNNING) {
+                // Break out of our main thread loop
+                break;
+            }
+
+            if (mFrameBusy) {
+                // Can't do anything right now -- skip this frame
+                ALOGW("Skipped a frame because client hasn't returned a buffer\n");
+            }
+            else {
+                // We're going to make the frame busy
+                mFrameBusy = true;
+                timeForFrame = true;
+            }
+        }
+
+        if (timeForFrame) {
+            // Lock our output buffer for writing
+            uint32_t *pixels = nullptr;
+            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+            mapper.lock(mBuffer,
+                        GRALLOC_USAGE_SW_WRITE_OFTEN,
+                        android::Rect(mWidth, mHeight),
+                        (void **) &pixels);
+
+            // If we failed to lock the pixel buffer, we're about to crash, but log it first
+            if (!pixels) {
+                ALOGE("Camera failed to gain access to image buffer for writing");
+            }
+
+            // Fill in the test pixels
+            for (unsigned row = 0; row < mHeight; row++) {
+                for (unsigned col = 0; col < mWidth; col++) {
+                    // Index into the row to set the pixel at this column
+                    // (We're making vertical gradient in the green channel, and
+                    // horitzontal gradient in the blue channel)
+                    pixels[col] = 0xFF0000FF | ((row & 0xFF) << 16) | ((col & 0xFF) << 8);
+                }
+                // Point to the next row
+                pixels = pixels + (mStride / sizeof(*pixels));
+            }
+
+            // Release our output buffer
+            mapper.unlock(mBuffer);
+
+            // Issue the (asynchronous) callback to the client
+            mStream->deliverFrame(frameNumber, mBuffer);
+            ALOGD("Delivered %p as frame %d", mBuffer, frameNumber);
+        }
+
+        // We arbitrarily choose to generate frames at 10 fps (1/10 * uSecPerSec)
+        usleep(100000);
+    }
+
+    // If we've been asked to stop, send one last NULL frame to signal the actual end of stream
+    mStream->deliverFrame(frameNumber, nullptr);
+
+    return;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
diff --git a/evs/1.0/default/EvsCamera.h b/evs/1.0/default/EvsCamera.h
new file mode 100644
index 0000000..5d29125
--- /dev/null
+++ b/evs/1.0/default/EvsCamera.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_EVS_V1_0_EVSCAMERA_H
+#define ANDROID_HARDWARE_EVS_V1_0_EVSCAMERA_H
+
+#include <android/hardware/evs/1.0/types.h>
+#include <android/hardware/evs/1.0/IEvsCamera.h>
+#include <ui/GraphicBuffer.h>
+
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+class EvsCamera : public IEvsCamera {
+public:
+    // Methods from ::android::hardware::evs::V1_0::IEvsCamera follow.
+    Return<void> getId(getId_cb id_cb)  override;
+    Return<EvsResult> setMaxFramesInFlight(uint32_t bufferCount)  override;
+    Return<EvsResult> startVideoStream(const ::android::sp<IEvsCameraStream>& stream) override;
+    Return<EvsResult> doneWithFrame(uint32_t frameId, const hidl_handle& bufferHandle)  override;
+    Return<void> stopVideoStream()  override;
+    Return<int32_t> getExtendedInfo(uint32_t opaqueIdentifier)  override;
+    Return<EvsResult> setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue)  override;
+
+    // Implementation details
+    EvsCamera(const char* id);
+    virtual ~EvsCamera() override;
+
+    const CameraDesc& getDesc() { return mDescription; };
+    void GenerateFrames();
+
+    static const char kCameraName_Backup[];
+    static const char kCameraName_RightTurn[];
+
+private:
+    CameraDesc              mDescription = {};  // The properties of this camera
+
+    buffer_handle_t         mBuffer = nullptr;  // A graphics buffer into which we'll store images
+    uint32_t                mWidth  = 0;        // number of pixels across the buffer
+    uint32_t                mHeight = 0;        // number of pixels vertically in the buffer
+    uint32_t                mStride = 0;        // Bytes per line in the buffer
+
+    sp<IEvsCameraStream>    mStream = nullptr;  // The callback the user expects when a frame is ready
+
+    std::thread             mCaptureThread;     // The thread we'll use to synthesize frames
+
+    uint32_t                mFrameId;           // A frame counter used to identify specific frames
+
+    enum StreamStateValues {
+        STOPPED,
+        RUNNING,
+        STOPPING,
+    };
+    StreamStateValues       mStreamState;
+    bool                    mFrameBusy;         // A flag telling us our one buffer is in use
+
+    std::mutex              mAccessLock;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
+
+#endif  // ANDROID_HARDWARE_EVS_V1_0_EVSCAMERA_H
diff --git a/evs/1.0/default/EvsDisplay.cpp b/evs/1.0/default/EvsDisplay.cpp
new file mode 100644
index 0000000..9dba6fc
--- /dev/null
+++ b/evs/1.0/default/EvsDisplay.cpp
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.evs@1.0-service"
+
+#include "EvsDisplay.h"
+
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+
+// TODO(b/31632518):  Need to get notification when our client dies so we can close the camera.
+// As it stands, if the client dies suddently, the buffer may be stranded.
+// As possible work around would be to give the client a HIDL object to exclusively hold
+// and use it's destructor to perform some work in the server side.
+
+
+EvsDisplay::EvsDisplay() {
+    ALOGD("EvsDisplay instantiated");
+
+    // Set up our self description
+    mInfo.displayId             = "Mock Display";
+    mInfo.vendorFlags           = 3870;
+    mInfo.defaultHorResolution  = 320;
+    mInfo.defaultVerResolution  = 240;
+}
+
+
+EvsDisplay::~EvsDisplay() {
+    ALOGD("EvsDisplay being destroyed");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // Report if we're going away while a buffer is outstanding.  This could be bad.
+    if (mFrameBusy) {
+        ALOGE("EvsDisplay going down while client is holding a buffer\n");
+    }
+
+    // Make sure we release our frame buffer
+    if (mBuffer) {
+        // Drop the graphics buffer we've been using
+        GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+        alloc.free(mBuffer);
+    }
+    ALOGD("EvsDisplay destroyed");
+}
+
+
+/**
+ * Returns basic information about the EVS display provided by the system.
+ * See the description of the DisplayDesc structure below for details.
+ */
+Return<void> EvsDisplay::getDisplayInfo(getDisplayInfo_cb _hidl_cb)  {
+    ALOGD("getDisplayInfo");
+
+    // Send back our self description
+    _hidl_cb(mInfo);
+    return Void();
+}
+
+
+/**
+ * Clients may set the display state to express their desired state.
+ * The HAL implementation must gracefully accept a request for any state
+ * while in any other state, although the response may be to ignore the request.
+ * The display is defined to start in the NOT_VISIBLE state upon initialization.
+ * The client is then expected to request the VISIBLE_ON_NEXT_FRAME state, and
+ * then begin providing video.  When the display is no longer required, the client
+ * is expected to request the NOT_VISIBLE state after passing the last video frame.
+ */
+Return<EvsResult> EvsDisplay::setDisplayState(DisplayState state) {
+    ALOGD("setDisplayState");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // Ensure we recognize the requested state so we don't go off the rails
+    if (state < DisplayState::NUM_STATES) {
+        // Record the requested state
+        mRequestedState = state;
+        return EvsResult::OK;
+    }
+    else {
+        // Turn off the display if asked for an unrecognized state
+        mRequestedState = DisplayState::NOT_VISIBLE;
+        return EvsResult::INVALID_ARG;
+    }
+}
+
+
+/**
+ * The HAL implementation should report the actual current state, which might
+ * transiently differ from the most recently requested state.  Note, however, that
+ * the logic responsible for changing display states should generally live above
+ * the device layer, making it undesirable for the HAL implementation to
+ * spontaneously change display states.
+ */
+Return<DisplayState> EvsDisplay::getDisplayState()  {
+    ALOGD("getDisplayState");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // At the moment, we treat the requested state as immediately active
+    DisplayState currentState = mRequestedState;
+
+    return currentState;
+}
+
+
+/**
+ * This call returns a handle to a frame buffer associated with the display.
+ * This buffer may be locked and written to by software and/or GL.  This buffer
+ * must be returned via a call to returnTargetBufferForDisplay() even if the
+ * display is no longer visible.
+ */
+// TODO: We need to know if/when our client dies so we can get the buffer back! (blocked b/31632518)
+Return<void> EvsDisplay::getTargetBuffer(getTargetBuffer_cb _hidl_cb)  {
+    ALOGD("getTargetBuffer");
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // If we don't already have a buffer, allocate one now
+    if (!mBuffer) {
+        GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+        status_t result = alloc.allocate(mInfo.defaultHorResolution, mInfo.defaultVerResolution,
+                                         HAL_PIXEL_FORMAT_RGBA_8888, 1,
+                                         GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER,
+                                         &mBuffer, &mStride, 0, "EvsDisplay");
+        mFrameBusy = false;
+        ALOGD("Allocated new buffer %p with stride %u", mBuffer, mStride);
+    }
+
+    // Do we have a frame available?
+    if (mFrameBusy) {
+        // This means either we have a 2nd client trying to compete for buffers
+        // (an unsupported mode of operation) or else the client hasn't returned
+        // a previously issues buffer yet (they're behaving badly).
+        // NOTE:  We have to make callback even if we have nothing to provide
+        ALOGE("getTargetBuffer called while no buffers available.");
+        _hidl_cb(nullptr);
+    }
+    else {
+        // Mark our buffer as busy
+        mFrameBusy = true;
+
+        // Send the buffer to the client
+        ALOGD("Providing display buffer %p", mBuffer);
+        _hidl_cb(mBuffer);
+    }
+
+    // All done
+    return Void();
+}
+
+
+/**
+ * This call tells the display that the buffer is ready for display.
+ * The buffer is no longer valid for use by the client after this call.
+ */
+Return<EvsResult> EvsDisplay::returnTargetBufferForDisplay(const hidl_handle& bufferHandle)  {
+    ALOGD("returnTargetBufferForDisplay %p", bufferHandle.getNativeHandle());
+    std::lock_guard<std::mutex> lock(mAccessLock);
+
+    // This shouldn't happen if we haven't issued the buffer!
+    if (!bufferHandle) {
+        ALOGE ("returnTargetBufferForDisplay called without a valid buffer handle.\n");
+        return EvsResult::INVALID_ARG;
+    }
+    /* TODO(b/33492405): It would be nice to validate we got back the buffer we expect,
+     * but HIDL doesn't support that (yet?)
+    if (bufferHandle != mBuffer) {
+        ALOGE ("Got an unrecognized frame returned.\n");
+        return EvsResult::INVALID_ARG;
+    }
+    */
+    if (!mFrameBusy) {
+        ALOGE ("A frame was returned with no outstanding frames.\n");
+        return EvsResult::BUFFER_NOT_AVAILABLE;
+    }
+
+    mFrameBusy = false;
+
+    // If we were waiting for a new frame, this is it!
+    if (mRequestedState == DisplayState::VISIBLE_ON_NEXT_FRAME) {
+        mRequestedState = DisplayState::VISIBLE;
+    }
+
+    // Validate we're in an expected state
+    if (mRequestedState != DisplayState::VISIBLE) {
+        // We shouldn't get frames back when we're not visible.
+        ALOGE ("Got an unexpected frame returned while not visible - ignoring.\n");
+    }
+    else {
+        // Make this buffer visible
+        // TODO:  Add code to put this image on the screen (or validate it somehow?)
+    }
+
+    return EvsResult::OK;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
diff --git a/evs/1.0/default/EvsDisplay.h b/evs/1.0/default/EvsDisplay.h
new file mode 100644
index 0000000..a2d5d3e
--- /dev/null
+++ b/evs/1.0/default/EvsDisplay.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_EVS_V1_0_EVSDISPLAY_H
+#define ANDROID_HARDWARE_EVS_V1_0_EVSDISPLAY_H
+
+#include <android/hardware/evs/1.0/IEvsDisplay.h>
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+class EvsDisplay : public IEvsDisplay {
+public:
+    // Methods from ::android::hardware::evs::V1_0::IEvsDisplay follow.
+    Return<void> getDisplayInfo(getDisplayInfo_cb _hidl_cb)  override;
+    Return<EvsResult> setDisplayState(DisplayState state)  override;
+    Return<DisplayState> getDisplayState()  override;
+    Return<void> getTargetBuffer(getTargetBuffer_cb _hidl_cb)  override;
+    Return<EvsResult> returnTargetBufferForDisplay(const hidl_handle& bufferHandle)  override;
+
+    // Implementation details
+    EvsDisplay();
+    virtual ~EvsDisplay() override;
+
+private:
+    DisplayDesc     mInfo           = {};
+    buffer_handle_t mBuffer         = nullptr;      // A graphics buffer into which we'll store images
+    uint32_t        mStride         = 0;            // Bytes per line in the buffer
+
+    bool            mFrameBusy      = false;        // A flag telling us our buffer is in use
+    DisplayState    mRequestedState = DisplayState::NOT_VISIBLE;
+
+    std::mutex      mAccessLock;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
+
+#endif  // ANDROID_HARDWARE_EVS_V1_0_EVSDISPLAY_H
diff --git a/evs/1.0/default/EvsEnumerator.cpp b/evs/1.0/default/EvsEnumerator.cpp
new file mode 100644
index 0000000..9f38041
--- /dev/null
+++ b/evs/1.0/default/EvsEnumerator.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.evs@1.0-service"
+
+#include "EvsEnumerator.h"
+#include "EvsCamera.h"
+#include "EvsDisplay.h"
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+
+EvsEnumerator::EvsEnumerator() {
+    ALOGD("EvsEnumerator created");
+
+    // Add sample camera data to our list of cameras
+    // NOTE:  The id strings trigger special initialization inside the EvsCamera constructor
+    mCameraList.emplace_back( new EvsCamera(EvsCamera::kCameraName_Backup),    false );
+    mCameraList.emplace_back( new EvsCamera("LaneView"),                       false );
+    mCameraList.emplace_back( new EvsCamera(EvsCamera::kCameraName_RightTurn), false );
+}
+
+// Methods from ::android::hardware::evs::V1_0::IEvsEnumerator follow.
+Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb)  {
+    ALOGD("getCameraList");
+
+    const unsigned numCameras = mCameraList.size();
+
+    // Build up a packed array of CameraDesc for return
+    // NOTE:  Only has to live until the callback returns
+    std::vector<CameraDesc> descriptions;
+    descriptions.reserve(numCameras);
+    for (const auto& cam : mCameraList) {
+        descriptions.push_back( cam.pCamera->getDesc() );
+    }
+
+    // Encapsulate our camera descriptions in the HIDL vec type
+    hidl_vec<CameraDesc> hidlCameras(descriptions);
+
+    // Send back the results
+    ALOGD("reporting %zu cameras available", hidlCameras.size());
+    _hidl_cb(hidlCameras);
+
+    // HIDL convention says we return Void if we sent our result back via callback
+    return Void();
+}
+
+Return<void> EvsEnumerator::openCamera(const hidl_string& cameraId,
+                                             openCamera_cb callback) {
+    ALOGD("openCamera");
+
+    // Find the named camera
+    CameraRecord *pRecord = nullptr;
+    for (auto &&cam : mCameraList) {
+        if (cam.pCamera->getDesc().cameraId == cameraId) {
+            // Found a match!
+            pRecord = &cam;
+            break;
+        }
+    }
+
+    if (!pRecord) {
+        ALOGE("Requested camera %s not found", cameraId.c_str());
+        callback(nullptr);
+    }
+    else if (pRecord->inUse) {
+        ALOGE("Cannot open camera %s which is already in use", cameraId.c_str());
+        callback(nullptr);
+    }
+    else {
+        /* TODO(b/33492405):  Do this, When HIDL can give us back a recognizable pointer
+        pRecord->inUse = true;
+         */
+        callback(pRecord->pCamera);
+    }
+
+    return Void();
+}
+
+Return<void> EvsEnumerator::closeCamera(const ::android::sp<IEvsCamera>& camera) {
+    ALOGD("closeCamera");
+
+    if (camera == nullptr) {
+        ALOGE("Ignoring call to closeCamera with null camera pointer");
+    }
+    else {
+        // Make sure the camera has stopped streaming
+        camera->stopVideoStream();
+
+        /* TODO(b/33492405):  Do this, When HIDL can give us back a recognizable pointer
+        pRecord->inUse = false;
+         */
+    }
+
+    return Void();
+}
+
+Return<void> EvsEnumerator::openDisplay(openDisplay_cb callback) {
+    ALOGD("openDisplay");
+
+    // If we already have a display active, then this request must be denied
+    if (mActiveDisplay != nullptr) {
+        ALOGW("Rejecting openDisplay request the display is already in use.");
+        callback(nullptr);
+    }
+    else {
+        // Create a new display interface and return it
+        mActiveDisplay = new EvsDisplay();
+        ALOGD("Returning new EvsDisplay object %p", mActiveDisplay.get());
+        callback(mActiveDisplay);
+    }
+
+    return Void();
+}
+
+Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay>& display) {
+    ALOGD("closeDisplay");
+
+    if (mActiveDisplay == nullptr) {
+        ALOGE("Ignoring closeDisplay when display is not active");
+    }
+    else if (display == nullptr) {
+        ALOGE("Ignoring closeDisplay with null display pointer");
+    }
+    else {
+        // Drop the active display
+        // TODO(b/33492405):  When HIDL provides recognizable pointers, add validation here.
+        mActiveDisplay = nullptr;
+    }
+
+    return Void();
+}
+
+
+// TODO(b/31632518):  Need to get notification when our client dies so we can close the camera.
+// As possible work around would be to give the client a HIDL object to exclusively hold
+// and use it's destructor to perform some work in the server side.
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
diff --git a/evs/1.0/default/EvsEnumerator.h b/evs/1.0/default/EvsEnumerator.h
new file mode 100644
index 0000000..69caa17
--- /dev/null
+++ b/evs/1.0/default/EvsEnumerator.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_EVS_V1_0_EVSCAMERAENUMERATOR_H
+#define ANDROID_HARDWARE_EVS_V1_0_EVSCAMERAENUMERATOR_H
+
+#include <android/hardware/evs/1.0/IEvsEnumerator.h>
+#include <android/hardware/evs/1.0/IEvsCamera.h>
+
+#include <list>
+
+#include "EvsCamera.h"
+
+namespace android {
+namespace hardware {
+namespace evs {
+namespace V1_0 {
+namespace implementation {
+
+class EvsEnumerator : public IEvsEnumerator {
+public:
+    // Methods from ::android::hardware::evs::V1_0::IEvsEnumerator follow.
+    Return<void> getCameraList(getCameraList_cb _hidl_cb)  override;
+    Return<void> openCamera(const hidl_string& cameraId, openCamera_cb callback)  override;
+    Return<void> closeCamera(const ::android::sp<IEvsCamera>& carCamera)  override;
+    Return<void> openDisplay(openDisplay_cb callback)  override;
+    Return<void> closeDisplay(const ::android::sp<IEvsDisplay>& display)  override;
+
+    // Implementation details
+    EvsEnumerator();
+
+private:
+    struct CameraRecord {
+        sp<EvsCamera>   pCamera;
+        bool            inUse;
+        CameraRecord(EvsCamera* p, bool b) : pCamera(p), inUse(b) {}
+    };
+    std::list<CameraRecord> mCameraList;
+
+    sp<IEvsDisplay>         mActiveDisplay;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace evs
+} // namespace hardware
+} // namespace android
+
+#endif  // ANDROID_HARDWARE_EVS_V1_0_EVSCAMERAENUMERATOR_H
diff --git a/evs/1.0/default/ServiceNames.h b/evs/1.0/default/ServiceNames.h
new file mode 100644
index 0000000..d20a37f
--- /dev/null
+++ b/evs/1.0/default/ServiceNames.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+const static char kEnumeratorServiceName[] = "EvsEnumeratorHw-Mock";
diff --git a/evs/1.0/default/android.hardware.evs@1.0-service.rc b/evs/1.0/default/android.hardware.evs@1.0-service.rc
new file mode 100644
index 0000000..be7c9f9
--- /dev/null
+++ b/evs/1.0/default/android.hardware.evs@1.0-service.rc
@@ -0,0 +1,4 @@
+service evs-hal-1-0 /system/bin/hw/android.hardware.evs@1.0-service
+    class hal
+    user cameraserver
+    group camera
diff --git a/evs/1.0/default/service.cpp b/evs/1.0/default/service.cpp
new file mode 100644
index 0000000..6ab2975
--- /dev/null
+++ b/evs/1.0/default/service.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.evs@1.0-service"
+
+#include <unistd.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Log.h>
+
+#include "ServiceNames.h"
+#include "EvsEnumerator.h"
+#include "EvsDisplay.h"
+
+
+// libhwbinder:
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
+
+// Generated HIDL files
+using android::hardware::evs::V1_0::IEvsEnumerator;
+using android::hardware::evs::V1_0::IEvsDisplay;
+
+// The namespace in which all our implementation code lives
+using namespace android::hardware::evs::V1_0::implementation;
+using namespace android;
+
+
+int main() {
+    ALOGI("EVS Hardware Enumerator service is starting");
+    android::sp<IEvsEnumerator> service = new EvsEnumerator();
+
+    // Register our service -- if somebody is already registered by our name,
+    // they will be killed (their thread pool will throw an exception).
+    status_t status = service->registerAsService(kEnumeratorServiceName);
+    if (status == OK) {
+        ALOGD("%s is ready.", kEnumeratorServiceName);
+
+        // Set thread pool size to ensure the API is not called in parallel.
+        // By setting the size to zero, the main thread will be the only one
+        // serving requests once we "joinThreadPool".
+        ProcessState::self()->setThreadPoolMaxThreadCount(0);
+
+        // Note:  We don't start the thread pool because it'll add at least one (default)
+        //        thread to it, which we don't want.  See b/31226656
+        // ProcessState::self()->startThreadPool();
+
+        // Send this main thread to become a permanent part of the thread pool.
+        // This bumps up the thread count by 1 (from zero in this case).
+        // This is not expected to return.
+        IPCThreadState::self()->joinThreadPool();
+    } else {
+        ALOGE("Could not register service %s (%d).", kEnumeratorServiceName, status);
+    }
+
+    // In normal operation, we don't expect the thread pool to exit
+    ALOGE("EVS Hardware Enumerator is shutting down");
+    return 1;
+}
diff --git a/evs/1.0/types.hal b/evs/1.0/types.hal
new file mode 100644
index 0000000..e0051e1
--- /dev/null
+++ b/evs/1.0/types.hal
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.evs@1.0;
+
+
+/*
+ * Bit flags indicating suggested uses for a given EVS camera
+ *
+ * The values in the UsageHint bit field provide a generic expression of how a
+ * given camera is intended to be used. The values for these flags support
+ * existing use cases, and are used by the default EVS application to select
+ * appropriate cameras for display based on observed vehicle state (such as
+ * turn signal activation or selection of reverse gear). When implementing
+ * their own specialized EVS Applications, OEMs are free to use these flags
+ * and/or the opaque vendor_flags to drive their own vehicle specific logic.
+ */
+enum UsageHint : uint32_t {
+    USAGE_HINT_REVERSE      = 0x00000001,
+    USAGE_HINT_LEFT_TURN    = 0x00000002,
+    USAGE_HINT_RIGHT_TURN   = 0x00000004,
+    // remaining bits are reserved for future use
+};
+
+
+/*
+ * Structure describing the basic properties of an EVS camera
+ *
+ * The HAL is responsible for filling out this structure for each
+ * EVS camera in the system. Attention should be given to the field
+ * of view, direction of view, and location parameters as these may
+ * be used to (if available) to project overlay graphics into the
+ * scene by an EVS application.
+ * Any of these values for which the HAL does not have reasonable values
+ * should be set to ZERO.
+ */
+struct CameraDesc {
+    string      cameraId;
+    UsageHint   hints;                  // Bit flags (legal to | values together) (TODO: b/31702236)
+    uint32_t    vendorFlags;            // Opaque value from driver
+    uint32_t    defaultHorResolution;   // Units of pixels
+    uint32_t    defaultVerResolution;   // Units of pixels
+};
+
+
+/*
+ * Structure describing the basic properties of an EVS display
+ *
+ * The HAL is responsible for filling out this structure to describe
+ * the EVS display. As an implementation detail, this may be a physical
+ * display or a virtual display that is overlaid or mixed with another
+ * presentation device.
+ */
+struct DisplayDesc {
+    string      displayId;
+    uint32_t    vendorFlags;                // Opaque value from driver
+    uint32_t    defaultHorResolution;       // Units of pixels
+    uint32_t    defaultVerResolution;       // Units of pixels
+};
+
+
+/*
+ * States for control of the EVS display
+ *
+ * The DisplayInfo structure describes the basic properties of an EVS display. Any EVS
+ * implementation is required to have one. The HAL is responsible for filling out this
+ * structure to describe the EVS display. As an implementation detail, this may be a
+ * physical display or a virtual display that is overlaid or mixed with another
+ * presentation device.
+ */
+enum DisplayState : uint32_t {
+    NOT_VISIBLE = 0,        // Display is inhibited
+    VISIBLE_ON_NEXT_FRAME,  // Will become visible with next frame
+    VISIBLE,                // Display is currently active
+    NUM_STATES              // Must be last
+};
+
+
+/* Error codes used in EVS HAL interface. */
+/* TODO:  Adopt a common set of function return codes */
+enum EvsResult : uint32_t {
+    OK = 0,
+    INVALID_ARG,
+    STREAM_ALREADY_RUNNING,
+    BUFFER_NOT_AVAILABLE,
+};
\ No newline at end of file
diff --git a/evs/Android.bp b/evs/Android.bp
new file mode 100644
index 0000000..ba90f2c
--- /dev/null
+++ b/evs/Android.bp
@@ -0,0 +1,5 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+    "1.0/default",
+]
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 9726c3a..67ff353 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -40,11 +40,11 @@
     /*
      * The following formats use a 16bit float per color component.
      */
-    RGBA_FP16          = 0x10,
-    RGBX_FP16          = 0x11,
+    RGBA_FP16          = 0x16,
+    RGBX_FP16          = 0x17,
 
     /*
-     * 0x100 - 0x1FF
+     * 0x101 - 0x1FF
      *
      * This range is reserved for pixel formats that are specific to the HAL
      * implementation.  Implementations can use any value in this range to
@@ -422,9 +422,10 @@
     FLEX_RGBA_8888 = 0x2A,
 
     /* Legacy formats (deprecated), used by ImageFormat.java */
-    YCBCR_422_SP       = 0x10, // NV16
-    YCRCB_420_SP       = 0x11, // NV21
-    YCBCR_422_I        = 0x14, // YUY2
+    YCBCR_422_SP       = 0x10,  // NV16
+    YCRCB_420_SP       = 0x11,  // NV21
+    YCBCR_422_I        = 0x14,  // YUY2
+    JPEG               = 0x100,
 };
 
 /**
diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp
index 60e8f8e..a98801c 100644
--- a/light/2.0/Android.bp
+++ b/light/2.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.light.vts.driver@2.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.light@2.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+    srcs: [
+        "types.hal",
+        "ILight.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/types.vts.cpp",
+        "android/hardware/light/2.0/Light.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.light.vts.driver@2.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.light@2.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+    srcs: [
+        "types.hal",
+        "ILight.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/types.vts.h",
+        "android/hardware/light/2.0/Light.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.light.vts.driver@2.0",
+    generated_sources: ["android.hardware.light.vts.driver@2.0_genc++"],
+    generated_headers: ["android.hardware.light.vts.driver@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.light.vts.driver@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.light@2.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/light/2.0/vts/Android.mk b/light/2.0/vts/Android.mk
index 0df4772..089503b 100644
--- a/light/2.0/vts/Android.mk
+++ b/light/2.0/vts/Android.mk
@@ -16,34 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Light v2.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_light@2.0
-
-LOCAL_SRC_FILES := \
-    Light.vts \
-    types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-    android.hardware.light@2.0 \
-    libbase \
-    libutils \
-    libcutils \
-    liblog \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    libprotobuf-cpp-full \
-    libvts_common \
-    libvts_datatype \
-    libvts_measurement \
-    libvts_multidevice_proto
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/light/2.0/vts/functional/Android.bp b/light/2.0/vts/functional/Android.bp
index edb5ca9..889457f 100644
--- a/light/2.0/vts/functional/Android.bp
+++ b/light/2.0/vts/functional/Android.bp
@@ -20,6 +20,7 @@
     srcs: ["light_hidl_hal_test.cpp"],
     shared_libs: [
         "libbase",
+        "libhidlbase",
         "liblog",
         "libutils",
         "android.hardware.light@2.0",
diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp
index b56ffeb..c80ebf8 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.memtrack.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.memtrack@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+    srcs: [
+        "types.hal",
+        "IMemtrack.hal",
+    ],
+    out: [
+        "android/hardware/memtrack/1.0/types.vts.cpp",
+        "android/hardware/memtrack/1.0/Memtrack.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.memtrack.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.memtrack@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+    srcs: [
+        "types.hal",
+        "IMemtrack.hal",
+    ],
+    out: [
+        "android/hardware/memtrack/1.0/types.vts.h",
+        "android/hardware/memtrack/1.0/Memtrack.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.memtrack.vts.driver@1.0",
+    generated_sources: ["android.hardware.memtrack.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.memtrack.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.memtrack.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.memtrack@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk
index 8a5ceb1..4a5ca4f 100644
--- a/memtrack/1.0/vts/Android.mk
+++ b/memtrack/1.0/vts/Android.mk
@@ -16,36 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for memtrack v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_memtrack@1.0
-
-LOCAL_SRC_FILES := \
-  Memtrack.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.memtrack@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for memtrack.
 include $(CLEAR_VARS)
 
diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp
index 518b8e3..930fb14 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -62,3 +62,65 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.nfc.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "types.hal",
+        "INfc.hal",
+        "INfcClientCallback.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/types.vts.cpp",
+        "android/hardware/nfc/1.0/Nfc.vts.cpp",
+        "android/hardware/nfc/1.0/NfcClientCallback.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.nfc.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.nfc@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "types.hal",
+        "INfc.hal",
+        "INfcClientCallback.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/types.vts.h",
+        "android/hardware/nfc/1.0/Nfc.vts.h",
+        "android/hardware/nfc/1.0/NfcClientCallback.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.nfc.vts.driver@1.0",
+    generated_sources: ["android.hardware.nfc.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.nfc.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.nfc.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.nfc@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/nfc/1.0/vts/Android.mk b/nfc/1.0/vts/Android.mk
index b008b63..e7dec14 100644
--- a/nfc/1.0/vts/Android.mk
+++ b/nfc/1.0/vts/Android.mk
@@ -5,7 +5,7 @@
 # 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
+#      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,
@@ -16,37 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Nfc v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_nfc@1.0
-
-LOCAL_SRC_FILES := \
-  Nfc.vts \
-  NfcClientCallback.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.nfc@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for Nfc.
 include $(CLEAR_VARS)
 
diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp
index 3503f0e..2eb9e34 100644
--- a/power/1.0/Android.bp
+++ b/power/1.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.power.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+    srcs: [
+        "types.hal",
+        "IPower.hal",
+    ],
+    out: [
+        "android/hardware/power/1.0/types.vts.cpp",
+        "android/hardware/power/1.0/Power.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.power.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+    srcs: [
+        "types.hal",
+        "IPower.hal",
+    ],
+    out: [
+        "android/hardware/power/1.0/types.vts.h",
+        "android/hardware/power/1.0/Power.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.power.vts.driver@1.0",
+    generated_sources: ["android.hardware.power.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.power.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.power.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.power@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/power/1.0/vts/Android.mk b/power/1.0/vts/Android.mk
index 4164baf..db7e98e 100644
--- a/power/1.0/vts/Android.mk
+++ b/power/1.0/vts/Android.mk
@@ -16,36 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Power v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_power@1.0
-
-LOCAL_SRC_FILES := \
-  Power.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.power@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for power.
 include $(CLEAR_VARS)
 
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
index 7fbe117..994febe 100644
--- a/sensors/1.0/default/Android.bp
+++ b/sensors/1.0/default/Android.bp
@@ -8,7 +8,6 @@
         "libhardware",
         "libhwbinder",
         "libbase",
-        "libcutils",
         "libutils",
         "libhidlbase",
         "libhidltransport",
@@ -16,6 +15,7 @@
     ],
     static_libs: [
         "android.hardware.sensors@1.0-convert",
+        "multihal",
     ],
     local_include_dirs: ["include/sensors"],
 }
@@ -30,7 +30,6 @@
         "libhardware",
         "libhwbinder",
         "libbase",
-        "libcutils",
         "libutils",
         "libhidlbase",
         "libhidltransport",
diff --git a/sensors/1.0/default/Android.mk b/sensors/1.0/default/Android.mk
index b2b2c60..f37c3cb 100644
--- a/sensors/1.0/default/Android.mk
+++ b/sensors/1.0/default/Android.mk
@@ -5,21 +5,21 @@
 LOCAL_MODULE := android.hardware.sensors@1.0-service
 LOCAL_INIT_RC := android.hardware.sensors@1.0-service.rc
 LOCAL_SRC_FILES := \
-	service.cpp \
+        service.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
-	liblog \
-	libcutils \
-	libdl \
-	libbase \
-	libutils \
-	libhardware_legacy \
-	libhardware \
+        liblog \
+        libcutils \
+        libdl \
+        libbase \
+        libutils \
+        libhardware_legacy \
+        libhardware \
 
 LOCAL_SHARED_LIBRARIES += \
-	libhwbinder \
-	libhidlbase \
-	libhidltransport \
-	android.hardware.sensors@1.0 \
+        libhwbinder \
+        libhidlbase \
+        libhidltransport \
+        android.hardware.sensors@1.0 \
 
 include $(BUILD_EXECUTABLE)
diff --git a/sensors/1.0/default/Sensors.cpp b/sensors/1.0/default/Sensors.cpp
index ef052c3..c76369f 100644
--- a/sensors/1.0/default/Sensors.cpp
+++ b/sensors/1.0/default/Sensors.cpp
@@ -15,17 +15,29 @@
  */
 
 #include "Sensors.h"
-
 #include "convert.h"
+#include "multihal.h"
 
 #include <android-base/logging.h>
 
+#include <sys/stat.h>
+
 namespace android {
 namespace hardware {
 namespace sensors {
 namespace V1_0 {
 namespace implementation {
 
+/*
+ * If a multi-hal configuration file exists in the proper location,
+ * return true indicating we need to use multi-hal functionality.
+ */
+static bool UseMultiHal() {
+    const std::string& name = MULTI_HAL_CONFIG_FILE_PATH;
+    struct stat buffer;
+    return (stat (name.c_str(), &buffer) == 0);
+}
+
 static Result ResultFromStatus(status_t err) {
     switch (err) {
         case OK:
@@ -43,10 +55,14 @@
     : mInitCheck(NO_INIT),
       mSensorModule(nullptr),
       mSensorDevice(nullptr) {
-    status_t err = hw_get_module(
+    status_t err = OK;
+    if (UseMultiHal()) {
+        mSensorModule = ::get_multi_hal_module_info();
+    } else {
+        err = hw_get_module(
             SENSORS_HARDWARE_MODULE_ID,
             (hw_module_t const **)&mSensorModule);
-
+    }
     if (mSensorModule == NULL) {
         err = UNKNOWN_ERROR;
     }
diff --git a/tests/bar/1.0/default/Bar.cpp b/tests/bar/1.0/default/Bar.cpp
index a9b6c25..a750fe4 100644
--- a/tests/bar/1.0/default/Bar.cpp
+++ b/tests/bar/1.0/default/Bar.cpp
@@ -122,36 +122,10 @@
     return Void();
 }
 
-// TODO: remove after b/33173166 is fixed.
-struct Simple : public ISimple {
-    Simple(int32_t cookie)
-        : mCookie(cookie) {
-    }
-
-    Return<int32_t> getCookie() override {
-        return mCookie;
-    }
-
-private:
-    int32_t mCookie;
-};
-
-// TODO: use _hidl_cb(in) after b/33173166 is fixed.
 Return<void> Bar::haveAVectorOfGenericInterfaces(
         const hidl_vec<sp<android::hidl::base::V1_0::IBase> > &in,
         haveAVectorOfGenericInterfaces_cb _hidl_cb) {
-    // _hidl_cb(in);
-    hidl_vec<sp<android::hidl::base::V1_0::IBase> > out;
-    out.resize(in.size());
-    for (size_t i = 0; i < in.size(); ++i) {
-        sp<ISimple> s = ISimple::castFrom(in[i]);
-        if (s.get() == nullptr) {
-            out[i] = new Simple(-1);
-        } else {
-            out[i] = new Simple(s->getCookie());
-        }
-    }
-    _hidl_cb(out);
+    _hidl_cb(in);
 
     return Void();
 }
diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp
index b887f16..c73ab42 100644
--- a/thermal/1.0/Android.bp
+++ b/thermal/1.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.thermal.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.thermal@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+    srcs: [
+        "types.hal",
+        "IThermal.hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.0/types.vts.cpp",
+        "android/hardware/thermal/1.0/Thermal.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.thermal.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.thermal@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+    srcs: [
+        "types.hal",
+        "IThermal.hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.0/types.vts.h",
+        "android/hardware/thermal/1.0/Thermal.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.thermal.vts.driver@1.0",
+    generated_sources: ["android.hardware.thermal.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.thermal.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.thermal.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.thermal@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp
index 53b1ce8..b6dc3b1 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -62,3 +62,65 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.tv.cec.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tv.cec@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "types.hal",
+        "IHdmiCec.hal",
+        "IHdmiCecCallback.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/types.vts.cpp",
+        "android/hardware/tv/cec/1.0/HdmiCec.vts.cpp",
+        "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tv.cec.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tv.cec@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "types.hal",
+        "IHdmiCec.hal",
+        "IHdmiCecCallback.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/types.vts.h",
+        "android/hardware/tv/cec/1.0/HdmiCec.vts.h",
+        "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.tv.cec.vts.driver@1.0",
+    generated_sources: ["android.hardware.tv.cec.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.tv.cec.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.tv.cec.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.tv.cec@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/tv/cec/1.0/vts/Android.mk b/tv/cec/1.0/vts/Android.mk
index 2666ca6..a7eeb33 100644
--- a/tv/cec/1.0/vts/Android.mk
+++ b/tv/cec/1.0/vts/Android.mk
@@ -16,42 +16,10 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for TvCec v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_tv_hdmi_cec@1.0
-
-LOCAL_SRC_FILES := \
-  HdmiCec.vts \
-  HdmiCecCallback.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.cec@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
 # build VTS profiler for HdmiCec
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := libvts_profiler_hidl_tv_hdmi_cec@1.0
+LOCAL_MODULE := libvts_profiler_hidl_tv_cec@1.0
 
 LOCAL_SRC_FILES := \
   HdmiCec.vts \
@@ -86,7 +54,7 @@
 # build VTS profiler for HdmiCecCallback
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := libvts_profiler_hidl_tv_hdmi_cec_callback_@1.0
+LOCAL_MODULE := libvts_profiler_hidl_tv_cec_callback_@1.0
 
 LOCAL_SRC_FILES := \
   HdmiCecCallback.vts \
@@ -115,4 +83,6 @@
 
 LOCAL_MULTILIB := both
 
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tv/cec/1.0/vts/functional/Android.mk b/tv/cec/1.0/vts/functional/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/Android.mk b/tv/cec/1.0/vts/functional/vts/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/hal/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/__init__.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/__init__.py
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/__init__.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/__init__.py
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk
new file mode 100644
index 0000000..ece38d7
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := TvCecHidlTest
+VTS_CONFIG_SRC_DIR := testcases/hal/tv_cec/hidl/host
+include test/vts/tools/build/Android.host_config.mk
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/AndroidTest.xml b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/AndroidTest.xml
new file mode 100644
index 0000000..79584d5
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS Tv Input HIDL HAL's host-side test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="push-group" value="HidlHalTest.push" />
+        <option name="push" value="spec/hardware/interfaces/tv/cec/1.0/vts/HdmiCec.vts->/data/local/tmp/spec/HdmiCec.vts" />
+        <option name="push" value="spec/hardware/interfaces/tv/cec/1.0/vts/HdmiCecCallback.vts->/data/local/tmp/spec/HdmiCecCallback.vts" />
+        <option name="push" value="spec/hardware/interfaces/tv/cec/1.0/vts/types.vts->/data/local/tmp/spec/types.vts" />
+        <option name="cleanup" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer">
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="TvCecHidlTest" />
+        <option name="test-case-path" value="vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
new file mode 100644
index 0000000..ba062d9
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+import logging
+
+from vts.runners.host import asserts
+from vts.runners.host import base_test_with_webdb
+from vts.runners.host import const
+from vts.runners.host import test_runner
+from vts.utils.python.controllers import android_device
+
+
+class TvCecHidlTest(base_test_with_webdb.BaseTestWithWebDbClass):
+    """Host testcase class for the TV HDMI_CEC HIDL HAL."""
+
+    def setUpClass(self):
+        """Creates a mirror and init tv hdmi cec hal service."""
+        self.dut = self.registerController(android_device)[0]
+
+        self.dut.shell.InvokeTerminal("one")
+        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
+
+        self.dut.hal.InitHidlHal(target_type="tv_cec",
+                                 target_basepaths=["/system/lib64"],
+                                 target_version=1.0,
+                                 target_package="android.hardware.tv.cec",
+                                 target_component_name="IHdmiCec",
+                                 bits=64)
+
+    def testGetCecVersion1(self):
+        """A simple test case which queries the cec version."""
+        logging.info('DIR HAL %s', dir(self.dut.hal))
+        version = self.dut.hal.tv_cec.getCecVersion()
+        logging.info('Cec version: %s', version)
+
+
+if __name__ == "__main__":
+    test_runner.main()
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/__init__.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/__init__.py
diff --git a/vehicle/2.0/Android.bp b/vehicle/2.0/Android.bp
index 6c96d3f..571ef2b 100644
--- a/vehicle/2.0/Android.bp
+++ b/vehicle/2.0/Android.bp
@@ -62,3 +62,65 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vehicle.vts.driver@2.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vehicle@2.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "types.hal",
+        "IVehicle.hal",
+        "IVehicleCallback.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/types.vts.cpp",
+        "android/hardware/vehicle/2.0/Vehicle.vts.cpp",
+        "android/hardware/vehicle/2.0/VehicleCallback.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vehicle.vts.driver@2.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vehicle@2.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "types.hal",
+        "IVehicle.hal",
+        "IVehicleCallback.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/types.vts.h",
+        "android/hardware/vehicle/2.0/Vehicle.vts.h",
+        "android/hardware/vehicle/2.0/VehicleCallback.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vehicle.vts.driver@2.0",
+    generated_sources: ["android.hardware.vehicle.vts.driver@2.0_genc++"],
+    generated_headers: ["android.hardware.vehicle.vts.driver@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.vehicle.vts.driver@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vehicle@2.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/vehicle/2.0/default/android.hardware.vehicle@2.0-service.rc b/vehicle/2.0/default/android.hardware.vehicle@2.0-service.rc
index 7c96da6..622cb1e 100644
--- a/vehicle/2.0/default/android.hardware.vehicle@2.0-service.rc
+++ b/vehicle/2.0/default/android.hardware.vehicle@2.0-service.rc
@@ -1,4 +1,4 @@
 service vehicle-hal-2.0 /system/bin/hw/android.hardware.vehicle@2.0-service
     class hal
-    user system
+    user vehicle_network
     group system
diff --git a/vehicle/2.0/vts/Android.mk b/vehicle/2.0/vts/Android.mk
index 8370067..b7f185d 100644
--- a/vehicle/2.0/vts/Android.mk
+++ b/vehicle/2.0/vts/Android.mk
@@ -16,38 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Vehicle v2.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vehicle@2.0
-
-LOCAL_SRC_FILES := \
-  Vehicle.vts \
-  VehicleCallback.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.vehicle@2.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
 # build profiler for Vehicle.
 include $(CLEAR_VARS)
 
diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp
index 75a3bfa..ec97cfb 100644
--- a/vibrator/1.0/Android.bp
+++ b/vibrator/1.0/Android.bp
@@ -54,3 +54,61 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vibrator.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vibrator@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+    srcs: [
+        "types.hal",
+        "IVibrator.hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.0/types.vts.cpp",
+        "android/hardware/vibrator/1.0/Vibrator.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vibrator.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vibrator@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+    srcs: [
+        "types.hal",
+        "IVibrator.hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.0/types.vts.h",
+        "android/hardware/vibrator/1.0/Vibrator.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vibrator.vts.driver@1.0",
+    generated_sources: ["android.hardware.vibrator.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.vibrator.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.vibrator.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vibrator@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/vibrator/1.0/vts/Android.mk b/vibrator/1.0/vts/Android.mk
index 080eb88..084dcf7 100644
--- a/vibrator/1.0/vts/Android.mk
+++ b/vibrator/1.0/vts/Android.mk
@@ -16,36 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Vibrator v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vibrator@1.0
-
-LOCAL_SRC_FILES := \
-  Vibrator.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.vibrator@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for vibrator.
 include $(CLEAR_VARS)
 
diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp
index 57c9257..240b7ad 100644
--- a/vr/1.0/Android.bp
+++ b/vr/1.0/Android.bp
@@ -50,3 +50,57 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vr.vts.driver@1.0_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vr@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+    srcs: [
+        "IVr.hal",
+    ],
+    out: [
+        "android/hardware/vr/1.0/Vr.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vr.vts.driver@1.0_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.vr@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/vr/1.0/ $(genDir)/android/hardware/vr/1.0/",
+    srcs: [
+        "IVr.hal",
+    ],
+    out: [
+        "android/hardware/vr/1.0/Vr.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vr.vts.driver@1.0",
+    generated_sources: ["android.hardware.vr.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.vr.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.vr.vts.driver@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "libvts_common",
+        "libvts_datatype",
+        "libvts_measurement",
+        "libvts_multidevice_proto",
+        "libcamera_metadata",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vr@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/vr/1.0/vts/Android.mk b/vr/1.0/vts/Android.mk
index 12f0175..ac1cad5 100644
--- a/vr/1.0/vts/Android.mk
+++ b/vr/1.0/vts/Android.mk
@@ -16,35 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Vr v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_vr@1.0
-
-LOCAL_SRC_FILES := \
-  Vr.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.vr@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
 # build profiler for Vr.
 include $(CLEAR_VARS)
 
@@ -76,3 +47,5 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+# include hidl test makefiles
+include $(LOCAL_PATH)/functional/vts/testcases/hal/vr/hidl/Android.mk
diff --git a/vr/1.0/vts/functional/Android.bp b/vr/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..2929fe7
--- /dev/null
+++ b/vr/1.0/vts/functional/Android.bp
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "vr_hidl_hal_test",
+    gtest: true,
+    srcs: ["vr_hidl_hal_test.cpp"],
+    shared_libs: [
+        "liblog",
+        "libhidlbase",
+        "libutils",
+        "android.hardware.vr@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/vr/1.0/vts/functional/vr_hidl_hal_test.cpp b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
new file mode 100644
index 0000000..85ecbdc
--- /dev/null
+++ b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "vr_hidl_hal_test"
+#include <android-base/logging.h>
+#include <android/hardware/vr/1.0/IVr.h>
+#include <android/log.h>
+#include <gtest/gtest.h>
+#include <hardware/vr.h>
+
+using ::android::hardware::vr::V1_0::IVr;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+#define VR_SERVICE_NAME "vr"
+
+// The main test class for VR HIDL HAL.
+class VrHidlTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    // currently test passthrough mode only
+    vr = IVr::getService(VR_SERVICE_NAME, true);
+    ASSERT_NE(vr, nullptr);
+    ASSERT_TRUE(!vr->isRemote());
+  }
+
+  void TearDown() override {}
+
+  sp<IVr> vr;
+};
+
+
+// A class for test environment setup (kept since this file is a template).
+class VrHidlEnvironment : public ::testing::Environment {
+ public:
+  void SetUp() {}
+  void TearDown() {}
+
+ private:
+};
+
+// Sanity check that Vr::init does not crash.
+TEST_F(VrHidlTest, Init) {
+  EXPECT_TRUE(vr->init().isOk());
+}
+
+// Sanity check Vr::setVrMode is able to enable and disable VR mode.
+TEST_F(VrHidlTest, SetVrMode) {
+  EXPECT_TRUE(vr->init().isOk());
+  EXPECT_TRUE(vr->setVrMode(true).isOk());
+  EXPECT_TRUE(vr->setVrMode(false).isOk());
+}
+
+// Sanity check that Vr::init and Vr::setVrMode can be used in any order.
+TEST_F(VrHidlTest, ReInit) {
+  EXPECT_TRUE(vr->init().isOk());
+  EXPECT_TRUE(vr->setVrMode(true).isOk());
+  EXPECT_TRUE(vr->init().isOk());
+  EXPECT_TRUE(vr->setVrMode(false).isOk());
+  EXPECT_TRUE(vr->init().isOk());
+  EXPECT_TRUE(vr->setVrMode(false).isOk());
+}
+
+int main(int argc, char **argv) {
+  ::testing::AddGlobalTestEnvironment(new VrHidlEnvironment);
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
diff --git a/vr/1.0/vts/functional/vts/Android.mk b/vr/1.0/vts/functional/vts/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/vr/1.0/vts/functional/vts/testcases/Android.mk b/vr/1.0/vts/functional/vts/testcases/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/Android.mk b/vr/1.0/vts/functional/vts/testcases/hal/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/Android.mk b/vr/1.0/vts/functional/vts/testcases/hal/vr/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/__init__.py b/vr/1.0/vts/functional/vts/testcases/hal/vr/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/__init__.py
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/Android.mk b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/__init__.py b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/__init__.py
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/Android.mk b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/Android.mk
new file mode 100644
index 0000000..691d1a4
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VrHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/vr/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..a29c23b
--- /dev/null
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VR HIDL HAL's target-side test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="push-group" value="HidlHalTest.push" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VrHidlTargetTest" />
+        <option name="binary-test-sources" value="
+            _32bit::DATA/nativetest/vr_hidl_hal_test/vr_hidl_hal_test,
+            _64bit::DATA/nativetest64/vr_hidl_hal_test/vr_hidl_hal_test,
+            "/>
+        <option name="binary-test-type" value="gtest" />
+        <option name="test-timeout" value="1m" />
+    </test>
+</configuration>
+
diff --git a/vr/Android.bp b/vr/Android.bp
index ba90f2c..ed19a37 100644
--- a/vr/Android.bp
+++ b/vr/Android.bp
@@ -2,4 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/vts/functional",
 ]
diff --git a/wifi/1.0/Android.mk b/wifi/1.0/Android.mk
index ee7f980..bb8d144 100644
--- a/wifi/1.0/Android.mk
+++ b/wifi/1.0/Android.mk
@@ -1556,6 +1556,63 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (StaRoamingCapabilities)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingCapabilities.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingCapabilities
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (StaRoamingConfig)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingConfig.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingConfig
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (StaRoamingState)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingState.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (StaScanData)
 #
 GEN := $(intermediates)/android/hardware/wifi/V1_0/StaScanData.java
@@ -1822,177 +1879,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (WifiDebugRingEntryConnectivityEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryConnectivityEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryConnectivityEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlv)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlv.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventTlv
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlvType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlvType.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventTlvType
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventType.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventType
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryFlags)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryFlags.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryFlags
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryHeader)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryHeader.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryHeader
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryPowerEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryPowerEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryPowerEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryVendorData)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryVendorData.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryVendorData
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryWakelockEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryWakelockEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryWakelockEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (WifiDebugRxPacketFate)
 #
 GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRxPacketFate.java
@@ -4041,6 +3927,63 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (StaRoamingCapabilities)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingCapabilities.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingCapabilities
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (StaRoamingConfig)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingConfig.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingConfig
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (StaRoamingState)
+#
+GEN := $(intermediates)/android/hardware/wifi/V1_0/StaRoamingState.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.wifi@1.0::types.StaRoamingState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (StaScanData)
 #
 GEN := $(intermediates)/android/hardware/wifi/V1_0/StaScanData.java
@@ -4307,177 +4250,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (WifiDebugRingEntryConnectivityEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryConnectivityEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryConnectivityEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlv)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlv.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventTlv
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventTlvType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventTlvType.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventTlvType
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryEventType)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryEventType.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryEventType
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryFlags)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryFlags.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryFlags
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryHeader)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryHeader.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryHeader
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryPowerEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryPowerEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryPowerEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryVendorData)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryVendorData.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryVendorData
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (WifiDebugRingEntryWakelockEvent)
-#
-GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRingEntryWakelockEvent.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.wifi@1.0::types.WifiDebugRingEntryWakelockEvent
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (WifiDebugRxPacketFate)
 #
 GEN := $(intermediates)/android/hardware/wifi/V1_0/WifiDebugRxPacketFate.java
diff --git a/wifi/1.0/IWifiChip.hal b/wifi/1.0/IWifiChip.hal
index 051a088..d790404 100644
--- a/wifi/1.0/IWifiChip.hal
+++ b/wifi/1.0/IWifiChip.hal
@@ -137,32 +137,36 @@
     /**
      * Memory dump of Firmware.
      */
-    DEBUG_MEMORY_FIRMWARE_DUMP_SUPPORTED = 1 << 0,
+    DEBUG_MEMORY_FIRMWARE_DUMP = 1 << 0,
     /**
      * Memory dump of Driver.
      */
-    DEBUG_MEMORY_DRIVER_DUMP_SUPPORTED = 1 << 1,
+    DEBUG_MEMORY_DRIVER_DUMP = 1 << 1,
     /**
      * Connectivity events reported via debug ring buffer.
      */
-    DEBUG_RING_BUFFER_CONNECT_EVENT_SUPPORTED = 1 << 2,
+    DEBUG_RING_BUFFER_CONNECT_EVENT = 1 << 2,
     /**
      * Power events reported via debug ring buffer.
      */
-    DEBUG_RING_BUFFER_POWER_EVENT_SUPPORTED = 1 << 3,
+    DEBUG_RING_BUFFER_POWER_EVENT = 1 << 3,
     /**
      * Wakelock events reported via debug ring buffer.
      */
-    DEBUG_RING_BUFFER_WAKELOCK_EVENT_SUPPORTED = 1 << 4,
+    DEBUG_RING_BUFFER_WAKELOCK_EVENT = 1 << 4,
     /**
      * Vendor data reported via debug ring buffer.
      * This mostly contains firmware event logs.
      */
-    DEBUG_RING_BUFFER_VENDOR_DATA_SUPPORTED = 1 << 5,
+    DEBUG_RING_BUFFER_VENDOR_DATA = 1 << 5,
     /**
      * Host wake reasons stats collection.
      */
     DEBUG_HOST_WAKE_REASON_STATS = 1 << 6,
+    /**
+     * Error alerts.
+     */
+    DEBUG_ERROR_ALERTS = 1 << 7
   };
 
   /**
@@ -288,7 +292,7 @@
    * Create an AP iface on the chip.
    *
    * Depending on the mode the chip is configured in, the interface creation
-   * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+   * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
    * allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP
    * type.
    *
@@ -348,7 +352,7 @@
    * Create a NAN iface on the chip.
    *
    * Depending on the mode the chip is configured in, the interface creation
-   * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+   * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
    * allowed (specified in |ChipIfaceCombination|) number of ifaces of the NAN
    * type.
    *
@@ -408,7 +412,7 @@
    * Create a P2P iface on the chip.
    *
    * Depending on the mode the chip is configured in, the interface creation
-   * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+   * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
    * allowed (specified in |ChipIfaceCombination|) number of ifaces of the P2P
    * type.
    *
@@ -468,7 +472,7 @@
    * Create an STA iface on the chip.
    *
    * Depending on the mode the chip is configured in, the interface creation
-   * may fail (code: |ERROR_NOT_SUPPORTED|) if we've already reached the maximum
+   * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum
    * allowed (specified in |ChipIfaceCombination|) number of ifaces of the STA
    * type.
    *
@@ -554,7 +558,7 @@
    *   ring. The vebose level for each ring buffer can be specified in this API.
    * - During wifi operations, driver must periodically report per ring data to
    *   framework by invoking the
-   *   |IWifiChipEventCallback.onDebugRingBuffer<Type>EntriesAvailable| callback.
+   *   |IWifiChipEventCallback.onDebugRingBufferDataAvailable| callback.
    * - When capturing a bug report, framework must indicate to driver that all
    *   the data has to be uploaded urgently by calling
    *   |forceDumpToDebugRingBuffer|.
@@ -640,4 +644,21 @@
    */
   getDebugHostWakeReasonStats()
       generates (WifiStatus status, WifiDebugHostWakeReasonStats stats);
+
+  /**
+   * API to enable/disable alert notifications from the chip.
+   * These alerts must be used to notify framework of any fatal error events
+   * that the chip encounters via |IWifiChipEventCallback.onDebugErrorAlert| method.
+   * Must fail if |ChipCapabilityMask.DEBUG_ERROR_ALERTS| is not set.
+   *
+   * @param enable true to enable, false to disable.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  enableDebugErrorAlerts(bool enable) generates (WifiStatus status);
 };
diff --git a/wifi/1.0/IWifiChipEventCallback.hal b/wifi/1.0/IWifiChipEventCallback.hal
index 292b10f..0d9e329 100644
--- a/wifi/1.0/IWifiChipEventCallback.hal
+++ b/wifi/1.0/IWifiChipEventCallback.hal
@@ -20,7 +20,7 @@
   /**
    * Callback indicating that the chip has been reconfigured successfully. At
    * this point the interfaces available in the mode must be able to be
-   * configured. When this is called any previous interface indexes will be
+   * configured. When this is called any previous iface objects must be
    * considered invalid.
    *
    * @param modeId The mode that the chip switched to, corresponding to the id
@@ -29,6 +29,32 @@
   oneway onChipReconfigured(ChipModeId modeId);
 
   /**
+   * Callback indicating that a chip reconfiguration failed. This is a fatal
+   * error and any iface objects available previously must be considered
+   * invalid. The client can attempt to recover by trying to reconfigure the
+   * chip again using |IWifiChip.configureChip|.
+   *
+   * @param status Failure reason code.
+   */
+  oneway onChipReconfigureFailure(WifiStatus status);
+
+  /**
+   * Callback indicating that a new iface has been added to the chip.
+   *
+   * @param type Type of iface added.
+   * @param name Name of iface added.
+   */
+  oneway onIfaceAdded(IfaceType type, string name);
+
+  /**
+   * Callback indicating that an existing iface has been removed from the chip.
+   *
+   * @param type Type of iface removed.
+   * @param name Name of iface removed.
+   */
+  oneway onIfaceRemoved(IfaceType type, string name);
+
+  /**
    * Callbacks for reporting debug ring buffer data.
    *
    * The ring buffer data collection is event based:
@@ -48,26 +74,19 @@
    * @return status Status of the corresponding ring buffer. This should
    *         contain the name of the ring buffer on which the data is
    *         available.
-   * @return entries Vector of debug ring buffer data entries. These
-   *         should be parsed based on the type of entry.
+   * @return data Raw bytes of data sent by the driver. Must be dumped
+   *         out to a bugreport and post processed.
    */
-  /** Connectivity event data callback */
-  oneway onDebugRingBufferConnectivityEventEntriesAvailable(
-      WifiDebugRingBufferStatus status,
-      vec<WifiDebugRingEntryConnectivityEvent> entries);
+  oneway onDebugRingBufferDataAvailable(
+      WifiDebugRingBufferStatus status, vec<uint8_t> data);
 
-  /** Power event data callback */
-  oneway onDebugRingBufferPowerEventEntriesAvailable(
-      WifiDebugRingBufferStatus status,
-      vec<WifiDebugRingEntryPowerEvent> entries);
-
-  /** Wakelock event data callback */
-  oneway onDebugRingBufferWakelockEventEntriesAvailable(
-      WifiDebugRingBufferStatus status,
-      vec<WifiDebugRingEntryWakelockEvent> entries);
-
-  /** Vendor data event data callback */
-  oneway onDebugRingBufferVendorDataEntriesAvailable(
-      WifiDebugRingBufferStatus status,
-      vec<WifiDebugRingEntryVendorData> entries);
+  /**
+   * Callback indicating that the chip has encountered a fatal error.
+   * Client must not attempt to parse either the errorCode or debugData.
+   * Must only be captured in a bugreport.
+   *
+   * @param errorCode Vendor defined error code.
+   * @param debugData Vendor defined data used for debugging.
+   */
+  oneway onDebugErrorAlert(int32_t errorCode, vec<uint8_t> debugData);
 };
diff --git a/wifi/1.0/IWifiStaIface.hal b/wifi/1.0/IWifiStaIface.hal
index 7b514a7..98af043 100644
--- a/wifi/1.0/IWifiStaIface.hal
+++ b/wifi/1.0/IWifiStaIface.hal
@@ -49,9 +49,41 @@
      */
     RSSI_MONITOR = 1 << 3,
     /**
-     * Tracks connection packets' fate.
+     * If set indicates that the roaming API's are supported.
      */
-    DEBUG_PACKET_FATE_SUPPORTED = 1 << 4
+    CONTROL_ROAMING = 1 << 4,
+    /**
+     * If set indicates support for Probe IE white listing.
+     */
+    PROBE_IE_WHITELIST =  1 << 5,
+    /**
+     * If set indicates support for MAC & Probe Sequence Number randomization.
+     */
+    SCAN_RAND = 1 << 6,
+    /**
+     * Support for 5 GHz Band.
+     */
+    STA_5G = 1 << 7,
+    /**
+     * Support for GAS/ANQP queries.
+     */
+    HOTSPOT = 1 << 8,
+    /**
+     * Support for Preferred Network Offload.
+     */
+    PNO = 1 << 9,
+    /**
+     * Support for Tunneled Direct Link Setup.
+     */
+    TDLS = 1 << 10,
+    /**
+     * Support for Tunneled Direct Link Setup off channel.
+     */
+    TDLS_OFFCHANNEL = 1 << 11,
+    /**
+     * Support for tracking connection packets' fate.
+     */
+    DEBUG_PACKET_FATE = 1 << 12
   };
 
   /**
@@ -301,6 +333,52 @@
   stopRssiMonitoring(CommandId cmdId) generates (WifiStatus status);
 
   /**
+   * Get roaming control capabilities.
+   * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+   *
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   * @return caps Instance of |StaRoamingCapabilities|.
+   */
+  getRoamingCapabilities()
+      generates (WifiStatus status, StaRoamingCapabilities caps);
+
+  /**
+   * Configure roaming control parameters.
+   * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+   *
+   * @param config Instance of |StaRoamingConfig|.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  configureRoaming(StaRoamingConfig config) generates (WifiStatus status);
+
+  /**
+   * Set the roaming control state with the parameters configured
+   * using |configureRoaming|. Depending on the roaming state set, the
+   * driver/firmware would enable/disable control over roaming decisions.
+   * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+   *
+   * @param state State of the roaming control.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.ERROR_BUSY|,
+   *         |WifiStatusCode.ERROR_UNKNOWN|
+   */
+  setRoamingState(StaRoamingState state) generates (WifiStatus status);
+
+  /**
    * API to start packet fate monitoring.
    * - Once stared, monitoring must remain active until HAL is unloaded.
    * - When HAL is unloaded, all packet fate buffers must be cleared.
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index 61a2c2c..a94d812 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -31,15 +31,15 @@
   using HidlChipCaps = IWifiChip::ChipCapabilityMask;
   switch (feature) {
     case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED:
-      return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP_SUPPORTED;
+      return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP;
     case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED:
-      return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP_SUPPORTED;
+      return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP;
     case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED:
-      return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT_SUPPORTED;
+      return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT;
     case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED:
-      return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT_SUPPORTED;
+      return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT;
     case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED:
-      return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT_SUPPORTED;
+      return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT;
   };
   CHECK(false) << "Unknown legacy feature: " << feature;
   return {};
@@ -50,7 +50,7 @@
   using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
   switch (feature) {
     case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED:
-      return HidlStaIfaceCaps::DEBUG_PACKET_FATE_SUPPORTED;
+      return HidlStaIfaceCaps::DEBUG_PACKET_FATE;
   };
   CHECK(false) << "Unknown legacy feature: " << feature;
   return {};
@@ -66,6 +66,22 @@
       return HidlStaIfaceCaps::LINK_LAYER_STATS;
     case WIFI_FEATURE_RSSI_MONITOR:
       return HidlStaIfaceCaps::RSSI_MONITOR;
+    case WIFI_FEATURE_CONTROL_ROAMING:
+      return HidlStaIfaceCaps::CONTROL_ROAMING;
+    case WIFI_FEATURE_IE_WHITELIST:
+      return HidlStaIfaceCaps::PROBE_IE_WHITELIST;
+    case WIFI_FEATURE_SCAN_RAND:
+      return HidlStaIfaceCaps::SCAN_RAND;
+    case WIFI_FEATURE_INFRA_5G:
+      return HidlStaIfaceCaps::STA_5G;
+    case WIFI_FEATURE_HOTSPOT:
+      return HidlStaIfaceCaps::HOTSPOT;
+    case WIFI_FEATURE_PNO:
+      return HidlStaIfaceCaps::PNO;
+    case WIFI_FEATURE_TDLS:
+      return HidlStaIfaceCaps::TDLS;
+    case WIFI_FEATURE_TDLS_OFFCHANNEL:
+      return HidlStaIfaceCaps::TDLS_OFFCHANNEL;
   };
   CHECK(false) << "Unknown legacy feature: " << feature;
   return {};
@@ -87,10 +103,11 @@
       *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
     }
   }
-  // There is no flags for these 2 in the legacy feature set. Adding it to the
-  // set because all the current devices support it.
-  *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA_SUPPORTED;
+  // There are no flags for these 3 in the legacy feature set. Adding them to
+  // the set because all the current devices support it.
+  *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
   *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS;
+  *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS;
   return true;
 }
 
@@ -214,7 +231,15 @@
   }
   for (const auto feature : {WIFI_FEATURE_GSCAN,
                              WIFI_FEATURE_LINK_LAYER_STATS,
-                             WIFI_FEATURE_RSSI_MONITOR}) {
+                             WIFI_FEATURE_RSSI_MONITOR,
+                             WIFI_FEATURE_CONTROL_ROAMING,
+                             WIFI_FEATURE_IE_WHITELIST,
+                             WIFI_FEATURE_SCAN_RAND,
+                             WIFI_FEATURE_INFRA_5G,
+                             WIFI_FEATURE_HOTSPOT,
+                             WIFI_FEATURE_PNO,
+                             WIFI_FEATURE_TDLS,
+                             WIFI_FEATURE_TDLS_OFFCHANNEL}) {
     if (feature & legacy_feature_set) {
       *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
     }
@@ -669,6 +694,55 @@
   return true;
 }
 
+bool convertLegacyRoamingCapabilitiesToHidl(
+    const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+    StaRoamingCapabilities* hidl_caps) {
+  if (!hidl_caps) {
+    return false;
+  }
+  hidl_caps->maxBlacklistSize = legacy_caps.max_blacklist_size;
+  hidl_caps->maxWhitelistSize = legacy_caps.max_whitelist_size;
+  return true;
+}
+
+bool convertHidlRoamingConfigToLegacy(
+    const StaRoamingConfig& hidl_config,
+    legacy_hal::wifi_roaming_config* legacy_config) {
+  if (!legacy_config) {
+    return false;
+  }
+  if (hidl_config.bssidBlacklist.size() > MAX_BLACKLIST_BSSID ||
+      hidl_config.ssidWhitelist.size() > MAX_WHITELIST_SSID) {
+    return false;
+  }
+  legacy_config->num_blacklist_bssid = hidl_config.bssidBlacklist.size();
+  uint32_t i = 0;
+  for (const auto& bssid : hidl_config.bssidBlacklist) {
+    CHECK(bssid.size() == sizeof(legacy_hal::mac_addr));
+    memcpy(legacy_config->blacklist_bssid[i++], bssid.data(), bssid.size());
+  }
+  legacy_config->num_whitelist_ssid = hidl_config.ssidWhitelist.size();
+  i = 0;
+  for (const auto& ssid : hidl_config.ssidWhitelist) {
+    CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
+    legacy_config->whitelist_ssid[i].length = ssid.size();
+    memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size());
+    i++;
+  }
+  return true;
+}
+
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(
+    StaRoamingState state) {
+  switch (state) {
+    case StaRoamingState::ENABLED:
+      return legacy_hal::ROAMING_ENABLE;
+    case StaRoamingState::DISABLED:
+      return legacy_hal::ROAMING_DISABLE;
+  };
+  CHECK(false);
+}
+
 legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(
     NanPublishType type) {
   switch (type) {
diff --git a/wifi/1.0/default/hidl_struct_util.h b/wifi/1.0/default/hidl_struct_util.h
index 3ff94fd..9086666 100644
--- a/wifi/1.0/default/hidl_struct_util.h
+++ b/wifi/1.0/default/hidl_struct_util.h
@@ -39,6 +39,9 @@
 // Chip conversion methods.
 bool convertLegacyFeaturesToHidlChipCapabilities(
     uint32_t legacy_logger_feature_set, uint32_t* hidl_caps);
+bool convertLegacyDebugRingBufferStatusToHidl(
+    const legacy_hal::wifi_ring_buffer_status& legacy_status,
+    WifiDebugRingBufferStatus* hidl_status);
 bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
     const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
     std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
@@ -75,6 +78,14 @@
 bool convertLegacyLinkLayerStatsToHidl(
     const legacy_hal::LinkLayerStats& legacy_stats,
     StaLinkLayerStats* hidl_stats);
+bool convertLegacyRoamingCapabilitiesToHidl(
+    const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+    StaRoamingCapabilities* hidl_caps);
+bool convertHidlRoamingConfigToLegacy(
+    const StaRoamingConfig& hidl_config,
+    legacy_hal::wifi_roaming_config* legacy_config);
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(
+    StaRoamingState state);
 bool convertLegacyVectorOfDebugTxPacketFateToHidl(
     const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
     std::vector<WifiDebugTxPacketFateReport>* hidl_fates);
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
index d70f548..e15178d 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -25,12 +25,13 @@
 using android::sp;
 using android::hardware::hidl_vec;
 using android::hardware::hidl_string;
+using android::hardware::wifi::V1_0::ChipModeId;
 using android::hardware::wifi::V1_0::IWifiChip;
 using android::hardware::wifi::V1_0::IfaceType;
 
-constexpr uint32_t kStaChipModeId = 0;
-constexpr uint32_t kApChipModeId = 1;
-constexpr uint32_t kInvalidModeId = UINT32_MAX;
+constexpr ChipModeId kStaChipModeId = 0;
+constexpr ChipModeId kApChipModeId = 1;
+constexpr ChipModeId kInvalidModeId = UINT32_MAX;
 
 template <typename Iface>
 void invalidateAndClear(sp<Iface>& iface) {
@@ -56,7 +57,8 @@
       legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
       is_valid_(true),
-      current_mode_id_(kInvalidModeId) {}
+      current_mode_id_(kInvalidModeId),
+      debug_ring_buffer_cb_registered_(false) {}
 
 void WifiChip::invalidate() {
   invalidateAndRemoveAllIfaces();
@@ -69,6 +71,10 @@
   return is_valid_;
 }
 
+std::vector<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+  return event_callbacks_;
+}
+
 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
   return validateAndCall(this,
                          WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
@@ -100,7 +106,7 @@
                          hidl_status_cb);
 }
 
-Return<void> WifiChip::configureChip(uint32_t mode_id,
+Return<void> WifiChip::configureChip(ChipModeId mode_id,
                                      configureChip_cb hidl_status_cb) {
   return validateAndCall(this,
                          WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
@@ -319,6 +325,15 @@
                          hidl_status_cb);
 }
 
+Return<void> WifiChip::enableDebugErrorAlerts(
+    bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                         &WifiChip::enableDebugErrorAlertsInternal,
+                         hidl_status_cb,
+                         enable);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
   invalidateAndClear(ap_iface_);
   invalidateAndClear(nan_iface_);
@@ -389,7 +404,7 @@
           {sta_chip_mode, ap_chip_mode}};
 }
 
-WifiStatus WifiChip::configureChipInternal(uint32_t mode_id) {
+WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id) {
   if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
   }
@@ -397,40 +412,18 @@
     LOG(DEBUG) << "Already in the specified mode " << mode_id;
     return createWifiStatus(WifiStatusCode::SUCCESS);
   }
-  // If the chip is already configured in a different mode, stop
-  // the legacy HAL and then start it after firmware mode change.
-  if (current_mode_id_ != kInvalidModeId) {
-    invalidateAndRemoveAllIfaces();
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop([]() {});
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-      LOG(ERROR) << "Failed to stop legacy HAL: "
-                 << legacyErrorToString(legacy_status);
-      // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
-      return createWifiStatusFromLegacyError(legacy_status);
+  WifiStatus status = handleChipConfiguration(mode_id);
+  if (status.code != WifiStatusCode::SUCCESS) {
+    for (const auto& callback : event_callbacks_) {
+      callback->onChipReconfigureFailure(status);
     }
-  }
-  bool success;
-  if (mode_id == kStaChipModeId) {
-    success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
-  } else {
-    success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
-  }
-  if (!success) {
-    // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
-    return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-  }
-  legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
-  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-    LOG(ERROR) << "Failed to start legacy HAL: "
-               << legacyErrorToString(legacy_status);
-    // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
-    return createWifiStatusFromLegacyError(legacy_status);
+    return status;
   }
   for (const auto& callback : event_callbacks_) {
     callback->onChipReconfigured(mode_id);
   }
   current_mode_id_ = mode_id;
-  return createWifiStatus(WifiStatusCode::SUCCESS);
+  return status;
 }
 
 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
@@ -506,6 +499,9 @@
   }
   std::string ifname = legacy_hal_.lock()->getApIfaceName();
   ap_iface_ = new WifiApIface(ifname, legacy_hal_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceAdded(IfaceType::AP, ifname);
+  }
   return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
 }
 
@@ -531,6 +527,9 @@
     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
   }
   invalidateAndClear(ap_iface_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceRemoved(IfaceType::AP, ifname);
+  }
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
@@ -542,6 +541,9 @@
   }
   std::string ifname = legacy_hal_.lock()->getNanIfaceName();
   nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceAdded(IfaceType::NAN, ifname);
+  }
   return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
 }
 
@@ -567,6 +569,9 @@
     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
   }
   invalidateAndClear(nan_iface_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceRemoved(IfaceType::NAN, ifname);
+  }
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
@@ -578,6 +583,9 @@
   }
   std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
   p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceAdded(IfaceType::P2P, ifname);
+  }
   return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
 }
 
@@ -603,6 +611,9 @@
     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
   }
   invalidateAndClear(p2p_iface_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceRemoved(IfaceType::P2P, ifname);
+  }
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
@@ -612,6 +623,9 @@
   }
   std::string ifname = legacy_hal_.lock()->getStaIfaceName();
   sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceAdded(IfaceType::STA, ifname);
+  }
   return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
 }
 
@@ -637,6 +651,9 @@
     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
   }
   invalidateAndClear(sta_iface_);
+  for (const auto& callback : event_callbacks_) {
+    callback->onIfaceRemoved(IfaceType::STA, ifname);
+  }
   return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
@@ -671,6 +688,10 @@
     WifiDebugRingBufferVerboseLevel verbose_level,
     uint32_t max_interval_in_sec,
     uint32_t min_data_size_in_bytes) {
+  WifiStatus status = registerDebugRingBufferCallback();
+  if (status.code != WifiStatusCode::SUCCESS) {
+    return status;
+  }
   legacy_hal::wifi_error legacy_status =
       legacy_hal_.lock()->startRingBufferLogging(
           ring_name,
@@ -684,6 +705,10 @@
 
 WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
     const hidl_string& ring_name) {
+  WifiStatus status = registerDebugRingBufferCallback();
+  if (status.code != WifiStatusCode::SUCCESS) {
+    return status;
+  }
   legacy_hal::wifi_error legacy_status =
       legacy_hal_.lock()->getRingBufferData(ring_name);
   return createWifiStatusFromLegacyError(legacy_status);
@@ -706,6 +731,94 @@
   return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
 }
 
+WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
+  legacy_hal::wifi_error legacy_status;
+  if (enable) {
+    android::wp<WifiChip> weak_ptr_this(this);
+    const auto& on_alert_callback = [weak_ptr_this](
+        int32_t error_code, std::vector<uint8_t> debug_data) {
+      const auto shared_ptr_this = weak_ptr_this.promote();
+      if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+        LOG(ERROR) << "Callback invoked on an invalid object";
+        return;
+      }
+      for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+        callback->onDebugErrorAlert(error_code, debug_data);
+      }
+    };
+    legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
+        on_alert_callback);
+  } else {
+    legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler();
+  }
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
+  // If the chip is already configured in a different mode, stop
+  // the legacy HAL and then start it after firmware mode change.
+  if (current_mode_id_ != kInvalidModeId) {
+    invalidateAndRemoveAllIfaces();
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop([]() {});
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+      LOG(ERROR) << "Failed to stop legacy HAL: "
+                 << legacyErrorToString(legacy_status);
+      return createWifiStatusFromLegacyError(legacy_status);
+    }
+  }
+  bool success;
+  if (mode_id == kStaChipModeId) {
+    success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
+  } else {
+    success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
+  }
+  if (!success) {
+    return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+  }
+  legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
+  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+    LOG(ERROR) << "Failed to start legacy HAL: "
+               << legacyErrorToString(legacy_status);
+    return createWifiStatusFromLegacyError(legacy_status);
+  }
+  return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiChip::registerDebugRingBufferCallback() {
+  if (debug_ring_buffer_cb_registered_) {
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+  }
+
+  android::wp<WifiChip> weak_ptr_this(this);
+  const auto& on_ring_buffer_data_callback = [weak_ptr_this](
+      const std::string& /* name */,
+      const std::vector<uint8_t>& data,
+      const legacy_hal::wifi_ring_buffer_status& status) {
+    const auto shared_ptr_this = weak_ptr_this.promote();
+    if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+      LOG(ERROR) << "Callback invoked on an invalid object";
+      return;
+    }
+    WifiDebugRingBufferStatus hidl_status;
+    if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
+            status, &hidl_status)) {
+      LOG(ERROR) << "Error converting ring buffer status";
+      return;
+    }
+    for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+      callback->onDebugRingBufferDataAvailable(hidl_status, data);
+    }
+  };
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->registerRingBufferCallbackHandler(
+          on_ring_buffer_data_callback);
+
+  if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+    debug_ring_buffer_cb_registered_ = true;
+  }
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace wifi
diff --git a/wifi/1.0/default/wifi_chip.h b/wifi/1.0/default/wifi_chip.h
index 5e7a0c3..938b180 100644
--- a/wifi/1.0/default/wifi_chip.h
+++ b/wifi/1.0/default/wifi_chip.h
@@ -62,6 +62,7 @@
   // valid before processing them.
   void invalidate();
   bool isValid();
+  std::vector<sp<IWifiChipEventCallback>> getEventCallbacks();
 
   // HIDL methods exposed.
   Return<void> getId(getId_cb hidl_status_cb) override;
@@ -70,7 +71,7 @@
       registerEventCallback_cb hidl_status_cb) override;
   Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
   Return<void> getAvailableModes(getAvailableModes_cb hidl_status_cb) override;
-  Return<void> configureChip(uint32_t mode_id,
+  Return<void> configureChip(ChipModeId mode_id,
                              configureChip_cb hidl_status_cb) override;
   Return<void> getMode(getMode_cb hidl_status_cb) override;
   Return<void> requestChipDebugInfo(
@@ -119,6 +120,8 @@
       forceDumpToDebugRingBuffer_cb hidl_status_cb) override;
   Return<void> getDebugHostWakeReasonStats(
       getDebugHostWakeReasonStats_cb hidl_status_cb) override;
+  Return<void> enableDebugErrorAlerts(
+      bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
 
  private:
   void invalidateAndRemoveAllIfaces();
@@ -129,7 +132,7 @@
       const sp<IWifiChipEventCallback>& event_callback);
   std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
   std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal();
-  WifiStatus configureChipInternal(uint32_t mode_id);
+  WifiStatus configureChipInternal(ChipModeId mode_id);
   std::pair<WifiStatus, uint32_t> getModeInternal();
   std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
   requestChipDebugInfoInternal();
@@ -168,6 +171,10 @@
   WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name);
   std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
   getDebugHostWakeReasonStatsInternal();
+  WifiStatus enableDebugErrorAlertsInternal(bool enable);
+
+  WifiStatus handleChipConfiguration(ChipModeId mode_id);
+  WifiStatus registerDebugRingBufferCallback();
 
   ChipId chip_id_;
   std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
@@ -180,6 +187,10 @@
   std::vector<sp<WifiRttController>> rtt_controllers_;
   bool is_valid_;
   uint32_t current_mode_id_;
+  // The legacy ring buffer callback API has only a global callback
+  // registration mechanism. Use this to check if we have already
+  // registered a callback.
+  bool debug_ring_buffer_cb_registered_;
 
   DISALLOW_COPY_AND_ASSIGN(WifiChip);
 };
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index d7a1f15..3b99e60 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -121,6 +121,18 @@
   }
 }
 
+// Callback to be invoked for error alert indication.
+std::function<void(wifi_request_id, char*, int, int)>
+    on_error_alert_internal_callback;
+void onErrorAlert(wifi_request_id id,
+                  char* buffer,
+                  int buffer_size,
+                  int err_code) {
+  if (on_error_alert_internal_callback) {
+    on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
+  }
+}
+
 // Callback to be invoked for rtt results results.
 std::function<void(
     wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
@@ -613,6 +625,25 @@
   return status;
 }
 
+std::pair<wifi_error, wifi_roaming_capabilities>
+WifiLegacyHal::getRoamingCapabilities() {
+  wifi_roaming_capabilities caps;
+  wifi_error status = global_func_table_.wifi_get_roaming_capabilities(
+      wlan_interface_handle_, &caps);
+  return {status, caps};
+}
+
+wifi_error WifiLegacyHal::enableFirmwareRoaming(fw_roaming_state_t state) {
+  return global_func_table_.wifi_enable_firmware_roaming(wlan_interface_handle_,
+                                                         state);
+}
+
+wifi_error WifiLegacyHal::configureRoaming(const wifi_roaming_config& config) {
+  wifi_roaming_config config_internal = config;
+  return global_func_table_.wifi_configure_roaming(wlan_interface_handle_,
+                                                   &config_internal);
+}
+
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
   uint32_t supported_features;
   wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
@@ -710,15 +741,27 @@
       on_user_data_callback(ring_name, buffer_vector, *status);
     }
   };
-  return global_func_table_.wifi_set_log_handler(
+  wifi_error status = global_func_table_.wifi_set_log_handler(
       0, wlan_interface_handle_, {onRingBufferData});
+  if (status != WIFI_SUCCESS) {
+    on_ring_buffer_data_internal_callback = nullptr;
+  }
+  return status;
+}
+
+wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler() {
+  if (!on_ring_buffer_data_internal_callback) {
+    return WIFI_ERROR_NOT_AVAILABLE;
+  }
+  on_ring_buffer_data_internal_callback = nullptr;
+  return global_func_table_.wifi_reset_log_handler(0, wlan_interface_handle_);
 }
 
 std::pair<wifi_error, std::vector<wifi_ring_buffer_status>>
 WifiLegacyHal::getRingBuffersStatus() {
   std::vector<wifi_ring_buffer_status> ring_buffers_status;
   ring_buffers_status.resize(kMaxRingBuffers);
-  uint32_t num_rings = 0;
+  uint32_t num_rings = kMaxRingBuffers;
   wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
       wlan_interface_handle_, &num_rings, ring_buffers_status.data());
   CHECK(num_rings <= kMaxRingBuffers);
@@ -745,6 +788,38 @@
                                                ring_name_internal.data());
 }
 
+wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
+    const on_error_alert_callback& on_user_alert_callback) {
+  if (on_error_alert_internal_callback) {
+    return WIFI_ERROR_NOT_AVAILABLE;
+  }
+  on_error_alert_internal_callback = [on_user_alert_callback](
+      wifi_request_id id, char* buffer, int buffer_size, int err_code) {
+    if (buffer) {
+      CHECK(id == 0);
+      on_user_alert_callback(
+          err_code,
+          std::vector<uint8_t>(
+              reinterpret_cast<uint8_t*>(buffer),
+              reinterpret_cast<uint8_t*>(buffer) + buffer_size));
+    }
+  };
+  wifi_error status = global_func_table_.wifi_set_alert_handler(
+      0, wlan_interface_handle_, {onErrorAlert});
+  if (status != WIFI_SUCCESS) {
+    on_error_alert_internal_callback = nullptr;
+  }
+  return status;
+}
+
+wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler() {
+  if (!on_error_alert_internal_callback) {
+    return WIFI_ERROR_NOT_AVAILABLE;
+  }
+  on_error_alert_internal_callback = nullptr;
+  return global_func_table_.wifi_reset_alert_handler(0, wlan_interface_handle_);
+}
+
 wifi_error WifiLegacyHal::startRttRangeRequest(
     wifi_request_id id,
     const std::vector<wifi_rtt_config>& rtt_configs,
@@ -1095,6 +1170,7 @@
   on_link_layer_stats_result_internal_callback = nullptr;
   on_rssi_threshold_breached_internal_callback = nullptr;
   on_ring_buffer_data_internal_callback = nullptr;
+  on_error_alert_internal_callback = nullptr;
   on_rtt_results_internal_callback = nullptr;
   on_nan_notify_response_user_callback = nullptr;
   on_nan_event_publish_terminated_user_callback = nullptr;
diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h
index 07bc93a..b585314 100644
--- a/wifi/1.0/default/wifi_legacy_hal.h
+++ b/wifi/1.0/default/wifi_legacy_hal.h
@@ -118,6 +118,9 @@
                        const std::vector<uint8_t>&,
                        const wifi_ring_buffer_status&)>;
 
+// Callback for alerts.
+using on_error_alert_callback =
+    std::function<void(int32_t, const std::vector<uint8_t>&)>;
 /**
  * Class that encapsulates all legacy HAL interactions.
  * This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -178,6 +181,9 @@
                                  const on_rssi_threshold_breached_callback&
                                      on_threshold_breached_callback);
   wifi_error stopRssiMonitoring(wifi_request_id id);
+  std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities();
+  wifi_error enableFirmwareRoaming(fw_roaming_state_t state);
+  wifi_error configureRoaming(const wifi_roaming_config& config);
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
@@ -186,6 +192,7 @@
   std::pair<wifi_error, WakeReasonStats> getWakeReasonStats();
   wifi_error registerRingBufferCallbackHandler(
       const on_ring_buffer_data_callback& on_data_callback);
+  wifi_error deregisterRingBufferCallbackHandler();
   std::pair<wifi_error, std::vector<wifi_ring_buffer_status>>
   getRingBuffersStatus();
   wifi_error startRingBufferLogging(const std::string& ring_name,
@@ -193,6 +200,9 @@
                                     uint32_t max_interval_sec,
                                     uint32_t min_data_size);
   wifi_error getRingBufferData(const std::string& ring_name);
+  wifi_error registerErrorAlertCallbackHandler(
+      const on_error_alert_callback& on_alert_callback);
+  wifi_error deregisterErrorAlertCallbackHandler();
   // RTT functions.
   wifi_error startRttRangeRequest(
       wifi_request_id id,
diff --git a/wifi/1.0/default/wifi_sta_iface.cpp b/wifi/1.0/default/wifi_sta_iface.cpp
index c91a99b..e48978e 100644
--- a/wifi/1.0/default/wifi_sta_iface.cpp
+++ b/wifi/1.0/default/wifi_sta_iface.cpp
@@ -186,6 +186,32 @@
                          cmd_id);
 }
 
+Return<void> WifiStaIface::getRoamingCapabilities(
+    getRoamingCapabilities_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::getRoamingCapabilitiesInternal,
+                         hidl_status_cb);
+}
+
+Return<void> WifiStaIface::configureRoaming(
+    const StaRoamingConfig& config, configureRoaming_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::configureRoamingInternal,
+                         hidl_status_cb,
+                         config);
+}
+
+Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
+                                           setRoamingState_cb hidl_status_cb) {
+  return validateAndCall(this,
+                         WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                         &WifiStaIface::setRoamingStateInternal,
+                         hidl_status_cb,
+                         state);
+}
+
 Return<void> WifiStaIface::startDebugPacketFateMonitoring(
     startDebugPacketFateMonitoring_cb hidl_status_cb) {
   return validateAndCall(this,
@@ -436,6 +462,42 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
+std::pair<WifiStatus, StaRoamingCapabilities>
+WifiStaIface::getRoamingCapabilitiesInternal() {
+  legacy_hal::wifi_error legacy_status;
+  legacy_hal::wifi_roaming_capabilities legacy_caps;
+  std::tie(legacy_status, legacy_caps) =
+      legacy_hal_.lock()->getRoamingCapabilities();
+  if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+    return {createWifiStatusFromLegacyError(legacy_status), {}};
+  }
+  StaRoamingCapabilities hidl_caps;
+  if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps,
+                                                                &hidl_caps)) {
+    return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+  }
+  return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+WifiStatus WifiStaIface::configureRoamingInternal(
+    const StaRoamingConfig& config) {
+  legacy_hal::wifi_roaming_config legacy_config;
+  if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config,
+                                                          &legacy_config)) {
+    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+  }
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->configureRoaming(legacy_config);
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
+  legacy_hal::wifi_error legacy_status =
+      legacy_hal_.lock()->enableFirmwareRoaming(
+          hidl_struct_util::convertHidlRoamingStateToLegacy(state));
+  return createWifiStatusFromLegacyError(legacy_status);
+}
+
 WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
   legacy_hal::wifi_error legacy_status =
       legacy_hal_.lock()->startPktFateMonitoring();
diff --git a/wifi/1.0/default/wifi_sta_iface.h b/wifi/1.0/default/wifi_sta_iface.h
index b4f2721..90126cd 100644
--- a/wifi/1.0/default/wifi_sta_iface.h
+++ b/wifi/1.0/default/wifi_sta_iface.h
@@ -77,6 +77,12 @@
       startRssiMonitoring_cb hidl_status_cb) override;
   Return<void> stopRssiMonitoring(
       uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
+  Return<void> getRoamingCapabilities(
+      getRoamingCapabilities_cb hidl_status_cb) override;
+  Return<void> configureRoaming(const StaRoamingConfig& config,
+                                configureRoaming_cb hidl_status_cb) override;
+  Return<void> setRoamingState(StaRoamingState state,
+                               setRoamingState_cb hidl_status_cb) override;
   Return<void> startDebugPacketFateMonitoring(
       startDebugPacketFateMonitoring_cb hidl_status_cb) override;
   Return<void> stopDebugPacketFateMonitoring(
@@ -111,6 +117,10 @@
                                          int32_t max_rssi,
                                          int32_t min_rssi);
   WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
+  std::pair<WifiStatus, StaRoamingCapabilities>
+  getRoamingCapabilitiesInternal();
+  WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
+  WifiStatus setRoamingStateInternal(StaRoamingState state);
   WifiStatus startDebugPacketFateMonitoringInternal();
   WifiStatus stopDebugPacketFateMonitoringInternal();
   std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
diff --git a/wifi/1.0/default/wifi_status_util.cpp b/wifi/1.0/default/wifi_status_util.cpp
index 9a7ad0d..518032f 100644
--- a/wifi/1.0/default/wifi_status_util.cpp
+++ b/wifi/1.0/default/wifi_status_util.cpp
@@ -83,6 +83,9 @@
       return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
                               desc + ", out of memory");
 
+    case legacy_hal::WIFI_ERROR_BUSY:
+      return createWifiStatus(WifiStatusCode::ERROR_BUSY);
+
     case legacy_hal::WIFI_ERROR_NONE:
       return createWifiStatus(WifiStatusCode::SUCCESS, desc);
 
diff --git a/wifi/1.0/types.hal b/wifi/1.0/types.hal
index 8dd33b5..76c89e3 100644
--- a/wifi/1.0/types.hal
+++ b/wifi/1.0/types.hal
@@ -32,6 +32,7 @@
   ERROR_NOT_AVAILABLE,
   ERROR_NOT_STARTED,
   ERROR_INVALID_ARGS,
+  ERROR_BUSY,
   ERROR_UNKNOWN
 };
 
@@ -213,7 +214,7 @@
  * TODO(b/32159498): Move to a separate nan_types.hal.
  */
 /**
- * Parameters to specify the APF capability of this iface.
+ * Parameters to specify the APF capabilities of this iface.
  */
 struct StaApfPacketFilterCapabilities {
   /**
@@ -227,7 +228,7 @@
 };
 
 /**
- * Parameters to specify the Background Scan capability of this iface.
+ * Parameters to specify the Background Scan capabilities of this iface.
  */
 struct StaBackgroundScanCapabilities {
   /**
@@ -515,6 +516,50 @@
 };
 
 /**
+ * Structure describing the roaming control capabilities supported.
+ */
+struct StaRoamingCapabilities {
+  /**
+   * Maximum number of BSSID's that may be blacklisted.
+   */
+  uint32_t maxBlacklistSize;
+  /**
+   * Maximum number of SSID's that may be whitelisted.
+   */
+  uint32_t maxWhitelistSize;
+};
+
+/**
+ * Structure describing the roaming control configuration.
+ */
+struct StaRoamingConfig {
+  /**
+   * List of BSSID's that are blacklisted for roaming.
+   */
+  vec<Bssid> bssidBlacklist;
+  /**
+   * List of SSID's that are whitelisted for roaming.
+   */
+  vec<Ssid> ssidWhitelist;
+};
+
+/**
+ * Enum describing the various states to set the roaming
+ * control to.
+ */
+enum StaRoamingState : uint8_t {
+  /**
+   * Driver/Firmware is allowed to perform roaming respecting
+   * the |StaRoamingConfig| parameters set using |configureRoaming|.
+   */
+  ENABLED = 0,
+  /**
+   * Driver/Firmware must not perform any roaming.
+   */
+  DISABLED = 1
+};
+
+/**
  * NAN specific types.
  * TODO(b/32159498): Move to a separate nan_types.hal.
  */
@@ -2314,468 +2359,6 @@
 typedef uint32_t WifiRingBufferId;
 
 /**
- * Mask of flags present in |WifiDebugRingEntryHeader.flags| field.
- */
-enum WifiDebugRingEntryFlags : uint8_t {
-  /**
-   * Set for binary entries
-   */
-  HAS_BINARY = 1 << 0,
-  /**
-   * Set if 64 bits timestamp is present
-   */
-  HAS_TIMESTAMP = 1 << 1,
-};
-
-/**
- * This structure represent an entry within a debug ring buffer.
- * Wifi driver are responsible to manage the debug ring buffer and write the
- * debug information into those buffer.
- *
- * In general, the debug entries can be used to store meaningful 802.11
- * information (SME, MLME, connection and packet statistics) as well as vendor
- * proprietary data that is specific to a specific driver or chipset.
- * Binary entries can be used so as to store packet data or vendor specific
- * information and will be treated as blobs of data by android framework.
- *
- * A user land process will be started by framework so as to periodically
- * retrieve the data logged by drivers into their debug ring buffer, store the
- * data into log files and include the logs into android bugreports.
- */
-struct WifiDebugRingEntryHeader {
-  /**
-   * The size of |payload| excluding the header.
-   */
-  uint16_t sizeInBytes;
-  /**
-   * Combination of |WifiDebugRingEntryFlags| values.
-   */
-  uint8_t flags;
-  /**
-   * Present if |HAS_TIMESTAMP| bit is set.
-   */
-  TimeStampInUs timestamp;
-};
-
-/**
- * Below event types are used for both the connect and power event
- * ring entries.
- */
-enum WifiDebugRingEntryEventType : uint16_t {
-  /**
-   * Driver receives association command from kernel.
-   */
-  ASSOCIATION_REQUESTED = 0,
-  AUTH_COMPLETE = 1,
-  ASSOC_COMPLETE = 2,
-  /**
-   * Firmware event indicating auth frames are sent.
-   */
-  FW_AUTH_STARTED = 3,
-  /**
-   * Firmware event indicating assoc frames are sent.
-   */
-  FW_ASSOC_STARTED = 4,
-  /**
-   * Firmware event indicating reassoc frames are sent.
-   */
-  FW_RE_ASSOC_STARTED = 5,
-  DRIVER_SCAN_REQUESTED = 6,
-  DRIVER_SCAN_RESULT_FOUND = 7,
-  DRIVER_SCAN_COMPLETE = 8,
-  BACKGROUND_SCAN_STARTED = 9,
-  BACKGROUND_SCAN_COMPLETE = 10,
-  DISASSOCIATION_REQUESTED = 11,
-  RE_ASSOCIATION_REQUESTED = 12,
-  ROAM_REQUESTED = 13,
-  /**
-   * Received beacon from AP (event enabled  only in verbose mode).
-   */
-  BEACON_RECEIVED = 14,
-  /**
-   * Firmware has triggered a roam scan (not g-scan).
-   */
-  ROAM_SCAN_STARTED = 15,
-  /**
-   * Firmware has completed a roam scan (not g-scan).
-   */
-  ROAM_SCAN_COMPLETE = 16,
-  /**
-   * Firmware has started searching for roam candidates (with reason =xx).
-   */
-  ROAM_SEARCH_STARTED = 17,
-  /**
-   * Firmware has stopped searching for roam candidates (with reason =xx).
-   */
-  ROAM_SEARCH_STOPPED = 18,
-  /**
-   * Received channel switch anouncement from AP.
-   */
-  CHANNEL_SWITCH_ANOUNCEMENT = 20,
-  /**
-   * Firmware start transmit eapol frame, with  EAPOL index 1-4.
-   */
-  FW_EAPOL_FRAME_TRANSMIT_START = 21,
-  /**
-   * Firmware gives up eapol frame, with rate, success/failure and number
-   * retries.
-   */
-  FW_EAPOL_FRAME_TRANSMIT_STOP = 22,
-  /**
-   * Kernel queue EAPOL for transmission  in driver with EAPOL index 1-4.
-   */
-  DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED = 23,
-  /**
-   * With rate, regardless of the fact that EAPOL frame is accepted or
-   * rejected by firmware.
-   */
-  FW_EAPOL_FRAME_RECEIVED = 24,
-  /**
-   * With rate, and eapol index, driver has received EAPOL frame and will
-   * queue it up to wpa_supplicant.
-   */
-  DRIVER_EAPOL_FRAME_RECEIVED = 26,
-  /**
-   * With success/failure, parameters
-   */
-  BLOCK_ACK_NEGOTIATION_COMPLETE = 27,
-  BT_COEX_BT_SCO_START = 28,
-  BT_COEX_BT_SCO_STOP = 29,
-  /**
-   * For paging/scan etc., when BT starts transmiting twice per BT slot.
-   */
-  BT_COEX_BT_SCAN_START = 30,
-  BT_COEX_BT_SCAN_STOP = 31,
-  BT_COEX_BT_HID_START = 32,
-  BT_COEX_BT_HID_STOP = 33,
-  /**
-   * Firmware sends auth frame in roaming to next candidate.
-   */
-  ROAM_AUTH_STARTED = 34,
-  /**
-   * Firmware receive auth confirm from ap
-   */
-  ROAM_AUTH_COMPLETE = 35,
-  /**
-   * Firmware sends assoc/reassoc frame in roaming to next candidate.
-   */
-  ROAM_ASSOC_STARTED = 36,
-  /**
-   * Firmware receive assoc/reassoc confirm from ap.
-   */
-  ROAM_ASSOC_COMPLETE = 37,
-  /**
-   * Firmware sends stop BACKGROUND_SCAN
-   */
-  BACKGROUND_SCAN_STOP = 38,
-  /**
-   * Firmware indicates BACKGROUND_SCAN scan cycle started.
-   */
-  BACKGROUND_SCAN_CYCLE_STARTED = 39,
-  /**
-   * Firmware indicates BACKGROUND_SCAN scan cycle completed.
-   */
-  BACKGROUND_SCAN_CYCLE_COMPLETED = 40,
-  /**
-   * Firmware indicates BACKGROUND_SCAN scan start for a particular bucket.
-   */
-  BACKGROUND_SCAN_BUCKET_STARTED = 41,
-  /**
-   * Firmware indicates BACKGROUND_SCAN scan completed for for a particular bucket.
-   */
-  BACKGROUND_SCAN_BUCKET_COMPLETED = 42,
-  /**
-   * Event received from firmware about BACKGROUND_SCAN scan results being available.
-   */
-  BACKGROUND_SCAN_RESULTS_AVAILABLE = 43,
-  /**
-   * Event received from firmware with BACKGROUND_SCAN capabilities.
-   */
-  BACKGROUND_SCAN_CAPABILITIES = 44,
-  /**
-   * Event received from firmware when eligible candidate is found.
-   */
-  ROAM_CANDIDATE_FOUND = 45,
-  /**
-   * Event received from firmware when roam scan configuration gets
-   * enabled or disabled.
-   */
-  ROAM_SCAN_CONFIG = 46,
-  /**
-   * Firmware/driver timed out authentication.
-   */
-  AUTH_TIMEOUT = 47,
-  /**
-   * Firmware/driver timed out association.
-   */
-  ASSOC_TIMEOUT = 48,
-  /**
-   * Firmware/driver encountered allocation failure.
-   */
-  MEM_ALLOC_FAILURE = 49,
-  /**
-   * Driver added a PNO network in firmware.
-   */
-  DRIVER_PNO_ADD = 50,
-  /**
-   * Driver removed a PNO network in firmware.
-   */
-  DRIVER_PNO_REMOVE = 51,
-  /**
-   * Driver received PNO networks found indication from firmware.
-   */
-  DRIVER_PNO_NETWORK_FOUND = 52,
-  /**
-   * Driver triggered a scan for PNO networks.
-   */
-  DRIVER_PNO_SCAN_REQUESTED = 53,
-  /**
-   * Driver received scan results  of PNO networks.
-   */
-  DRIVER_PNO_SCAN_RESULT_FOUND = 54,
-  /**
-   * Driver updated scan results from  PNO networks to cfg80211.
-   */
-  DRIVER_PNO_SCAN_COMPLETE = 55,
-};
-
-/**
- * Parameters of the various events are a sequence of TLVs
- * (type, length, value). The types for different TLV's are defined below.
- */
-enum WifiDebugRingEntryEventTlvType : uint16_t {
-  /**
-   * Take a byte stream as parameter.
-   */
-  VENDOR_SPECIFIC = 0,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  BSSID = 1,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  ADDR = 2,
-  /**
-   * Takes an SSID as parameter.
-   */
-  SSID = 3,
-  /**
-   * Takes an integer as parameter.
-   */
-  STATUS = 4,
-  /**
-   * Takes a |WifiChannelInfo| struct as parameter.
-   */
-  CHANNEL_SPEC = 5,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  ADDR_1 = 6,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  ADDR_2 = 7,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  ADDR_3 = 8,
-  /**
-   * Takes a MAC address as parameter.
-   */
-  ADDR_4 = 9,
-  /**
-   * Takes a TSF value as parameter.
-   */
-  TSF = 10,
-  /**
-   * Takes one or more specific 802.11 IEs parameter IEs are in turn
-   * indicated in TLV format as per 802.11, spec.
-   */
-  IE = 11,
-  /**
-   * Takes a string interface name as parameter.
-   */
-  IFACE_NAME = 12,
-  /**
-   * Takes a integer reason code as per 802.11 as parameter.
-   */
-  REASON_CODE = 13,
-  /**
-   * Takes an integer representing wifi rate in 1 mbps as parameter.
-   */
-  RATE_MBPS = 14,
-  /**
-   * Takes an integer as parameter.
-   */
-  REQUEST_ID = 15,
-  /**
-   * Takes an integer as parameter.
-   */
-  BUCKET_ID = 16,
-  /**
-   * Takes a |BackgroundScanParameters| struct as parameter.
-   */
-  BACKGROUND_SCAN_PARAMS = 17,
-  /**
-   * Takes a |BackgroundScanCapabilities| struct as parameter.
-   */
-  BACKGROUND_SCAN_CAPABILITIES = 18,
-  /**
-   * Takes an integer as parameter.
-   */
-  SCAN_ID = 19,
-  /**
-   * Takes an integer as parameter.
-   */
-  RSSI = 20,
-  /**
-   * Takes a |WifiChannelInMhz| as parameter.
-   */
-  CHANNEL = 21,
-  /**
-   * Takes an integer as parameter.
-   */
-  LINK_ID = 22,
-  /**
-   * Takes an integer as parameter.
-   */
-  LINK_ROLE = 23,
-  /**
-   * Takes an integer as parameter.
-   */
-  LINK_STATE = 24,
-  /**
-   * Takes an integer as parameter.
-   */
-  LINK_TYPE = 25,
-  /**
-   * Takes an integer as parameter.
-   */
-  TSCO = 26,
-  /**
-   * Takes an integer as parameter.
-   */
-  RSCO = 27,
-  /**
-   * Takes an integer as parameter.
-   * M1=1, M2=2, M3=3, M=4,
-   */
-  EAPOL_MESSAGE_TYPE = 28,
-};
-
-/**
- * Used to describe a specific TLV in an event entry.
- */
-struct WifiDebugRingEntryEventTlv {
-  WifiDebugRingEntryEventTlvType type;
-  /**
-   * All possible types of values that can be held in the TLV.
-   * Note: This should ideally be a union. But, since this HIDL package
-   * is going to be used by a java client, we cannot have unions in this
-   * package.
-   */
-  /* TODO(b/32207606): This can be moved to vendor extension. */
-  vec<uint8_t> vendorSpecific;
-  Bssid bssid;
-  MacAddress addr;
-  Ssid ssid;
-  WifiChannelInfo channelSpec;
-  uint64_t tsf;
-  vec<WifiInformationElement> ie;
-  string ifaceName;
-  StaBackgroundScanParameters bgScanParams;
-  StaBackgroundScanCapabilities bgScanCapabilities;
-  Rssi rssi;
-  WifiChannelInMhz channel;
-  uint32_t integerVal;
-};
-
-/**
- * Used to describe a connect event ring entry.
- */
-struct WifiDebugRingEntryConnectivityEvent {
-  /**
-   * Ring entry header.
-   */
-  WifiDebugRingEntryHeader header;
-  /**
-   * Type of connection event.
-   */
-  WifiDebugRingEntryEventType event;
-  /**
-   * Separate parameter structure per event to be provided and optional data.
-   * The event data is expected to include an official android part, with some
-   * parameter as transmit rate, num retries, num scan result found, etc.
-   * event data can include a vendor proprietary part which is understood by
-   * the vendor only.
-   */
-  vec<WifiDebugRingEntryEventTlv> tlvs;
-};
-
-/**
- * Used to describe a power event ring entry.
- */
-struct WifiDebugRingEntryPowerEvent {
-  /**
-   * Ring entry header.
-   */
-  WifiDebugRingEntryHeader header;
-  /**
-   * Type of power event.
-   */
-  WifiDebugRingEntryEventType event;
-  /**
-   * Separate parameter structure per event to be provided and optional data.
-   * The event data is expected to include an official android part, with some
-   * parameter as transmit rate, num retries, num scan result found, etc.
-   * event data can include a vendor proprietary part which is understood by
-   * the vendor only.
-   */
-  vec<WifiDebugRingEntryEventTlv> tlvs;
-};
-
-/**
- * Used to describe a wakelock event ring entry.
- */
-struct WifiDebugRingEntryWakelockEvent {
-  /**
-   * Ring entry header.
-   */
-  WifiDebugRingEntryHeader header;
-  /**
-   * true = wake lock acquired.
-   * false = wake lock released.
-   */
-  bool wasAcquired;
-  /**
-   * Reason why this wake lock is taken.
-   * This is a vendor defined reason and can only be understood by the
-   * vendor.
-   */
-  uint32_t vendorSpecificReason;
-  /**
-   * Wake lock name.
-   */
-  string wakelockName;
-};
-
-/**
- * Used to describe a vendor specific data ring entry.
- */
-struct WifiDebugRingEntryVendorData {
-  /**
-   * Ring entry header.
-   */
-  WifiDebugRingEntryHeader header;
-  /**
-   * This is a blob that will only be understood by the
-   * vendor.
-   */
-  vec<uint8_t> vendorData;
-};
-
-/**
  * Flags describing each debug ring buffer.
  */
 enum WifiDebugRingBufferFlags : uint32_t {
diff --git a/wifi/supplicant/1.0/ISupplicant.hal b/wifi/supplicant/1.0/ISupplicant.hal
index 32d73da..34cea18 100644
--- a/wifi/supplicant/1.0/ISupplicant.hal
+++ b/wifi/supplicant/1.0/ISupplicant.hal
@@ -44,14 +44,14 @@
    * controlled by the supplicant.
    */
   struct IfaceInfo {
-      /**
-       * Type of the network interface.
-       */
-      IfaceType type;
-      /**
-       * Name of the network interface, e.g., wlan0
-       */
-      string name;
+    /**
+     * Type of the network interface.
+     */
+    IfaceType type;
+    /**
+     * Name of the network interface, e.g., wlan0
+     */
+    string name;
   };
 
   /**
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIface.hal b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
index 0cdac2d..cd5a7c5 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
@@ -60,6 +60,22 @@
   };
 
   /**
+   * Enum describing the modes of Miracast supported
+   * via driver commands.
+   */
+  enum MiracastMode : uint8_t {
+    DISABLED = 0,
+    /**
+     * Operating as source.
+     */
+    SOURCE = 1,
+    /**
+     * Operating as sink.
+     */
+    SINK = 2
+  };
+
+  /**
    * Register for callbacks from this interface.
    *
    * These callbacks are invoked for events that are specific to this interface.
@@ -511,4 +527,16 @@
    */
   cancelServiceDiscovery(uint64_t identifier)
       generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to set Miracast mode.
+   *
+   * @param mode Mode of Miracast.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  setMiracastMode(MiracastMode mode)
+      generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.0/ISupplicantStaIface.hal b/wifi/supplicant/1.0/ISupplicantStaIface.hal
index 31706cd..2fc4d0f 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIface.hal
@@ -49,6 +49,25 @@
   };
 
   /**
+   * Enum describing the types of RX filter supported
+   * via driver commands.
+   */
+  enum RxFilterType : uint8_t {
+    V4_MULTICAST = 0,
+    V6_MULTICAST = 1
+  };
+
+  /**
+   * Enum describing the modes of BT coexistence supported
+   * via driver commands.
+   */
+  enum BtCoexistenceMode : uint8_t {
+    ENABLED = 0,
+    DISABLED = 1,
+    SENSE = 2
+  };
+
+  /**
    * Register for callbacks from this interface.
    *
    * These callbacks are invoked for events that are specific to this interface.
@@ -120,7 +139,7 @@
   setPowerSave(bool enable) generates (SupplicantStatus status);
 
   /**
-   * Initiate TDLS discover with the provided peer mac address.
+   * Initiate TDLS discover with the provided peer MAC address.
    *
    * @param macAddress MAC address of the peer.
    * @return status Status of the operation.
@@ -133,7 +152,7 @@
       generates (SupplicantStatus status);
 
   /**
-   * Initiate TDLS setup with the provided peer mac address.
+   * Initiate TDLS setup with the provided peer MAC address.
    *
    * @param macAddress MAC address of the peer.
    * @return status Status of the operation.
@@ -146,7 +165,7 @@
       generates (SupplicantStatus status);
 
   /**
-   * Initiate TDLS teardown with the provided peer mac address.
+   * Initiate TDLS teardown with the provided peer MAC address.
    *
    * @param macAddress MAC address of the peer.
    * @return status Status of the operation.
@@ -193,4 +212,111 @@
    */
   initiateHs20IconQuery(MacAddress macAddress, string fileName)
       generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to get MAC address of the device.
+   *
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   * @return macAddr MAC address of the device.
+   */
+  getMacAddress()
+      generates (SupplicantStatus status, MacAddress macAddr);
+
+  /**
+   * Send driver command to start RX filter.
+   *
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  startRxFilter() generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to stop RX filter.
+   *
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  stopRxFilter() generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to add the specified RX filter.
+   *
+   * @param type Type of filter.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  addRxFilter(RxFilterType type)
+      generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to remove the specified RX filter.
+   *
+   * @param type Type of filter.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  removeRxFilter(RxFilterType type)
+      generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to set Bluetooth coexistence mode.
+   *
+   * @param mode Mode of Bluetooth coexistence.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  setBtCoexistenceMode(BtCoexistenceMode mode)
+      generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to set Bluetooth coexistence scan mode.
+   * When this mode is on, some of the low-level scan parameters
+   * used by the driver are changed to reduce interference
+   * with A2DP streaming.
+   *
+   * @param enable true to enable, false to disable.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  setBtCoexistenceScanModeEnabled(bool enable)
+      generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to set suspend optimizations for power save.
+   *
+   * @param enable true to enable, false to disable.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  setSuspendModeEnabled(bool enable)
+      generates (SupplicantStatus status);
+
+  /**
+   * Send driver command to set country code.
+   *
+   * @param code 2 byte country code (as defined in ISO 3166) to set.
+   * @return status Status of the operation.
+   *         Possible status codes:
+   *         |SupplicantStatusCode.SUCCESS|,
+   *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+   */
+  setCountryCode(int8_t[2] code)
+      generates (SupplicantStatus status);
 };