Merge "Add VR Hal host test."
diff --git a/audio/2.0/IStream.hal b/audio/2.0/IStream.hal
index dc43346..5c88a69 100644
--- a/audio/2.0/IStream.hal
+++ b/audio/2.0/IStream.hal
@@ -227,4 +227,56 @@
      * @param fd dump file descriptor.
      */
     debugDump(handle fd);
+
+    /*
+     * Called by the framework to start a stream operating in mmap mode.
+     * createMmapBuffer() must be called before calling start().
+     * Function only implemented by streams operating in mmap mode.
+     *
+     * @return retval OK in case the success.
+     *                NOT_SUPPORTED on non mmap mode streams
+     *                INVALID_STATE if called out of sequence
+     */
+    start() generates (Result retval);
+
+    /**
+     * Called by the framework to stop a stream operating in mmap mode.
+     * Function only implemented by streams operating in mmap mode.
+     *
+     * @return retval OK in case the succes.
+     *                NOT_SUPPORTED on non mmap mode streams
+     *                INVALID_STATE if called out of sequence
+     */
+    stop() generates (Result retval) ;
+
+    /*
+     * Called by the framework to retrieve information on the mmap buffer used for audio
+     * samples transfer.
+     * Function only implemented by streams operating in mmap mode.
+     *
+     * @param minSizeFrames minimum buffer size requested. The actual buffer
+     *                     size returned in struct MmapBufferInfo can be larger.
+     * @return retval OK in case the success.
+     *                NOT_SUPPORTED on non mmap mode streams
+     *                NOT_INITIALIZED in case of memory allocation error
+     *                INVALID_ARGUMENTS if the requested buffer size is too large
+     *                INVALID_STATE if called out of sequence
+     * @return info    a MmapBufferInfo struct containing information on the MMMAP buffer created.
+     */
+    createMmapBuffer(int32_t minSizeFrames)
+            generates (Result retval, MmapBufferInfo info);
+
+    /*
+     * Called by the framework to read current read/write position in the mmap buffer
+     * with associated time stamp.
+     * Function only implemented by streams operating in mmap mode.
+     *
+     * @return retval OK in case the success.
+     *                NOT_SUPPORTED on non mmap mode streams
+     *                INVALID_STATE if called out of sequence
+     * @return position a MmapPosition struct containing current HW read/write position in frames
+     *                  with associated time stamp.
+     */
+    getMmapPosition()
+            generates (Result retval, MmapPosition position);
 };
diff --git a/audio/2.0/IStreamOutCallback.hal b/audio/2.0/IStreamOutCallback.hal
index 267c46d..cdb38de 100644
--- a/audio/2.0/IStreamOutCallback.hal
+++ b/audio/2.0/IStreamOutCallback.hal
@@ -23,15 +23,15 @@
     /*
      * Non blocking write completed.
      */
-    onWriteReady();
+    oneway onWriteReady();
 
     /*
      * Drain completed.
      */
-    onDrainReady();
+    oneway onDrainReady();
 
     /*
      * Stream hit an error.
      */
-    onError();
+    oneway onError();
 };
diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk
index 2b1aa4f..c3cfd69 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/2.0/default/Android.mk
@@ -33,6 +33,7 @@
     libhidlbase \
     libhidltransport \
     libhwbinder \
+    libcutils \
     libutils \
     libhardware \
     liblog \
diff --git a/audio/2.0/default/Stream.cpp b/audio/2.0/default/Stream.cpp
index 40f67f0..f214eed 100644
--- a/audio/2.0/default/Stream.cpp
+++ b/audio/2.0/default/Stream.cpp
@@ -43,9 +43,10 @@
     mStream = nullptr;
 }
 
+// static
 Result Stream::analyzeStatus(const char* funcName, int status, int ignoreError) {
     if (status != 0 && status != -ignoreError) {
-        ALOGW("Stream %p %s: %s", mStream, funcName, strerror(-status));
+        ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status));
     }
     switch (status) {
         case 0: return Result::OK;
@@ -229,6 +230,29 @@
     return Void();
 }
 
+Return<Result>  Stream::start() {
+    return Result::NOT_SUPPORTED;
+}
+
+Return<Result>  Stream::stop() {
+    return Result::NOT_SUPPORTED;
+}
+
+Return<void>  Stream::createMmapBuffer(int32_t minSizeFrames __unused,
+                                       createMmapBuffer_cb _hidl_cb) {
+    Result retval(Result::NOT_SUPPORTED);
+    MmapBufferInfo info;
+    _hidl_cb(retval, info);
+    return Void();
+}
+
+Return<void>  Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+    Result retval(Result::NOT_SUPPORTED);
+    MmapPosition position;
+    _hidl_cb(retval, position);
+    return Void();
+}
+
 } // namespace implementation
 }  // namespace V2_0
 }  // namespace audio
diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h
index 0ebd723..819bbf7 100644
--- a/audio/2.0/default/Stream.h
+++ b/audio/2.0/default/Stream.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
 
 #include <android/hardware/audio/2.0/IStream.h>
+#include <hardware/audio.h>
 #include <hidl/Status.h>
 
 #include <hidl/MQDescriptor.h>
@@ -71,9 +72,13 @@
             const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  override;
     Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters)  override;
     Return<void> debugDump(const hidl_handle& fd)  override;
+    Return<Result> start() override;
+    Return<Result> stop() override;
+    Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+    Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
 
     // Utility methods for extending interfaces.
-    Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
+    static Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
 
   private:
     audio_stream_t *mStream;
@@ -85,6 +90,80 @@
     int halSetParameters(const char* keysAndValues) override;
 };
 
+
+template <typename T>
+struct StreamMmap : public RefBase {
+    explicit StreamMmap(T* stream) : mStream(stream) {}
+
+    Return<Result> start();
+    Return<Result> stop();
+    Return<void> createMmapBuffer(
+            int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb);
+    Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb);
+
+ private:
+   StreamMmap() {}
+
+   T *mStream;
+};
+
+template <typename T>
+Return<Result> StreamMmap<T>::start() {
+    if (mStream->start == NULL) return Result::NOT_SUPPORTED;
+    int result = mStream->start(mStream);
+    return Stream::analyzeStatus("start", result);
+}
+
+template <typename T>
+Return<Result> StreamMmap<T>::stop() {
+    if (mStream->stop == NULL) return Result::NOT_SUPPORTED;
+    int result = mStream->stop(mStream);
+    return Stream::analyzeStatus("stop", result);
+}
+
+template <typename T>
+Return<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize,
+                                             IStream::createMmapBuffer_cb _hidl_cb) {
+    Result retval(Result::NOT_SUPPORTED);
+    MmapBufferInfo info;
+
+    if (mStream->create_mmap_buffer != NULL) {
+        struct audio_mmap_buffer_info halInfo;
+        retval = Stream::analyzeStatus(
+                "create_mmap_buffer",
+                mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
+        if (retval == Result::OK) {
+            native_handle_t* hidlHandle = native_handle_create(1, 0);
+            hidlHandle->data[0] = halInfo.shared_memory_fd;
+            info.sharedMemory = hidl_memory("audio_buffer", hidlHandle,
+                                            frameSize *halInfo.buffer_size_frames);
+            info.bufferSizeFrames = halInfo.buffer_size_frames;
+            info.burstSizeFrames = halInfo.burst_size_frames;
+        }
+    }
+    _hidl_cb(retval, info);
+    return Void();
+}
+
+template <typename T>
+Return<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) {
+    Result retval(Result::NOT_SUPPORTED);
+    MmapPosition position;
+
+    if (mStream->get_mmap_position != NULL) {
+        struct audio_mmap_position halPosition;
+        retval = Stream::analyzeStatus(
+                "get_mmap_position",
+                mStream->get_mmap_position(mStream, &halPosition));
+        if (retval == Result::OK) {
+            position.timeNanoseconds = halPosition.time_nanoseconds;
+            position.positionFrames = halPosition.position_frames;
+        }
+    }
+    _hidl_cb(retval, position);
+    return Void();
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace audio
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index 1bc9dfb..1441e74 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -28,7 +28,9 @@
 namespace implementation {
 
 StreamIn::StreamIn(audio_hw_device_t* device, audio_stream_in_t* stream)
-        : mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
+        : mDevice(device), mStream(stream),
+          mStreamCommon(new Stream(&stream->common)),
+          mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)) {
 }
 
 StreamIn::~StreamIn() {
@@ -130,6 +132,22 @@
     return mStreamCommon->debugDump(fd);
 }
 
+Return<Result> StreamIn::start() {
+    return mStreamMmap->start();
+}
+
+Return<Result> StreamIn::stop() {
+    return mStreamMmap->stop();
+}
+
+Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+    return mStreamMmap->createMmapBuffer(
+            minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb);
+}
+
+Return<void> StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+    return mStreamMmap->getMmapPosition(_hidl_cb);
+}
 
 // Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
 Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb)  {
@@ -144,7 +162,7 @@
 }
 
 Return<Result> StreamIn::setGain(float gain)  {
-    return mStreamCommon->analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
+    return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
 }
 
 Return<void> StreamIn::read(uint64_t size, read_cb _hidl_cb)  {
@@ -157,7 +175,7 @@
         data.resize(readResult);
     } else if (readResult < 0) {
         data.resize(0);
-        retval = mStreamCommon->analyzeStatus("read", readResult);
+        retval = Stream::analyzeStatus("read", readResult);
     }
     _hidl_cb(retval, data);
     return Void();
@@ -172,7 +190,7 @@
     uint64_t frames = 0, time = 0;
     if (mStream->get_capture_position != NULL) {
         int64_t halFrames, halTime;
-        retval = mStreamCommon->analyzeStatus(
+        retval = Stream::analyzeStatus(
                 "get_capture_position",
                 mStream->get_capture_position(mStream, &halFrames, &halTime));
         if (retval == Result::OK) {
diff --git a/audio/2.0/default/StreamIn.h b/audio/2.0/default/StreamIn.h
index f7c17b7..65e94bb 100644
--- a/audio/2.0/default/StreamIn.h
+++ b/audio/2.0/default/StreamIn.h
@@ -80,11 +80,17 @@
     Return<void> read(uint64_t size, read_cb _hidl_cb)  override;
     Return<uint32_t> getInputFramesLost()  override;
     Return<void> getCapturePosition(getCapturePosition_cb _hidl_cb)  override;
+    Return<Result> start() override;
+    Return<Result> stop() override;
+    Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+    Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
 
   private:
     audio_hw_device_t *mDevice;
     audio_stream_in_t *mStream;
     sp<Stream> mStreamCommon;
+    sp<StreamMmap<audio_stream_in_t>> mStreamMmap;
+
 
     virtual ~StreamIn();
 };
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 913b6ae..3d20d11 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "StreamOutHAL"
+//#define LOG_NDEBUG 0
 
 #include <hardware/audio.h>
 #include <android/log.h>
@@ -28,7 +29,9 @@
 namespace implementation {
 
 StreamOut::StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream)
-        : mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
+        : mDevice(device), mStream(stream),
+          mStreamCommon(new Stream(&stream->common)),
+          mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)) {
 }
 
 StreamOut::~StreamOut() {
@@ -132,7 +135,6 @@
     return mStreamCommon->debugDump(fd);
 }
 
-
 // Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
 Return<uint32_t> StreamOut::getLatency()  {
     return mStream->get_latency(mStream);
@@ -141,7 +143,7 @@
 Return<Result> StreamOut::setVolume(float left, float right)  {
     Result retval(Result::NOT_SUPPORTED);
     if (mStream->set_volume != NULL) {
-        retval = mStreamCommon->analyzeStatus(
+        retval = Stream::analyzeStatus(
                 "set_volume", mStream->set_volume(mStream, left, right));
     }
     return retval;
@@ -155,7 +157,7 @@
     if (writeResult >= 0) {
         written = writeResult;
     } else {
-        retval = mStreamCommon->analyzeStatus("write", writeResult);
+        retval = Stream::analyzeStatus("write", writeResult);
         written = 0;
     }
     _hidl_cb(retval, written);
@@ -164,7 +166,7 @@
 
 Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb)  {
     uint32_t halDspFrames;
-    Result retval = mStreamCommon->analyzeStatus(
+    Result retval = Stream::analyzeStatus(
             "get_render_position", mStream->get_render_position(mStream, &halDspFrames));
     _hidl_cb(retval, halDspFrames);
     return Void();
@@ -174,7 +176,7 @@
     Result retval(Result::NOT_SUPPORTED);
     int64_t timestampUs = 0;
     if (mStream->get_next_write_timestamp != NULL) {
-        retval = mStreamCommon->analyzeStatus(
+        retval = Stream::analyzeStatus(
                 "get_next_write_timestamp",
                 mStream->get_next_write_timestamp(mStream, &timestampUs));
     }
@@ -188,7 +190,7 @@
     if (result == 0) {
         mCallback = callback;
     }
-    return mStreamCommon->analyzeStatus("set_callback", result);
+    return Stream::analyzeStatus("set_callback", result);
 }
 
 Return<Result> StreamOut::clearCallback()  {
@@ -227,13 +229,13 @@
 
 Return<Result> StreamOut::pause()  {
     return mStream->pause != NULL ?
-            mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) :
+            Stream::analyzeStatus("pause", mStream->pause(mStream)) :
             Result::NOT_SUPPORTED;
 }
 
 Return<Result> StreamOut::resume()  {
     return mStream->resume != NULL ?
-            mStreamCommon->analyzeStatus("resume", mStream->resume(mStream)) :
+            Stream::analyzeStatus("resume", mStream->resume(mStream)) :
             Result::NOT_SUPPORTED;
 }
 
@@ -243,14 +245,14 @@
 
 Return<Result> StreamOut::drain(AudioDrain type)  {
     return mStream->drain != NULL ?
-            mStreamCommon->analyzeStatus(
+            Stream::analyzeStatus(
                     "drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
             Result::NOT_SUPPORTED;
 }
 
 Return<Result> StreamOut::flush()  {
     return mStream->flush != NULL ?
-            mStreamCommon->analyzeStatus("flush", mStream->flush(mStream)) :
+            Stream::analyzeStatus("flush", mStream->flush(mStream)) :
             Result::NOT_SUPPORTED;
 }
 
@@ -260,7 +262,7 @@
     TimeSpec timeStamp = { 0, 0 };
     if (mStream->get_presentation_position != NULL) {
         struct timespec halTimeStamp;
-        retval = mStreamCommon->analyzeStatus(
+        retval = Stream::analyzeStatus(
                 "get_presentation_position",
                 mStream->get_presentation_position(mStream, &frames, &halTimeStamp),
                 // Don't logspam on EINVAL--it's normal for get_presentation_position
@@ -275,6 +277,23 @@
     return Void();
 }
 
+Return<Result> StreamOut::start() {
+    return mStreamMmap->start();
+}
+
+Return<Result> StreamOut::stop() {
+    return mStreamMmap->stop();
+}
+
+Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
+    return mStreamMmap->createMmapBuffer(
+            minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb);
+}
+
+Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+    return mStreamMmap->getMmapPosition(_hidl_cb);
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace audio
diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h
index dc9a604..9b7f9f8 100644
--- a/audio/2.0/default/StreamOut.h
+++ b/audio/2.0/default/StreamOut.h
@@ -91,11 +91,16 @@
     Return<Result> drain(AudioDrain type)  override;
     Return<Result> flush()  override;
     Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb)  override;
+    Return<Result> start() override;
+    Return<Result> stop() override;
+    Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
+    Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
 
   private:
     audio_hw_device_t *mDevice;
     audio_stream_out_t *mStream;
     sp<Stream> mStreamCommon;
+    sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
     sp<IStreamOutCallback> mCallback;
 
     virtual ~StreamOut();
diff --git a/audio/2.0/default/service.cpp b/audio/2.0/default/service.cpp
index 28ef660..646d898 100644
--- a/audio/2.0/default/service.cpp
+++ b/audio/2.0/default/service.cpp
@@ -16,14 +16,17 @@
 
 #define LOG_TAG "audiohalservice"
 
+#include <hidl/HidlTransportSupport.h>
 #include <hidl/LegacySupport.h>
 #include <android/hardware/audio/2.0/IDevicesFactory.h>
 #include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
 #include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
 #include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
 
-using android::hardware::IPCThreadState;
-using android::hardware::ProcessState;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+
 using android::hardware::audio::effect::V2_0::IEffectsFactory;
 using android::hardware::audio::V2_0::IDevicesFactory;
 using android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
@@ -31,9 +34,10 @@
 using android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
 
 int main(int /* argc */, char* /* argv */ []) {
+    configureRpcThreadpool(16, true /*callerWillJoin*/);
     registerPassthroughServiceImplementation<IDevicesFactory>("audio_devices_factory");
     registerPassthroughServiceImplementation<IEffectsFactory>("audio_effects_factory");
     registerPassthroughServiceImplementation<ISoundTriggerHw>("sound_trigger.primary");
     registerPassthroughServiceImplementation<IBroadcastRadioFactory>("broadcastradio");
-    return android::hardware::launchRpcServer(16);
+    joinRpcThreadpool();
 }
diff --git a/audio/2.0/types.hal b/audio/2.0/types.hal
index 7002f38..37c39e4 100644
--- a/audio/2.0/types.hal
+++ b/audio/2.0/types.hal
@@ -70,3 +70,22 @@
     string busAddress;      // used for BUS
     string rSubmixAddress;  // used for REMOTE_SUBMIX
 };
+
+/*
+ * Mmap buffer descriptor returned by IStream.createMmapBuffer().
+ * Used by streams opened in mmap mode.
+ */
+struct MmapBufferInfo {
+    memory  sharedMemory;         // mmap memory buffer
+    int32_t bufferSizeFrames;     // total buffer size in frames
+    int32_t burstSizeFrames;      // transfer size granularity in frames
+};
+
+/*
+ * Mmap buffer read/write position returned by IStream.getMmapPosition().
+ * Used by streams opened in mmap mode.
+ */
+struct MmapPosition {
+    int64_t  timeNanoseconds; // time stamp in ns, CLOCK_MONOTONIC
+    int32_t  positionFrames;  // increasing 32 bit frame count reset when IStream.stop() is called
+};
diff --git a/audio/common/2.0/default/HidlUtils.cpp b/audio/common/2.0/default/HidlUtils.cpp
index b1bff00..241ca90 100644
--- a/audio/common/2.0/default/HidlUtils.cpp
+++ b/audio/common/2.0/default/HidlUtils.cpp
@@ -97,6 +97,7 @@
         const audio_offload_info_t& halOffload, AudioOffloadInfo* offload) {
     offload->sampleRateHz = halOffload.sample_rate;
     offload->channelMask = AudioChannelMask(halOffload.channel_mask);
+    offload->format = AudioFormat(halOffload.format);
     offload->streamType = AudioStreamType(halOffload.stream_type);
     offload->bitRatePerSecond = halOffload.bit_rate;
     offload->durationMicroseconds = halOffload.duration_us;
@@ -109,6 +110,7 @@
     *halOffload = AUDIO_INFO_INITIALIZER;
     halOffload->sample_rate = offload.sampleRateHz;
     halOffload->channel_mask = static_cast<audio_channel_mask_t>(offload.channelMask);
+    halOffload->format = static_cast<audio_format_t>(offload.format);
     halOffload->stream_type = static_cast<audio_stream_type_t>(offload.streamType);
     halOffload->bit_rate = offload.bitRatePerSecond;
     halOffload->duration_us = offload.durationMicroseconds;
diff --git a/audio/common/2.0/types.hal b/audio/common/2.0/types.hal
index 13fd19b..eec4ac2 100644
--- a/audio/common/2.0/types.hal
+++ b/audio/common/2.0/types.hal
@@ -705,6 +705,7 @@
     ASSISTANCE_SONIFICATION            = 13,
     GAME                               = 14,
     VIRTUAL_SOURCE                     = 15,
+    ASSISTANT                          = 16,
 
     CNT,
     MAX                                = CNT - 1,
diff --git a/audio/common/2.0/vts/types.vts b/audio/common/2.0/vts/types.vts
index 9c79611..8d1a9db 100644
--- a/audio/common/2.0/vts/types.vts
+++ b/audio/common/2.0/vts/types.vts
@@ -132,7 +132,7 @@
         }
         enumerator: "PUBLIC_CNT"
         scalar_value: {
-            int32_t: 10
+            int32_t: 11
         }
         enumerator: "FOR_POLICY_CNT"
         scalar_value: {
@@ -309,6 +309,82 @@
         scalar_value: {
             uint32_t: 234881024
         }
+        enumerator: "EVRC"
+        scalar_value: {
+            uint32_t: 268435456
+        }
+        enumerator: "EVRCB"
+        scalar_value: {
+            uint32_t: 285212672
+        }
+        enumerator: "EVRCWB"
+        scalar_value: {
+            uint32_t: 301989888
+        }
+        enumerator: "EVRCNW"
+        scalar_value: {
+            uint32_t: 318767104
+        }
+        enumerator: "AAC_ADIF"
+        scalar_value: {
+            uint32_t: 335544320
+        }
+        enumerator: "WMA"
+        scalar_value: {
+            uint32_t: 352321536
+        }
+        enumerator: "WMA_PRO"
+        scalar_value: {
+            uint32_t: 369098752
+        }
+        enumerator: "AMR_WB_PLUS"
+        scalar_value: {
+            uint32_t: 385875968
+        }
+        enumerator: "MP2"
+        scalar_value: {
+            uint32_t: 402653184
+        }
+        enumerator: "QCELP"
+        scalar_value: {
+            uint32_t: 419430400
+        }
+        enumerator: "DSD"
+        scalar_value: {
+            uint32_t: 436207616
+        }
+        enumerator: "FLAC"
+        scalar_value: {
+            uint32_t: 452984832
+        }
+        enumerator: "ALAC"
+        scalar_value: {
+            uint32_t: 469762048
+        }
+        enumerator: "APE"
+        scalar_value: {
+            uint32_t: 486539264
+        }
+        enumerator: "AAC_ADTS"
+        scalar_value: {
+            uint32_t: 503316480
+        }
+        enumerator: "SBC"
+        scalar_value: {
+            uint32_t: 520093696
+        }
+        enumerator: "APTX"
+        scalar_value: {
+            uint32_t: 536870912
+        }
+        enumerator: "APTX_HD"
+        scalar_value: {
+            uint32_t: 553648128
+        }
+        enumerator: "LDAC"
+        scalar_value: {
+            uint32_t: 570425344
+        }
         enumerator: "MAIN_MASK"
         scalar_value: {
             uint32_t: 4278190080
@@ -457,6 +533,46 @@
         scalar_value: {
             uint32_t: 67109376
         }
+        enumerator: "AAC_ADTS_MAIN"
+        scalar_value: {
+            uint32_t: 503316481
+        }
+        enumerator: "AAC_ADTS_LC"
+        scalar_value: {
+            uint32_t: 503316482
+        }
+        enumerator: "AAC_ADTS_SSR"
+        scalar_value: {
+            uint32_t: 503316484
+        }
+        enumerator: "AAC_ADTS_LTP"
+        scalar_value: {
+            uint32_t: 503316488
+        }
+        enumerator: "AAC_ADTS_HE_V1"
+        scalar_value: {
+            uint32_t: 503316496
+        }
+        enumerator: "AAC_ADTS_SCALABLE"
+        scalar_value: {
+            uint32_t: 503316512
+        }
+        enumerator: "AAC_ADTS_ERLC"
+        scalar_value: {
+            uint32_t: 503316544
+        }
+        enumerator: "AAC_ADTS_LD"
+        scalar_value: {
+            uint32_t: 503316608
+        }
+        enumerator: "AAC_ADTS_HE_V2"
+        scalar_value: {
+            uint32_t: 503316736
+        }
+        enumerator: "AAC_ADTS_ELD"
+        scalar_value: {
+            uint32_t: 503316992
+        }
     }
 }
 
@@ -579,6 +695,10 @@
         scalar_value: {
             uint32_t: 3
         }
+        enumerator: "OUT_2POINT1"
+        scalar_value: {
+            uint32_t: 11
+        }
         enumerator: "OUT_QUAD"
         scalar_value: {
             uint32_t: 51
@@ -591,6 +711,14 @@
         scalar_value: {
             uint32_t: 1539
         }
+        enumerator: "OUT_SURROUND"
+        scalar_value: {
+            uint32_t: 263
+        }
+        enumerator: "OUT_PENTA"
+        scalar_value: {
+            uint32_t: 55
+        }
         enumerator: "OUT_5POINT1"
         scalar_value: {
             uint32_t: 63
@@ -603,6 +731,10 @@
         scalar_value: {
             uint32_t: 1551
         }
+        enumerator: "OUT_6POINT1"
+        scalar_value: {
+            uint32_t: 319
+        }
         enumerator: "OUT_7POINT1"
         scalar_value: {
             uint32_t: 1599
@@ -679,6 +811,18 @@
         scalar_value: {
             uint32_t: 48
         }
+        enumerator: "IN_VOICE_UPLINK_MONO"
+        scalar_value: {
+            uint32_t: 16400
+        }
+        enumerator: "IN_VOICE_DNLINK_MONO"
+        scalar_value: {
+            uint32_t: 32784
+        }
+        enumerator: "IN_VOICE_CALL_MONO"
+        scalar_value: {
+            uint32_t: 49168
+        }
         enumerator: "IN_ALL"
         scalar_value: {
             uint32_t: 65532
@@ -906,13 +1050,17 @@
         scalar_value: {
             uint32_t: 16777216
         }
+        enumerator: "OUT_PROXY"
+        scalar_value: {
+            uint32_t: 33554432
+        }
         enumerator: "OUT_DEFAULT"
         scalar_value: {
             uint32_t: 1073741824
         }
         enumerator: "OUT_ALL"
         scalar_value: {
-            uint32_t: 1107296255
+            uint32_t: 1140850687
         }
         enumerator: "OUT_ALL_A2DP"
         scalar_value: {
@@ -1018,13 +1166,17 @@
         scalar_value: {
             uint32_t: 2148532224
         }
+        enumerator: "IN_PROXY"
+        scalar_value: {
+            uint32_t: 2164260864
+        }
         enumerator: "IN_DEFAULT"
         scalar_value: {
             uint32_t: 3221225472
         }
         enumerator: "IN_ALL"
         scalar_value: {
-            uint32_t: 3223322623
+            uint32_t: 3240099839
         }
         enumerator: "IN_ALL_SCO"
         scalar_value: {
@@ -1091,6 +1243,14 @@
         scalar_value: {
             int32_t: 1024
         }
+        enumerator: "DIRECT_PCM"
+        scalar_value: {
+            int32_t: 8192
+        }
+        enumerator: "MMAP_NOIRQ"
+        scalar_value: {
+            int32_t: 16384
+        }
     }
 }
 
@@ -1120,6 +1280,91 @@
         scalar_value: {
             int32_t: 8
         }
+        enumerator: "MMAP_NOIRQ"
+        scalar_value: {
+            int32_t: 16
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::audio::common::V2_0::AudioUsage"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "UNKNOWN"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "MEDIA"
+        scalar_value: {
+            int32_t: 1
+        }
+        enumerator: "VOICE_COMMUNICATION"
+        scalar_value: {
+            int32_t: 2
+        }
+        enumerator: "VOICE_COMMUNICATION_SIGNALLING"
+        scalar_value: {
+            int32_t: 3
+        }
+        enumerator: "ALARM"
+        scalar_value: {
+            int32_t: 4
+        }
+        enumerator: "NOTIFICATION"
+        scalar_value: {
+            int32_t: 5
+        }
+        enumerator: "NOTIFICATION_TELEPHONY_RINGTONE"
+        scalar_value: {
+            int32_t: 6
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_REQUEST"
+        scalar_value: {
+            int32_t: 7
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_INSTANT"
+        scalar_value: {
+            int32_t: 8
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_DELAYED"
+        scalar_value: {
+            int32_t: 9
+        }
+        enumerator: "NOTIFICATION_EVENT"
+        scalar_value: {
+            int32_t: 10
+        }
+        enumerator: "ASSISTANCE_ACCESSIBILITY"
+        scalar_value: {
+            int32_t: 11
+        }
+        enumerator: "ASSISTANCE_NAVIGATION_GUIDANCE"
+        scalar_value: {
+            int32_t: 12
+        }
+        enumerator: "ASSISTANCE_SONIFICATION"
+        scalar_value: {
+            int32_t: 13
+        }
+        enumerator: "GAME"
+        scalar_value: {
+            int32_t: 14
+        }
+        enumerator: "VIRTUAL_SOURCE"
+        scalar_value: {
+            int32_t: 15
+        }
+        enumerator: "CNT"
+        scalar_value: {
+            int32_t: 16
+        }
+        enumerator: "MAX"
+        scalar_value: {
+            int32_t: 15
+        }
     }
 }
 
@@ -1166,6 +1411,21 @@
         type: TYPE_SCALAR
         scalar_type: "bool_t"
     }
+    struct_value: {
+        name: "bitWidth"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "bufferSize"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "usage"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::audio::common::V2_0::AudioUsage"
+    }
 }
 
 attribute: {
@@ -1440,6 +1700,11 @@
                 type: TYPE_SCALAR
                 scalar_type: "int32_t"
             }
+            struct_value: {
+                name: "useCase"
+                type: TYPE_UNION
+                predefined_type: "::android::hardware::audio::common::V2_0::AudioPortConfig::Ext::AudioPortConfigMixExt::UseCase"
+            }
         }
         union_value: {
             name: "device"
@@ -1497,6 +1762,11 @@
         type: TYPE_ENUM
         predefined_type: "::android::hardware::audio::common::V2_0::AudioPortRole"
     }
+    struct_value: {
+        name: "ext"
+        type: TYPE_UNION
+        predefined_type: "::android::hardware::audio::common::V2_0::AudioPortConfig::Ext"
+    }
 }
 
 attribute: {
@@ -1648,31 +1918,10 @@
         type: TYPE_ENUM
         predefined_type: "::android::hardware::audio::common::V2_0::AudioPortType"
     }
-}
-
-attribute: {
-    name: "::android::hardware::audio::common::V2_0::AudioPatch"
-    type: TYPE_STRUCT
     struct_value: {
-        name: "id"
-        type: TYPE_SCALAR
-        scalar_type: "int32_t"
-    }
-    struct_value: {
-        name: "sources"
-        type: TYPE_VECTOR
-        vector_value: {
-            type: TYPE_STRUCT
-            predefined_type: "::android::hardware::audio::common::V2_0::AudioPortConfig"
-        }
-    }
-    struct_value: {
-        name: "sinks"
-        type: TYPE_VECTOR
-        vector_value: {
-            type: TYPE_STRUCT
-            predefined_type: "::android::hardware::audio::common::V2_0::AudioPortConfig"
-        }
+        name: "ext"
+        type: TYPE_UNION
+        predefined_type: "::android::hardware::audio::common::V2_0::AudioPort::Ext"
     }
 }
 
diff --git a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
index ef70215..1e0ab32 100644
--- a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
+++ b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
@@ -97,49 +97,6 @@
   EXPECT_NE(effect, nullptr);
 }
 
-// See b/32834072 -- we should have those operator== generated by hidl-gen.
-
-namespace android {
-namespace hardware {
-namespace audio {
-namespace common {
-namespace V2_0 {
-
-static bool operator==(const Uuid& lhs, const Uuid& rhs) {
-  return lhs.timeLow == rhs.timeLow && lhs.timeMid == rhs.timeMid &&
-         lhs.versionAndTimeHigh == rhs.versionAndTimeHigh &&
-         lhs.variantAndClockSeqHigh == rhs.variantAndClockSeqHigh &&
-         memcmp(lhs.node.data(), rhs.node.data(), lhs.node.size()) == 0;
-}
-
-}  // namespace V2_0
-}  // namespace common
-}  // namespace audio
-}  // namespace hardware
-}  // namespace android
-
-namespace android {
-namespace hardware {
-namespace audio {
-namespace effect {
-namespace V2_0 {
-
-static bool operator==(const EffectDescriptor& lhs,
-                       const EffectDescriptor& rhs) {
-  return lhs.type == rhs.type && lhs.uuid == rhs.uuid &&
-         lhs.flags == rhs.flags && lhs.cpuLoad == rhs.cpuLoad &&
-         lhs.memoryUsage == rhs.memoryUsage &&
-         memcmp(lhs.name.data(), rhs.name.data(), lhs.name.size()) == 0 &&
-         memcmp(lhs.implementor.data(), rhs.implementor.data(),
-                lhs.implementor.size()) == 0;
-}
-
-}  // namespace V2_0
-}  // namespace effect
-}  // namespace audio
-}  // namespace hardware
-}  // namespace android
-
 TEST_F(AudioEffectHidlTest, GetDescriptor) {
   hidl_vec<EffectDescriptor> allDescriptors;
   Return<void> ret = effectsFactory->getAllDescriptors(
diff --git a/benchmarks/msgq/1.0/IBenchmarkMsgQ.hal b/benchmarks/msgq/1.0/IBenchmarkMsgQ.hal
index 3af0b71..c4b9d95 100644
--- a/benchmarks/msgq/1.0/IBenchmarkMsgQ.hal
+++ b/benchmarks/msgq/1.0/IBenchmarkMsgQ.hal
@@ -25,7 +25,7 @@
      * by the service. Client can use it to set up the FMQ at its end.
      */
     configureClientInboxSyncReadWrite()
-        generates(bool ret, MQDescriptorSync mqDescIn);
+        generates(bool ret, fmq_sync<uint8_t> mqDescIn);
 
     /*
      * This method requests the service to set up Synchronous read/write
@@ -35,7 +35,7 @@
      * by the service. Client can use it to set up the FMQ at its end.
      */
     configureClientOutboxSyncReadWrite()
-        generates(bool ret, MQDescriptorSync mqDescOut);
+        generates(bool ret, fmq_sync<uint8_t> mqDescOut);
 
     /*
      * This method request the service to write into the FMQ.
diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp
new file mode 100644
index 0000000..32e5328
--- /dev/null
+++ b/bluetooth/1.0/default/Android.bp
@@ -0,0 +1,52 @@
+//
+// 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_library_shared {
+    name: "android.hardware.bluetooth@1.0-impl",
+    relative_install_path: "hw",
+    srcs: [
+        "async_fd_watcher.cc",
+        "bluetooth_hci.cc",
+        "bluetooth_address.cc",
+        "vendor_interface.cc",
+    ],
+    shared_libs: [
+        "android.hardware.bluetooth@1.0",
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhwbinder",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_test_host {
+    name: "bluetooth-vendor-interface-unit-tests",
+    srcs: [
+        "bluetooth_address.cc",
+        "test/bluetooth_address_test.cc",
+        "test/properties.cc",
+    ],
+    local_include_dirs: [
+        "test",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+}
diff --git a/bluetooth/1.0/default/Android.mk b/bluetooth/1.0/default/Android.mk
new file mode 100644
index 0000000..08bfb4e
--- /dev/null
+++ b/bluetooth/1.0/default/Android.mk
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.bluetooth@1.0-service
+LOCAL_INIT_RC := android.hardware.bluetooth@1.0-service.rc
+LOCAL_SRC_FILES := \
+  service.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+  liblog \
+  libcutils \
+  libdl \
+  libbase \
+  libutils \
+  libhardware_legacy \
+  libhardware \
+
+LOCAL_SHARED_LIBRARIES += \
+  libhwbinder \
+  libhidlbase \
+  libhidltransport \
+  android.hardware.bluetooth@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
new file mode 100644
index 0000000..8c5c02a
--- /dev/null
+++ b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
@@ -0,0 +1,4 @@
+service bluetooth-1-0 /system/bin/hw/android.hardware.bluetooth@1.0-service
+    class hal
+    user bluetooth
+    group bluetooth
diff --git a/bluetooth/1.0/default/async_fd_watcher.cc b/bluetooth/1.0/default/async_fd_watcher.cc
new file mode 100644
index 0000000..636b4b6
--- /dev/null
+++ b/bluetooth/1.0/default/async_fd_watcher.cc
@@ -0,0 +1,133 @@
+//
+// Copyright 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.
+//
+
+#include "async_fd_watcher.h"
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <vector>
+#include "fcntl.h"
+#include "sys/select.h"
+#include "unistd.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+int AsyncFdWatcher::WatchFdForNonBlockingReads(
+    int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
+  // Add file descriptor and callback
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    read_fd_ = file_descriptor;
+    cb_ = on_read_fd_ready_callback;
+  }
+
+  // Start the thread if not started yet
+  int started = tryStartThread();
+  if (started != 0) {
+    return started;
+  }
+
+  return 0;
+}
+
+void AsyncFdWatcher::StopWatchingFileDescriptor() { stopThread(); }
+
+AsyncFdWatcher::~AsyncFdWatcher() {}
+
+// Make sure to call this with at least one file descriptor ready to be
+// watched upon or the thread routine will return immediately
+int AsyncFdWatcher::tryStartThread() {
+  if (std::atomic_exchange(&running_, true)) return 0;
+
+  // Set up the communication channel
+  int pipe_fds[2];
+  if (pipe2(pipe_fds, O_NONBLOCK)) return -1;
+
+  notification_listen_fd_ = pipe_fds[0];
+  notification_write_fd_ = pipe_fds[1];
+
+  thread_ = std::thread([this]() { ThreadRoutine(); });
+  if (!thread_.joinable()) return -1;
+
+  return 0;
+}
+
+int AsyncFdWatcher::stopThread() {
+  if (!std::atomic_exchange(&running_, false)) return 0;
+
+  notifyThread();
+  if (std::this_thread::get_id() != thread_.get_id()) {
+    thread_.join();
+  }
+
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    cb_ = nullptr;
+    read_fd_ = -1;
+  }
+
+  return 0;
+}
+
+int AsyncFdWatcher::notifyThread() {
+  uint8_t buffer[] = {0};
+  if (TEMP_FAILURE_RETRY(write(notification_write_fd_, &buffer, 1)) < 0) {
+    return -1;
+  }
+  return 0;
+}
+
+void AsyncFdWatcher::ThreadRoutine() {
+  while (running_) {
+    fd_set read_fds;
+    FD_ZERO(&read_fds);
+    FD_SET(notification_listen_fd_, &read_fds);
+    FD_SET(read_fd_, &read_fds);
+
+    // Wait until there is data available to read on some FD
+    int nfds = std::max(notification_listen_fd_, read_fd_);
+    int retval = select(nfds + 1, &read_fds, NULL, NULL, NULL);
+    if (retval <= 0) continue;  // there was some error or a timeout
+
+    // Read data from the notification FD
+    if (FD_ISSET(notification_listen_fd_, &read_fds)) {
+      char buffer[] = {0};
+      TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, 1));
+    }
+
+    // Make sure we're still running
+    if (!running_) break;
+
+    // Invoke the data ready callback if appropriate
+    if (FD_ISSET(read_fd_, &read_fds)) {
+      std::unique_lock<std::mutex> guard(internal_mutex_);
+      if (cb_) cb_(read_fd_);
+    }
+  }
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/1.0/default/async_fd_watcher.h b/bluetooth/1.0/default/async_fd_watcher.h
new file mode 100644
index 0000000..1e4da8c
--- /dev/null
+++ b/bluetooth/1.0/default/async_fd_watcher.h
@@ -0,0 +1,63 @@
+//
+// Copyright 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.
+//
+
+#pragma once
+
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+using ReadCallback = std::function<void(int)>;
+
+class AsyncFdWatcher {
+ public:
+  AsyncFdWatcher() = default;
+  ~AsyncFdWatcher();
+
+  int WatchFdForNonBlockingReads(int file_descriptor,
+                                 const ReadCallback& on_read_fd_ready_callback);
+  void StopWatchingFileDescriptor();
+
+ private:
+  AsyncFdWatcher(const AsyncFdWatcher&) = delete;
+  AsyncFdWatcher& operator=(const AsyncFdWatcher&) = delete;
+
+  int tryStartThread();
+  int stopThread();
+  int notifyThread();
+  void ThreadRoutine();
+
+  std::atomic_bool running_{false};
+  std::thread thread_;
+  std::mutex internal_mutex_;
+
+  int read_fd_;
+  int notification_listen_fd_;
+  int notification_write_fd_;
+  ReadCallback cb_;
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_address.cc b/bluetooth/1.0/default/bluetooth_address.cc
new file mode 100644
index 0000000..b917de9
--- /dev/null
+++ b/bluetooth/1.0/default/bluetooth_address.cc
@@ -0,0 +1,93 @@
+//
+// Copyright 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.
+//
+
+#include "bluetooth_address.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+void BluetoothAddress::bytes_to_string(const uint8_t* addr, char* addr_str) {
+  sprintf(addr_str, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2],
+          addr[3], addr[4], addr[5]);
+}
+
+bool BluetoothAddress::string_to_bytes(const char* addr_str, uint8_t* addr) {
+  if (addr_str == NULL) return false;
+  if (strnlen(addr_str, kStringLength) != kStringLength) return false;
+  unsigned char trailing_char = '\0';
+
+  return (sscanf(addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx%1c",
+                 &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5],
+                 &trailing_char) == kBytes);
+}
+
+bool BluetoothAddress::get_local_address(uint8_t* local_addr) {
+  char property[PROPERTY_VALUE_MAX] = {0};
+  bool valid_bda = false;
+
+  // Get local bdaddr storage path from a system property.
+  if (property_get(PROPERTY_BT_BDADDR_PATH, property, NULL)) {
+    int addr_fd;
+
+    ALOGD("%s: Trying %s", __func__, property);
+
+    addr_fd = open(property, O_RDONLY);
+    if (addr_fd != -1) {
+      int bytes_read = read(addr_fd, property, kStringLength);
+      CHECK(bytes_read == kStringLength);
+      close(addr_fd);
+
+      // Null terminate the string.
+      property[kStringLength] = '\0';
+
+      // If the address is not all zeros, then use it.
+      const uint8_t zero_bdaddr[kBytes] = {0, 0, 0, 0, 0, 0};
+      if ((string_to_bytes(property, local_addr)) &&
+          (memcmp(local_addr, zero_bdaddr, kBytes) != 0)) {
+        valid_bda = true;
+        ALOGD("%s: Got Factory BDA %s", __func__, property);
+      }
+    }
+  }
+
+  // No BDADDR found in the file. Look for BDA in a factory property.
+  if (!valid_bda && property_get(FACTORY_BDADDR_PROPERTY, property, NULL) &&
+      string_to_bytes(property, local_addr)) {
+    valid_bda = true;
+  }
+
+  // No factory BDADDR found. Look for a previously stored BDA.
+  if (!valid_bda && property_get(PERSIST_BDADDR_PROPERTY, property, NULL) &&
+      string_to_bytes(property, local_addr)) {
+    valid_bda = true;
+  }
+
+  return valid_bda;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_address.h b/bluetooth/1.0/default/bluetooth_address.h
new file mode 100644
index 0000000..94bf616
--- /dev/null
+++ b/bluetooth/1.0/default/bluetooth_address.h
@@ -0,0 +1,61 @@
+//
+// Copyright 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.
+//
+
+#pragma once
+
+#include <fcntl.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+// The property key stores the storage location of Bluetooth Device Address
+static constexpr char PROPERTY_BT_BDADDR_PATH[] = "ro.bt.bdaddr_path";
+
+// Check for a legacy address stored as a property.
+static constexpr char PERSIST_BDADDR_PROPERTY[] =
+    "persist.service.bdroid.bdaddr";
+
+// If there is no valid bdaddr available from PROPERTY_BT_BDADDR_PATH and there
+// is no available persistent bdaddr available from PERSIST_BDADDR_PROPERTY,
+// use a factory set address.
+static constexpr char FACTORY_BDADDR_PROPERTY[] = "ro.boot.btmacaddr";
+
+// Encapsulate handling for Bluetooth Addresses:
+class BluetoothAddress {
+ public:
+  // Conversion constants
+  static constexpr size_t kStringLength = sizeof("XX:XX:XX:XX:XX:XX") - 1;
+  static constexpr size_t kBytes = (kStringLength + 1) / 3;
+
+  static void bytes_to_string(const uint8_t* addr, char* addr_str);
+
+  static bool string_to_bytes(const char* addr_str, uint8_t* addr);
+
+  static bool get_local_address(uint8_t* addr);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
new file mode 100644
index 0000000..d12bfb9
--- /dev/null
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -0,0 +1,95 @@
+//
+// Copyright 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.bluetooth@1.0-impl"
+#include <utils/Log.h>
+
+#include "bluetooth_hci.h"
+#include "vendor_interface.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+static const uint8_t HCI_DATA_TYPE_COMMAND = 1;
+static const uint8_t HCI_DATA_TYPE_ACL = 2;
+static const uint8_t HCI_DATA_TYPE_SCO = 3;
+
+Return<Status> BluetoothHci::initialize(
+    const ::android::sp<IBluetoothHciCallbacks>& cb) {
+  ALOGW("BluetoothHci::initialize()");
+  event_cb_ = cb;
+
+  bool rc = VendorInterface::Initialize(
+      [this](HciPacketType type, const hidl_vec<uint8_t>& packet) {
+        switch (type) {
+          case HCI_PACKET_TYPE_EVENT:
+            event_cb_->hciEventReceived(packet);
+            break;
+          case HCI_PACKET_TYPE_ACL_DATA:
+            event_cb_->aclDataReceived(packet);
+            break;
+          case HCI_PACKET_TYPE_SCO_DATA:
+            event_cb_->scoDataReceived(packet);
+            break;
+          default:
+            ALOGE("%s Unexpected event type %d", __func__, type);
+            break;
+        }
+      });
+  if (!rc) return Status::INITIALIZATION_ERROR;
+
+  return Status::SUCCESS;
+}
+
+Return<void> BluetoothHci::close() {
+  ALOGW("BluetoothHci::close()");
+  VendorInterface::Shutdown();
+  return Void();
+}
+
+Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
+  sendDataToController(HCI_DATA_TYPE_COMMAND, command);
+  return Void();
+}
+
+Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
+  sendDataToController(HCI_DATA_TYPE_ACL, data);
+  return Void();
+}
+
+Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
+  sendDataToController(HCI_DATA_TYPE_SCO, data);
+  return Void();
+}
+
+void BluetoothHci::sendDataToController(const uint8_t type,
+                                        const hidl_vec<uint8_t>& data) {
+  VendorInterface::get()->Send(&type, 1);
+  VendorInterface::get()->Send(data.data(), data.size());
+}
+
+IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
+  return new BluetoothHci();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/bluetooth_hci.h b/bluetooth/1.0/default/bluetooth_hci.h
new file mode 100644
index 0000000..d297570
--- /dev/null
+++ b/bluetooth/1.0/default/bluetooth_hci.h
@@ -0,0 +1,55 @@
+//
+// Copyright 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 HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+#define HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+
+class BluetoothHci : public IBluetoothHci {
+ public:
+  Return<Status> initialize(
+      const ::android::sp<IBluetoothHciCallbacks>& cb) override;
+  Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
+  Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
+  Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
+  Return<void> close() override;
+
+ private:
+  void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
+  ::android::sp<IBluetoothHciCallbacks> event_cb_;
+};
+
+extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
diff --git a/bluetooth/1.0/default/bt_vendor_lib.h b/bluetooth/1.0/default/bt_vendor_lib.h
new file mode 100644
index 0000000..c140e52
--- /dev/null
+++ b/bluetooth/1.0/default/bt_vendor_lib.h
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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 BT_VENDOR_LIB_H
+#define BT_VENDOR_LIB_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Struct types */
+
+/** Typedefs and defines */
+
+/** Vendor specific operations OPCODE */
+typedef enum {
+  /*  [operation]
+   *      Power on or off the BT Controller.
+   *  [input param]
+   *      A pointer to int type with content of bt_vendor_power_state_t.
+   *      Typecasting conversion: (int *) param.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_POWER_CTRL,
+
+  /*  [operation]
+   *      Perform any vendor specific initialization or configuration
+   *      on the BT Controller. This is called before stack initialization.
+   *  [input param]
+   *      None.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      Must call fwcfg_cb to notify the stack of the completion of vendor
+   *      specific initialization once it has been done.
+   */
+  BT_VND_OP_FW_CFG,
+
+  /*  [operation]
+   *      Perform any vendor specific SCO/PCM configuration on the BT
+   * Controller.
+   *      This is called after stack initialization.
+   *  [input param]
+   *      None.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      Must call scocfg_cb to notify the stack of the completion of vendor
+   *      specific SCO configuration once it has been done.
+   */
+  BT_VND_OP_SCO_CFG,
+
+  /*  [operation]
+   *      Open UART port on where the BT Controller is attached.
+   *      This is called before stack initialization.
+   *  [input param]
+   *      A pointer to int array type for open file descriptors.
+   *      The mapping of HCI channel to fd slot in the int array is given in
+   *      bt_vendor_hci_channels_t.
+   *      And, it requires the vendor lib to fill up the content before
+   * returning
+   *      the call.
+   *      Typecasting conversion: (int (*)[]) param.
+   *  [return]
+   *      Numbers of opened file descriptors.
+   *      Valid number:
+   *          1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART)
+   *          2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd
+   *          4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_USERIAL_OPEN,
+
+  /*  [operation]
+   *      Close the previously opened UART port.
+   *  [input param]
+   *      None.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_USERIAL_CLOSE,
+
+  /*  [operation]
+   *      Get the LPM idle timeout in milliseconds.
+   *      The stack uses this information to launch a timer delay before it
+   *      attempts to de-assert LPM WAKE signal once downstream HCI packet
+   *      has been delivered.
+   *  [input param]
+   *      A pointer to uint32_t type which is passed in by the stack. And, it
+   *      requires the vendor lib to fill up the content before returning
+   *      the call.
+   *      Typecasting conversion: (uint32_t *) param.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_GET_LPM_IDLE_TIMEOUT,
+
+  /*  [operation]
+   *      Enable or disable LPM mode on BT Controller.
+   *  [input param]
+   *      A pointer to uint8_t type with content of bt_vendor_lpm_mode_t.
+   *      Typecasting conversion: (uint8_t *) param.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      Must call lpm_cb to notify the stack of the completion of LPM
+   *      disable/enable process once it has been done.
+   */
+  BT_VND_OP_LPM_SET_MODE,
+
+  /*  [operation]
+   *      Assert or Deassert LPM WAKE on BT Controller.
+   *  [input param]
+   *      A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t.
+   *      Typecasting conversion: (uint8_t *) param.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_LPM_WAKE_SET_STATE,
+
+  /*  [operation]
+   *      Perform any vendor specific commands related to audio state changes.
+   *  [input param]
+   *      a pointer to bt_vendor_op_audio_state_t indicating what audio state is
+   *      set.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      None.
+   */
+  BT_VND_OP_SET_AUDIO_STATE,
+
+  /*  [operation]
+   *      The epilog call to the vendor module so that it can perform any
+   *      vendor-specific processes (e.g. send a HCI_RESET to BT Controller)
+   *      before the caller calls for cleanup().
+   *  [input param]
+   *      None.
+   *  [return]
+   *      0 - default, don't care.
+   *  [callback]
+   *      Must call epilog_cb to notify the stack of the completion of vendor
+   *      specific epilog process once it has been done.
+   */
+  BT_VND_OP_EPILOG,
+
+  /*  [operation]
+   *      Call to the vendor module so that it can perform all vendor-specific
+   *      operations to start offloading a2dp media encode & tx.
+   *  [input param]
+   *      pointer to bt_vendor_op_a2dp_offload_start_t containing elements
+   *      required for VND FW to setup a2dp offload.
+   *  [return]
+   *      0  - default, dont care.
+   *  [callback]
+   *      Must call a2dp_offload_start_cb to notify the stack of the
+   *      completion of vendor specific setup process once it has been done.
+   */
+  BT_VND_OP_A2DP_OFFLOAD_START,
+
+  /*  [operation]
+   *      Call to the vendor module so that it can perform all vendor-specific
+   *      operations to suspend offloading a2dp media encode & tx.
+   *  [input param]
+   *      pointer to bt_vendor_op_a2dp_offload_t containing elements
+   *      required for VND FW to setup a2dp offload.
+   *  [return]
+   *      0  - default, dont care.
+   *  [callback]
+   *      Must call a2dp_offload_cb to notify the stack of the
+   *      completion of vendor specific setup process once it has been done.
+   */
+  BT_VND_OP_A2DP_OFFLOAD_STOP,
+
+} bt_vendor_opcode_t;
+
+/** Power on/off control states */
+typedef enum {
+  BT_VND_PWR_OFF,
+  BT_VND_PWR_ON,
+} bt_vendor_power_state_t;
+
+/** Define HCI channel identifier in the file descriptors array
+    used in BT_VND_OP_USERIAL_OPEN operation.
+ */
+typedef enum {
+  CH_CMD,      // HCI Command channel
+  CH_EVT,      // HCI Event channel
+  CH_ACL_OUT,  // HCI ACL downstream channel
+  CH_ACL_IN,   // HCI ACL upstream channel
+
+  CH_MAX  // Total channels
+} bt_vendor_hci_channels_t;
+
+/** LPM disable/enable request */
+typedef enum {
+  BT_VND_LPM_DISABLE,
+  BT_VND_LPM_ENABLE,
+} bt_vendor_lpm_mode_t;
+
+/** LPM WAKE set state request */
+typedef enum {
+  BT_VND_LPM_WAKE_ASSERT,
+  BT_VND_LPM_WAKE_DEASSERT,
+} bt_vendor_lpm_wake_state_t;
+
+/** Callback result values */
+typedef enum {
+  BT_VND_OP_RESULT_SUCCESS,
+  BT_VND_OP_RESULT_FAIL,
+} bt_vendor_op_result_t;
+
+/** audio (SCO) state changes triggering VS commands for configuration */
+typedef struct {
+  uint16_t handle;
+  uint16_t peer_codec;
+  uint16_t state;
+} bt_vendor_op_audio_state_t;
+
+/*
+ * Bluetooth Host/Controller Vendor callback structure.
+ */
+
+/* vendor initialization/configuration callback */
+typedef void (*cfg_result_cb)(bt_vendor_op_result_t result);
+
+/* datapath buffer allocation callback (callout)
+ *
+ *  Vendor lib needs to request a buffer through the alloc callout function
+ *  from HCI lib if the buffer is for constructing a HCI Command packet which
+ *  will be sent through xmit_cb to BT Controller.
+ *
+ *  For each buffer allocation, the requested size needs to be big enough to
+ *  accommodate the below header plus a complete HCI packet --
+ *      typedef struct
+ *      {
+ *          uint16_t          event;
+ *          uint16_t          len;
+ *          uint16_t          offset;
+ *          uint16_t          layer_specific;
+ *      } HC_BT_HDR;
+ *
+ *  HCI lib returns a pointer to the buffer where Vendor lib should use to
+ *  construct a HCI command packet as below format:
+ *
+ *  --------------------------------------------
+ *  |  HC_BT_HDR  |  HCI command               |
+ *  --------------------------------------------
+ *  where
+ *      HC_BT_HDR.event = 0x2000;
+ *      HC_BT_HDR.len = Length of HCI command;
+ *      HC_BT_HDR.offset = 0;
+ *      HC_BT_HDR.layer_specific = 0;
+ *
+ *  For example, a HCI_RESET Command will be formed as
+ *  ------------------------
+ *  |  HC_BT_HDR  |03|0c|00|
+ *  ------------------------
+ *  with
+ *      HC_BT_HDR.event = 0x2000;
+ *      HC_BT_HDR.len = 3;
+ *      HC_BT_HDR.offset = 0;
+ *      HC_BT_HDR.layer_specific = 0;
+ */
+typedef void* (*malloc_cb)(int size);
+
+/* datapath buffer deallocation callback (callout) */
+typedef void (*mdealloc_cb)(void* p_buf);
+
+/* define callback of the cmd_xmit_cb
+ *
+ *  The callback function which HCI lib will call with the return of command
+ *  complete packet. Vendor lib is responsible for releasing the buffer passed
+ *  in at the p_mem parameter by calling dealloc callout function.
+ */
+typedef void (*tINT_CMD_CBACK)(void* p_mem);
+
+/* hci command packet transmit callback (callout)
+ *
+ *  Vendor lib calls xmit_cb callout function in order to send a HCI Command
+ *  packet to BT Controller. The buffer carrying HCI Command packet content
+ *  needs to be first allocated through the alloc callout function.
+ *  HCI lib will release the buffer for Vendor lib once it has delivered the
+ *  packet content to BT Controller.
+ *
+ *  Vendor lib needs also provide a callback function (p_cback) which HCI lib
+ *  will call with the return of command complete packet.
+ *
+ *  The opcode parameter gives the HCI OpCode (combination of OGF and OCF) of
+ *  HCI Command packet. For example, opcode = 0x0c03 for the HCI_RESET command
+ *  packet.
+ */
+typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void* p_buf,
+                               tINT_CMD_CBACK p_cback);
+
+typedef void (*cfg_a2dp_cb)(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
+                            uint8_t bta_av_handle);
+
+typedef struct {
+  /** set to sizeof(bt_vendor_callbacks_t) */
+  size_t size;
+
+  /*
+   * Callback and callout functions have implemented in HCI libray
+   * (libbt-hci.so).
+   */
+
+  /* notifies caller result of firmware configuration request */
+  cfg_result_cb fwcfg_cb;
+
+  /* notifies caller result of sco configuration request */
+  cfg_result_cb scocfg_cb;
+
+  /* notifies caller result of lpm enable/disable */
+  cfg_result_cb lpm_cb;
+
+  /* notifies the result of codec setting */
+  cfg_result_cb audio_state_cb;
+
+  /* buffer allocation request */
+  malloc_cb alloc;
+
+  /* buffer deallocation request */
+  mdealloc_cb dealloc;
+
+  /* hci command packet transmit request */
+  cmd_xmit_cb xmit_cb;
+
+  /* notifies caller completion of epilog process */
+  cfg_result_cb epilog_cb;
+
+  /* notifies status of a2dp offload cmd's */
+  cfg_a2dp_cb a2dp_offload_cb;
+} bt_vendor_callbacks_t;
+
+/** A2DP offload request */
+typedef struct {
+  uint8_t bta_av_handle;  /* BTA_AV Handle for callbacks */
+  uint16_t xmit_quota;    /* Total ACL quota for light stack */
+  uint16_t acl_data_size; /* Max ACL data size across HCI transport */
+  uint16_t stream_mtu;
+  uint16_t local_cid;
+  uint16_t remote_cid;
+  uint16_t lm_handle;
+  uint8_t is_flushable; /* true if flushable channel */
+  uint32_t stream_source;
+  uint8_t codec_info[10]; /* Codec capabilities array */
+} bt_vendor_op_a2dp_offload_t;
+
+/*
+ * Bluetooth Host/Controller VENDOR Interface
+ */
+typedef struct {
+  /** Set to sizeof(bt_vndor_interface_t) */
+  size_t size;
+
+  /*
+   * Functions need to be implemented in Vendor libray (libbt-vendor.so).
+   */
+
+  /**
+   * Caller will open the interface and pass in the callback routines
+   * to the implemenation of this interface.
+   */
+  int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char* local_bdaddr);
+
+  /**  Vendor specific operations */
+  int (*op)(bt_vendor_opcode_t opcode, void* param);
+
+  /** Closes the interface */
+  void (*cleanup)(void);
+} bt_vendor_interface_t;
+
+/*
+ * External shared lib functions/data
+ */
+
+/* Entry point of DLib --
+ *      Vendor library needs to implement the body of bt_vendor_interface_t
+ *      structure and uses the below name as the variable name. HCI library
+ *      will use this symbol name to get address of the object through the
+ *      dlsym call.
+ */
+extern const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE;
+
+// MODIFICATION FOR NEW HAL/HIDL IMPLEMENTATION:
+// EXPOSE THE BT_HDR STRUCT HERE FOR THE VENDOR INTERFACE
+// ONLY, WITHOUT REQUIRING INCLUDES FROM system/bt OR OTHER
+// DIRECTORIES.
+// ONLY USED INSIDE transmit_cb.
+// DO NOT USE IN NEW HAL IMPLEMENTATIONS GOING FORWARD
+typedef struct
+{
+    uint16_t          event;
+    uint16_t          len;
+    uint16_t          offset;
+    uint16_t          layer_specific;
+    uint8_t           data[];
+} HC_BT_HDR;
+// /MODIFICATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BT_VENDOR_LIB_H */
diff --git a/bluetooth/1.0/default/hci_internals.h b/bluetooth/1.0/default/hci_internals.h
new file mode 100644
index 0000000..d839590
--- /dev/null
+++ b/bluetooth/1.0/default/hci_internals.h
@@ -0,0 +1,44 @@
+//
+// Copyright 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.
+//
+
+#pragma once
+
+// HCI UART transport packet types (Volume 4, Part A, 2)
+enum HciPacketType {
+  HCI_PACKET_TYPE_UNKNOWN = 0,
+  HCI_PACKET_TYPE_COMMAND = 1,
+  HCI_PACKET_TYPE_ACL_DATA = 2,
+  HCI_PACKET_TYPE_SCO_DATA = 3,
+  HCI_PACKET_TYPE_EVENT = 4
+};
+
+// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
+const size_t HCI_COMMAND_PREAMBLE_SIZE = 3;
+const size_t HCI_LENGTH_OFFSET_CMD = 2;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
+const size_t HCI_ACL_PREAMBLE_SIZE = 4;
+const size_t HCI_LENGTH_OFFSET_ACL = 2;
+
+// 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
+const size_t HCI_SCO_PREAMBLE_SIZE = 3;
+const size_t HCI_LENGTH_OFFSET_SCO = 2;
+
+// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4)
+const size_t HCI_EVENT_PREAMBLE_SIZE = 2;
+const size_t HCI_LENGTH_OFFSET_EVT = 1;
+
+const size_t HCI_PREAMBLE_SIZE_MAX = HCI_ACL_PREAMBLE_SIZE;
diff --git a/bluetooth/1.0/default/service.cpp b/bluetooth/1.0/default/service.cpp
new file mode 100644
index 0000000..a3c3cad
--- /dev/null
+++ b/bluetooth/1.0/default/service.cpp
@@ -0,0 +1,29 @@
+//
+// Copyright 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.bluetooth@1.0-service"
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+
+#include <hidl/LegacySupport.h>
+
+// Generated HIDL files
+using android::hardware::bluetooth::V1_0::IBluetoothHci;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+  return defaultPassthroughServiceImplementation<IBluetoothHci>("bluetooth");
+}
diff --git a/bluetooth/1.0/default/test/bluetooth_address_test.cc b/bluetooth/1.0/default/test/bluetooth_address_test.cc
new file mode 100644
index 0000000..9f80ec2
--- /dev/null
+++ b/bluetooth/1.0/default/test/bluetooth_address_test.cc
@@ -0,0 +1,246 @@
+//
+// Copyright 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.
+//
+
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <gtest/gtest.h>
+
+#include <string>
+#include <vector>
+using std::vector;
+
+#include "bluetooth_address.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+constexpr char kTestAddr1[BluetoothAddress::kStringLength + 1] =
+    "12:34:56:78:9a:bc";
+constexpr uint8_t kTestAddr1_bytes[BluetoothAddress::kBytes] = {
+    0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc};
+constexpr char kZeros[BluetoothAddress::kStringLength + 1] =
+    "00:00:00:00:00:00";
+constexpr uint8_t kZeros_bytes[BluetoothAddress::kBytes] = {0x00, 0x00, 0x00,
+                                                            0x00, 0x00, 0x00};
+constexpr char kTestAddrBad1[BluetoothAddress::kStringLength + 1] =
+    "bb:aa:dd:00:00:01";
+constexpr uint8_t kTestAddrBad1_bytes[BluetoothAddress::kBytes] = {
+    0xbb, 0xaa, 0xdd, 0x00, 0x00, 0x01};
+
+constexpr char kAddrPath[] = "/tmp/my_address_in_a_file.txt";
+
+class BluetoothAddressTest : public ::testing::Test {
+ public:
+  BluetoothAddressTest() {}
+  ~BluetoothAddressTest() {}
+
+  void FileWriteString(const char* path, const char* string);
+};
+
+void BluetoothAddressTest::FileWriteString(const char* path,
+                                           const char* string) {
+  int fd = open(path, O_CREAT | O_RDWR);
+  EXPECT_TRUE(fd > 0) << "err = " << strerror(errno);
+
+  size_t length = strlen(string);
+  size_t bytes_written = write(fd, string, length);
+
+  EXPECT_EQ(length, bytes_written) << strerror(errno);
+
+  close(fd);
+}
+
+TEST_F(BluetoothAddressTest, string_to_bytes) {
+  uint8_t addr[BluetoothAddress::kBytes];
+
+  // Malformed addresses
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("000000000000", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("00:00:00:00:0000", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("00:00:00:00:00:0", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("00:00:00:00:00:0;", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("aB:cD:eF:Gh:iJ:Kl", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("00:00:000:00:00:0;", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("12:34:56:78:90:12;", addr));
+  EXPECT_FALSE(BluetoothAddress::string_to_bytes("12:34:56:78:90:123", addr));
+
+  // Reasonable addresses
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes("00:00:00:00:00:00", addr));
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes("a5:a5:a5:a5:a5:a5", addr));
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes("5A:5A:5A:5A:5A:5A", addr));
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes("AA:BB:CC:DD:EE:FF", addr));
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes("aa:bb:cc:dd:ee:ff", addr));
+
+  // Compare the output to known bytes
+  uint8_t addrA[BluetoothAddress::kBytes];
+  uint8_t addrB[BluetoothAddress::kBytes];
+
+  // kTestAddr1
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes(kTestAddr1, addrA));
+  EXPECT_TRUE(memcmp(addrA, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
+
+  // kZeros
+  EXPECT_TRUE(BluetoothAddress::string_to_bytes(kZeros, addrB));
+  EXPECT_TRUE(memcmp(addrB, kZeros_bytes, BluetoothAddress::kBytes) == 0);
+
+  // kTestAddr1 != kZeros
+  EXPECT_FALSE(memcmp(addrA, addrB, BluetoothAddress::kBytes) == 0);
+}
+
+TEST_F(BluetoothAddressTest, bytes_to_string) {
+  char addrA[BluetoothAddress::kStringLength + 1] = "";
+  char addrB[BluetoothAddress::kStringLength + 1] = "";
+
+  // kTestAddr1
+  BluetoothAddress::bytes_to_string(kTestAddr1_bytes, addrA);
+  EXPECT_TRUE(memcmp(addrA, kTestAddr1, BluetoothAddress::kStringLength) == 0);
+
+  // kZeros
+  BluetoothAddress::bytes_to_string(kZeros_bytes, addrB);
+  EXPECT_TRUE(memcmp(addrB, kZeros, BluetoothAddress::kStringLength) == 0);
+
+  // kTestAddr1 != kZeros
+  EXPECT_FALSE(memcmp(addrA, addrB, BluetoothAddress::kStringLength) == 0);
+}
+
+TEST_F(BluetoothAddressTest, property_set) {
+  // Set the properties to empty strings.
+  property_set(PERSIST_BDADDR_PROPERTY, "");
+  property_set(PROPERTY_BT_BDADDR_PATH, "");
+  property_set(FACTORY_BDADDR_PROPERTY, "");
+
+  // Get returns 0.
+  char prop[PROP_VALUE_MAX] = "";
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) == 0);
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) == 0);
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) == 0);
+
+  // Set the properties to known strings.
+  property_set(PERSIST_BDADDR_PROPERTY, "1");
+  property_set(PROPERTY_BT_BDADDR_PATH, "22");
+  property_set(FACTORY_BDADDR_PROPERTY, "333");
+
+  // Get returns the correct length.
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) == 1);
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) == 2);
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) == 3);
+
+  // Set the properties to empty strings again.
+  property_set(PERSIST_BDADDR_PROPERTY, "");
+  property_set(PROPERTY_BT_BDADDR_PATH, "");
+  property_set(FACTORY_BDADDR_PROPERTY, "");
+
+  // Get returns 0.
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) == 0);
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) == 0);
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) == 0);
+}
+
+TEST_F(BluetoothAddressTest, property_get) {
+  // Set the properties to known strings.
+  property_set(PERSIST_BDADDR_PROPERTY, PERSIST_BDADDR_PROPERTY);
+  property_set(PROPERTY_BT_BDADDR_PATH, PROPERTY_BT_BDADDR_PATH);
+  property_set(FACTORY_BDADDR_PROPERTY, FACTORY_BDADDR_PROPERTY);
+
+  // Get returns the same strings.
+  char prop[PROP_VALUE_MAX] = "";
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(PERSIST_BDADDR_PROPERTY, prop) == 0);
+
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(PROPERTY_BT_BDADDR_PATH, prop) == 0);
+
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(FACTORY_BDADDR_PROPERTY, prop) == 0);
+
+  // Set a property to a different known string.
+  char prop2[PROP_VALUE_MAX] = "Erased";
+  property_set(PERSIST_BDADDR_PROPERTY, prop2);
+
+  // Get returns the correct strings.
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(PROPERTY_BT_BDADDR_PATH, prop) == 0);
+
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(FACTORY_BDADDR_PROPERTY, prop) == 0);
+
+  // Set another property to prop2.
+  property_set(PROPERTY_BT_BDADDR_PATH, prop2);
+
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(FACTORY_BDADDR_PROPERTY, prop) == 0);
+
+  // Set the third property to prop2.
+  property_set(FACTORY_BDADDR_PROPERTY, prop2);
+
+  EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+
+  EXPECT_TRUE(property_get(PROPERTY_BT_BDADDR_PATH, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+
+  EXPECT_TRUE(property_get(FACTORY_BDADDR_PROPERTY, prop, NULL) > 0);
+  EXPECT_TRUE(strcmp(prop2, prop) == 0);
+}
+
+TEST_F(BluetoothAddressTest, get_local_address) {
+  EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, "") == 0);
+  EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
+  uint8_t address[BluetoothAddress::kBytes];
+
+  // File contains a non-zero Address.
+  FileWriteString(kAddrPath, kTestAddr1);
+  EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
+  EXPECT_TRUE(BluetoothAddress::get_local_address(address));
+  EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
+
+  // File contains a zero address.
+  FileWriteString(kAddrPath, kZeros);
+  EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
+  EXPECT_FALSE(BluetoothAddress::get_local_address(address));
+
+  // Factory property contains an address.
+  EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddrBad1) == 0);
+  EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, kTestAddr1) == 0);
+  EXPECT_TRUE(BluetoothAddress::get_local_address(address));
+  EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
+
+  // Persistent property contains an address.
+  memcpy(address, kTestAddrBad1_bytes, BluetoothAddress::kBytes);
+  EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddr1) == 0);
+  EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
+  EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, "") == 0);
+  EXPECT_TRUE(BluetoothAddress::get_local_address(address));
+  EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/test/properties.cc b/bluetooth/1.0/default/test/properties.cc
new file mode 100644
index 0000000..ad5c194
--- /dev/null
+++ b/bluetooth/1.0/default/test/properties.cc
@@ -0,0 +1,79 @@
+//
+// Copyright 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 "properties"
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+static const int MAX_PROPERTIES = 5;
+
+struct property {
+  char key[PROP_KEY_MAX + 2];
+  char value[PROP_VALUE_MAX + 2];
+};
+
+int num_properties = 0;
+struct property properties[MAX_PROPERTIES];
+
+// Find the correct entry.
+static int property_find(const char *key) {
+  for (int i = 0; i < num_properties; i++) {
+    if (strncmp(properties[i].key, key, PROP_KEY_MAX) == 0) {
+      return i;
+    }
+  }
+  return MAX_PROPERTIES;
+}
+
+int property_set(const char *key, const char *value) {
+  if (strnlen(value, PROP_VALUE_MAX) > PROP_VALUE_MAX) return -1;
+
+  // Check to see if the property exists.
+  int prop_index = property_find(key);
+
+  if (prop_index == MAX_PROPERTIES) {
+    if (num_properties >= MAX_PROPERTIES) return -1;
+    prop_index = num_properties;
+    num_properties += 1;
+  }
+
+  // This is test code.  Be nice and don't push the boundary cases!
+  strncpy(properties[prop_index].key, key, PROP_KEY_MAX + 1);
+  strncpy(properties[prop_index].value, value, PROP_VALUE_MAX + 1);
+  return 0;
+}
+
+int property_get(const char *key, char *value, const char *default_value) {
+  // This doesn't mock the behavior of default value
+  if (default_value != NULL) ALOGE("%s: default_value is ignored!", __func__);
+
+  // Check to see if the property exists.
+  int prop_index = property_find(key);
+
+  if (prop_index == MAX_PROPERTIES) return 0;
+
+  int len = strlen(properties[prop_index].value);
+  memcpy(value, properties[prop_index].value, len);
+  value[len] = '\0';
+  return len;
+}
diff --git a/bluetooth/1.0/default/test/sys/system_properties.h b/bluetooth/1.0/default/test/sys/system_properties.h
new file mode 100644
index 0000000..b477a6b
--- /dev/null
+++ b/bluetooth/1.0/default/test/sys/system_properties.h
@@ -0,0 +1,20 @@
+//
+// Copyright 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.
+//
+
+// Mock sys/system_properties.h for testing
+
+#define PROP_VALUE_MAX 50
+#define PROP_KEY_MAX 50
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
new file mode 100644
index 0000000..905e1a6
--- /dev/null
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -0,0 +1,356 @@
+//
+// Copyright 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.
+//
+
+#include "vendor_interface.h"
+
+#define LOG_TAG "android.hardware.bluetooth@1.0-impl"
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+
+#include "bluetooth_address.h"
+
+static const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
+static const char* VENDOR_LIBRARY_SYMBOL_NAME =
+    "BLUETOOTH_VENDOR_LIB_INTERFACE";
+
+static const int INVALID_FD = -1;
+
+namespace {
+
+using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
+
+tINT_CMD_CBACK internal_command_cb;
+VendorInterface* g_vendor_interface = nullptr;
+
+const size_t preamble_size_for_type[] = {
+    0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE,
+    HCI_EVENT_PREAMBLE_SIZE};
+const size_t packet_length_offset_for_type[] = {
+    0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
+    HCI_LENGTH_OFFSET_EVT};
+
+size_t HciGetPacketLengthForType(
+    HciPacketType type, const android::hardware::hidl_vec<uint8_t>& packet) {
+  size_t offset = packet_length_offset_for_type[type];
+  if (type == HCI_PACKET_TYPE_ACL_DATA) {
+    return (((packet[offset + 1]) << 8) | packet[offset]);
+  }
+  return packet[offset];
+}
+
+HC_BT_HDR* WrapPacketAndCopy(uint16_t event,
+                             const android::hardware::hidl_vec<uint8_t>& data) {
+  size_t packet_size = data.size() + sizeof(HC_BT_HDR);
+  HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
+  packet->offset = 0;
+  packet->len = data.size();
+  packet->layer_specific = 0;
+  packet->event = event;
+  // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
+  // be the only way the data is accessed, a pointer could be passed here...
+  memcpy(packet->data, data.data(), data.size());
+  return packet;
+}
+
+uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
+  ALOGV("%s opcode: 0x%04x, ptr: %p", __func__, opcode, buffer);
+  HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
+
+  internal_command_cb = callback;
+  uint8_t type = HCI_PACKET_TYPE_COMMAND;
+  VendorInterface::get()->SendPrivate(&type, 1);
+  VendorInterface::get()->SendPrivate(bt_hdr->data, bt_hdr->len);
+  return true;
+}
+
+void firmware_config_cb(bt_vendor_op_result_t result) {
+  ALOGD("%s result: %d", __func__, result);
+  VendorInterface::get()->OnFirmwareConfigured(result);
+}
+
+void sco_config_cb(bt_vendor_op_result_t result) {
+  ALOGD("%s result: %d", __func__, result);
+}
+
+void low_power_mode_cb(bt_vendor_op_result_t result) {
+  ALOGD("%s result: %d", __func__, result);
+}
+
+void sco_audiostate_cb(bt_vendor_op_result_t result) {
+  ALOGD("%s result: %d", __func__, result);
+}
+
+void* buffer_alloc_cb(int size) {
+  void* p = new uint8_t[size];
+  ALOGV("%s pts: %p, size: %d", __func__, p, size);
+  return p;
+}
+
+void buffer_free_cb(void* buffer) {
+  ALOGV("%s ptr: %p", __func__, buffer);
+  delete[] reinterpret_cast<uint8_t*>(buffer);
+}
+
+void epilog_cb(bt_vendor_op_result_t result) {
+  ALOGD("%s result: %d", __func__, result);
+}
+
+void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
+                     uint8_t av_handle) {
+  ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
+}
+
+const bt_vendor_callbacks_t lib_callbacks = {
+    sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
+    low_power_mode_cb,     sco_audiostate_cb,  buffer_alloc_cb,
+    buffer_free_cb,        transmit_cb,        epilog_cb,
+    a2dp_offload_cb};
+
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+bool VendorInterface::Initialize(PacketReadCallback packet_read_cb) {
+  assert(!g_vendor_interface);
+  g_vendor_interface = new VendorInterface();
+  return g_vendor_interface->Open(packet_read_cb);
+}
+
+void VendorInterface::Shutdown() {
+  CHECK(g_vendor_interface);
+  g_vendor_interface->Close();
+  delete g_vendor_interface;
+  g_vendor_interface = nullptr;
+}
+
+VendorInterface* VendorInterface::get() { return g_vendor_interface; }
+
+bool VendorInterface::Open(PacketReadCallback packet_read_cb) {
+  firmware_configured_ = false;
+  packet_read_cb_ = packet_read_cb;
+
+  // Initialize vendor interface
+
+  lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
+  if (!lib_handle_) {
+    ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
+          dlerror());
+    return false;
+  }
+
+  lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
+      dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
+  if (!lib_interface_) {
+    ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
+          VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
+    return false;
+  }
+
+  // Get the local BD address
+
+  uint8_t local_bda[BluetoothAddress::kBytes];
+  CHECK(BluetoothAddress::get_local_address(local_bda));
+  int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
+  if (status) {
+    ALOGE("%s unable to initialize vendor library: %d", __func__, status);
+    return false;
+  }
+
+  ALOGD("%s vendor library loaded", __func__);
+
+  // Power cycle chip
+
+  int power_state = BT_VND_PWR_OFF;
+  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+  power_state = BT_VND_PWR_ON;
+  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+
+  // Get the UART socket
+
+  int fd_list[CH_MAX] = {0};
+  int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
+
+  if (fd_count != 1) {
+    ALOGE("%s fd count %d != 1; we can't handle this currently...", __func__,
+          fd_count);
+    return false;
+  }
+
+  uart_fd_ = fd_list[0];
+  if (uart_fd_ == INVALID_FD) {
+    ALOGE("%s unable to determine UART fd", __func__);
+    return false;
+  }
+
+  ALOGD("%s UART fd: %d", __func__, uart_fd_);
+
+  fd_watcher_.WatchFdForNonBlockingReads(uart_fd_,
+                                         [this](int fd) { OnDataReady(fd); });
+
+  // Start configuring the firmware
+  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
+
+  return true;
+}
+
+void VendorInterface::Close() {
+  fd_watcher_.StopWatchingFileDescriptor();
+
+  if (lib_interface_ != nullptr) {
+    lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
+    uart_fd_ = INVALID_FD;
+    int power_state = BT_VND_PWR_OFF;
+    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+  }
+
+  if (lib_handle_ != nullptr) {
+    dlclose(lib_handle_);
+    lib_handle_ = nullptr;
+  }
+
+  firmware_configured_ = false;
+}
+
+size_t VendorInterface::Send(const uint8_t* data, size_t length) {
+  if (firmware_configured_ && queued_data_.size() == 0)
+    return SendPrivate(data, length);
+
+  if (!firmware_configured_) {
+    ALOGI("%s queueing command", __func__);
+    queued_data_.resize(queued_data_.size() + length);
+    uint8_t* append_ptr = &queued_data_[queued_data_.size() - length];
+    memcpy(append_ptr, data, length);
+    return length;
+  }
+
+  ALOGI("%s sending queued command", __func__);
+  SendPrivate(queued_data_.data(), queued_data_.size());
+  queued_data_.resize(0);
+
+  ALOGI("%s done sending queued command", __func__);
+
+  return SendPrivate(data, length);
+}
+
+size_t VendorInterface::SendPrivate(const uint8_t* data, size_t length) {
+  if (uart_fd_ == INVALID_FD) return 0;
+
+  size_t transmitted_length = 0;
+  while (length > 0) {
+    ssize_t ret =
+        TEMP_FAILURE_RETRY(write(uart_fd_, data + transmitted_length, length));
+
+    if (ret == -1) {
+      if (errno == EAGAIN) continue;
+      ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+      break;
+
+    } else if (ret == 0) {
+      // Nothing written :(
+      ALOGE("%s zero bytes written - something went wrong...", __func__);
+      break;
+    }
+
+    transmitted_length += ret;
+    length -= ret;
+  }
+
+  return transmitted_length;
+}
+
+void VendorInterface::OnFirmwareConfigured(uint8_t result) {
+  ALOGI("%s: result = %d", __func__, result);
+  firmware_configured_ = true;
+  VendorInterface::get()->Send(NULL, 0);
+}
+
+void VendorInterface::OnDataReady(int fd) {
+  switch (hci_parser_state_) {
+    case HCI_IDLE: {
+      uint8_t buffer[1] = {0};
+      size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
+      CHECK(bytes_read == 1);
+      hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
+      // TODO(eisenbach): Check for workaround(s)
+      CHECK(hci_packet_type_ >= HCI_PACKET_TYPE_ACL_DATA &&
+            hci_packet_type_ <= HCI_PACKET_TYPE_EVENT)
+          << "buffer[0] = " << buffer[0];
+      hci_parser_state_ = HCI_TYPE_READY;
+      hci_packet_.resize(HCI_PREAMBLE_SIZE_MAX);
+      hci_packet_bytes_remaining_ = preamble_size_for_type[hci_packet_type_];
+      hci_packet_bytes_read_ = 0;
+      break;
+    }
+
+    case HCI_TYPE_READY: {
+      size_t bytes_read = TEMP_FAILURE_RETRY(
+          read(fd, hci_packet_.data() + hci_packet_bytes_read_,
+               hci_packet_bytes_remaining_));
+      CHECK(bytes_read > 0);
+      hci_packet_bytes_remaining_ -= bytes_read;
+      hci_packet_bytes_read_ += bytes_read;
+      if (hci_packet_bytes_remaining_ == 0) {
+        size_t packet_length =
+            HciGetPacketLengthForType(hci_packet_type_, hci_packet_);
+        hci_packet_.resize(preamble_size_for_type[hci_packet_type_] +
+                           packet_length);
+        hci_packet_bytes_remaining_ = packet_length;
+        hci_parser_state_ = HCI_PAYLOAD;
+        hci_packet_bytes_read_ = 0;
+      }
+      break;
+    }
+
+    case HCI_PAYLOAD: {
+      size_t bytes_read = TEMP_FAILURE_RETRY(
+          read(fd,
+               hci_packet_.data() + preamble_size_for_type[hci_packet_type_] +
+                   hci_packet_bytes_read_,
+               hci_packet_bytes_remaining_));
+      hci_packet_bytes_remaining_ -= bytes_read;
+      hci_packet_bytes_read_ += bytes_read;
+      if (hci_packet_bytes_remaining_ == 0) {
+        if (firmware_configured_) {
+          if (packet_read_cb_ != nullptr) {
+            packet_read_cb_(hci_packet_type_, hci_packet_);
+          }
+        } else {
+          if (internal_command_cb != nullptr) {
+            HC_BT_HDR* bt_hdr =
+                WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet_);
+            internal_command_cb(bt_hdr);
+          }
+        }
+        hci_parser_state_ = HCI_IDLE;
+      }
+      break;
+    }
+  }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
new file mode 100644
index 0000000..73ff2eb
--- /dev/null
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -0,0 +1,83 @@
+//
+// Copyright 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.
+//
+
+#pragma once
+
+#include <hidl/HidlSupport.h>
+
+#include "async_fd_watcher.h"
+#include "bt_vendor_lib.h"
+#include "hci_internals.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using PacketReadCallback =
+    std::function<void(HciPacketType, const hidl_vec<uint8_t> &)>;
+
+class VendorInterface {
+ public:
+  static bool Initialize(PacketReadCallback packet_read_cb);
+  static void Shutdown();
+  static VendorInterface* get();
+
+  size_t Send(const uint8_t *data, size_t length);
+
+  void OnFirmwareConfigured(uint8_t result);
+
+  // Actually send the data.
+  size_t SendPrivate(const uint8_t *data, size_t length);
+
+ private:
+  VendorInterface() { queued_data_.resize(0); }
+  virtual ~VendorInterface() = default;
+
+  bool Open(PacketReadCallback packet_read_cb);
+  void Close();
+
+  void OnDataReady(int fd);
+
+  // Queue data from Send() until the interface is ready.
+  hidl_vec<uint8_t> queued_data_;
+
+  void *lib_handle_;
+  bt_vendor_interface_t *lib_interface_;
+  AsyncFdWatcher fd_watcher_;
+  int uart_fd_;
+  PacketReadCallback packet_read_cb_;
+  bool firmware_configured_;
+
+  enum HciParserState {
+    HCI_IDLE,
+    HCI_TYPE_READY,
+    HCI_PAYLOAD
+  };
+  HciParserState hci_parser_state_{HCI_IDLE};
+  HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
+  hidl_vec<uint8_t> hci_packet_;
+  size_t hci_packet_bytes_remaining_;
+  size_t hci_packet_bytes_read_;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/1.0/vts/functional/Android.bp b/bluetooth/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..7d04736
--- /dev/null
+++ b/bluetooth/1.0/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// 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: "bluetooth_hidl_hal_test",
+    gtest: true,
+    srcs: ["bluetooth_hidl_hal_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.bluetooth@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "--coverage",
+        "-O0",
+        "-g",
+    ],
+    ldflags: [
+        "--coverage",
+    ],
+}
diff --git a/bluetooth/1.0/vts/functional/bluetooth_hidl_hal_test.cpp b/bluetooth/1.0/vts/functional/bluetooth_hidl_hal_test.cpp
new file mode 100644
index 0000000..2a4bbdd
--- /dev/null
+++ b/bluetooth/1.0/vts/functional/bluetooth_hidl_hal_test.cpp
@@ -0,0 +1,683 @@
+/*
+ * 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 "bluetooth_hidl_hal_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
+#include <android/hardware/bluetooth/1.0/types.h>
+#include <hardware/bluetooth.h>
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+
+using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
+using ::android::hardware::bluetooth::V1_0::Status;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+#define Bluetooth_HCI_SERVICE_NAME "bluetooth"
+
+#define HCI_MINIMUM_HCI_VERSION 5  // Bluetooth Core Specification 3.0 + HS
+#define HCI_MINIMUM_LMP_VERSION 5  // Bluetooth Core Specification 3.0 + HS
+#define NUM_HCI_COMMANDS_BANDWIDTH 1000
+#define NUM_SCO_PACKETS_BANDWIDTH 1000
+#define NUM_ACL_PACKETS_BANDWIDTH 1000
+#define WAIT_FOR_HCI_EVENT_TIMEOUT std::chrono::milliseconds(2000)
+#define WAIT_FOR_SCO_DATA_TIMEOUT std::chrono::milliseconds(1000)
+#define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000)
+
+#define COMMAND_HCI_SHOULD_BE_UNKNOWN \
+  { 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
+#define COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION \
+  { 0x01, 0x10, 0x00 }
+#define COMMAND_HCI_READ_BUFFER_SIZE \
+  { 0x05, 0x10, 0x00 }
+#define COMMAND_HCI_WRITE_LOOPBACK_MODE_LOCAL \
+  { 0x02, 0x18, 0x01, 0x01 }
+#define COMMAND_HCI_RESET \
+  { 0x03, 0x0c, 0x00 }
+#define COMMAND_HCI_WRITE_LOCAL_NAME \
+  { 0x13, 0x0c, 0xf8 }
+#define HCI_STATUS_SUCCESS 0x00
+#define HCI_STATUS_UNKNOWN_HCI_COMMAND 0x01
+
+#define EVENT_CONNECTION_COMPLETE 0x03
+#define EVENT_COMMAND_COMPLETE 0x0e
+#define EVENT_COMMAND_STATUS 0x0f
+#define EVENT_NUMBER_OF_COMPLETED_PACKETS 0x13
+#define EVENT_LOOPBACK_COMMAND 0x19
+
+#define EVENT_CODE_BYTE 0
+#define EVENT_LENGTH_BYTE 1
+#define EVENT_FIRST_PAYLOAD_BYTE 2
+#define EVENT_COMMAND_STATUS_STATUS_BYTE 2
+#define EVENT_COMMAND_STATUS_ALLOWED_PACKETS_BYTE 3
+#define EVENT_COMMAND_STATUS_OPCODE_LSBYTE 4  // Bytes 4 and 5
+#define EVENT_COMMAND_COMPLETE_ALLOWED_PACKETS_BYTE 2
+#define EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE 3  // Bytes 3 and 4
+#define EVENT_COMMAND_COMPLETE_STATUS_BYTE 5
+#define EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE 6
+#define EVENT_LOCAL_HCI_VERSION_BYTE EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE
+#define EVENT_LOCAL_LMP_VERSION_BYTE EVENT_LOCAL_HCI_VERSION_BYTE + 3
+
+#define EVENT_CONNECTION_COMPLETE_PARAM_LENGTH 11
+#define EVENT_CONNECTION_COMPLETE_TYPE 11
+#define EVENT_CONNECTION_COMPLETE_TYPE_SCO 0
+#define EVENT_CONNECTION_COMPLETE_TYPE_ACL 1
+#define EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE 3
+#define EVENT_COMMAND_STATUS_LENGTH 4
+
+#define EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES 2
+
+#define ACL_BROADCAST_ACTIVE_SLAVE (0x1 << 4)
+#define ACL_PACKET_BOUNDARY_COMPLETE (0x3 << 6)
+
+class ThroughputLogger {
+ public:
+  ThroughputLogger(std::string task)
+      : task_(task), start_time_(std::chrono::steady_clock::now()) {}
+
+  ~ThroughputLogger() {
+    if (total_bytes_ == 0) return;
+    std::chrono::duration<double> duration =
+        std::chrono::steady_clock::now() - start_time_;
+    double s = duration.count();
+    if (s == 0) return;
+    double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
+    ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
+          total_bytes_, s);
+  }
+
+  void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
+
+ private:
+  size_t total_bytes_;
+  std::string task_;
+  std::chrono::steady_clock::time_point start_time_;
+};
+
+// The main test class for Bluetooth HIDL HAL.
+class BluetoothHidlTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    // currently test passthrough mode only
+    bluetooth = IBluetoothHci::getService(Bluetooth_HCI_SERVICE_NAME);
+    ALOGW("%s: getService(%s) is %s", __func__, Bluetooth_HCI_SERVICE_NAME,
+          bluetooth->isRemote() ? "remote" : "local");
+    ASSERT_NE(bluetooth, nullptr);
+
+    bluetooth_cb = new BluetoothHciCallbacks(*this);
+    ASSERT_NE(bluetooth_cb, nullptr);
+
+    max_acl_data_packet_length = 0;
+    max_sco_data_packet_length = 0;
+    max_acl_data_packets = 0;
+    max_sco_data_packets = 0;
+
+    event_count = 0;
+    acl_count = 0;
+    sco_count = 0;
+    event_cb_count = 0;
+    acl_cb_count = 0;
+    sco_cb_count = 0;
+
+    // Collision with android::hardware::Status
+    EXPECT_EQ(android::hardware::bluetooth::V1_0::Status::SUCCESS,
+              bluetooth->initialize(bluetooth_cb));
+  }
+
+  virtual void TearDown() override {
+    bluetooth->close();
+    EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
+  }
+
+  void setBufferSizes();
+
+  // Functions called from within tests in loopback mode
+  void sendAndCheckHCI(int num_packets);
+  void sendAndCheckSCO(int num_packets, size_t size, uint16_t handle);
+  void sendAndCheckACL(int num_packets, size_t size, uint16_t handle);
+
+  // Helper functions to try to get a handle on verbosity
+  void enterLoopbackMode(std::vector<uint16_t>& sco_handles,
+                         std::vector<uint16_t>& acl_handles);
+  void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
+  int wait_for_completed_packets_event(uint16_t handle);
+
+  // Inform the test about an event callback
+  inline void notify_event_received() {
+    std::unique_lock<std::mutex> lock(event_mutex);
+    event_count++;
+    event_condition.notify_one();
+  }
+
+  // Test code calls this function to wait for an event callback
+  inline void wait_for_event() {
+    std::unique_lock<std::mutex> lock(event_mutex);
+
+    auto start_time = std::chrono::steady_clock::now();
+    while (event_count == 0)
+      if (event_condition.wait_until(lock,
+                                     start_time + WAIT_FOR_HCI_EVENT_TIMEOUT) ==
+          std::cv_status::timeout)
+        return;
+    event_count--;
+  }
+
+  // Inform the test about an acl data callback
+  inline void notify_acl_data_received() {
+    std::unique_lock<std::mutex> lock(acl_mutex);
+    acl_count++;
+    acl_condition.notify_one();
+  }
+
+  // Test code calls this function to wait for an acl data callback
+  inline void wait_for_acl() {
+    std::unique_lock<std::mutex> lock(acl_mutex);
+
+    while (acl_count == 0)
+      acl_condition.wait_until(
+          lock, std::chrono::steady_clock::now() + WAIT_FOR_ACL_DATA_TIMEOUT);
+    acl_count--;
+  }
+
+  // Inform the test about a sco data callback
+  inline void notify_sco_data_received() {
+    std::unique_lock<std::mutex> lock(sco_mutex);
+    sco_count++;
+    sco_condition.notify_one();
+  }
+
+  // Test code calls this function to wait for a sco data callback
+  inline void wait_for_sco() {
+    std::unique_lock<std::mutex> lock(sco_mutex);
+
+    while (sco_count == 0)
+      sco_condition.wait_until(
+          lock, std::chrono::steady_clock::now() + WAIT_FOR_SCO_DATA_TIMEOUT);
+    sco_count--;
+  }
+
+  // A simple test implementation of BluetoothHciCallbacks.
+  class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
+    BluetoothHidlTest& parent_;
+
+   public:
+    BluetoothHciCallbacks(BluetoothHidlTest& parent) : parent_(parent){};
+
+    virtual ~BluetoothHciCallbacks() = default;
+
+    Return<void> hciEventReceived(
+        const ::android::hardware::hidl_vec<uint8_t>& event) override {
+      parent_.event_cb_count++;
+      parent_.event_queue.push(event);
+      parent_.notify_event_received();
+      ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
+      return Void();
+    };
+
+    Return<void> aclDataReceived(
+        const ::android::hardware::hidl_vec<uint8_t>& data) override {
+      parent_.acl_cb_count++;
+      parent_.acl_queue.push(data);
+      parent_.notify_acl_data_received();
+      return Void();
+    };
+
+    Return<void> scoDataReceived(
+        const ::android::hardware::hidl_vec<uint8_t>& data) override {
+      parent_.sco_cb_count++;
+      parent_.sco_queue.push(data);
+      parent_.notify_sco_data_received();
+      return Void();
+    };
+  };
+
+  sp<IBluetoothHci> bluetooth;
+  sp<IBluetoothHciCallbacks> bluetooth_cb;
+  std::queue<hidl_vec<uint8_t>> event_queue;
+  std::queue<hidl_vec<uint8_t>> acl_queue;
+  std::queue<hidl_vec<uint8_t>> sco_queue;
+
+  int event_cb_count;
+  int sco_cb_count;
+  int acl_cb_count;
+
+  int max_acl_data_packet_length;
+  int max_sco_data_packet_length;
+  int max_acl_data_packets;
+  int max_sco_data_packets;
+
+ private:
+  std::mutex event_mutex;
+  std::mutex sco_mutex;
+  std::mutex acl_mutex;
+  std::condition_variable event_condition;
+  std::condition_variable sco_condition;
+  std::condition_variable acl_condition;
+  int event_count;
+  int sco_count;
+  int acl_count;
+};
+
+// A class for test environment setup (kept since this file is a template).
+class BluetoothHidlEnvironment : public ::testing::Environment {
+ public:
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+
+ private:
+};
+
+// Receive and check status events until a COMMAND_COMPLETE is received.
+void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+  // Allow intermediate COMMAND_STATUS events
+  int status_event_count = 0;
+  hidl_vec<uint8_t> event;
+  do {
+    wait_for_event();
+    EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+    if (event_queue.size() == 0) {
+      event.resize(0);
+      break;
+    }
+    event = event_queue.front();
+    event_queue.pop();
+    EXPECT_GT(event.size(),
+              static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
+    if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) {
+      EXPECT_EQ(EVENT_COMMAND_STATUS_LENGTH, event[EVENT_LENGTH_BYTE]);
+      EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
+      EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
+      EXPECT_EQ(event[EVENT_COMMAND_STATUS_STATUS_BYTE], HCI_STATUS_SUCCESS);
+      status_event_count++;
+    }
+  } while (event.size() > 0 && event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS);
+
+  EXPECT_GT(event.size(),
+            static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+}
+
+// Send the command to read the controller's buffer sizes.
+void BluetoothHidlTest::setBufferSizes() {
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_BUFFER_SIZE;
+  bluetooth->sendHciCommand(cmd);
+
+  wait_for_event();
+
+  EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+  if (event_queue.size() == 0) return;
+
+  hidl_vec<uint8_t> event = event_queue.front();
+  event_queue.pop();
+
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+  max_acl_data_packet_length =
+      event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 1] +
+      (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 2] << 8);
+  max_sco_data_packet_length = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 3];
+  max_acl_data_packets = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 4] +
+                         (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 5] << 8);
+  max_sco_data_packets = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 6] +
+                         (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 7] << 8);
+
+  ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
+        static_cast<int>(max_acl_data_packet_length),
+        static_cast<int>(max_acl_data_packets),
+        static_cast<int>(max_sco_data_packet_length),
+        static_cast<int>(max_sco_data_packets));
+}
+
+// Send an HCI command (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckHCI(int num_packets) {
+  ThroughputLogger logger = {__func__};
+  for (int n = 0; n < num_packets; n++) {
+    // Send an HCI packet
+    std::vector<uint8_t> write_name = COMMAND_HCI_WRITE_LOCAL_NAME;
+    // With a name
+    char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0";
+    size_t new_name_length = strlen(new_name);
+    for (size_t i = 0; i < new_name_length; i++)
+      write_name.push_back(static_cast<uint8_t>(new_name[i]));
+    // And the packet number
+    {
+      size_t i = new_name_length - 1;
+      for (int digits = n; digits > 0; digits = digits / 10, i--)
+        write_name[i] = static_cast<uint8_t>('0' + digits % 10);
+    }
+    // And padding
+    for (size_t i = 0; i < 248 - new_name_length; i++)
+      write_name.push_back(static_cast<uint8_t>(0));
+
+    hidl_vec<uint8_t> cmd = write_name;
+    bluetooth->sendHciCommand(cmd);
+
+    // Check the loopback of the HCI packet
+    wait_for_event();
+    hidl_vec<uint8_t> event = event_queue.front();
+    event_queue.pop();
+    size_t compare_length =
+        (cmd.size() > static_cast<size_t>(0xff) ? static_cast<size_t>(0xff)
+                                                : cmd.size());
+    EXPECT_GT(event.size(), compare_length + EVENT_FIRST_PAYLOAD_BYTE - 1);
+
+    EXPECT_EQ(EVENT_LOOPBACK_COMMAND, event[EVENT_CODE_BYTE]);
+    EXPECT_EQ(compare_length, event[EVENT_LENGTH_BYTE]);
+    if (n == 0) logger.setTotalBytes(cmd.size() * num_packets * 2);
+
+    for (size_t i = 0; i < compare_length; i++)
+      EXPECT_EQ(cmd[i], event[EVENT_FIRST_PAYLOAD_BYTE + i]);
+  }
+}
+
+// Send a SCO data packet (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckSCO(int num_packets, size_t size,
+                                        uint16_t handle) {
+  ThroughputLogger logger = {__func__};
+  for (int n = 0; n < num_packets; n++) {
+    // Send a SCO packet
+    hidl_vec<uint8_t> sco_packet;
+    std::vector<uint8_t> sco_vector;
+    sco_vector.push_back(static_cast<uint8_t>(handle & 0xff));
+    sco_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8));
+    sco_vector.push_back(static_cast<uint8_t>(size & 0xff));
+    sco_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+    for (size_t i = 0; i < size; i++) {
+      sco_vector.push_back(static_cast<uint8_t>(i + n));
+    }
+    sco_packet = sco_vector;
+    bluetooth->sendScoData(sco_vector);
+
+    // Check the loopback of the SCO packet
+    wait_for_sco();
+    hidl_vec<uint8_t> sco_loopback = sco_queue.front();
+    sco_queue.pop();
+
+    EXPECT_EQ(sco_packet.size(), sco_loopback.size());
+    size_t successful_bytes = 0;
+
+    if (n == 0) logger.setTotalBytes(num_packets * size * 2);
+
+    for (size_t i = 0; i < sco_packet.size(); i++) {
+      if (sco_packet[i] == sco_loopback[i]) {
+        successful_bytes = i;
+      } else {
+        ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
+              sco_packet[i], sco_loopback[i]);
+        ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
+              sco_packet[i + 1], sco_loopback[i + 1]);
+        break;
+      }
+    }
+    EXPECT_EQ(sco_packet.size(), successful_bytes + 1);
+  }
+}
+
+// Send an ACL data packet (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckACL(int num_packets, size_t size,
+                                        uint16_t handle) {
+  ThroughputLogger logger = {__func__};
+  for (int n = 0; n < num_packets; n++) {
+    // Send an ACL packet
+    hidl_vec<uint8_t> acl_packet;
+    std::vector<uint8_t> acl_vector;
+    acl_vector.push_back(static_cast<uint8_t>(handle & 0xff));
+    acl_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
+                         ACL_BROADCAST_ACTIVE_SLAVE |
+                         ACL_PACKET_BOUNDARY_COMPLETE);
+    acl_vector.push_back(static_cast<uint8_t>(size & 0xff));
+    acl_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+    for (size_t i = 0; i < size; i++) {
+      acl_vector.push_back(static_cast<uint8_t>(i + n));
+    }
+    acl_packet = acl_vector;
+    bluetooth->sendAclData(acl_vector);
+
+    // Check the loopback of the ACL packet
+    wait_for_acl();
+    hidl_vec<uint8_t> acl_loopback = acl_queue.front();
+    acl_queue.pop();
+
+    EXPECT_EQ(acl_packet.size(), acl_loopback.size());
+    size_t successful_bytes = 0;
+
+    if (n == 0) logger.setTotalBytes(num_packets * size * 2);
+
+    for (size_t i = 0; i < acl_packet.size(); i++) {
+      if (acl_packet[i] == acl_loopback[i]) {
+        successful_bytes = i;
+      } else {
+        ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
+              acl_packet[i], acl_loopback[i]);
+        ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
+              acl_packet[i + 1], acl_loopback[i + 1]);
+        break;
+      }
+    }
+    EXPECT_EQ(acl_packet.size(), successful_bytes + 1);
+  }
+}
+
+// Return the number of completed packets reported by the controller.
+int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
+  wait_for_event();
+  int packets_processed = 0;
+  while (event_queue.size() > 0) {
+    hidl_vec<uint8_t> event = event_queue.front();
+    event_queue.pop();
+
+    EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
+    EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
+
+    uint16_t event_handle = event[3] + (event[4] << 8);
+    EXPECT_EQ(handle, event_handle);
+
+    packets_processed += event[5] + (event[6] << 8);
+  }
+  return packets_processed;
+}
+
+// Send local loopback command and initialize SCO and ACL handles.
+void BluetoothHidlTest::enterLoopbackMode(std::vector<uint16_t>& sco_handles,
+                                          std::vector<uint16_t>& acl_handles) {
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_WRITE_LOOPBACK_MODE_LOCAL;
+  bluetooth->sendHciCommand(cmd);
+
+  // Receive connection complete events with data channels
+  int connection_event_count = 0;
+  hidl_vec<uint8_t> event;
+  do {
+    wait_for_event();
+    event = event_queue.front();
+    event_queue.pop();
+    EXPECT_GT(event.size(),
+              static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+    if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+      EXPECT_GT(event.size(),
+                static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
+      EXPECT_EQ(event[EVENT_LENGTH_BYTE],
+                EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
+      uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
+
+      EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
+                  connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
+
+      // Save handles
+      uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
+                        event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1] << 8;
+      if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
+        sco_handles.push_back(handle);
+      else
+        acl_handles.push_back(handle);
+
+      ALOGD("Connect complete type = %d handle = %d",
+            event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
+      connection_event_count++;
+    }
+  } while (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE);
+
+  EXPECT_GT(connection_event_count, 0);
+
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+}
+
+// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
+TEST_F(BluetoothHidlTest, InitializeAndClose) { }
+
+// Send an HCI Reset with sendHciCommand and wait for a command complete event.
+TEST_F(BluetoothHidlTest, HciReset) {
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_RESET;
+  bluetooth->sendHciCommand(cmd);
+
+  wait_for_command_complete_event(cmd);
+}
+
+// Read and check the HCI version of the controller.
+TEST_F(BluetoothHidlTest, HciVersionTest) {
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
+  bluetooth->sendHciCommand(cmd);
+
+  wait_for_event();
+
+  hidl_vec<uint8_t> event = event_queue.front();
+  event_queue.pop();
+  EXPECT_GT(event.size(), static_cast<size_t>(EVENT_LOCAL_LMP_VERSION_BYTE));
+
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+  EXPECT_LE(HCI_MINIMUM_HCI_VERSION, event[EVENT_LOCAL_HCI_VERSION_BYTE]);
+  EXPECT_LE(HCI_MINIMUM_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
+}
+
+// Send an unknown HCI command and wait for the error message.
+TEST_F(BluetoothHidlTest, HciUnknownCommand) {
+  hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
+  bluetooth->sendHciCommand(cmd);
+
+  wait_for_event();
+
+  hidl_vec<uint8_t> event = event_queue.front();
+  event_queue.pop();
+  EXPECT_GT(event.size(),
+            static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
+
+  EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+  EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+  EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+  EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+            event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+}
+
+// Enter loopback mode, but don't send any packets.
+TEST_F(BluetoothHidlTest, WriteLoopbackMode) {
+  std::vector<uint16_t> sco_connection_handles;
+  std::vector<uint16_t> acl_connection_handles;
+  enterLoopbackMode(sco_connection_handles, acl_connection_handles);
+}
+
+// Enter loopback mode and send single packets.
+TEST_F(BluetoothHidlTest, LoopbackModeSinglePackets) {
+  setBufferSizes();
+  EXPECT_LT(0, max_sco_data_packet_length);
+  EXPECT_LT(0, max_acl_data_packet_length);
+
+  std::vector<uint16_t> sco_connection_handles;
+  std::vector<uint16_t> acl_connection_handles;
+  enterLoopbackMode(sco_connection_handles, acl_connection_handles);
+
+  sendAndCheckHCI(1);
+
+  // This should work, but breaks on some current platforms.  Figure out how to
+  // grandfather older devices but test new ones.
+  int sco_packets_sent = 0;
+  if (0 && sco_connection_handles.size() > 0) {
+    sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
+    sco_packets_sent = 1;
+    EXPECT_EQ(sco_packets_sent,
+              wait_for_completed_packets_event(sco_connection_handles[0]));
+  }
+
+  int acl_packets_sent = 0;
+  if (acl_connection_handles.size() > 0) {
+    sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
+    acl_packets_sent = 1;
+    EXPECT_EQ(acl_packets_sent,
+              wait_for_completed_packets_event(acl_connection_handles[0]));
+  }
+}
+
+// Enter loopback mode and send packets for bandwidth measurements.
+TEST_F(BluetoothHidlTest, LoopbackModeBandwidth) {
+  setBufferSizes();
+
+  std::vector<uint16_t> sco_connection_handles;
+  std::vector<uint16_t> acl_connection_handles;
+  enterLoopbackMode(sco_connection_handles, acl_connection_handles);
+
+  sendAndCheckHCI(NUM_HCI_COMMANDS_BANDWIDTH);
+
+  // This should work, but breaks on some current platforms.  Figure out how to
+  // grandfather older devices but test new ones.
+  int sco_packets_sent = 0;
+  if (0 && sco_connection_handles.size() > 0) {
+    sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
+                    sco_connection_handles[0]);
+    sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
+    EXPECT_EQ(sco_packets_sent,
+              wait_for_completed_packets_event(sco_connection_handles[0]));
+  }
+
+  int acl_packets_sent = 0;
+  if (acl_connection_handles.size() > 0) {
+    sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
+                    acl_connection_handles[0]);
+    acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
+    EXPECT_EQ(acl_packets_sent,
+              wait_for_completed_packets_event(acl_connection_handles[0]));
+  }
+}
+
+int main(int argc, char** argv) {
+  ::testing::AddGlobalTestEnvironment(new BluetoothHidlEnvironment);
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
diff --git a/bluetooth/Android.bp b/bluetooth/Android.bp
index bbb3e4b..ed19a37 100644
--- a/bluetooth/Android.bp
+++ b/bluetooth/Android.bp
@@ -1,4 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/default",
+    "1.0/vts/functional",
 ]
diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp
index 4eb728d..266ef4d 100644
--- a/boot/1.0/Android.bp
+++ b/boot/1.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.boot@1.0-IBootControl-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+    srcs: [
+        "IBootControl.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/boot/1.0/BootControl.vts.cpp",
+        "android/hardware/boot/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.boot@1.0-IBootControl-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/boot/1.0/ $(genDir)/android/hardware/boot/1.0/",
+    srcs: [
+        "IBootControl.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/boot/1.0/BootControl.vts.h",
+        "android/hardware/boot/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.boot@1.0-IBootControl-vts.profiler",
+    generated_sources: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.boot@1.0-IBootControl-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.boot@1.0",
+    ],
+}
diff --git a/boot/1.0/vts/Android.mk b/boot/1.0/vts/Android.mk
index d3a3851..df5dac8 100644
--- a/boot/1.0/vts/Android.mk
+++ b/boot/1.0/vts/Android.mk
@@ -16,36 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for boot.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_boot@1.0
-
-LOCAL_SRC_FILES := \
-  BootControl.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.boot@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
index 6c7809c..bc759bf 100644
--- a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
             _32bit::DATA/nativetest/boot_hidl_hal_test/boot_hidl_hal_test,
             _64bit::DATA/nativetest64/boot_hidl_hal_test/boot_hidl_hal_test,
             "/>
+        <option name="test-config-path" value="vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config" />
         <option name="binary-test-type" value="gtest" />
         <option name="test-timeout" value="1m" />
     </test>
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
new file mode 100644
index 0000000..ebb4d1b
--- /dev/null
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
@@ -0,0 +1,20 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [
+        {
+            "module_name": "system/lib64/hw/bootctrl.msm8996",
+            "git_project": {
+                "name": "platform/hardware/qcom/bootctrl",
+                "path": "hardware/qcom/bootctrl"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/android.hardware.boot@1.0-impl",
+            "git_project": {
+                "name": "platform/hardware/interfaces",
+                "path": "hardware/interfaces"
+            }
+        }
+    ]
+}
diff --git a/broadcastradio/1.0/vts/functional/broadcastradio_hidl_hal_test.cpp b/broadcastradio/1.0/vts/functional/broadcastradio_hidl_hal_test.cpp
index 26666d6..6802c3c 100644
--- a/broadcastradio/1.0/vts/functional/broadcastradio_hidl_hal_test.cpp
+++ b/broadcastradio/1.0/vts/functional/broadcastradio_hidl_hal_test.cpp
@@ -19,9 +19,8 @@
 #include <android-base/logging.h>
 #include <cutils/native_handle.h>
 #include <cutils/properties.h>
+#include <hidl/HidlTransportSupport.h>
 #include <utils/threads.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
 
 #include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
 #include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
@@ -33,7 +32,6 @@
 using ::android::sp;
 using ::android::Mutex;
 using ::android::Condition;
-using ::android::hardware::ProcessState;
 using ::android::hardware::Return;
 using ::android::hardware::Status;
 using ::android::hardware::Void;
@@ -461,8 +459,6 @@
 
 
 int main(int argc, char** argv) {
-  sp<ProcessState> proc(ProcessState::self());
-  ProcessState::self()->startThreadPool();
   ::testing::AddGlobalTestEnvironment(new BroadcastRadioHidlEnvironment);
   ::testing::InitGoogleTest(&argc, argv);
   int status = RUN_ALL_TESTS();
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 3ce5037..a7ab4ab 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -20,6 +20,9 @@
 import android.hardware.graphics.common@1.0::types;
 
 typedef vec<uint8_t> CameraMetadata;
+typedef bitfield<ProducerUsage> ProducerUsageFlags;
+typedef bitfield<ConsumerUsage> ConsumerUsageFlags;
+typedef bitfield<Dataspace> DataspaceFlags;
 
 /**
  * StreamType:
@@ -221,24 +224,12 @@
      * together and then passed to the platform gralloc HAL module for
      * allocating the gralloc buffers for each stream.
      *
-     * For streamType OUTPUT, when passed via
-     * configureStreams(), the initial value of this is the consumer's usage
-     * flags. The HAL may use these consumer flags to decide stream
-     * configuration. For streamType INPUT, when passed via
-     * configureStreams(), the initial value of this is 0. For all streams
-     * passed via configureStreams(), the HAL must set its desired producer
-     * usage flags in the final stream configuration.
+     * The HAL may use these consumer flags to decide stream configuration. For
+     * streamType INPUT, the value of this field is always 0. For all streams
+     * passed via configureStreams(), the HAL must set its own
+     * additional usage flags in its output HalStreamConfiguration.
      */
-    ConsumerUsage usage;
-
-    /**
-     * The maximum number of buffers the HAL device may need to have dequeued at
-     * the same time. The HAL device may not have more buffers in-flight from
-     * this stream than this value. For all streams passed via
-     * configureStreams(), the HAL must set its desired max buffer count in the
-     * final stream configuration.
-     */
-    uint32_t maxBuffers;
+    ConsumerUsageFlags usage;
 
     /**
      * A field that describes the contents of the buffer. The format and buffer
@@ -256,7 +247,7 @@
      * supported. The dataspace values are set using the V0 dataspace
      * definitions.
      */
-    Dataspace dataSpace;
+    DataspaceFlags dataSpace;
 
     /**
      * The required output rotation of the stream.
@@ -328,18 +319,18 @@
     int32_t id;
 
     /**
-     * The pixel format for the buffers in this stream.
-     *
-     * If HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
-     * gralloc module must select a format based on the usage flags provided by
-     * the camera device and the other endpoint of the stream.
+     * An override pixel format for the buffers in this stream.
      *
      * The HAL must respect the requested format in Stream unless it is
      * IMPLEMENTATION_DEFINED, in which case the override format here must be
-     * used instead. This allows cross-platform HALs to use a standard format
-     * since IMPLEMENTATION_DEFINED formats often require device-specific
-     * information. In all other cases, the overrideFormat must match the
-     * requested format.
+     * used by the client instead, for this stream. This allows cross-platform
+     * HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
+     * require device-specific information. In all other cases, the
+     * overrideFormat must match the requested format.
+     *
+     * When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
+     * gralloc module must select a format based on the usage flags provided by
+     * the camera device and the other endpoint of the stream.
      */
     android.hardware.graphics.common@1.0::PixelFormat overrideFormat;
 
@@ -356,8 +347,8 @@
      * consumerUsage must be set. For other types, producerUsage must be set,
      * and consumerUsage must be 0.
      */
-    ProducerUsage producerUsage;
-    ConsumerUsage consumerUsage;
+    ProducerUsageFlags producerUsage;
+    ConsumerUsageFlags consumerUsage;
 
     /**
      * The maximum number of buffers the HAL device may need to have dequeued at
@@ -417,7 +408,16 @@
     int32_t streamId;
 
     /**
-     * The graphics buffer handle to the buffer
+     * The graphics buffer handle to the buffer.
+     *
+     * For StreamBuffers sent to the HAL in a CaptureRequest, this must be a
+     * valid handle to a graphics buffer, with dimensions and format matching
+     * that of the stream.
+     *
+     * For StreamBuffers returned in a CaptureResult, this must be null, since
+     * the handle to the buffer is already known to the client (since the client
+     * sent it in the matching CaptureRequest), and the handle can be identified
+     * by the combination of frame number and stream ID.
      */
     handle buffer;
 
@@ -433,44 +433,34 @@
      * The acquire sync fence for this buffer. The HAL must wait on this fence
      * fd before attempting to read from or write to this buffer.
      *
-     * The framework may be set to -1 to indicate that no waiting is necessary
-     * for this buffer.
+     * In a buffer included in a CaptureRequest, the client may set this to null
+     * to indicate that no waiting is necessary for this buffer.
      *
-     * When the HAL returns an output buffer to the framework with
-     * processCaptureResult(), the acquireFence must be set to -1. If the HAL
-     * never waits on the acquireFence due to an error in filling a buffer,
-     * when calling processCaptureResult() the HAL must set the releaseFence
-     * of the buffer to be the acquireFence passed to it by the framework. This
-     * allows the framework to wait on the fence before reusing the buffer.
-     *
-     * For input buffers, the HAL must not change the acquireFence field during
-     * the processCaptureRequest() call.
-     *
-     * When the HAL returns an input buffer to the framework with
-     * processCaptureResult(), the acquireFence must be set to -1. If the HAL
-     * never waits on input buffer acquire fence due to an error, the sync
-     * fences must be handled similarly to the way they are handled for output
-     * buffers.
+     * When the HAL returns an input or output buffer to the framework with
+     * processCaptureResult(), the acquireFence must be set to null. If the HAL
+     * never waits on the acquireFence due to an error in filling or reading a
+     * buffer, when calling processCaptureResult() the HAL must set the
+     * releaseFence of the buffer to be the acquireFence passed to it by the
+     * client. This allows the client to wait on the fence before reusing the
+     * buffer.
      */
     handle acquireFence;
 
     /**
-     * The release sync fence for this buffer. The HAL must set this fence when
-     * returning buffers to the framework, or write -1 to indicate that no
-     * waiting is required for this buffer.
+     * The release sync fence for this buffer. The HAL must set this to a valid
+     * fence fd when returning the input buffer or output buffers to the client
+     * in a CaptureResult, or set it to null to indicate that no waiting is
+     * required for this buffer.
      *
-     * For the output buffers, the fences must be set in the outputBuffers
-     * array passed to processCaptureResult().
-     *
-     * For the input buffer, the fences must be set in the inputBuffer
-     * passed to processCaptureResult().
+     * The client must set this to be null for all buffers included in a
+     * processCaptureRequest call.
      *
      * After signaling the releaseFence for this buffer, the HAL
      * must not make any further attempts to access this buffer as the
-     * ownership has been fully transferred back to the framework.
+     * ownership has been fully transferred back to the client.
      *
-     * If a fence of -1 was specified then the ownership of this buffer
-     * is transferred back immediately upon the call of processCaptureResult.
+     * If this is null, then the ownership of this buffer is transferred back
+     * immediately upon the call of processCaptureResult.
      */
     handle releaseFence;
 
@@ -635,7 +625,7 @@
          * Shutter message contents. Valid if type is MsgType::SHUTTER
          */
         ShutterMsg shutter;
-    };
+    } msg;
 
 };
 
@@ -731,13 +721,13 @@
     /**
      * The input stream buffer to use for this request, if any.
      *
+     * An invalid inputBuffer is signified by a null inputBuffer::buffer, in
+     * which case the value of all other members of inputBuffer must be ignored.
+     *
      * If inputBuffer is invalid, then the request is for a new capture from the
      * imager. If inputBuffer is valid, the request is for reprocessing the
-     * image contained in inputBuffer.
-     *
-     * In the latter case, the HAL must set the releaseFence of the
-     * inputBuffer to a valid sync fence, or to -1 if the HAL does not support
-     * sync, before processCaptureRequest() returns.
+     * image contained in inputBuffer, and the HAL must release the inputBuffer
+     * back to the client in a subsequent processCaptureResult call.
      *
      * The HAL is required to wait on the acquire sync fence of the input buffer
      * before accessing it.
@@ -750,9 +740,8 @@
      * data from this capture/reprocess. The HAL must wait on the acquire fences
      * of each stream buffer before writing to them.
      *
-     * The HAL takes ownership of the actual buffer_handle_t entries in
-     * outputBuffers; the framework must not access them until they are
-     * returned in a CaptureResult.
+     * The HAL takes ownership of the handles in outputBuffers; the client
+     * must not access them until they are returned in a CaptureResult.
      *
      * Any or all of the buffers included here may be brand new in this
      * request (having never before seen by the HAL).
@@ -832,10 +821,15 @@
     CameraMetadata result;
 
     /**
-     * The handles for the output stream buffers for this capture. They may not
-     * yet be filled at the time the HAL calls processCaptureResult(); the
-     * framework must wait on the release sync fences provided by the HAL before
-     * reading the buffers.
+     * The completed output stream buffers for this capture.
+     *
+     * They may not yet be filled at the time the HAL calls
+     * processCaptureResult(); the framework must wait on the release sync
+     * fences provided by the HAL before reading the buffers.
+     *
+     * The StreamBuffer::buffer handle must be null for all returned buffers;
+     * the client must cache the handle and look it up via the combination of
+     * frame number and stream ID.
      *
      * The number of output buffers returned must be less than or equal to the
      * matching capture request's count. If this is less than the buffer count
@@ -845,7 +839,7 @@
      * valid result metadata or an input buffer is returned in this result.
      *
      * The HAL must set the stream buffer's release sync fence to a valid sync
-     * fd, or to -1 if the buffer has already been filled.
+     * fd, or to null if the buffer has already been filled.
      *
      * If the HAL encounters an error while processing the buffer, and the
      * buffer is not filled, the buffer's status field must be set to ERROR. If
@@ -853,7 +847,7 @@
      * the acquire fence must be copied into the release fence, to allow the
      * framework to wait on the fence before reusing the buffer.
      *
-     * The acquire fence must be set to -1 for all output buffers.
+     * The acquire fence must be set to null for all output buffers.
      *
      * This vector may be empty; if so, at least one other processCaptureResult
      * call must be made (or have been made) by the HAL to provide the filled
@@ -863,8 +857,8 @@
      * all previous frames' buffers for that corresponding stream must have been
      * already delivered (the fences need not have yet been signaled).
      *
-     * Gralloc buffers for a frame may be sent to framework before the
-     * corresponding SHUTTER-notify.
+     * Buffers for a frame may be sent to framework before the corresponding
+     * SHUTTER-notify call is made by the HAL.
      *
      * Performance considerations:
      *
@@ -876,10 +870,11 @@
     vec<StreamBuffer> outputBuffers;
 
     /**
-     * The handle for the input stream buffer for this capture. It may not
-     * yet be consumed at the time the HAL calls processCaptureResult(); the
-     * framework must wait on the release sync fence provided by the HAL before
-     * reusing the buffer.
+     * The handle for the input stream buffer for this capture, if any.
+     *
+     * It may not yet be consumed at the time the HAL calls
+     * processCaptureResult(); the framework must wait on the release sync fence
+     * provided by the HAL before reusing the buffer.
      *
      * The HAL must handle the sync fences the same way they are done for
      * outputBuffers.
diff --git a/contexthub/1.0/IContexthub.hal b/contexthub/1.0/IContexthub.hal
index 8d19aeb..8c792fd 100644
--- a/contexthub/1.0/IContexthub.hal
+++ b/contexthub/1.0/IContexthub.hal
@@ -60,9 +60,11 @@
      * After the init method for nanoApp returns success, this must be indicated
      * to the service by an asynchronous call to handleTxnResult.
      *
+     * Loading a nanoapp must not take more than 30 seconds.
+     *
      * @param hubId identifer of the contextHub
-     *        appBinary binary for the nanoApp
-     *        msg   message to be sent
+     *        appBinary serialized NanoApppBinary for the nanoApp
+     *        transactionId transactionId for this call
      *
      * @return result OK if transation started
      *                BAD_VALUE if parameters are not sane
@@ -71,7 +73,9 @@
      *                TRANSACTION_FAILED if load failed synchronously
      *
      */
-    loadNanoApp(uint32_t hubId, NanoAppBinary appBinary, uint32_t transactionId)
+    loadNanoApp(uint32_t hubId,
+                vec<uint8_t> appBinary,
+                uint32_t transactionId)
             generates (Result result);
 
     /**
@@ -79,6 +83,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous call to handleTxnResult.
      *
+     * Unloading a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -98,6 +104,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous message.
      *
+     * Enabling a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -117,6 +125,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous message.
      *
+     * Disabling a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -136,7 +146,11 @@
      *
      * @param hubId identifer of the contextHub
      *
-     * @return apps all nanoApps on the hub
+     * @return apps all nanoApps on the hub.
+     *              All nanoApps that can be modified by the service must
+     *              be returned. A non-modifiable nanoapps must not be
+     *              returned. A modifiable nanoApp is one that can be
+     *              unloaded/disabled/enabled by the service.
      *
      */
     queryApps(uint32_t hubId) generates (Result result);
diff --git a/contexthub/1.0/IContexthubCallback.hal b/contexthub/1.0/IContexthubCallback.hal
index 29c41ce..9e9cf27 100644
--- a/contexthub/1.0/IContexthubCallback.hal
+++ b/contexthub/1.0/IContexthubCallback.hal
@@ -22,41 +22,44 @@
      * implementation to allow the HAL to send asynchronous messages back
      * to the service and registered clients of the ContextHub service.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         msg   : message
+     * @params msg : message
      *
      */
-     handleClientMsg(uint32_t hubId, ContextHubMsg msg);
+     handleClientMsg(ContextHubMsg msg);
 
     /*
      * This callback is passed by the Contexthub service to the HAL
      * implementation to allow the HAL to send the response for a
      * transaction.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         txnId : transaction id whose result is being sent
+     * @params txnId : transaction id whose result is being sent
      *                 passed in by the service at start of transacation.
      *         result: result of transaction.
      *
      */
-     handleTxnResult(uint32_t hubId, uint32_t txnId,
-             TransactionResult result);
+     handleTxnResult(uint32_t txnId, TransactionResult result);
 
     /*
      * This callback is passed by the Contexthub service to the HAL
      * implementation to allow the HAL to send an asynchronous event
      * to the ContextHub service.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         msg   : message
+     * @params msg : message
      *
      */
-     handleHubEvent(uint32_t hubId, AsyncEventType evt);
+     handleHubEvent(AsyncEventType evt);
 
      /*
       * This callback is passed by the Contexthub service to the HAL
       * implementation to allow the HAL to send information about the
       * currently loaded and active nanoapps on the hub.
+      *
+      * @params appInfo : vector of HubAppinfo structure for each nanoApp
+      *                   on the hub that can be enabled, disabled and
+      *                   unloaded by the service. Any nanoApps that cannot
+      *                   be controlled by the service must not be reported.
+      *                   All nanoApps that can be controlled by the service
+      *                   must be reported.
       */
-      handleAppsInfo(uint32_t hubId, vec<HubAppInfo> appInfo);
+      handleAppsInfo(vec<HubAppInfo> appInfo);
 };
diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp
new file mode 100644
index 0000000..7c5f79d
--- /dev/null
+++ b/contexthub/1.0/default/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * 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_library_shared {
+    name: "android.hardware.contexthub@1.0-impl",
+    relative_install_path: "hw",
+    srcs: ["Contexthub.cpp"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libhwbinder",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "libhidlbase",
+        "libhidltransport",
+        "android.hardware.contexthub@1.0",
+    ],
+}
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
new file mode 100644
index 0000000..ad40878
--- /dev/null
+++ b/contexthub/1.0/default/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.contexthub@1.0-service
+LOCAL_INIT_RC := android.hardware.contexthub@1.0-service.rc
+LOCAL_SRC_FILES := \
+        service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+        libbase \
+        libcutils \
+        libdl \
+        libhardware \
+        libhardware_legacy \
+        libhidlbase \
+        libhidltransport \
+        libhwbinder \
+        liblog \
+        libutils \
+        android.hardware.contexthub@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp
new file mode 100644
index 0000000..d530a87
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.cpp
@@ -0,0 +1,528 @@
+/*
+ * 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.
+ */
+
+#include "Contexthub.h"
+
+#include <inttypes.h>
+
+#include <android/log.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+#undef LOG_TAG
+#define LOG_TAG "ContextHubHalAdapter"
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);
+
+Contexthub::Contexthub()
+        : mInitCheck(NO_INIT),
+          mContextHubModule(nullptr),
+          mIsTransactionPending(false) {
+    const hw_module_t *module;
+
+    mInitCheck = hw_get_module(CONTEXT_HUB_MODULE_ID, &module);
+
+    if (mInitCheck != OK) {
+        ALOGE("Could not load %s module: %s", CONTEXT_HUB_MODULE_ID, strerror(-mInitCheck));
+    } else if (module == nullptr) {
+        ALOGE("hal returned succes but a null module!");
+        // Assign an error, this should not really happen...
+        mInitCheck = UNKNOWN_ERROR;
+    } else {
+        ALOGI("Loaded Context Hub module");
+        mContextHubModule = reinterpret_cast<const context_hub_module_t *>(module);
+    }
+}
+
+bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) {
+    if (!isValidHubId(hubId)) {
+        ALOGW("%s: Hub information is null for hubHandle %d",
+              __FUNCTION__,
+              hubId);
+        return false;
+    } else {
+        msg->app_name = mCachedHubInfo[hubId].osAppName;
+        return true;
+    }
+}
+
+Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
+    std::vector<ContextHub> hubs;
+    if (isInitialized()) {
+        const context_hub_t *hubArray = nullptr;
+        size_t numHubs;
+
+        // Explicitly discarding const. HAL method discards it.
+        numHubs = mContextHubModule->get_hubs(const_cast<context_hub_module_t *>(mContextHubModule),
+                                              &hubArray);
+        ALOGI("Context Hub Hal Adapter reports %zu hubs", numHubs);
+
+        mCachedHubInfo.clear();
+
+        for (size_t i = 0; i < numHubs; i++) {
+            CachedHubInformation info;
+            ContextHub c;
+
+            c.hubId = hubArray[i].hub_id;
+            c.name = hubArray[i].name;
+            c.vendor = hubArray[i].vendor;
+            c.toolchain = hubArray[i].toolchain;
+            c.toolchainVersion = hubArray[i].toolchain_version;
+            c.platformVersion = hubArray[i].platform_version;
+            c.maxSupportedMsgLen = hubArray[i].max_supported_msg_len;
+            c.peakMips = hubArray[i].peak_mips;
+            c.peakPowerDrawMw = hubArray[i].peak_power_draw_mw;
+            c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw;
+            c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw;
+
+            info.callBack = nullptr;
+            info.osAppName = hubArray[i].os_app_name;
+            mCachedHubInfo[hubArray[i].hub_id] = info;
+
+            hubs.push_back(c);
+        }
+    } else {
+        ALOGW("Context Hub Hal Adapter not initialized");
+    }
+
+    _hidl_cb(hubs);
+    return Void();
+}
+
+bool Contexthub::isValidHubId(uint32_t hubId) {
+    if (!mCachedHubInfo.count(hubId)) {
+        ALOGW("Hub information not found for hubId %" PRIu32, hubId);
+        return false;
+    } else {
+        return true;
+    }
+}
+
+sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
+    if (!isValidHubId(hubId)) {
+        return nullptr;
+    } else {
+        return mCachedHubInfo[hubId].callBack;
+    }
+}
+
+Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
+                                            const ContextHubMsg &msg) {
+    if (!isInitialized()) {
+        return Result::NOT_INIT;
+    }
+
+    if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) {
+        return Result::BAD_PARAMS;
+    }
+
+    hub_message_t txMsg = {
+        .app_name.id = msg.appName,
+        .message_type = msg.msgType,
+        .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above
+        .message = static_cast<const uint8_t *>(msg.msg.data()),
+    };
+
+    ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64,
+          txMsg.message_type,
+          txMsg.message_len,
+          txMsg.app_name.id);
+
+    if(mContextHubModule->send_message(hubId, &txMsg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    }
+
+    return Result::OK;
+}
+
+Return<Result> Contexthub::reboot(uint32_t hubId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    msg.message_type = CONTEXT_HUB_OS_REBOOT;
+    msg.message_len = 0;
+    msg.message = nullptr;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::registerCallback(uint32_t hubId,
+                                            const sp<IContexthubCallback> &cb) {
+    Return<Result> retVal = Result::BAD_PARAMS;
+
+    if (!isInitialized()) {
+        // Not initilalized
+        ALOGW("Context hub not initialized successfully");
+        retVal = Result::NOT_INIT;
+    } else if (!isValidHubId(hubId)) {
+        // Initialized, but hubId is  not valid
+        retVal = Result::BAD_PARAMS;
+    } else if (mContextHubModule->subscribe_messages(hubId,
+                                                     contextHubCb,
+                                                     this) == 0) {
+        // Initialized && valid hub && subscription successful
+        retVal = Result::OK;
+        mCachedHubInfo[hubId].callBack = cb;
+    } else {
+        // Initalized && valid hubId - but subscription unsuccessful
+        // This is likely an internal error in the HAL implementation, but we
+        // cannot add more information.
+        ALOGW("Could not subscribe to the hub for callback");
+        retVal = Result::UNKNOWN_FAILURE;
+    }
+
+    return retVal;
+}
+
+static bool isValidOsStatus(const uint8_t *msg,
+                            size_t msgLen,
+                            status_response_t *rsp) {
+    // Workaround a bug in some HALs
+    if (msgLen == 1) {
+        rsp->result = msg[0];
+        return true;
+    }
+
+    if (msg == nullptr || msgLen != sizeof(*rsp)) {
+        ALOGI("Received invalid response (is null : %d, size %zu)",
+              msg == nullptr ? 1 : 0,
+              msgLen);
+        return false;
+    }
+
+    memcpy(rsp, msg, sizeof(*rsp));
+
+    // No sanity checks on return values
+    return true;
+}
+
+int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
+                                uint32_t msgType,
+                                const uint8_t *msg,
+                                int msgLen) {
+    int retVal = -1;
+
+
+    switch(msgType) {
+        case CONTEXT_HUB_APPS_ENABLE:
+        case CONTEXT_HUB_APPS_DISABLE:
+        case CONTEXT_HUB_LOAD_APP:
+        case CONTEXT_HUB_UNLOAD_APP:
+        {
+            struct status_response_t rsp;
+            TransactionResult result;
+            if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) {
+                retVal = 0;
+                result = TransactionResult::SUCCESS;
+            } else {
+                result = TransactionResult::FAILURE;
+            }
+
+            if (cb != nullptr) {
+                cb->handleTxnResult(mTransactionId, result);
+            }
+            retVal = 0;
+            mIsTransactionPending = false;
+            break;
+        }
+
+        case CONTEXT_HUB_QUERY_APPS:
+        {
+            std::vector<HubAppInfo> apps;
+            int numApps = msgLen / sizeof(hub_app_info);
+            const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg);
+
+            for (int i = 0; i < numApps; i++) {
+                hub_app_info query_info;
+                memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
+                HubAppInfo app;
+                app.appId = query_info.app_name.id;
+                app.version = query_info.version;
+                // TODO :: Add memory ranges
+
+                apps.push_back(app);
+            }
+
+            if (cb != nullptr) {
+                cb->handleAppsInfo(apps);
+            }
+            retVal = 0;
+            break;
+        }
+
+        case CONTEXT_HUB_QUERY_MEMORY:
+        {
+            // Deferring this use
+            retVal = 0;
+            break;
+        }
+
+        case CONTEXT_HUB_OS_REBOOT:
+        {
+            mIsTransactionPending = false;
+            if (cb != nullptr) {
+                cb->handleHubEvent(AsyncEventType::RESTARTED);
+            }
+            retVal = 0;
+            break;
+        }
+
+        default:
+        {
+            retVal = -1;
+            break;
+        }
+      }
+
+      return retVal;
+}
+
+int Contexthub::contextHubCb(uint32_t hubId,
+                             const struct hub_message_t *rxMsg,
+                             void *cookie) {
+    Contexthub *obj = static_cast<Contexthub *>(cookie);
+
+    if (rxMsg == nullptr) {
+        ALOGW("Ignoring NULL message");
+        return -1;
+    }
+
+    if (!obj->isValidHubId(hubId)) {
+        ALOGW("Invalid hub Id %" PRIu32, hubId);
+        return -1;
+    }
+
+    sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId);
+
+    if (cb == nullptr) {
+        // This should not ever happen
+        ALOGW("No callback registered, returning");
+        return -1;
+    }
+
+    if (rxMsg->message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
+        obj->handleOsMessage(cb,
+                             rxMsg->message_type,
+                             static_cast<const uint8_t *>(rxMsg->message),
+                             rxMsg->message_len);
+    } else {
+        ContextHubMsg msg;
+
+        msg.appName = rxMsg->app_name.id;
+        msg.msgType = rxMsg->message_type;
+        msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg->message),
+                                       static_cast<const uint8_t *>(rxMsg->message) +
+                                       rxMsg->message_len);
+
+        cb->handleClientMsg(msg);
+    }
+
+    return 0;
+}
+
+Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
+                                         uint64_t appId,
+                                         uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_disable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_UNLOAD_APP;
+    msg.message_len = sizeof(req);
+    msg.message = &req;
+    req.app_name.id = appId;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
+                                       const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+                                       uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t hubMsg;
+
+    if (setOsAppAsDestination(&hubMsg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    hubMsg.message_type = CONTEXT_HUB_LOAD_APP;
+    hubMsg.message_len = appBinary.size();
+    hubMsg.message = appBinary.data();
+
+    if(mContextHubModule->send_message(hubId, &hubMsg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
+                                         uint64_t appId,
+                                         uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_enable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_APPS_ENABLE;
+    msg.message_len = sizeof(req);
+    req.app_name.id = appId;
+    msg.message = &req;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
+                                          uint64_t appId,
+                                          uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_disable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_APPS_DISABLE;
+    msg.message_len = sizeof(req);
+    req.app_name.id = appId;
+    msg.message = &req;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        ALOGW("Could not find hubId %" PRIu32, hubId);
+        return Result::BAD_PARAMS;
+    }
+
+    query_apps_request_t payload;
+    payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter
+    msg.message = &payload;
+    msg.message_len = sizeof(payload);
+    msg.message_type = CONTEXT_HUB_QUERY_APPS;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        ALOGW("Query Apps sendMessage failed");
+        return Result::TRANSACTION_FAILED;
+    }
+
+    return Result::OK;
+}
+
+bool Contexthub::isInitialized() {
+    return (mInitCheck == OK && mContextHubModule != nullptr);
+}
+
+IContexthub *HIDL_FETCH_IContexthub(const char * halName) {
+    ALOGI("%s Called for %s", __FUNCTION__, halName);
+    Contexthub *contexthub = new Contexthub;
+
+    if (!contexthub->isInitialized()) {
+        delete contexthub;
+        contexthub = nullptr;
+    }
+
+    return contexthub;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace contexthub
+}  // namespace hardware
+}  // namespace android
diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h
new file mode 100644
index 0000000..0883ce8
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.h
@@ -0,0 +1,105 @@
+/*
+ * 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_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+#define ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+
+#include <unordered_map>
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub {
+    Contexthub();
+
+    Return<void> getHubs(getHubs_cb _hidl_cb) override;
+
+    Return<Result> registerCallback(uint32_t hubId,
+                                    const sp<IContexthubCallback> &cb) override;
+
+    Return<Result> sendMessageToHub(uint32_t hubId,
+                                    const ContextHubMsg &msg) override;
+
+    Return<Result> loadNanoApp(uint32_t hubId,
+                               const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+                               uint32_t transactionId) override;
+
+    Return<Result> unloadNanoApp(uint32_t hubId,
+                                 uint64_t appId,
+                                 uint32_t transactionId) override;
+
+    Return<Result> enableNanoApp(uint32_t hubId,
+                                 uint64_t appId,
+                                 uint32_t transactionId) override;
+
+    Return<Result> disableNanoApp(uint32_t hubId,
+                                  uint64_t appId,
+                                  uint32_t transactionId) override;
+
+    Return<Result> queryApps(uint32_t hubId) override;
+
+    Return<Result> reboot(uint32_t hubId);
+
+    bool isInitialized();
+
+private:
+
+    struct CachedHubInformation{
+        struct hub_app_name_t osAppName;
+        sp<IContexthubCallback> callBack;
+    };
+
+    status_t mInitCheck;
+    const struct context_hub_module_t *mContextHubModule;
+    std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo;
+
+    sp<IContexthubCallback> mCb;
+    bool mIsTransactionPending;
+    uint32_t mTransactionId;
+
+    bool isValidHubId(uint32_t hubId);
+
+    sp<IContexthubCallback> getCallBackForHubId(uint32_t hubId);
+
+    int handleOsMessage(sp<IContexthubCallback> cb,
+                        uint32_t msgType,
+                        const uint8_t *msg,
+                        int msgLen);
+
+    static int contextHubCb(uint32_t hubId,
+                            const struct hub_message_t *rxMsg,
+                            void *cookie);
+
+    bool setOsAppAsDestination(hub_message_t *msg, int hubId);
+
+    DISALLOW_COPY_AND_ASSIGN(Contexthub);
+};
+
+extern "C" IContexthub *HIDL_FETCH_IContexthub(const char *name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace contexthub
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
new file mode 100644
index 0000000..8dba85f
--- /dev/null
+++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
@@ -0,0 +1,4 @@
+service contexthub-hal-1-0 /system/bin/hw/android.hardware.contexthub@1.0-service
+    class hal
+    user system
+    group system
diff --git a/contexthub/1.0/default/service.cpp b/contexthub/1.0/default/service.cpp
new file mode 100644
index 0000000..db9a4e7
--- /dev/null
+++ b/contexthub/1.0/default/service.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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.contexthub@1.0-service"
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::contexthub::V1_0::IContexthub;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    return defaultPassthroughServiceImplementation<IContexthub>("context_hub");
+}
diff --git a/contexthub/1.0/types.hal b/contexthub/1.0/types.hal
index b9f014b..043bb39 100644
--- a/contexthub/1.0/types.hal
+++ b/contexthub/1.0/types.hal
@@ -18,6 +18,7 @@
 
 enum Result : uint32_t {
     OK,                  // Success
+    UNKNOWN_FAILURE,     // Failure, unknown reason
     BAD_PARAMS,          // Parameters not sane
     NOT_INIT,            // not initialized
     TRANSACTION_FAILED,  // transaction failed
diff --git a/contexthub/Android.bp b/contexthub/Android.bp
index bbb3e4b..ba90f2c 100644
--- a/contexthub/Android.bp
+++ b/contexthub/Android.bp
@@ -1,4 +1,5 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/default",
 ]
diff --git a/drm/crypto/1.0/ICryptoFactory.hal b/drm/crypto/1.0/ICryptoFactory.hal
index 58f86df..4b60ccc 100644
--- a/drm/crypto/1.0/ICryptoFactory.hal
+++ b/drm/crypto/1.0/ICryptoFactory.hal
@@ -25,7 +25,7 @@
  * which are used by a codec to decrypt protected video content.
  */
 interface ICryptoFactory {
-    /*
+    /**
      * Determine if a crypto scheme is supported by this HAL
      *
      * @param uuid identifies the crypto scheme in question
@@ -33,23 +33,18 @@
      */
     isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
 
-    /*
+    /**
      * Create a crypto plugin for the specified uuid and scheme-specific
      * initialization data.
      *
      * @param uuid uniquely identifies the drm scheme. See
      * http://dashif.org/identifiers/protection for uuid assignments
      * @param initData scheme-specific init data.
-     * @return the status of the call
-     * @return the created ICryptoPlugin
-    */
+     * @return status the status of the call. The HAL implementation must return
+     * OK if the plugin is created and ERROR_DRM_CANNOT_HANDLE if the plugin
+     * cannot be created.
+     * @return cryptoPlugin the created ICryptoPlugin
+     */
     createPlugin(uint8_t[16] uuid, vec<uint8_t> initData)
         generates (Status status, ICryptoPlugin cryptoPlugin);
-
-    /*
-     * Destroy a previously created crypto plugin
-     *
-     * @return status the status of the call
-     */
-    destroyPlugin() generates(Status status);
 };
diff --git a/drm/crypto/1.0/ICryptoPlugin.hal b/drm/crypto/1.0/ICryptoPlugin.hal
index 1255fdb..e892e3c 100644
--- a/drm/crypto/1.0/ICryptoPlugin.hal
+++ b/drm/crypto/1.0/ICryptoPlugin.hal
@@ -25,7 +25,7 @@
  * load crypto keys for a codec to decrypt protected video content.
  */
 interface ICryptoPlugin {
-    /*
+    /**
      * Check if the specified mime-type requires a secure decoder
      * component.
      *
@@ -36,7 +36,7 @@
     requiresSecureDecoderComponent(string mime)
         generates(bool secureRequired);
 
-    /*
+    /**
      * Notify a plugin of the currently configured resolution
      *
      * @param width - the display resolutions's width
@@ -44,16 +44,19 @@
      */
     notifyResolution(uint32_t width, uint32_t height);
 
-    /*
+    /**
      * Associate a mediadrm session with this crypto session
      *
      * @param sessionId the MediaDrm session ID to associate with this crypto
      * session
-     * @return the status of the call
+     * @return status the status of the call, status must be
+     * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or
+     * ERROR_DRM_CANNOT_HANDLE if the operation is not supported by the drm
+     * scheme.
      */
     setMediaDrmSession(vec<uint8_t> sessionId) generates(Status status);
 
-    /*
+    /**
      * Decrypt an array of subsamples from the source memory buffer to the
      * destination memory buffer.
      *
@@ -71,14 +74,18 @@
      * call to operate on a range of subsamples in a single call
      * @param source the input buffer for the decryption
      * @param destination the output buffer for the decryption
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_NO_LICENSE if no license keys have been
+     * loaded, ERROR_DRM_LICENSE_EXPIRED if the license keys have expired,
+     * ERROR_DRM_RESOURCE_BUSY if the resources required to perform the
+     * decryption are not available, ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
+     * if required output protections are not active,
+     * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened, or
+     * ERROR_DRM_CANNOT_HANDLE in other failure cases.
      * @return bytesWritten the number of bytes output from the decryption
-     * @return detailedError if the error is a vendor-specific error, the
-     * vendor's crypto HAL may provide a detailed error string to help
-     * describe the error.
      */
     decrypt(bool secure, uint8_t[16] keyId, uint8_t[16] iv, Mode mode,
         Pattern pattern, vec<SubSample> subSamples,
             memory source, DestinationBuffer destination)
-        generates(Status status, uint32_t bytesWritten, string detailedError);
+        generates(Status status, uint32_t bytesWritten);
 };
diff --git a/drm/crypto/1.0/default/Android.mk b/drm/crypto/1.0/default/Android.mk
new file mode 100644
index 0000000..83794ac
--- /dev/null
+++ b/drm/crypto/1.0/default/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2016, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.drm.crypto@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    CryptoFactory.cpp \
+    CryptoPlugin.cpp \
+    TypeConvert.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    libhidlmemory \
+    libutils \
+    liblog \
+    libmediadrm \
+    libstagefright_foundation \
+    android.hardware.drm.crypto@1.0 \
+    android.hidl.memory@1.0
+
+LOCAL_C_INCLUDES := \
+    frameworks/native/include \
+    frameworks/av/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/crypto/1.0/default/CryptoFactory.cpp b/drm/crypto/1.0/default/CryptoFactory.cpp
new file mode 100644
index 0000000..187d564
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include "CryptoFactory.h"
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+    CryptoFactory::CryptoFactory() :
+        loader("/vendor/lib/mediadrm", "createCryptoFactory") {}
+
+    // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+    Return<bool> CryptoFactory::isCryptoSchemeSupported(
+            const hidl_array<uint8_t, 16>& uuid) {
+        for (size_t i = 0; i < loader.factoryCount(); i++) {
+            if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+            const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
+
+        for (size_t i = 0; i < loader.factoryCount(); i++) {
+            if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+                android::CryptoPlugin *legacyPlugin = NULL;
+                status_t status = loader.getFactory(i)->createPlugin(uuid.data(),
+                        initData.data(), initData.size(), &legacyPlugin);
+                CryptoPlugin *newPlugin = NULL;
+                if (legacyPlugin == NULL) {
+                    ALOGE("Crypto legacy HAL: failed to create crypto plugin");
+                } else {
+                    newPlugin = new CryptoPlugin(legacyPlugin);
+                }
+                _hidl_cb(toStatus(status), newPlugin);
+                return Void();
+            }
+        }
+        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
+        return Void();
+    }
+
+    ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char /* *name */) {
+        return new CryptoFactory();
+    }
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/crypto/1.0/default/CryptoFactory.h b/drm/crypto/1.0/default/CryptoFactory.h
new file mode 100644
index 0000000..0855996
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.h
@@ -0,0 +1,70 @@
+/*
+ * 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_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+
+#include <android/hardware/drm/crypto/1.0/ICryptoFactory.h>
+#include <hidl/Status.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/PluginLoader.h>
+#include <media/SharedLibrary.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::ICryptoFactory;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoFactory : public ICryptoFactory {
+    CryptoFactory();
+    virtual ~CryptoFactory() {}
+
+    // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+
+    Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+            override;
+
+    Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
+            const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb)
+            override;
+
+private:
+    android::PluginLoader<android::CryptoFactory> loader;
+
+    CryptoFactory(const CryptoFactory &) = delete;
+    void operator=(const CryptoFactory &) = delete;
+};
+
+extern "C" ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
diff --git a/drm/crypto/1.0/default/CryptoPlugin.cpp b/drm/crypto/1.0/default/CryptoPlugin.cpp
new file mode 100644
index 0000000..7921852
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+
+#include <media/stagefright/foundation/AString.h>
+
+#include <hidlmemory/mapping.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using android::hidl::memory::V1_0::IMemory;
+
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+    // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin follow
+    Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
+            const hidl_string& mime) {
+        return mLegacyPlugin->requiresSecureDecoderComponent(mime);
+    }
+
+    Return<void> CryptoPlugin::notifyResolution(uint32_t width,
+            uint32_t height) {
+        mLegacyPlugin->notifyResolution(width, height);
+        return Void();
+    }
+
+    Return<Status> CryptoPlugin::setMediaDrmSession(
+            const hidl_vec<uint8_t>& sessionId) {
+        return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
+    }
+
+    Return<void> CryptoPlugin::decrypt(bool secure,
+            const hidl_array<uint8_t, 16>& keyId,
+            const hidl_array<uint8_t, 16>& iv, Mode mode,
+            const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
+            const hidl_memory &source, const DestinationBuffer& destination,
+            decrypt_cb _hidl_cb) {
+
+        android::CryptoPlugin::Mode legacyMode;
+        switch(mode) {
+        case Mode::UNENCRYPTED:
+            legacyMode = android::CryptoPlugin::kMode_Unencrypted;
+            break;
+        case Mode::AES_CTR:
+            legacyMode = android::CryptoPlugin::kMode_AES_CTR;
+            break;
+        case Mode::AES_CBC_CTS:
+            legacyMode = android::CryptoPlugin::kMode_AES_WV;
+            break;
+        case Mode::AES_CBC:
+            legacyMode = android::CryptoPlugin::kMode_AES_CBC;
+            break;
+        }
+        android::CryptoPlugin::Pattern legacyPattern;
+        legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
+        legacyPattern.mSkipBlocks = pattern.skipBlocks;
+
+        android::CryptoPlugin::SubSample *legacySubSamples =
+            new android::CryptoPlugin::SubSample[subSamples.size()];
+
+        for (size_t i = 0; i < subSamples.size(); i++) {
+            legacySubSamples[i].mNumBytesOfClearData
+                = subSamples[i].numBytesOfClearData;
+            legacySubSamples[i].mNumBytesOfEncryptedData
+                = subSamples[i].numBytesOfEncryptedData;
+        }
+
+        AString detailMessage;
+
+        void *destPtr = NULL;
+        sp<IMemory> sharedMemory;
+
+        if (destination.type == BufferType::SHARED_MEMORY) {
+            sharedMemory = mapMemory(source);
+            destPtr = sharedMemory->getPointer();
+            sharedMemory->update();
+        } else if (destination.type == BufferType::NATIVE_HANDLE) {
+            native_handle_t *handle = const_cast<native_handle_t *>(
+                    destination.secureMemory.getNativeHandle());
+            destPtr = static_cast<void *>(handle);
+        }
+        ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
+                legacyMode, legacyPattern, sharedMemory->getPointer(),
+                legacySubSamples, subSamples.size(), destPtr, &detailMessage);
+
+        if (destination.type == BufferType::SHARED_MEMORY) {
+            sharedMemory->commit();
+        }
+        delete[] legacySubSamples;
+
+        uint32_t status;
+        uint32_t bytesWritten;
+
+        if (result >= 0) {
+            status = android::OK;
+            bytesWritten = result;
+        } else {
+            status = -result;
+            bytesWritten = 0;
+        }
+
+        _hidl_cb(toStatus(status), bytesWritten);
+        return Void();
+    }
+
+} // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/crypto/1.0/default/CryptoPlugin.h b/drm/crypto/1.0/default/CryptoPlugin.h
new file mode 100644
index 0000000..b17dade
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.h
@@ -0,0 +1,78 @@
+/*
+ * 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_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+
+#include <media/hardware/CryptoAPI.h>
+#include <android/hardware/drm/crypto/1.0/ICryptoPlugin.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::DestinationBuffer;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::drm::crypto::V1_0::Mode;
+using ::android::hardware::drm::crypto::V1_0::Pattern;
+using ::android::hardware::drm::crypto::V1_0::SubSample;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoPlugin : public ICryptoPlugin {
+    CryptoPlugin(android::CryptoPlugin *plugin) : mLegacyPlugin(plugin) {}
+    ~CryptoPlugin() {delete mLegacyPlugin;}
+
+    // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin
+    // follow.
+
+    Return<bool> requiresSecureDecoderComponent(const hidl_string& mime)
+            override;
+
+    Return<void> notifyResolution(uint32_t width, uint32_t height) override;
+
+    Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
+            override;
+
+    Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
+            const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
+            const hidl_vec<SubSample>& subSamples, const hidl_memory& source,
+            const DestinationBuffer& destination, decrypt_cb _hidl_cb) override;
+
+private:
+    android::CryptoPlugin *mLegacyPlugin;
+
+    CryptoPlugin() = delete;
+    CryptoPlugin(const CryptoPlugin &) = delete;
+    void operator=(const CryptoPlugin &) = delete;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
diff --git a/drm/crypto/1.0/default/TypeConvert.cpp b/drm/crypto/1.0/default/TypeConvert.cpp
new file mode 100644
index 0000000..ed95d15
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+    Status status;
+    switch(legacyStatus) {
+    case android::OK:
+        status = Status::OK;
+        break;
+    case android::ERROR_DRM_NO_LICENSE:
+        status = Status::ERROR_DRM_NO_LICENSE;
+        break;
+    case android::ERROR_DRM_LICENSE_EXPIRED:
+        status = Status::ERROR_DRM_LICENSE_EXPIRED;
+        break;
+    case android::ERROR_DRM_RESOURCE_BUSY:
+        status = Status::ERROR_DRM_RESOURCE_BUSY;
+        break;
+    case android::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
+        status = Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
+        break;
+    case android::ERROR_DRM_SESSION_NOT_OPENED:
+        status = Status::ERROR_DRM_SESSION_NOT_OPENED;
+        break;
+    case android::ERROR_DRM_CANNOT_HANDLE:
+    case android::BAD_VALUE:
+        status = Status::ERROR_DRM_CANNOT_HANDLE;
+        break;
+    default:
+        ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
+                legacyStatus);
+        status = Status::ERROR_UNKNOWN_CRYPTO_EXCEPTION;
+        break;
+    }
+    return status;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/crypto/1.0/default/TypeConvert.h b/drm/crypto/1.0/default/TypeConvert.h
new file mode 100644
index 0000000..1655bab
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.h
@@ -0,0 +1,83 @@
+/*
+ * 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_DRM_CRYPTO_V1_0_TYPECONVERT
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
+
+#include <utils/Vector.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/hardware/CryptoAPI.h>
+
+#include <hidl/MQDescriptor.h>
+#include <android/hardware/drm/crypto/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
+    hidl_vec<T> vec;
+    vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
+    return vec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
+    hidl_vec<T> vec;
+    vec.setToExternal(Vector.editArray(), Vector.size());
+    return vec;
+}
+
+template<typename T> const Vector<T> toVector(const hidl_vec<T> &vec) {
+    Vector<T> vector;
+    vector.appendArray(vec.data(), vec.size());
+    return *const_cast<const Vector<T> *>(&vector);
+}
+
+template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
+    Vector<T> vector;
+    vector.appendArray(vec.data(), vec.size());
+    return vector;
+}
+
+template<typename T, size_t SIZE> const Vector<T> toVector(
+        const hidl_array<T, SIZE> &array) {
+    Vector<T> vector;
+    vector.appendArray(array.data(), array.size());
+    return vector;
+}
+
+template<typename T, size_t SIZE> Vector<T> toVector(
+        hidl_array<T, SIZE> &array) {
+    Vector<T> vector;
+    vector.appendArray(array.data(), array.size());
+    return vector;
+}
+
+Status toStatus(status_t legacyStatus);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace crypto
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
diff --git a/drm/crypto/1.0/types.hal b/drm/crypto/1.0/types.hal
index 7e853b8..e71d73a 100644
--- a/drm/crypto/1.0/types.hal
+++ b/drm/crypto/1.0/types.hal
@@ -18,6 +18,12 @@
 
 enum Status : uint32_t {
     /**
+     * The Crypto plugin must return OK when an operation completes without any
+     * errors.
+     */
+    OK,
+
+    /**
      * The Crypto Plugin must return ERROR_DRM_NO_LICENSE if decryption is
      * attempted when the license keys have not been loaded into the crypto
      * session.
diff --git a/drm/drm/1.0/IDrmFactory.hal b/drm/drm/1.0/IDrmFactory.hal
index a4ee0f1..1ef1d27 100644
--- a/drm/drm/1.0/IDrmFactory.hal
+++ b/drm/drm/1.0/IDrmFactory.hal
@@ -27,7 +27,7 @@
  */
 
 interface IDrmFactory {
-    /*
+    /**
      * Determine if a crypto scheme is supported by this HAL
      *
      * @param uuid identifies the crypto scheme in question
@@ -35,22 +35,25 @@
      */
     isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
 
-    /*
+    /**
+     * Determine if the HAL factory is able to construct plugins that support a
+     * given media container format specified by mimeType
+     *
+     * @param mimeType identifies the mime type in question
+     * @return isSupported must be true only if the scheme is supported
+     */
+    isContentTypeSupported(string mimeType) generates(bool isSupported);
+
+    /**
      * Create a drm plugin instance for the specified uuid and scheme-specific
      * initialization data.
      *
      * @param uuid uniquely identifies the drm scheme. See
      * http://dashif.org/identifiers/protection for uuid assignments
-     * @param initData scheme-specific init data.
-     * @return the status of the call
-     * @return the created IDrmPlugin
+     * @return status the status of the call. The HAL implementation must return
+     * OK if the plugin is created and ERROR_DRM_CANNOT_HANDLE if the plugin
+     * cannot be created.
      */
-    createPlugin(uint8_t[16] uuid, vec<uint8_t> initData)
-        generates (Status status, IDrmPlugin drmPlugin);
-
-    /*
-     * Destroy a previously created drm plugin
-     * @return status the status of the call
-     */
-    destroyPlugin() generates(Status status);
+    createPlugin(uint8_t[16] uuid) generates (Status status,
+            IDrmPlugin drmPlugin);
 };
diff --git a/drm/drm/1.0/IDrmPlugin.hal b/drm/drm/1.0/IDrmPlugin.hal
index 7f396d9..881bf80 100644
--- a/drm/drm/1.0/IDrmPlugin.hal
+++ b/drm/drm/1.0/IDrmPlugin.hal
@@ -30,15 +30,25 @@
     /**
      * Open a new session with the DrmPlugin object. A session ID is returned
      * in the sessionId parameter.
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_NOT_PROVISIONED if the device requires
+     * provisioning before it can open a session, ERROR_DRM_RESOURCE_BUSY if
+     * there are insufficent resources available to open a session,
+     * ERROR_DRM_CANNOT_HANDLE, if openSession is not supported at the time of
+     * the call or ERROR_DRM_INVALID_STATE if the HAL is in a state where a
+     * session cannot be opened.
+     * @return sessionId the session ID for the newly opened session
      */
-    openSession() generates (SessionId sessionId, Status status);
+    openSession() generates (Status status, SessionId sessionId);
 
     /**
      * Close a session on the DrmPlugin object
      *
      * @param sessionId the session id the call applies to
-     * @return status the status of the call
+     * @return status the status of the call.  The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the session cannot be closed.
      */
     closeSession(SessionId sessionId) generates (Status status);
 
@@ -65,6 +75,13 @@
      * allow a client application to provide additional message parameters to
      * the server.
      *
+     * @return status the status of the call.  The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+     * before it can generate a key request, ERROR_DRM_CANNOT_HANDLE if
+     * getKeyRequest is not supported at the time of the call, BAD_VALUE if any
+     * parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL is in a state
+     * where a key request cannot be generated.
      * @return request if successful, the opaque key request blob is returned
      * @return requestType indicates type information about the returned
      * request. The type may be one of INITIAL, RENEWAL or RELEASE. An
@@ -72,15 +89,14 @@
      * subsequent key request used to refresh the keys in a license. RELEASE
      * corresponds to a keyType of RELEASE, which indicates keys are being
      * released.
-     * @return status the status of the call
      * @return defaultUrl the URL that the request may be sent to, if
      * provided by the drm HAL. The app may choose to override this
      * URL.
      */
     getKeyRequest(vec<uint8_t> scope, vec<uint8_t> initData,
-        string mimeType, KeyType keyType, KeyedVector optionalParameters)
-        generates (vec<uint8_t> request, KeyRequestType requestType,
-            Status status, string defaultUrl);
+            string mimeType, KeyType keyType, KeyedVector optionalParameters)
+        generates (Status status, vec<uint8_t> request,
+                KeyRequestType requestType, string defaultUrl);
 
     /**
      * After a key response is received by the app, it is provided to the
@@ -93,22 +109,31 @@
      * @param response the response from the key server that is being
      * provided to the drm HAL.
      *
+     * @return status the status of the call.  The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+     * before it can handle the key response, ERROR_DRM_DEVICE_REVOKED if the
+     * device has been disabled by the license policy, ERROR_DRM_CANNOT_HANDLE
+     * if provideKeyResponse is not supported at the time of the call, BAD_VALUE
+     * if any parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL is
+     * in a state where a key response cannot be handled.
      * @return keySetId when the response is for an offline key request, a
      * keySetId is returned in the keySetId vector parameter that can be used
      * to later restore the keys to a new session with the method restoreKeys.
      * When the response is for a streaming or release request, no keySetId is
      * returned.
-     *
-     * @return status the status of the call
      */
-    provideKeyResponse(vec<uint8_t> scope,
-        vec<uint8_t> response) generates (vec<uint8_t> keySetId, Status status);
+    provideKeyResponse(vec<uint8_t> scope, vec<uint8_t> response)
+        generates (Status status, vec<uint8_t> keySetId);
 
     /**
      * Remove the current keys from a session
      *
      * @param sessionId the session id the call applies to
-     * @return status the status of the call
+     * @return status the status of the call.  The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the keys cannot be removed.
      */
     removeKeys(SessionId sessionId) generates (Status status);
 
@@ -118,12 +143,15 @@
      * @param sessionId the session id the call applies to
      * @param keySetId identifies the keys to load, obtained from a prior
      * call to provideKeyResponse().
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where keys cannot be restored.
      */
     restoreKeys(SessionId sessionId,
-        vec<uint8_t> keySetId) generates (Status status);
+            vec<uint8_t> keySetId) generates (Status status);
 
-    /*
+    /**
      * Request an informative description of the license for the session. The
      * status is in the form of {name, value} pairs. Since DRM license policies
      * vary by vendor, the specific status field names are determined by each
@@ -131,45 +159,61 @@
      * the field names for a particular drm scheme.
      *
      * @param sessionId the session id the call applies to
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where key status cannot be queried.
      * @return infoList a list of name value pairs describing the license
-     * @return status the status of the call
      */
     queryKeyStatus(SessionId sessionId)
-        generates (KeyedVector infoList, Status status);
+        generates (Status status, KeyedVector infoList);
 
     /**
      * A provision request/response exchange occurs between the app and a
      * provisioning server to retrieve a device certificate. getProvisionRequest
-     * is used to obtain an opaque key request blob that is delivered to the
-     * provisioning server.
+     * is used to obtain an opaque provisioning request blob that is delivered
+     * to the provisioning server.
      *
      * @param certificateType the type of certificate requested, e.g. "X.509"
      * @param certificateAuthority identifies the certificate authority. A
      * certificate authority (CA) is an entity which issues digital certificates
-     * for use by other parties. It is an example of a trusted third party
-     * @return if successful the opaque certirequest blob is returned
-     * @return status the status of the call
+     * for use by other parties. It is an example of a trusted third party.
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the sessionId is invalid or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the provision
+     * request cannot be generated.
+     * @return request if successful the opaque certificate request blob
+     * is returned
+     * @return defaultUrl URL that the provisioning request should be
+     * sent to, if known by the HAL implementation.  If the HAL implementation
+     * does not provide a defaultUrl, the returned string must be empty.
      */
     getProvisionRequest(string certificateType, string certificateAuthority)
-        generates (vec<uint8_t> request, string defaultUrl, Status status);
+        generates (Status status, vec<uint8_t> request, string defaultUrl);
 
     /**
      * After a provision response is received by the app from a provisioning
-     * server, it can be provided to the Drm HAL using provideProvisionResponse.
+     * server, it is provided to the Drm HAL using provideProvisionResponse.
+     * The HAL implementation must receive the provision request and
+     * store the provisioned credentials.
      *
      * @param response the opaque provisioning response received by the
-     * app from a provisioning server
+     * app from a provisioning server.
+
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_DEVICE_REVOKED if the device has been
+     * disabled by the license policy, BAD_VALUE if any parameters are invalid
+     * or ERROR_DRM_INVALID_STATE if the HAL is in a state where the provision
+     * response cannot be handled.
      * @return certificate the public certificate resulting from the provisioning
      * operation, if any. An empty vector indicates that no certificate was
      * returned.
      * @return wrappedKey an opaque object containing encrypted private key
      * material to be used by signRSA when computing an RSA signature on a
      * message, see the signRSA method.
-     * @return status the status of the call
      */
-    provideProvisionResponse(vec<uint8_t> response)
-        generates (vec<uint8_t> certificate, vec<uint8_t> wrappedKey,
-            Status status);
+    provideProvisionResponse(vec<uint8_t> response) generates (Status status,
+            vec<uint8_t> certificate, vec<uint8_t> wrappedKey);
 
     /**
      * SecureStop is a way of enforcing the concurrent stream limit per
@@ -193,41 +237,52 @@
     /**
      * Get all secure stops on the device
      *
+     * @return status the status of the call. The status must be OK or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stops
+     * cannot be returned.
      * @return secureStops a list of the secure stop opaque objects
-     * @return status the status of the call
      */
     getSecureStops() generates
-        (vec<SecureStop> secureStops, Status status);
+        (Status status, vec<SecureStop> secureStops);
 
     /**
-    * Get all secure stops by secure stop ID
-    *
-    * @param secureStopId the ID of the secure stop to return. The
-    * secure stop ID is delivered by the key server as part of the key
-    * response and must also be known by the app.
-    *
-    * @return the secure stop opaque object
-    * @return status the status of the call
-    */
+     * Get all secure stops by secure stop ID
+     *
+     * @param secureStopId the ID of the secure stop to return. The
+     * secure stop ID is delivered by the key server as part of the key
+     * response and must also be known by the app.
+     *
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the secureStopId is invalid or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stop
+     * cannot be returned.
+     * @return secureStop the secure stop opaque object
+     */
+
     getSecureStop(SecureStopId secureStopId)
-        generates (SecureStop secureStop, Status status);
+        generates (Status status, SecureStop secureStop);
 
     /**
      * Release all secure stops on the device
      *
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure
+     * stops cannot be released.
      */
     releaseAllSecureStops() generates (Status status);
 
     /**
-    * Release a secure stop by secure stop ID
-    *
-    * @param secureStopId the ID of the secure stop to release. The
-    * secure stop ID is delivered by the key server as part of the key
-    * response and must also be known by the app.
-    *
-    * @return status the status of the call
-    */
+     * Release a secure stop by secure stop ID
+     *
+     * @param secureStopId the ID of the secure stop to release. The
+     * secure stop ID is delivered by the key server as part of the key
+     * response and must also be known by the app.
+     *
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the secureStopId is invalid or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stop
+     * cannot be released.
+     */
     releaseSecureStop(vec<uint8_t> secureStopId) generates (Status status);
 
     /**
@@ -252,30 +307,42 @@
      * Read a string property value given the property name.
      *
      * @param propertyName the name of the property
-     * @return the property value string
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the property name is invalid,
+     * ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
+     * cannot be obtained.
+     * @return value the property value string
      */
     getPropertyString(string propertyName)
-        generates (string value, Status status);
+        generates (Status status, string value);
 
     /**
      * Read a byte array property value given the property name.
      *
      * @param propertyName the name of the property
-     * @return the property value byte array
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the property name is invalid,
+     * ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
+     * cannot be obtained.
+     * @return value the property value byte array
      */
     getPropertyByteArray(string propertyName)
-        generates (vec<uint8_t> value, Status status);
+        generates (Status status, vec<uint8_t> value);
 
     /**
      * Write a property string value given the property name
      *
      * @param propertyName the name of the property
      * @param value the value to write
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the property name is invalid,
+     * ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
+     * cannot be set.
      */
-    setPropertyString(string propertyName, string value )
+    setPropertyString(string propertyName, string value)
         generates (Status status);
 
     /**
@@ -283,7 +350,11 @@
      *
      * @param propertyName the name of the property
      * @param value the value to write
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: BAD_VALUE if the property name is invalid,
+     * ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
+     * cannot be set.
      */
     setPropertyByteArray(string propertyName, vec<uint8_t> value )
         generates (Status status);
@@ -301,7 +372,10 @@
      * @param algorithm the algorithm to use. The string conforms to JCA
      * Standard Names for Cipher Transforms and is case insensitive. An
      * example algorithm is "AES/CBC/PKCS5Padding".
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the algorithm cannot be set.
      */
     setCipherAlgorithm(SessionId sessionId, string algorithm)
         generates (Status status);
@@ -313,7 +387,10 @@
      * @param algorithm the algorithm to use. The string conforms to JCA
      * Standard Names for Mac Algorithms and is case insensitive. An example MAC
      * algorithm string is "HmacSHA256".
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of the
+     * following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the algorithm cannot be set.
      */
     setMacAlgorithm(SessionId sessionId, string algorithm)
         generates (Status status);
@@ -327,12 +404,14 @@
      * @param keyId the ID of the key to use for encryption
      * @param input the input data to encrypt
      * @param iv the initialization vector to use for encryption
+     * @return status the status of the call. The status must be OK or one of the
+     * following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
+     * BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the encrypt operation cannot be performed.
      * @return output the decrypted data
-     * @return status the status of the call
      */
     encrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
-        vec<uint8_t> iv)
-        generates (vec<uint8_t> output, Status status);
+            vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
 
     /**
      * Decrypt the provided input buffer with the cipher algorithm
@@ -343,11 +422,15 @@
      * @param keyId the ID of the key to use for decryption
      * @param input the input data to decrypt
      * @param iv the initialization vector to use for decryption
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the decrypt operation cannot be
+     * performed.
      * @return output the decrypted data
-     * @return status the status of the call
      */
     decrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
-        vec<uint8_t> iv) generates (vec<uint8_t> output, Status status);
+            vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
 
     /**
      * Compute a signature over the provided message using the mac algorithm
@@ -357,11 +440,15 @@
      * @param sessionId the session id the call applies to
      * @param keyId the ID of the key to use for decryption
      * @param message the message to compute a signature over
-     * @return the computed signature
-     * @return status the status of the call
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the sign operation cannot be
+     * performed.
+     * @return signature the computed signature
      */
     sign(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message)
-        generates (vec<uint8_t> signature, Status status);
+        generates (Status status, vec<uint8_t> signature);
 
     /**
      * Compute a hash of the provided message using the mac algorithm specified
@@ -371,26 +458,43 @@
      * @param sessionId the session id the call applies to
      * @param keyId the ID of the key to use for decryption
      * @param message the message to compute a hash of
-     * @return status the status of the call
+     * @param signature the signature to verify
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
+     * opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
+     * if the HAL is in a state where the verify operation cannot be
+     * performed.
+     * @return match true if the signature is verified positively,
+     * false otherwise.
      */
     verify(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message,
-        vec<uint8_t> signature) generates (bool match, Status status);
+            vec<uint8_t> signature) generates (Status status, bool match);
 
     /**
      * Compute an RSA signature on the provided message using the specified
      * algorithm.
      *
+     * @param sessionId the session id the call applies to
      * @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1"
      * or "PKCS1-BlockType1"
-     * @param sessionId the session id the call applies to
-     * @param wrappedKey the private key returned during provisioning
-     * as returned by provideProvisionResponse.
+     * @param message the message to compute the signature on
+     * @param wrappedKey the private key returned during provisioning as
+     * returned by provideProvisionResponse.
+     * @return status the status of the call. The status must be OK or one of
+     * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is
+     * not opened, BAD_VALUE if any parameters are invalid or
+     * ERROR_DRM_INVALID_STATE if the HAL is in a state where the signRSA
+     * operation cannot be performed.
      * @return signature the RSA signature computed over the message
-     * @return status the status of the call
      */
     signRSA(SessionId sessionId, string algorithm, vec<uint8_t> message,
         vec<uint8_t> wrappedkey)
-        generates (vec<uint8_t> signature, Status status);
+        generates (Status status, vec<uint8_t> signature);
+
+    /**
+     * Plugins call the following methods to deliver events to the
+     * java app.
+     */
 
     /**
      * Set a listener for a drm session. This allows the drm HAL to
@@ -401,11 +505,6 @@
     setListener(IDrmPluginListener listener);
 
     /**
-     * HAL implementations call the following methods to deliver events to the
-     * listener
-     */
-
-    /**
      * Legacy event sending method, it sends events of various types using a
      * single overloaded set of parameters. This form is deprecated.
      *
@@ -413,24 +512,23 @@
      * @param sessionId identifies the session the event originated from
      * @param data event-specific data blob
      */
-    oneway sendEvent(EventType eventType, SessionId sessionId,
-            vec<uint8_t> data);
+    sendEvent(EventType eventType, SessionId sessionId, vec<uint8_t> data);
 
     /**
      * Send a license expiration update to the listener. The expiration
-     * update indicates how long the current keys are valid before they
-     * need to be renewed.
+     * update indicates how long the current license is valid before it
+     * needs to be renewed.
      *
      * @param sessionId identifies the session the event originated from
      * @param expiryTimeInMS the time when the keys need to be renewed.
      * The time is in milliseconds, relative to the Unix epoch. A time of 0
      * indicates that the keys never expire.
      */
-    oneway sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
+     sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
 
     /**
      * Send a keys change event to the listener. The keys change event
-     * indicates the status of each key in the session. `Keys can be
+     * indicates the status of each key in the session. Keys can be
      * indicated as being usable, expired, outputnotallowed or statuspending.
      *
      * @param sessionId identifies the session the event originated from
@@ -439,6 +537,6 @@
      * @param hasNewUsableKey indicates if the event includes at least one
      * key that has become usable.
      */
-    oneway sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
-        bool hasNewUsableKey);
+    sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
+            bool hasNewUsableKey);
 };
diff --git a/drm/drm/1.0/IDrmPluginListener.hal b/drm/drm/1.0/IDrmPluginListener.hal
index fe2d998..92010a1 100644
--- a/drm/drm/1.0/IDrmPluginListener.hal
+++ b/drm/drm/1.0/IDrmPluginListener.hal
@@ -36,7 +36,8 @@
      * @param sessionId identifies the session the event originated from
      * @param data event-specific data blob
      */
-    sendEvent(EventType eventType, SessionId sessionId, vec<uint8_t> data);
+    oneway sendEvent(EventType eventType, SessionId sessionId,
+            vec<uint8_t> data);
 
     /**
      * Send a license expiration update to the listener. The expiration
@@ -48,7 +49,7 @@
      * The time is in milliseconds, relative to the Unix epoch. A time
      * of 0 indicates that the keys never expire.
      */
-    sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
+    oneway sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
 
     /**
      * Send a keys change event to the listener. The keys change event
@@ -61,6 +62,6 @@
      * @param hasNewUsableKey indicates if the event includes at least one
      * key that has become usable.
      */
-    sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
+    oneway sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
             bool hasNewUsableKey);
 };
diff --git a/drm/drm/1.0/default/Android.mk b/drm/drm/1.0/default/Android.mk
new file mode 100644
index 0000000..952957c
--- /dev/null
+++ b/drm/drm/1.0/default/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.drm.drm@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    DrmFactory.cpp \
+    DrmPlugin.cpp \
+    TypeConvert.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    libutils \
+    liblog \
+    libmediadrm \
+    libstagefright_foundation \
+    android.hardware.drm.drm@1.0 \
+
+LOCAL_C_INCLUDES := \
+    frameworks/native/include \
+    frameworks/av/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/drm/1.0/default/DrmFactory.cpp b/drm/drm/1.0/default/DrmFactory.cpp
new file mode 100644
index 0000000..f2d4a5a
--- /dev/null
+++ b/drm/drm/1.0/default/DrmFactory.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.
+ */
+
+#include "DrmFactory.h"
+#include "DrmPlugin.h"
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+    DrmFactory::DrmFactory() :
+        loader("/vendor/lib/mediadrm", "createDrmFactory") {}
+
+    // Methods from ::android::hardware::drm::drm::V1_0::IDrmFactory follow.
+    Return<bool> DrmFactory::isCryptoSchemeSupported (
+            const hidl_array<uint8_t, 16>& uuid) {
+        for (size_t i = 0; i < loader.factoryCount(); i++) {
+            if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    Return<bool> DrmFactory::isContentTypeSupported (
+            const hidl_string& mimeType) {
+        for (size_t i = 0; i < loader.factoryCount(); i++) {
+            if (loader.getFactory(i)->isContentTypeSupported(String8(mimeType.c_str()))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    Return<void> DrmFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+            createPlugin_cb _hidl_cb) {
+
+        for (size_t i = 0; i < loader.factoryCount(); i++) {
+            if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+                android::DrmPlugin *legacyPlugin = NULL;
+                status_t status = loader.getFactory(i)->createDrmPlugin(
+                        uuid.data(), &legacyPlugin);
+                DrmPlugin *newPlugin = NULL;
+                if (legacyPlugin == NULL) {
+                    ALOGE("Drm legacy HAL: failed to create drm plugin");
+                } else {
+                    newPlugin = new DrmPlugin(legacyPlugin);
+                }
+                _hidl_cb(toStatus(status), newPlugin);
+                return Void();
+            }
+        }
+        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
+        return Void();
+    }
+
+    IDrmFactory* HIDL_FETCH_IDrmFactory(const char* /* name */) {
+        return new DrmFactory();
+    }
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/drm/1.0/default/DrmFactory.h b/drm/drm/1.0/default/DrmFactory.h
new file mode 100644
index 0000000..2b88d00
--- /dev/null
+++ b/drm/drm/1.0/default/DrmFactory.h
@@ -0,0 +1,72 @@
+/*
+ * 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_DRM_DRM_V1_0__DRMFACTORY_H
+#define ANDROID_HARDWARE_DRM_DRM_V1_0__DRMFACTORY_H
+
+#include <android/hardware/drm/drm/1.0/IDrmFactory.h>
+#include <hidl/Status.h>
+#include <media/drm/DrmAPI.h>
+#include <media/PluginLoader.h>
+#include <media/SharedLibrary.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::drm::V1_0::IDrmFactory;
+using ::android::hardware::drm::drm::V1_0::IDrmPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DrmFactory : public IDrmFactory {
+    DrmFactory();
+    virtual ~DrmFactory() {}
+
+    // Methods from ::android::hardware::drm::drm::V1_0::IDrmFactory follow.
+
+    Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+            override;
+
+    Return<bool> isContentTypeSupported(const hidl_string &mimeType)
+            override;
+
+    Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
+            createPlugin_cb _hidl_cb) override;
+
+private:
+    android::PluginLoader<android::DrmFactory> loader;
+
+    DrmFactory(const DrmFactory &) = delete;
+    void operator=(const DrmFactory &) = delete;
+};
+
+extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_DRM_DRM_V1_0__DRMFACTORY_H
diff --git a/drm/drm/1.0/default/DrmPlugin.cpp b/drm/drm/1.0/default/DrmPlugin.cpp
new file mode 100644
index 0000000..5c8f426
--- /dev/null
+++ b/drm/drm/1.0/default/DrmPlugin.cpp
@@ -0,0 +1,428 @@
+/*
+ * 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.
+ */
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+#include "DrmPlugin.h"
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+    // Methods from ::android::hardware::drm::drm::V1_0::IDrmPlugin follow.
+
+    Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
+
+        Vector<uint8_t> legacySessionId;
+        status_t status = mLegacyPlugin->openSession(legacySessionId);
+        _hidl_cb(toStatus(status), toHidlVec(legacySessionId));
+        return Void();
+    }
+
+    Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
+        return toStatus(mLegacyPlugin->closeSession(toVector(sessionId)));
+    }
+
+    Return<void> DrmPlugin::getKeyRequest(const hidl_vec<uint8_t>& scope,
+            const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
+            KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
+            getKeyRequest_cb _hidl_cb) {
+
+        status_t status = android::OK;
+
+        android::DrmPlugin::KeyType legacyKeyType;
+        switch(keyType) {
+        case KeyType::OFFLINE:
+            legacyKeyType = android::DrmPlugin::kKeyType_Offline;
+            break;
+        case KeyType::STREAMING:
+            legacyKeyType = android::DrmPlugin::kKeyType_Streaming;
+            break;
+        case KeyType::RELEASE:
+            legacyKeyType = android::DrmPlugin::kKeyType_Release;
+            break;
+        default:
+            status = android::BAD_VALUE;
+            break;
+        }
+
+        Vector<uint8_t> legacyRequest;
+        KeyRequestType requestType = KeyRequestType::UNKNOWN;
+        String8 defaultUrl;
+
+        if (status == android::OK) {
+            android::KeyedVector<String8, String8> legacyOptionalParameters;
+            for (size_t i = 0; i < optionalParameters.size(); i++) {
+                legacyOptionalParameters.add(String8(optionalParameters[i].key),
+                        String8(optionalParameters[i].value));
+            }
+
+            android::DrmPlugin::KeyRequestType legacyRequestType =
+                    android::DrmPlugin::kKeyRequestType_Unknown;
+
+            status_t status = mLegacyPlugin->getKeyRequest(toVector(scope),
+                    toVector(initData), String8(mimeType), legacyKeyType,
+                    legacyOptionalParameters, legacyRequest, defaultUrl,
+                    &legacyRequestType);
+
+            switch(legacyRequestType) {
+            case android::DrmPlugin::kKeyRequestType_Initial:
+                requestType = KeyRequestType::INITIAL;
+                break;
+            case android::DrmPlugin::kKeyRequestType_Renewal:
+                requestType = KeyRequestType::RENEWAL;
+                break;
+            case android::DrmPlugin::kKeyRequestType_Release:
+                requestType = KeyRequestType::RELEASE;
+                break;
+            case android::DrmPlugin::kKeyRequestType_Unknown:
+                status = android::BAD_VALUE;
+                break;
+            }
+        }
+        _hidl_cb(toStatus(status), toHidlVec(legacyRequest), requestType,
+                 defaultUrl.string());
+        return Void();
+    }
+
+    Return<void> DrmPlugin::provideKeyResponse(const hidl_vec<uint8_t>& scope,
+            const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) {
+
+        Vector<uint8_t> keySetId;
+        status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope),
+                toVector(response), keySetId);
+        _hidl_cb(toStatus(status), toHidlVec(keySetId));
+        return Void();
+    }
+
+    Return<Status> DrmPlugin::removeKeys(const hidl_vec<uint8_t>& sessionId) {
+        return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId)));
+    }
+
+    Return<Status> DrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keySetId) {
+        status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId),
+                toVector(keySetId));
+        return toStatus(legacyStatus);
+    }
+
+    Return<void> DrmPlugin::queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
+            queryKeyStatus_cb _hidl_cb) {
+
+        android::KeyedVector<String8, String8> legacyInfoMap;
+        status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId),
+                legacyInfoMap);
+
+        Vector<KeyValue> infoMapVec;
+        for (size_t i = 0; i < legacyInfoMap.size(); i++) {
+            KeyValue keyValuePair;
+            keyValuePair.key = String8(legacyInfoMap.keyAt(i));
+            keyValuePair.value = String8(legacyInfoMap.valueAt(i));
+            infoMapVec.push_back(keyValuePair);
+        }
+        _hidl_cb(toStatus(status), toHidlVec(infoMapVec));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::getProvisionRequest(
+            const hidl_string& certificateType,
+            const hidl_string& certificateAuthority,
+            getProvisionRequest_cb _hidl_cb) {
+
+        Vector<uint8_t> legacyRequest;
+        String8 legacyDefaultUrl;
+        status_t status = mLegacyPlugin->getProvisionRequest(
+                String8(certificateType), String8(certificateAuthority),
+                legacyRequest, legacyDefaultUrl);
+
+        _hidl_cb(toStatus(status), toHidlVec(legacyRequest),
+                hidl_string(legacyDefaultUrl));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::provideProvisionResponse(
+            const hidl_vec<uint8_t>& response,
+            provideProvisionResponse_cb _hidl_cb) {
+
+        Vector<uint8_t> certificate;
+        Vector<uint8_t> wrappedKey;
+
+        status_t legacyStatus = mLegacyPlugin->provideProvisionResponse(
+                toVector(response), certificate, wrappedKey);
+
+        _hidl_cb(toStatus(legacyStatus), toHidlVec(certificate),
+                toHidlVec(wrappedKey));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
+        List<Vector<uint8_t> > legacySecureStops;
+        status_t status = mLegacyPlugin->getSecureStops(legacySecureStops);
+
+        Vector<SecureStop> secureStopsVec;
+        List<Vector<uint8_t> >::iterator iter = legacySecureStops.begin();
+
+        while (iter != legacySecureStops.end()) {
+            SecureStop secureStop;
+            secureStop.opaqueData = toHidlVec(*iter++);
+            secureStopsVec.push_back(secureStop);
+        }
+
+        _hidl_cb(toStatus(status), toHidlVec(secureStopsVec));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
+            getSecureStop_cb _hidl_cb) {
+
+        Vector<uint8_t> legacySecureStop;
+        status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId),
+                legacySecureStop);
+
+        SecureStop secureStop;
+        secureStop.opaqueData = toHidlVec(legacySecureStop);
+        _hidl_cb(toStatus(status), secureStop);
+        return Void();
+    }
+
+    Return<Status> DrmPlugin::releaseAllSecureStops() {
+        return toStatus(mLegacyPlugin->releaseAllSecureStops());
+    }
+
+    Return<Status> DrmPlugin::releaseSecureStop(
+            const hidl_vec<uint8_t>& secureStopId) {
+        status_t legacyStatus =
+            mLegacyPlugin->releaseSecureStops(toVector(secureStopId));
+        return toStatus(legacyStatus);
+    }
+
+    Return<void> DrmPlugin::getPropertyString(const hidl_string& propertyName,
+            getPropertyString_cb _hidl_cb) {
+        String8 legacyValue;
+        status_t status = mLegacyPlugin->getPropertyString(
+                String8(propertyName), legacyValue);
+        _hidl_cb(toStatus(status), legacyValue.string());
+        return Void();
+    }
+
+    Return<void> DrmPlugin::getPropertyByteArray(const hidl_string& propertyName,
+            getPropertyByteArray_cb _hidl_cb) {
+        Vector<uint8_t> legacyValue;
+        status_t status = mLegacyPlugin->getPropertyByteArray(
+                String8(propertyName), legacyValue);
+        _hidl_cb(toStatus(status), toHidlVec(legacyValue));
+        return Void();
+    }
+
+    Return<Status> DrmPlugin::setPropertyString(const hidl_string& propertyName,
+            const hidl_string& value) {
+        status_t legacyStatus =
+            mLegacyPlugin->setPropertyString(String8(propertyName),
+                    String8(value));
+        return toStatus(legacyStatus);
+    }
+
+    Return<Status> DrmPlugin::setPropertyByteArray(
+            const hidl_string& propertyName, const hidl_vec<uint8_t>& value) {
+        status_t legacyStatus =
+            mLegacyPlugin->setPropertyByteArray(String8(propertyName),
+                    toVector(value));
+        return toStatus(legacyStatus);
+    }
+
+    Return<Status> DrmPlugin::setCipherAlgorithm(
+            const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+        status_t legacyStatus =
+            mLegacyPlugin->setCipherAlgorithm(toVector(sessionId),
+                String8(algorithm));
+        return toStatus(legacyStatus);
+    }
+
+    Return<Status> DrmPlugin::setMacAlgorithm(
+            const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+        status_t legacyStatus =
+            mLegacyPlugin->setMacAlgorithm(toVector(sessionId),
+                String8(algorithm));
+        return toStatus(legacyStatus);
+    }
+
+    Return<void> DrmPlugin::encrypt(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+            const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) {
+
+        Vector<uint8_t> legacyOutput;
+        status_t status = mLegacyPlugin->encrypt(toVector(sessionId),
+                toVector(keyId), toVector(input), toVector(iv), legacyOutput);
+        _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::decrypt(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+            const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) {
+
+        Vector<uint8_t> legacyOutput;
+        status_t status = mLegacyPlugin->decrypt(toVector(sessionId),
+                toVector(keyId), toVector(input), toVector(iv), legacyOutput);
+        _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::sign(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+            sign_cb _hidl_cb) {
+        Vector<uint8_t> legacySignature;
+        status_t status = mLegacyPlugin->sign(toVector(sessionId),
+                toVector(keyId), toVector(message), legacySignature);
+        _hidl_cb(toStatus(status), toHidlVec(legacySignature));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::verify(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+            const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) {
+
+        bool match;
+        status_t status = mLegacyPlugin->verify(toVector(sessionId),
+                toVector(keyId), toVector(message), toVector(signature),
+                match);
+        _hidl_cb(toStatus(status), match);
+        return Void();
+    }
+
+    Return<void> DrmPlugin::signRSA(const hidl_vec<uint8_t>& sessionId,
+            const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
+            const hidl_vec<uint8_t>& wrappedKey, signRSA_cb _hidl_cb) {
+
+        Vector<uint8_t> legacySignature;
+        status_t status = mLegacyPlugin->signRSA(toVector(sessionId),
+                String8(algorithm), toVector(message), toVector(wrappedKey),
+                legacySignature);
+        _hidl_cb(toStatus(status), toHidlVec(legacySignature));
+        return Void();
+    }
+
+    Return<void> DrmPlugin::setListener(const sp<IDrmPluginListener>& listener) {
+        mListener = listener;
+        return Void();
+    }
+
+    Return<void> DrmPlugin::sendEvent(EventType eventType,
+            const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
+        mListener->sendEvent(eventType, sessionId, data);
+        return Void();
+    }
+
+    Return<void> DrmPlugin::sendExpirationUpdate(
+            const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
+        mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
+        return Void();
+    }
+
+    Return<void> DrmPlugin::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
+        mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+        return Void();
+    }
+
+
+    // Methods from android::DrmPluginListener
+
+    void DrmPlugin::sendEvent(android::DrmPlugin::EventType legacyEventType,
+            int /*unused*/, Vector<uint8_t> const *sessionId,
+            Vector<uint8_t> const *data) {
+
+        EventType eventType;
+        bool sendEvent = true;
+        switch(legacyEventType) {
+        case android::DrmPlugin::kDrmPluginEventProvisionRequired:
+            eventType = EventType::PROVISION_REQUIRED;
+            break;
+        case android::DrmPlugin::kDrmPluginEventKeyNeeded:
+            eventType = EventType::KEY_NEEDED;
+            break;
+        case android::DrmPlugin::kDrmPluginEventKeyExpired:
+            eventType = EventType::KEY_EXPIRED;
+            break;
+        case android::DrmPlugin::kDrmPluginEventVendorDefined:
+            eventType = EventType::VENDOR_DEFINED;
+            break;
+        case android::DrmPlugin::kDrmPluginEventSessionReclaimed:
+            eventType = EventType::SESSION_RECLAIMED;
+            break;
+        default:
+            sendEvent = false;
+            break;
+        }
+        if (sendEvent) {
+            mListener->sendEvent(eventType, toHidlVec(*sessionId),
+                    toHidlVec(*data));
+        }
+    }
+
+    void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
+            int64_t expiryTimeInMS) {
+        mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS);
+    }
+
+    void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,
+            Vector<android::DrmPlugin::KeyStatus> const *legacyKeyStatusList,
+            bool hasNewUsableKey) {
+
+        Vector<KeyStatus> keyStatusVec;
+        for (size_t i = 0; i < legacyKeyStatusList->size(); i++) {
+            const android::DrmPlugin::KeyStatus &legacyKeyStatus =
+                legacyKeyStatusList->itemAt(i);
+
+            KeyStatus keyStatus;
+
+            switch(legacyKeyStatus.mType) {
+            case android::DrmPlugin::kKeyStatusType_Usable:
+                keyStatus.type = KeyStatusType::USABLE;
+                break;
+            case android::DrmPlugin::kKeyStatusType_Expired:
+                keyStatus.type = KeyStatusType::EXPIRED;
+                break;
+            case android::DrmPlugin::kKeyStatusType_OutputNotAllowed:
+                keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED;
+                break;
+            case android::DrmPlugin::kKeyStatusType_StatusPending:
+                keyStatus.type = KeyStatusType::STATUSPENDING;
+                break;
+            case android::DrmPlugin::kKeyStatusType_InternalError:
+            default:
+                keyStatus.type = KeyStatusType::INTERNALERROR;
+                break;
+            }
+
+            keyStatus.keyId = toHidlVec(legacyKeyStatus.mKeyId);
+            keyStatusVec.push_back(keyStatus);
+        }
+        mListener->sendKeysChange(toHidlVec(*sessionId),
+                toHidlVec(keyStatusVec), hasNewUsableKey);
+    }
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/drm/1.0/default/DrmPlugin.h b/drm/drm/1.0/default/DrmPlugin.h
new file mode 100644
index 0000000..2bf3b5e
--- /dev/null
+++ b/drm/drm/1.0/default/DrmPlugin.h
@@ -0,0 +1,172 @@
+/*
+ * 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_DRM_DRM_V1_0__DRMPLUGIN_H
+#define ANDROID_HARDWARE_DRM_DRM_V1_0__DRMPLUGIN_H
+
+#include <media/drm/DrmAPI.h>
+#include <android/hardware/drm/drm/1.0/IDrmPlugin.h>
+#include <android/hardware/drm/drm/1.0/IDrmPluginListener.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::drm::V1_0::EventType;
+using ::android::hardware::drm::drm::V1_0::IDrmPlugin;
+using ::android::hardware::drm::drm::V1_0::IDrmPluginListener;
+using ::android::hardware::drm::drm::V1_0::KeyRequestType;
+using ::android::hardware::drm::drm::V1_0::KeyStatus;
+using ::android::hardware::drm::drm::V1_0::KeyType;
+using ::android::hardware::drm::drm::V1_0::KeyValue;
+using ::android::hardware::drm::drm::V1_0::SecureStop;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DrmPlugin : public IDrmPlugin, android::DrmPluginListener {
+
+    DrmPlugin(android::DrmPlugin *plugin) : mLegacyPlugin(plugin) {}
+    ~DrmPlugin() {delete mLegacyPlugin;}
+
+    // Methods from ::android::hardware::drm::drm::V1_0::IDrmPlugin follow.
+
+    Return<void> openSession(openSession_cb _hidl_cb) override;
+
+    Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
+
+    Return<void> getKeyRequest(const hidl_vec<uint8_t>& scope,
+            const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
+            KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
+            getKeyRequest_cb _hidl_cb) override;
+
+    Return<void> provideKeyResponse(const hidl_vec<uint8_t>& scope,
+            const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb)
+            override;
+
+    Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
+
+    Return<Status> restoreKeys(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keySetId) override;
+
+    Return<void> queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
+            queryKeyStatus_cb _hidl_cb) override;
+
+    Return<void> getProvisionRequest(const hidl_string& certificateType,
+            const hidl_string& certificateAuthority,
+            getProvisionRequest_cb _hidl_cb) override;
+
+    Return<void> provideProvisionResponse(const hidl_vec<uint8_t>& response,
+            provideProvisionResponse_cb _hidl_cb) override;
+
+    Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
+
+    Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
+            getSecureStop_cb _hidl_cb) override;
+
+    Return<Status> releaseAllSecureStops() override;
+
+    Return<Status> releaseSecureStop(const hidl_vec<uint8_t>& secureStopId)
+            override;
+
+    Return<void> getPropertyString(const hidl_string& propertyName,
+            getPropertyString_cb _hidl_cb) override;
+
+    Return<void> getPropertyByteArray(const hidl_string& propertyName,
+            getPropertyByteArray_cb _hidl_cb) override;
+
+    Return<Status> setPropertyString(const hidl_string& propertyName,
+            const hidl_string& value) override;
+
+    Return<Status> setPropertyByteArray(const hidl_string& propertyName,
+            const hidl_vec<uint8_t>& value) override;
+
+    Return<Status> setCipherAlgorithm(const hidl_vec<uint8_t>& sessionId,
+            const hidl_string& algorithm) override;
+
+    Return<Status> setMacAlgorithm(const hidl_vec<uint8_t>& sessionId,
+            const hidl_string& algorithm) override;
+
+    Return<void> encrypt(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+            const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) override;
+
+    Return<void> decrypt(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
+            const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) override;
+
+    Return<void> sign(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+            sign_cb _hidl_cb) override;
+
+    Return<void> verify(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
+            const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) override;
+
+    Return<void> signRSA(const hidl_vec<uint8_t>& sessionId,
+            const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
+            const hidl_vec<uint8_t>& wrappedkey, signRSA_cb _hidl_cb) override;
+
+    Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
+
+    Return<void> sendEvent(EventType eventType,
+            const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data)
+            override;
+
+    Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
+            int64_t expiryTimeInMS) override;
+
+    Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+            const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey)
+            override;
+
+    // Methods from android::DrmPluginListener follow
+
+    virtual void sendEvent(android::DrmPlugin::EventType eventType, int extra,
+            Vector<uint8_t> const *sessionId, Vector<uint8_t> const *data);
+
+    virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
+            int64_t expiryTimeInMS);
+
+    virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
+            Vector<android::DrmPlugin::KeyStatus> const *keyStatusList,
+            bool hasNewUsableKey);
+
+private:
+    android::DrmPlugin *mLegacyPlugin;
+    sp<IDrmPluginListener> mListener;
+
+    DrmPlugin() = delete;
+    DrmPlugin(const DrmPlugin &) = delete;
+    void operator=(const DrmPlugin &) = delete;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_DRM_DRM_V1_0__DRMPLUGIN_H
diff --git a/drm/drm/1.0/default/TypeConvert.cpp b/drm/drm/1.0/default/TypeConvert.cpp
new file mode 100644
index 0000000..4bed284
--- /dev/null
+++ b/drm/drm/1.0/default/TypeConvert.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+    Status status;
+    switch(legacyStatus) {
+    case android::OK:
+        status = Status::OK;
+        break;
+    case android::ERROR_DRM_NO_LICENSE:
+        status = Status::ERROR_DRM_NO_LICENSE;
+        break;
+    case android::ERROR_DRM_LICENSE_EXPIRED:
+        status = Status::ERROR_DRM_LICENSE_EXPIRED;
+        break;
+    case android::ERROR_DRM_SESSION_NOT_OPENED:
+        status = Status::ERROR_DRM_SESSION_NOT_OPENED;
+        break;
+    case android::ERROR_DRM_CANNOT_HANDLE:
+        status = Status::ERROR_DRM_CANNOT_HANDLE;
+        break;
+    case android::ERROR_DRM_TAMPER_DETECTED:
+        status = Status::ERROR_DRM_INVALID_STATE;
+        break;
+    case android::BAD_VALUE:
+        status = Status::BAD_VALUE;
+        break;
+    case android::ERROR_DRM_NOT_PROVISIONED:
+        status = Status::ERROR_DRM_NOT_PROVISIONED;
+        break;
+    case android::ERROR_DRM_RESOURCE_BUSY:
+        status = Status::ERROR_DRM_RESOURCE_BUSY;
+        break;
+    case android::ERROR_DRM_DEVICE_REVOKED:
+        status = Status::ERROR_DRM_DEVICE_REVOKED;
+        break;
+    default:
+        ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
+            legacyStatus);
+        status = Status::ERROR_DRM_UNKNOWN;
+        break;
+    }
+    return status;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/drm/1.0/default/TypeConvert.h b/drm/drm/1.0/default/TypeConvert.h
new file mode 100644
index 0000000..2f7875e
--- /dev/null
+++ b/drm/drm/1.0/default/TypeConvert.h
@@ -0,0 +1,69 @@
+/*
+ * 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_DRM_DRM_V1_0_TYPECONVERT
+#define ANDROID_HARDWARE_DRM_DRM_V1_0_TYPECONVERT
+
+#include <utils/Vector.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/drm/DrmAPI.h>
+
+#include <hidl/MQDescriptor.h>
+#include <android/hardware/drm/drm/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
+    hidl_vec<T> vec;
+    vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
+    return vec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
+    hidl_vec<T> vec;
+    vec.setToExternal(Vector.editArray(), Vector.size());
+    return vec;
+}
+
+template<typename T> const Vector<T> toVector(const hidl_vec<T> & vec) {
+    Vector<T> vector;
+    vector.appendArray(vec.data(), vec.size());
+    return *const_cast<const Vector<T> *>(&vector);
+}
+
+template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
+    Vector<T> vector;
+    vector.appendArray(vec.data(), vec.size());
+    return vector;
+}
+
+Status toStatus(status_t legacyStatus);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_DRM_V1_0_TYPECONVERT
diff --git a/drm/drm/1.0/types.hal b/drm/drm/1.0/types.hal
index 05101c9..e099418 100644
--- a/drm/drm/1.0/types.hal
+++ b/drm/drm/1.0/types.hal
@@ -18,6 +18,12 @@
 
 enum Status : uint32_t {
     /**
+     * The DRM plugin must return OK when an operation completes without any
+     * errors.
+     */
+    OK,
+
+    /**
      * The DRM plugin must return ERROR_DRM_NO_LICENSE, when decryption is
      * attempted and no license keys have been provided.
      */
@@ -161,6 +167,11 @@
      * to become available for streaming.
      */
     RELEASE,
+
+    /**
+     * Key request type is unknown due to some error condition.
+     */
+    UNKNOWN,
 };
 
 /**
diff --git a/evs/1.0/default/service.cpp b/evs/1.0/default/service.cpp
index 6ab2975..112c879 100644
--- a/evs/1.0/default/service.cpp
+++ b/evs/1.0/default/service.cpp
@@ -18,8 +18,7 @@
 
 #include <unistd.h>
 
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 #include <utils/Log.h>
@@ -29,9 +28,9 @@
 #include "EvsDisplay.h"
 
 
-// libhwbinder:
-using android::hardware::IPCThreadState;
-using android::hardware::ProcessState;
+// libhidl:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
 
 // Generated HIDL files
 using android::hardware::evs::V1_0::IEvsEnumerator;
@@ -46,25 +45,14 @@
     ALOGI("EVS Hardware Enumerator service is starting");
     android::sp<IEvsEnumerator> service = new EvsEnumerator();
 
+    configureRpcThreadpool(1, true /* callerWillJoin */);
+
     // 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();
+        joinRpcThreadpool();
     } else {
         ALOGE("Could not register service %s (%d).", kEnumeratorServiceName, status);
     }
diff --git a/example/extension/light/2.0/default/service.cpp b/example/extension/light/2.0/default/service.cpp
index 3eb7bdf..d3fb4de 100644
--- a/example/extension/light/2.0/default/service.cpp
+++ b/example/extension/light/2.0/default/service.cpp
@@ -16,15 +16,14 @@
 #define LOG_TAG "android.hardware.light@2.0-service"
 
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 
 #include "Light.h"
 
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
 using android::sp;
 
-// libhwbinder:
-using android::hardware::IPCThreadState;
-using android::hardware::ProcessState;
-
 // Generated HIDL files
 using android::hardware::light::V2_0::ILight;
 
@@ -32,10 +31,7 @@
     const char instance[] = "light";
 
     android::sp<ILight> service = new Light();
-
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
     service->registerAsService(instance);
-
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
+    joinRpcThreadpool();
 }
diff --git a/gnss/1.0/default/Android.mk b/gnss/1.0/default/Android.mk
index 06ef331..6289491 100644
--- a/gnss/1.0/default/Android.mk
+++ b/gnss/1.0/default/Android.mk
@@ -27,3 +27,27 @@
     libhardware
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.gnss@1.0-service
+LOCAL_INIT_RC := android.hardware.gnss@1.0-service.rc
+LOCAL_SRC_FILES := \
+    service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libhardware_legacy \
+    libhardware \
+
+LOCAL_SHARED_LIBRARIES += \
+    libhwbinder \
+    libhidlbase \
+    libhidltransport \
+    android.hardware.gnss@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
new file mode 100644
index 0000000..eeb2e43
--- /dev/null
+++ b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
@@ -0,0 +1,4 @@
+service gnss_service /system/bin/hw/android.hardware.gnss@1.0-service
+    class main
+    user system
+    group system
diff --git a/gnss/1.0/default/service.cpp b/gnss/1.0/default/service.cpp
new file mode 100644
index 0000000..4e040c5
--- /dev/null
+++ b/gnss/1.0/default/service.cpp
@@ -0,0 +1,12 @@
+#define LOG_TAG "android.hardware.gnss@1.0-service"
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+#include <hidl/LegacySupport.h>
+
+using android::hardware::gnss::V1_0::IGnss;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    return defaultPassthroughServiceImplementation<IGnss>("gnss");
+}
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index e3d2703..3a102d1 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -47,21 +47,21 @@
 
     Error createDescriptor(
             const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-            BufferDescriptor& outDescriptor);
+            BufferDescriptor* outDescriptor);
     Error destroyDescriptor(BufferDescriptor descriptor);
 
     Error testAllocate(const hidl_vec<BufferDescriptor>& descriptors);
     Error allocate(const hidl_vec<BufferDescriptor>& descriptors,
-            hidl_vec<Buffer>& outBuffers);
+            hidl_vec<Buffer>* outBuffers);
     Error free(Buffer buffer);
 
-    Error exportHandle(Buffer buffer, const native_handle_t*& outHandle);
+    Error exportHandle(Buffer buffer, const native_handle_t** outHandle);
 
 private:
     void initCapabilities();
 
     template<typename T>
-    void initDispatch(T& func, gralloc1_function_descriptor_t desc);
+    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
     void initDispatch();
 
     bool hasCapability(Capability capability) const;
@@ -143,35 +143,35 @@
 }
 
 template<typename T>
-void GrallocHal::initDispatch(T& func, gralloc1_function_descriptor_t desc)
+void GrallocHal::initDispatch(gralloc1_function_descriptor_t desc, T* outPfn)
 {
     auto pfn = mDevice->getFunction(mDevice, desc);
     if (!pfn) {
         LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
     }
 
-    func = reinterpret_cast<T>(pfn);
+    *outPfn = reinterpret_cast<T>(pfn);
 }
 
 void GrallocHal::initDispatch()
 {
-    initDispatch(mDispatch.dump, GRALLOC1_FUNCTION_DUMP);
-    initDispatch(mDispatch.createDescriptor,
-            GRALLOC1_FUNCTION_CREATE_DESCRIPTOR);
-    initDispatch(mDispatch.destroyDescriptor,
-            GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR);
-    initDispatch(mDispatch.setDimensions, GRALLOC1_FUNCTION_SET_DIMENSIONS);
-    initDispatch(mDispatch.setFormat, GRALLOC1_FUNCTION_SET_FORMAT);
+    initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
+    initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
+            &mDispatch.createDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
+            &mDispatch.destroyDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
+    initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
     if (hasCapability(Capability::LAYERED_BUFFERS)) {
-        initDispatch(
-                mDispatch.setLayerCount, GRALLOC1_FUNCTION_SET_LAYER_COUNT);
+        initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
+                &mDispatch.setLayerCount);
     }
-    initDispatch(mDispatch.setConsumerUsage,
-            GRALLOC1_FUNCTION_SET_CONSUMER_USAGE);
-    initDispatch(mDispatch.setProducerUsage,
-            GRALLOC1_FUNCTION_SET_PRODUCER_USAGE);
-    initDispatch(mDispatch.allocate, GRALLOC1_FUNCTION_ALLOCATE);
-    initDispatch(mDispatch.release, GRALLOC1_FUNCTION_RELEASE);
+    initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
+            &mDispatch.setConsumerUsage);
+    initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
+            &mDispatch.setProducerUsage);
+    initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
+    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
 }
 
 bool GrallocHal::hasCapability(Capability capability) const
@@ -218,7 +218,7 @@
 
 Error GrallocHal::createDescriptor(
         const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-        BufferDescriptor& outDescriptor)
+        BufferDescriptor* outDescriptor)
 {
     gralloc1_buffer_descriptor_t descriptor;
     int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
@@ -261,7 +261,7 @@
     }
 
     if (err == GRALLOC1_ERROR_NONE) {
-        outDescriptor = descriptor;
+        *outDescriptor = descriptor;
     } else {
         mDispatch.destroyDescriptor(mDevice, descriptor);
     }
@@ -287,15 +287,15 @@
 }
 
 Error GrallocHal::allocate(const hidl_vec<BufferDescriptor>& descriptors,
-        hidl_vec<Buffer>& outBuffers)
+        hidl_vec<Buffer>* outBuffers)
 {
     std::vector<buffer_handle_t> buffers(descriptors.size());
     int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
             descriptors.data(), buffers.data());
     if (err == GRALLOC1_ERROR_NONE || err == GRALLOC1_ERROR_NOT_SHARED) {
-        outBuffers.resize(buffers.size());
-        for (size_t i = 0; i < outBuffers.size(); i++) {
-            outBuffers[i] = static_cast<Buffer>(
+        outBuffers->resize(buffers.size());
+        for (size_t i = 0; i < outBuffers->size(); i++) {
+            (*outBuffers)[i] = static_cast<Buffer>(
                     reinterpret_cast<uintptr_t>(buffers[i]));
         }
     }
@@ -313,10 +313,10 @@
 }
 
 Error GrallocHal::exportHandle(Buffer buffer,
-        const native_handle_t*& outHandle)
+        const native_handle_t** outHandle)
 {
     // we rely on the caller to validate buffer here
-    outHandle = reinterpret_cast<buffer_handle_t>(
+    *outHandle = reinterpret_cast<buffer_handle_t>(
             static_cast<uintptr_t>(buffer));
     return Error::NONE;
 }
@@ -347,8 +347,8 @@
         const BufferDescriptorInfo& descriptorInfo,
         createDescriptor_cb hidl_cb)
 {
-    BufferDescriptor descriptor;
-    Error err = mHal.createDescriptor(descriptorInfo, descriptor);
+    BufferDescriptor descriptor = 0;
+    Error err = mHal.createDescriptor(descriptorInfo, &descriptor);
 
     if (err == Error::NONE) {
         std::lock_guard<std::mutex> lock(mMutex);
@@ -387,7 +387,7 @@
         const hidl_vec<BufferDescriptor>& descriptors,
         allocate_cb hidl_cb) {
     hidl_vec<Buffer> buffers;
-    Error err = mHal.allocate(descriptors, buffers);
+    Error err = mHal.allocate(descriptors, &buffers);
 
     if (err == Error::NONE || err == Error::NOT_SHARED) {
         std::lock_guard<std::mutex> lock(mMutex);
@@ -440,14 +440,14 @@
         }
     }
 
-    Error err = mHal.exportHandle(buffer, handle);
+    Error err = mHal.exportHandle(buffer, &handle);
 
     hidl_cb(err, handle);
     return Void();
 }
 
 IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
-    const hw_module_t* module;
+    const hw_module_t* module = nullptr;
     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
     if (err) {
         ALOGE("failed to get gralloc module");
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 67ff353..e20fedc 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -39,9 +39,11 @@
 
     /*
      * The following formats use a 16bit float per color component.
+     *
+     * When used with ANativeWindow, the dataSpace field describes the color
+     * space of the buffer.
      */
     RGBA_FP16          = 0x16,
-    RGBX_FP16          = 0x17,
 
     /*
      * 0x101 - 0x1FF
diff --git a/graphics/composer/2.1/IComposerClient.hal b/graphics/composer/2.1/IComposerClient.hal
index 1a82215..b0bd837 100644
--- a/graphics/composer/2.1/IComposerClient.hal
+++ b/graphics/composer/2.1/IComposerClient.hal
@@ -554,7 +554,7 @@
      * @return error is NONE upon success. Otherwise,
      *         NO_RESOURCES when failed to set the queue temporarily.
      */
-    setInputCommandQueue(MQDescriptorSync descriptor)
+    setInputCommandQueue(fmq_sync<uint32_t> descriptor)
               generates (Error error);
 
     /*
@@ -568,7 +568,7 @@
      */
     getOutputCommandQueue()
               generates (Error error,
-                         MQDescriptorSync descriptor);
+                         fmq_sync<uint32_t> descriptor);
 
     /*
      * Executes commands from the input command message queue. Return values
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index d14de6f..4efb12b 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -62,88 +62,89 @@
 }
 
 template<typename T>
-void HwcHal::initDispatch(T& func, hwc2_function_descriptor_t desc)
+void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
 {
     auto pfn = mDevice->getFunction(mDevice, desc);
     if (!pfn) {
         LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
     }
 
-    func = reinterpret_cast<T>(pfn);
+    *outPfn = reinterpret_cast<T>(pfn);
 }
 
 void HwcHal::initDispatch()
 {
-    initDispatch(mDispatch.acceptDisplayChanges,
-            HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES);
-    initDispatch(mDispatch.createLayer, HWC2_FUNCTION_CREATE_LAYER);
-    initDispatch(mDispatch.createVirtualDisplay,
-            HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY);
-    initDispatch(mDispatch.destroyLayer, HWC2_FUNCTION_DESTROY_LAYER);
-    initDispatch(mDispatch.destroyVirtualDisplay,
-            HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY);
-    initDispatch(mDispatch.dump, HWC2_FUNCTION_DUMP);
-    initDispatch(mDispatch.getActiveConfig, HWC2_FUNCTION_GET_ACTIVE_CONFIG);
-    initDispatch(mDispatch.getChangedCompositionTypes,
-            HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES);
-    initDispatch(mDispatch.getClientTargetSupport,
-            HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT);
-    initDispatch(mDispatch.getColorModes, HWC2_FUNCTION_GET_COLOR_MODES);
-    initDispatch(mDispatch.getDisplayAttribute,
-            HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE);
-    initDispatch(mDispatch.getDisplayConfigs,
-            HWC2_FUNCTION_GET_DISPLAY_CONFIGS);
-    initDispatch(mDispatch.getDisplayName, HWC2_FUNCTION_GET_DISPLAY_NAME);
-    initDispatch(mDispatch.getDisplayRequests,
-            HWC2_FUNCTION_GET_DISPLAY_REQUESTS);
-    initDispatch(mDispatch.getDisplayType, HWC2_FUNCTION_GET_DISPLAY_TYPE);
-    initDispatch(mDispatch.getDozeSupport, HWC2_FUNCTION_GET_DOZE_SUPPORT);
-    initDispatch(mDispatch.getHdrCapabilities,
-            HWC2_FUNCTION_GET_HDR_CAPABILITIES);
-    initDispatch(mDispatch.getMaxVirtualDisplayCount,
-            HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT);
-    initDispatch(mDispatch.getReleaseFences,
-            HWC2_FUNCTION_GET_RELEASE_FENCES);
-    initDispatch(mDispatch.presentDisplay, HWC2_FUNCTION_PRESENT_DISPLAY);
-    initDispatch(mDispatch.registerCallback, HWC2_FUNCTION_REGISTER_CALLBACK);
-    initDispatch(mDispatch.setActiveConfig, HWC2_FUNCTION_SET_ACTIVE_CONFIG);
-    initDispatch(mDispatch.setClientTarget, HWC2_FUNCTION_SET_CLIENT_TARGET);
-    initDispatch(mDispatch.setColorMode, HWC2_FUNCTION_SET_COLOR_MODE);
-    initDispatch(mDispatch.setColorTransform,
-            HWC2_FUNCTION_SET_COLOR_TRANSFORM);
-    initDispatch(mDispatch.setCursorPosition,
-            HWC2_FUNCTION_SET_CURSOR_POSITION);
-    initDispatch(mDispatch.setLayerBlendMode,
-            HWC2_FUNCTION_SET_LAYER_BLEND_MODE);
-    initDispatch(mDispatch.setLayerBuffer, HWC2_FUNCTION_SET_LAYER_BUFFER);
-    initDispatch(mDispatch.setLayerColor, HWC2_FUNCTION_SET_LAYER_COLOR);
-    initDispatch(mDispatch.setLayerCompositionType,
-            HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE);
-    initDispatch(mDispatch.setLayerDataspace,
-            HWC2_FUNCTION_SET_LAYER_DATASPACE);
-    initDispatch(mDispatch.setLayerDisplayFrame,
-            HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME);
-    initDispatch(mDispatch.setLayerPlaneAlpha,
-            HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA);
+    initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
+            &mDispatch.acceptDisplayChanges);
+    initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer);
+    initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
+            &mDispatch.createVirtualDisplay);
+    initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer);
+    initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
+            &mDispatch.destroyVirtualDisplay);
+    initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump);
+    initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig);
+    initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
+            &mDispatch.getChangedCompositionTypes);
+    initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
+            &mDispatch.getClientTargetSupport);
+    initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes);
+    initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
+            &mDispatch.getDisplayAttribute);
+    initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
+            &mDispatch.getDisplayConfigs);
+    initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName);
+    initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
+            &mDispatch.getDisplayRequests);
+    initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType);
+    initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport);
+    initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES,
+            &mDispatch.getHdrCapabilities);
+    initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
+            &mDispatch.getMaxVirtualDisplayCount);
+    initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES,
+            &mDispatch.getReleaseFences);
+    initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay);
+    initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
+            &mDispatch.registerCallback);
+    initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig);
+    initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget);
+    initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode);
+    initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM,
+            &mDispatch.setColorTransform);
+    initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION,
+            &mDispatch.setCursorPosition);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
+            &mDispatch.setLayerBlendMode);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
+            &mDispatch.setLayerCompositionType);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE,
+            &mDispatch.setLayerDataspace);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
+            &mDispatch.setLayerDisplayFrame);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
+            &mDispatch.setLayerPlaneAlpha);
 
     if (hasCapability(Capability::SIDEBAND_STREAM)) {
-        initDispatch(mDispatch.setLayerSidebandStream,
-                HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM);
+        initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
+                &mDispatch.setLayerSidebandStream);
     }
 
-    initDispatch(mDispatch.setLayerSourceCrop,
-            HWC2_FUNCTION_SET_LAYER_SOURCE_CROP);
-    initDispatch(mDispatch.setLayerSurfaceDamage,
-            HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE);
-    initDispatch(mDispatch.setLayerTransform,
-            HWC2_FUNCTION_SET_LAYER_TRANSFORM);
-    initDispatch(mDispatch.setLayerVisibleRegion,
-            HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION);
-    initDispatch(mDispatch.setLayerZOrder, HWC2_FUNCTION_SET_LAYER_Z_ORDER);
-    initDispatch(mDispatch.setOutputBuffer, HWC2_FUNCTION_SET_OUTPUT_BUFFER);
-    initDispatch(mDispatch.setPowerMode, HWC2_FUNCTION_SET_POWER_MODE);
-    initDispatch(mDispatch.setVsyncEnabled, HWC2_FUNCTION_SET_VSYNC_ENABLED);
-    initDispatch(mDispatch.validateDisplay, HWC2_FUNCTION_VALIDATE_DISPLAY);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
+            &mDispatch.setLayerSourceCrop);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
+            &mDispatch.setLayerSurfaceDamage);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM,
+            &mDispatch.setLayerTransform);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
+            &mDispatch.setLayerVisibleRegion);
+    initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder);
+    initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer);
+    initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode);
+    initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled);
+    initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
 }
 
 bool HwcHal::hasCapability(Capability capability) const
@@ -165,7 +166,7 @@
 
 Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
 {
-    uint32_t len;
+    uint32_t len = 0;
     mDispatch.dump(mDevice, &len, nullptr);
 
     std::vector<char> buf(len + 1);
@@ -270,12 +271,12 @@
 }
 
 Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
-    PixelFormat& format, Display& display)
+    PixelFormat* format, Display* outDisplay)
 {
-    int32_t hwc_format = static_cast<int32_t>(format);
+    int32_t hwc_format = static_cast<int32_t>(*format);
     int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height,
-            &hwc_format, &display);
-    format = static_cast<PixelFormat>(hwc_format);
+            &hwc_format, outDisplay);
+    *format = static_cast<PixelFormat>(hwc_format);
 
     return static_cast<Error>(err);
 }
@@ -286,9 +287,9 @@
     return static_cast<Error>(err);
 }
 
-Error HwcHal::createLayer(Display display, Layer& layer)
+Error HwcHal::createLayer(Display display, Layer* outLayer)
 {
-    int32_t err = mDispatch.createLayer(mDevice, display, &layer);
+    int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
     return static_cast<Error>(err);
 }
 
@@ -298,9 +299,9 @@
     return static_cast<Error>(err);
 }
 
-Error HwcHal::getActiveConfig(Display display, Config& config)
+Error HwcHal::getActiveConfig(Display display, Config* outConfig)
 {
-    int32_t err = mDispatch.getActiveConfig(mDevice, display, &config);
+    int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
     return static_cast<Error>(err);
 }
 
@@ -314,7 +315,7 @@
     return static_cast<Error>(err);
 }
 
-Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>& modes)
+Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>* outModes)
 {
     uint32_t count = 0;
     int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
@@ -322,12 +323,12 @@
         return static_cast<Error>(err);
     }
 
-    modes.resize(count);
+    outModes->resize(count);
     err = mDispatch.getColorModes(mDevice, display, &count,
             reinterpret_cast<std::underlying_type<ColorMode>::type*>(
-                modes.data()));
+                outModes->data()));
     if (err != HWC2_ERROR_NONE) {
-        modes = hidl_vec<ColorMode>();
+        *outModes = hidl_vec<ColorMode>();
         return static_cast<Error>(err);
     }
 
@@ -335,14 +336,14 @@
 }
 
 Error HwcHal::getDisplayAttribute(Display display, Config config,
-        IComposerClient::Attribute attribute, int32_t& value)
+        IComposerClient::Attribute attribute, int32_t* outValue)
 {
     int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
-            static_cast<int32_t>(attribute), &value);
+            static_cast<int32_t>(attribute), outValue);
     return static_cast<Error>(err);
 }
 
-Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>& configs)
+Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs)
 {
     uint32_t count = 0;
     int32_t err = mDispatch.getDisplayConfigs(mDevice, display,
@@ -351,18 +352,18 @@
         return static_cast<Error>(err);
     }
 
-    configs.resize(count);
+    outConfigs->resize(count);
     err = mDispatch.getDisplayConfigs(mDevice, display,
-            &count, configs.data());
+            &count, outConfigs->data());
     if (err != HWC2_ERROR_NONE) {
-        configs = hidl_vec<Config>();
+        *outConfigs = hidl_vec<Config>();
         return static_cast<Error>(err);
     }
 
     return Error::NONE;
 }
 
-Error HwcHal::getDisplayName(Display display, hidl_string& name)
+Error HwcHal::getDisplayName(Display display, hidl_string* outName)
 {
     uint32_t count = 0;
     int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
@@ -378,44 +379,49 @@
     buf.resize(count + 1);
     buf[count] = '\0';
 
-    name = buf.data();
+    *outName = buf.data();
 
     return Error::NONE;
 }
 
-Error HwcHal::getDisplayType(Display display, IComposerClient::DisplayType& type)
+Error HwcHal::getDisplayType(Display display,
+        IComposerClient::DisplayType* outType)
 {
     int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
     int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
-    type = static_cast<IComposerClient::DisplayType>(hwc_type);
+    *outType = static_cast<IComposerClient::DisplayType>(hwc_type);
 
     return static_cast<Error>(err);
 }
 
-Error HwcHal::getDozeSupport(Display display, bool& support)
+Error HwcHal::getDozeSupport(Display display, bool* outSupport)
 {
     int32_t hwc_support = 0;
     int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
-    support = hwc_support;
+    *outSupport = hwc_support;
 
     return static_cast<Error>(err);
 }
 
-Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>& types,
-        float& maxLuminance, float& maxAverageLuminance, float& minLuminance)
+Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+        float* outMaxLuminance, float* outMaxAverageLuminance,
+        float* outMinLuminance)
 {
     uint32_t count = 0;
     int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count,
-            nullptr, &maxLuminance, &maxAverageLuminance, &minLuminance);
+            nullptr, outMaxLuminance, outMaxAverageLuminance,
+            outMinLuminance);
     if (err != HWC2_ERROR_NONE) {
         return static_cast<Error>(err);
     }
 
-    types.resize(count);
+    outTypes->resize(count);
     err = mDispatch.getHdrCapabilities(mDevice, display, &count,
-            reinterpret_cast<std::underlying_type<Hdr>::type*>(types.data()),
-            &maxLuminance, &maxAverageLuminance, &minLuminance);
+            reinterpret_cast<std::underlying_type<Hdr>::type*>(
+                outTypes->data()), outMaxLuminance,
+            outMaxAverageLuminance, outMinLuminance);
     if (err != HWC2_ERROR_NONE) {
+        *outTypes = hidl_vec<Hdr>();
         return static_cast<Error>(err);
     }
 
@@ -480,11 +486,11 @@
 }
 
 Error HwcHal::validateDisplay(Display display,
-        std::vector<Layer>& changedLayers,
-        std::vector<IComposerClient::Composition>& compositionTypes,
-        uint32_t& displayRequestMask,
-        std::vector<Layer>& requestedLayers,
-        std::vector<uint32_t>& requestMasks)
+        std::vector<Layer>* outChangedLayers,
+        std::vector<IComposerClient::Composition>* outCompositionTypes,
+        uint32_t* outDisplayRequestMask,
+        std::vector<Layer>* outRequestedLayers,
+        std::vector<uint32_t>* outRequestMasks)
 {
     uint32_t types_count = 0;
     uint32_t reqs_count = 0;
@@ -500,16 +506,16 @@
         return static_cast<Error>(err);
     }
 
-    changedLayers.resize(types_count);
-    compositionTypes.resize(types_count);
+    outChangedLayers->resize(types_count);
+    outCompositionTypes->resize(types_count);
     err = mDispatch.getChangedCompositionTypes(mDevice, display,
-            &types_count, changedLayers.data(),
+            &types_count, outChangedLayers->data(),
             reinterpret_cast<
             std::underlying_type<IComposerClient::Composition>::type*>(
-                compositionTypes.data()));
+                outCompositionTypes->data()));
     if (err != HWC2_ERROR_NONE) {
-        changedLayers.clear();
-        compositionTypes.clear();
+        outChangedLayers->clear();
+        outCompositionTypes->clear();
         return static_cast<Error>(err);
     }
 
@@ -517,26 +523,26 @@
     err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
             &reqs_count, nullptr, nullptr);
     if (err != HWC2_ERROR_NONE) {
-        changedLayers.clear();
-        compositionTypes.clear();
+        outChangedLayers->clear();
+        outCompositionTypes->clear();
         return static_cast<Error>(err);
     }
 
-    requestedLayers.resize(reqs_count);
-    requestMasks.resize(reqs_count);
+    outRequestedLayers->resize(reqs_count);
+    outRequestMasks->resize(reqs_count);
     err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
-            &reqs_count, requestedLayers.data(),
-            reinterpret_cast<int32_t*>(requestMasks.data()));
+            &reqs_count, outRequestedLayers->data(),
+            reinterpret_cast<int32_t*>(outRequestMasks->data()));
     if (err != HWC2_ERROR_NONE) {
-        changedLayers.clear();
-        compositionTypes.clear();
+        outChangedLayers->clear();
+        outCompositionTypes->clear();
 
-        requestedLayers.clear();
-        requestMasks.clear();
+        outRequestedLayers->clear();
+        outRequestMasks->clear();
         return static_cast<Error>(err);
     }
 
-    displayRequestMask = display_reqs;
+    *outDisplayRequestMask = display_reqs;
 
     return static_cast<Error>(err);
 }
@@ -547,11 +553,11 @@
     return static_cast<Error>(err);
 }
 
-Error HwcHal::presentDisplay(Display display, int32_t& presentFence,
-        std::vector<Layer>& layers, std::vector<int32_t>& releaseFences)
+Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence,
+        std::vector<Layer>* outLayers, std::vector<int32_t>* outReleaseFences)
 {
-    presentFence = -1;
-    int32_t err = mDispatch.presentDisplay(mDevice, display, &presentFence);
+    *outPresentFence = -1;
+    int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
     if (err != HWC2_ERROR_NONE) {
         return static_cast<Error>(err);
     }
@@ -564,14 +570,14 @@
         return Error::NONE;
     }
 
-    layers.resize(count);
-    releaseFences.resize(count);
+    outLayers->resize(count);
+    outReleaseFences->resize(count);
     err = mDispatch.getReleaseFences(mDevice, display, &count,
-            layers.data(), releaseFences.data());
+            outLayers->data(), outReleaseFences->data());
     if (err != HWC2_ERROR_NONE) {
         ALOGW("failed to get release fences");
-        layers.clear();
-        releaseFences.clear();
+        outLayers->clear();
+        outReleaseFences->clear();
         return Error::NONE;
     }
 
@@ -687,7 +693,7 @@
 
 IComposer* HIDL_FETCH_IComposer(const char*)
 {
-    const hw_module_t* module;
+    const hw_module_t* module = nullptr;
     int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
     if (err) {
         ALOGE("failed to get hwcomposer module");
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index 89ac4f7..6420b31 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -58,26 +58,27 @@
 
     uint32_t getMaxVirtualDisplayCount();
     Error createVirtualDisplay(uint32_t width, uint32_t height,
-        PixelFormat& format, Display& display);
+        PixelFormat* format, Display* outDisplay);
     Error destroyVirtualDisplay(Display display);
 
-    Error createLayer(Display display, Layer& layer);
+    Error createLayer(Display display, Layer* outLayer);
     Error destroyLayer(Display display, Layer layer);
 
-    Error getActiveConfig(Display display, Config& config);
+    Error getActiveConfig(Display display, Config* outConfig);
     Error getClientTargetSupport(Display display,
             uint32_t width, uint32_t height,
             PixelFormat format, Dataspace dataspace);
-    Error getColorModes(Display display, hidl_vec<ColorMode>& modes);
+    Error getColorModes(Display display, hidl_vec<ColorMode>* outModes);
     Error getDisplayAttribute(Display display, Config config,
-            IComposerClient::Attribute attribute, int32_t& value);
-    Error getDisplayConfigs(Display display, hidl_vec<Config>& configs);
-    Error getDisplayName(Display display, hidl_string& name);
-    Error getDisplayType(Display display, IComposerClient::DisplayType& type);
-    Error getDozeSupport(Display display, bool& support);
-    Error getHdrCapabilities(Display display, hidl_vec<Hdr>& types,
-            float& maxLuminance, float& maxAverageLuminance,
-            float& minLuminance);
+            IComposerClient::Attribute attribute, int32_t* outValue);
+    Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs);
+    Error getDisplayName(Display display, hidl_string* outName);
+    Error getDisplayType(Display display,
+            IComposerClient::DisplayType* outType);
+    Error getDozeSupport(Display display, bool* outSupport);
+    Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+            float* outMaxLuminance, float* outMaxAverageLuminance,
+            float* outMinLuminance);
 
     Error setActiveConfig(Display display, Config config);
     Error setColorMode(Display display, ColorMode mode);
@@ -92,14 +93,15 @@
     Error setOutputBuffer(Display display, buffer_handle_t buffer,
             int32_t releaseFence);
     Error validateDisplay(Display display,
-            std::vector<Layer>& changedLayers,
-            std::vector<IComposerClient::Composition>& compositionTypes,
-            uint32_t& displayRequestMask,
-            std::vector<Layer>& requestedLayers,
-            std::vector<uint32_t>& requestMasks);
+            std::vector<Layer>* outChangedLayers,
+            std::vector<IComposerClient::Composition>* outCompositionTypes,
+            uint32_t* outDisplayRequestMask,
+            std::vector<Layer>* outRequestedLayers,
+            std::vector<uint32_t>* outRequestMasks);
     Error acceptDisplayChanges(Display display);
-    Error presentDisplay(Display display, int32_t& presentFence,
-            std::vector<Layer>& layers, std::vector<int32_t>& releaseFences);
+    Error presentDisplay(Display display, int32_t* outPresentFence,
+            std::vector<Layer>* outLayers,
+            std::vector<int32_t>* outReleaseFences);
 
     Error setLayerCursorPosition(Display display, Layer layer,
             int32_t x, int32_t y);
@@ -131,7 +133,7 @@
     void initCapabilities();
 
     template<typename T>
-    void initDispatch(T& func, hwc2_function_descriptor_t desc);
+    void initDispatch(hwc2_function_descriptor_t desc, T* outPfn);
     void initDispatch();
 
     sp<HwcClient> getClient();
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
index 16af94c..8c2dd6d 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -102,7 +102,7 @@
 #ifdef BINDERIZED
     bool openGralloc()
     {
-        const hw_module_t* module;
+        const hw_module_t* module = nullptr;
         int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
         if (err) {
             ALOGE("failed to get gralloc module");
@@ -308,8 +308,9 @@
         PixelFormat formatHint, uint32_t outputBufferSlotCount,
         createVirtualDisplay_cb hidl_cb)
 {
-    Display display;
-    Error err = mHal.createVirtualDisplay(width, height, formatHint, display);
+    Display display = 0;
+    Error err = mHal.createVirtualDisplay(width, height,
+            &formatHint, &display);
     if (err == Error::NONE) {
         std::lock_guard<std::mutex> lock(mDisplayDataMutex);
 
@@ -336,8 +337,8 @@
 Return<void> HwcClient::createLayer(Display display, uint32_t bufferSlotCount,
         createLayer_cb hidl_cb)
 {
-    Layer layer;
-    Error err = mHal.createLayer(display, layer);
+    Layer layer = 0;
+    Error err = mHal.createLayer(display, &layer);
     if (err == Error::NONE) {
         std::lock_guard<std::mutex> lock(mDisplayDataMutex);
 
@@ -366,8 +367,8 @@
 Return<void> HwcClient::getActiveConfig(Display display,
         getActiveConfig_cb hidl_cb)
 {
-    Config config;
-    Error err = mHal.getActiveConfig(display, config);
+    Config config = 0;
+    Error err = mHal.getActiveConfig(display, &config);
 
     hidl_cb(err, config);
     return Void();
@@ -385,7 +386,7 @@
 Return<void> HwcClient::getColorModes(Display display, getColorModes_cb hidl_cb)
 {
     hidl_vec<ColorMode> modes;
-    Error err = mHal.getColorModes(display, modes);
+    Error err = mHal.getColorModes(display, &modes);
 
     hidl_cb(err, modes);
     return Void();
@@ -395,8 +396,8 @@
         Config config, Attribute attribute,
         getDisplayAttribute_cb hidl_cb)
 {
-    int32_t value;
-    Error err = mHal.getDisplayAttribute(display, config, attribute, value);
+    int32_t value = 0;
+    Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
 
     hidl_cb(err, value);
     return Void();
@@ -406,7 +407,7 @@
         getDisplayConfigs_cb hidl_cb)
 {
     hidl_vec<Config> configs;
-    Error err = mHal.getDisplayConfigs(display, configs);
+    Error err = mHal.getDisplayConfigs(display, &configs);
 
     hidl_cb(err, configs);
     return Void();
@@ -416,7 +417,7 @@
         getDisplayName_cb hidl_cb)
 {
     hidl_string name;
-    Error err = mHal.getDisplayName(display, name);
+    Error err = mHal.getDisplayName(display, &name);
 
     hidl_cb(err, name);
     return Void();
@@ -425,8 +426,8 @@
 Return<void> HwcClient::getDisplayType(Display display,
         getDisplayType_cb hidl_cb)
 {
-    DisplayType type;
-    Error err = mHal.getDisplayType(display, type);
+    DisplayType type = DisplayType::INVALID;
+    Error err = mHal.getDisplayType(display, &type);
 
     hidl_cb(err, type);
     return Void();
@@ -435,8 +436,8 @@
 Return<void> HwcClient::getDozeSupport(Display display,
         getDozeSupport_cb hidl_cb)
 {
-    bool support;
-    Error err = mHal.getDozeSupport(display, support);
+    bool support = false;
+    Error err = mHal.getDozeSupport(display, &support);
 
     hidl_cb(err, support);
     return Void();
@@ -449,8 +450,8 @@
     float max_lumi = 0.0f;
     float max_avg_lumi = 0.0f;
     float min_lumi = 0.0f;
-    Error err = mHal.getHdrCapabilities(display, types,
-            max_lumi, max_avg_lumi, min_lumi);
+    Error err = mHal.getHdrCapabilities(display, &types,
+            &max_lumi, &max_avg_lumi, &min_lumi);
 
     hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
     return Void();
@@ -496,7 +497,7 @@
 }
 
 Return<Error> HwcClient::setInputCommandQueue(
-        const MQDescriptorSync& descriptor)
+        const MQDescriptorSync<uint32_t>& descriptor)
 {
     std::lock_guard<std::mutex> lock(mCommandMutex);
     return mReader.setMQDescriptor(descriptor) ?
@@ -513,7 +514,7 @@
     if (outDescriptor) {
         hidl_cb(Error::NONE, *outDescriptor);
     } else {
-        hidl_cb(Error::NO_RESOURCES, MQDescriptorSync(0, nullptr, 0));
+        hidl_cb(Error::NO_RESOURCES, MQDescriptorSync<uint32_t>());
     }
 
     return Void();
@@ -536,7 +537,7 @@
 
     Error err = mReader.parse();
     if (err == Error::NONE &&
-            !mWriter.writeQueue(outChanged, outLength, outHandles)) {
+            !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
         err = Error::NO_RESOURCES;
     }
 
@@ -556,10 +557,10 @@
 Error HwcClient::CommandReader::parse()
 {
     IComposerClient::Command command;
-    uint16_t length;
+    uint16_t length = 0;
 
     while (!isEmpty()) {
-        if (!beginCommand(command, length)) {
+        if (!beginCommand(&command, &length)) {
             break;
         }
 
@@ -698,9 +699,9 @@
         return false;
     }
 
-    bool useCache;
+    bool useCache = false;
     auto slot = read();
-    auto clientTarget = readHandle(useCache);
+    auto clientTarget = readHandle(&useCache);
     auto fence = readFence();
     auto dataspace = readSigned();
     auto damage = readRegion((length - 4) / 4);
@@ -725,9 +726,9 @@
         return false;
     }
 
-    bool useCache;
+    bool useCache = false;
     auto slot = read();
-    auto outputBuffer = readHandle(useCache);
+    auto outputBuffer = readHandle(&useCache);
     auto fence = readFence();
 
     auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
@@ -751,12 +752,13 @@
 
     std::vector<Layer> changedLayers;
     std::vector<IComposerClient::Composition> compositionTypes;
-    uint32_t displayRequestMask;
+    uint32_t displayRequestMask = 0x0;
     std::vector<Layer> requestedLayers;
     std::vector<uint32_t> requestMasks;
 
-    auto err = mHal.validateDisplay(mDisplay, changedLayers, compositionTypes,
-            displayRequestMask, requestedLayers, requestMasks);
+    auto err = mHal.validateDisplay(mDisplay, &changedLayers,
+            &compositionTypes, &displayRequestMask,
+            &requestedLayers, &requestMasks);
     if (err == Error::NONE) {
         mWriter.setChangedCompositionTypes(changedLayers,
                 compositionTypes);
@@ -789,10 +791,10 @@
         return false;
     }
 
-    int presentFence;
+    int presentFence = -1;
     std::vector<Layer> layers;
     std::vector<int> fences;
-    auto err = mHal.presentDisplay(mDisplay, presentFence, layers, fences);
+    auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
     if (err == Error::NONE) {
         mWriter.setPresentFence(presentFence);
         mWriter.setReleaseFences(layers, fences);
@@ -824,9 +826,9 @@
         return false;
     }
 
-    bool useCache;
+    bool useCache = false;
     auto slot = read();
-    auto buffer = readHandle(useCache);
+    auto buffer = readHandle(&useCache);
     auto fence = readFence();
 
     auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
@@ -934,7 +936,7 @@
         return false;
     }
 
-    auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, read());
+    auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
     if (err != Error::NONE) {
         mWriter.setError(getCommandLoc(), err);
     }
diff --git a/graphics/composer/2.1/default/HwcClient.h b/graphics/composer/2.1/default/HwcClient.h
index a9bc4cd..c719774 100644
--- a/graphics/composer/2.1/default/HwcClient.h
+++ b/graphics/composer/2.1/default/HwcClient.h
@@ -97,7 +97,7 @@
     Return<Error> setClientTargetSlotCount(Display display,
             uint32_t clientTargetSlotCount) override;
     Return<Error> setInputCommandQueue(
-            const MQDescriptorSync& descriptor) override;
+            const MQDescriptorSync<uint32_t>& descriptor) override;
     Return<void> getOutputCommandQueue(
             getOutputCommandQueue_cb hidl_cb) override;
     Return<void> executeCommands(uint32_t inLength,
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
index 030db88..7e14f19 100644
--- a/graphics/composer/2.1/default/IComposerCommandBuffer.h
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -35,7 +35,7 @@
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <log/log.h>
 #include <sync/sync.h>
-#include <MessageQueue.h>
+#include <fmq/MessageQueue.h>
 
 namespace android {
 namespace hardware {
@@ -89,8 +89,8 @@
                 static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK));
     }
 
-    bool writeQueue(bool& queueChanged, uint32_t& commandLength,
-            hidl_vec<hidl_handle>& commandHandles)
+    bool writeQueue(bool* outQueueChanged, uint32_t* outCommandLength,
+            hidl_vec<hidl_handle>* outCommandHandles)
     {
         // write data to queue, optionally resizing it
         if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
@@ -99,7 +99,7 @@
                 return false;
             }
 
-            queueChanged = false;
+            *outQueueChanged = false;
         } else {
             auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
             if (!newQueue->isValid() ||
@@ -109,18 +109,18 @@
             }
 
             mQueue = std::move(newQueue);
-            queueChanged = true;
+            *outQueueChanged = true;
         }
 
-        commandLength = mDataWritten;
-        commandHandles.setToExternal(
+        *outCommandLength = mDataWritten;
+        outCommandHandles->setToExternal(
                 const_cast<hidl_handle*>(mDataHandles.data()),
                 mDataHandles.size());
 
         return true;
     }
 
-    const MQDescriptorSync* getMQDescriptor() const
+    const MQDescriptorSync<uint32_t>* getMQDescriptor() const
     {
         return (mQueue) ? mQueue->getDesc() : nullptr;
     }
@@ -626,7 +626,7 @@
         reset();
     }
 
-    bool setMQDescriptor(const MQDescriptorSync& descriptor)
+    bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor)
     {
         mQueue = std::make_unique<CommandQueueType>(descriptor, false);
         if (mQueue->isValid()) {
@@ -682,7 +682,8 @@
         return (mDataRead >= mDataSize);
     }
 
-    bool beginCommand(IComposerClient::Command& command, uint16_t& length)
+    bool beginCommand(IComposerClient::Command* outCommand,
+            uint16_t* outLength)
     {
         if (mCommandEnd) {
             LOG_FATAL("endCommand was not called before command 0x%x",
@@ -695,18 +696,19 @@
             static_cast<uint32_t>(IComposerClient::Command::LENGTH_MASK);
 
         uint32_t val = read();
-        command = static_cast<IComposerClient::Command>(val & opcode_mask);
-        length = static_cast<uint16_t>(val & length_mask);
+        *outCommand = static_cast<IComposerClient::Command>(
+                val & opcode_mask);
+        *outLength = static_cast<uint16_t>(val & length_mask);
 
-        if (mDataRead + length > mDataSize) {
+        if (mDataRead + *outLength > mDataSize) {
             ALOGE("command 0x%x has invalid command length %" PRIu16,
-                    command, length);
+                    *outCommand, *outLength);
             // undo the read() above
             mDataRead--;
             return false;
         }
 
-        mCommandEnd = mDataRead + length;
+        mCommandEnd = mDataRead + *outLength;
 
         return true;
     }
@@ -770,17 +772,17 @@
     }
 
     // ownership of handle is not transferred
-    const native_handle_t* readHandle(bool& useCache)
+    const native_handle_t* readHandle(bool* outUseCache)
     {
         const native_handle_t* handle = nullptr;
 
         int32_t index = readSigned();
         switch (index) {
         case static_cast<int32_t>(IComposerClient::HandleIndex::EMPTY):
-            useCache = false;
+            *outUseCache = false;
             break;
         case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
-            useCache = true;
+            *outUseCache = true;
             break;
         default:
             if (static_cast<size_t>(index) < mDataHandles.size()) {
@@ -788,7 +790,7 @@
             } else {
                 ALOGE("invalid handle index %zu", static_cast<size_t>(index));
             }
-            useCache = false;
+            *outUseCache = false;
             break;
         }
 
@@ -798,7 +800,7 @@
     const native_handle_t* readHandle()
     {
         bool useCache;
-        return readHandle(useCache);
+        return readHandle(&useCache);
     }
 
     // ownership of fence is transferred
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index 0384a53..c2a2b19 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -17,14 +17,13 @@
 #define LOG_TAG "HWComposerService"
 
 #include <binder/ProcessState.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
 #include <utils/StrongPointer.h>
 #include "Hwc.h"
 
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
 using android::sp;
-using android::hardware::IPCThreadState;
-using android::hardware::ProcessState;
 using android::hardware::graphics::composer::V2_1::IComposer;
 using android::hardware::graphics::composer::V2_1::implementation::HIDL_FETCH_IComposer;
 
@@ -34,6 +33,7 @@
 
     ALOGI("Service is starting.");
 
+    configureRpcThreadpool(1, true /* callerWillJoin */);
     sp<IComposer> service = HIDL_FETCH_IComposer(instance);
     if (service == nullptr) {
         ALOGI("getService returned NULL");
@@ -48,9 +48,7 @@
     android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
     android::ProcessState::self()->startThreadPool();
 
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
+    joinRpcThreadpool();
 
     return 0;
 }
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 19b1388..9ac6d50 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -1,4 +1,60 @@
-cc_library_static {
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.graphics.mapper@2.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.mapper@2.0",
+    srcs: [
+        "types.hal",
+        "IMapper.hal",
+    ],
+    out: [
+        "android/hardware/graphics/mapper/2.0/types.cpp",
+        "android/hardware/graphics/mapper/2.0/MapperAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.graphics.mapper@2.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.mapper@2.0",
+    srcs: [
+        "types.hal",
+        "IMapper.hal",
+    ],
+    out: [
+        "android/hardware/graphics/mapper/2.0/types.h",
+        "android/hardware/graphics/mapper/2.0/IMapper.h",
+        "android/hardware/graphics/mapper/2.0/IHwMapper.h",
+        "android/hardware/graphics/mapper/2.0/BnMapper.h",
+        "android/hardware/graphics/mapper/2.0/BpMapper.h",
+        "android/hardware/graphics/mapper/2.0/BsMapper.h",
+    ],
+}
+
+cc_library_shared {
     name: "android.hardware.graphics.mapper@2.0",
-    export_include_dirs: ["include"],
+    generated_sources: ["android.hardware.graphics.mapper@2.0_genc++"],
+    generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.common@1.0",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.common@1.0",
+        "android.hidl.base@1.0",
+    ],
 }
diff --git a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h b/graphics/mapper/2.0/IMapper.hal
similarity index 62%
rename from graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
rename to graphics/mapper/2.0/IMapper.hal
index ac8ec45..21a6dfa 100644
--- a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The Android Open Source Project
+ * 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.
@@ -14,165 +14,135 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H
-#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H
+package android.hardware.graphics.mapper@2.0;
 
-#include <type_traits>
+import android.hardware.graphics.common@1.0::PixelFormat;
+import android.hardware.graphics.allocator@2.0;
 
-#include <android/hardware/graphics/mapper/2.0/types.h>
-
-extern "C" {
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace mapper {
-namespace V2_0 {
-
-struct Device {
+interface IMapper {
     struct Rect {
         int32_t left;
         int32_t top;
         int32_t width;
         int32_t height;
     };
-    static_assert(std::is_pod<Rect>::value, "Device::Rect is not POD");
-
-    /*
-     * Create a mapper device.
-     *
-     * @return error is NONE upon success. Otherwise,
-     *                  NOT_SUPPORTED when creation will never succeed.
-     *                  BAD_RESOURCES when creation failed at this time.
-     * @return device is the newly created mapper device.
-     */
-    typedef Error (*createDevice)(Device** outDevice);
-
-    /*
-     * Destroy a mapper device.
-     *
-     * @return error is always NONE.
-     * @param device is the mapper device to destroy.
-     */
-    typedef Error (*destroyDevice)(Device* device);
 
     /*
      * Adds a reference to the given buffer handle.
      *
      * A buffer handle received from a remote process or exported by
-     * IAllocator::exportHandle is unknown to this client-side library. There
-     * is also no guarantee that the buffer's backing store will stay alive.
-     * This function must be called at least once in both cases to intrdouce
-     * the buffer handle to this client-side library and to secure the backing
-     * store. It may also be called more than once to increase the reference
-     * count if two components in the same process want to interact with the
-     * buffer independently.
+     * IAllocator::exportHandle is unknown to the mapper. There is also no
+     * guarantee that the buffer's backing store will stay alive. This
+     * function must be called at least once in both cases to intrdouce the
+     * buffer handle to the mapper and to secure the backing store. It may
+     * also be called more than once to increase the reference count if two
+     * components in the same process want to interact with the buffer
+     * independently.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer to which a reference must be added.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid
      *                  NO_RESOURCES when it is not possible to add a
      *                               reference to this buffer at this time
      */
-    typedef Error (*retain)(Device* device,
-                            const native_handle_t* bufferHandle);
+    @entry
+    @callflow(next="*")
+    retain(handle bufferHandle) generates (Error error);
 
     /*
      * Removes a reference from the given buffer buffer.
      *
-     * If no references remain, the buffer handle should be freed with
-     * native_handle_close/native_handle_delete. When the last buffer handle
-     * referring to a particular backing store is freed, that backing store
-     * should also be freed.
+     * If no references remain, the buffer handle must be freed with
+     * native_handle_close/native_handle_delete by the mapper. When the last
+     * buffer handle referring to a particular backing store is freed, that
+     * backing store must also be freed.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which a reference must be
      *        removed.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      */
-    typedef Error (*release)(Device* device,
-                             const native_handle_t* bufferHandle);
+    @exit
+    release(handle bufferHandle) generates (Error error);
 
     /*
      * Gets the width and height of the buffer in pixels.
      *
      * See IAllocator::BufferDescriptorInfo for more information.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which to get the dimensions.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return width is the width of the buffer in pixels.
      * @return height is the height of the buffer in pixels.
      */
-    typedef Error (*getDimensions)(Device* device,
-                                   const native_handle_t* bufferHandle,
-                                   uint32_t* outWidth,
-                                   uint32_t* outHeight);
+    @callflow(next="*")
+    getDimensions(handle bufferHandle)
+       generates (Error error,
+                  uint32_t width,
+                  uint32_t height);
 
     /*
      * Gets the format of the buffer.
      *
      * See IAllocator::BufferDescriptorInfo for more information.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which to get format.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return format is the format of the buffer.
      */
-    typedef Error (*getFormat)(Device* device,
-                               const native_handle_t* bufferHandle,
-                               PixelFormat* outFormat);
+    @callflow(next="*")
+    getFormat(handle bufferHandle)
+        generates (Error error,
+                   PixelFormat format);
 
     /*
      * Gets the number of layers of the buffer.
      *
      * See IAllocator::BufferDescriptorInfo for more information.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which to get format.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return layerCount is the number of layers of the buffer.
      */
-    typedef Error (*getLayerCount)(Device* device,
-                               const native_handle_t* bufferHandle,
-                               uint32_t* outLayerCount);
+    @callflow(next="*")
+    getLayerCount(handle bufferHandle)
+       generates (Error error,
+                  uint32_t layerCount);
 
     /*
      * Gets the producer usage flags which were used to allocate this buffer.
      *
      * See IAllocator::BufferDescriptorInfo for more information.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which to get the producer usage
      *        flags.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return usageMask contains the producer usage flags of the buffer.
      */
-    typedef Error (*getProducerUsageMask)(Device* device,
-                                          const native_handle_t* bufferHandle,
-                                          uint64_t* outUsageMask);
+    @callflow(next="*")
+    getProducerUsageMask(handle bufferHandle)
+              generates (Error error,
+                         uint64_t usageMask);
 
     /*
      * Gets the consumer usage flags which were used to allocate this buffer.
      *
      * See IAllocator::BufferDescriptorInfo for more information.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer from which to get the consumer usage
      *        flags.
      * @return error is NONE upon success. Otherwise,
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return usageMask contains the consumer usage flags of the buffer.
      */
-    typedef Error (*getConsumerUsageMask)(Device* device,
-                                          const native_handle_t* bufferHandle,
-                                          uint64_t* outUsageMask);
+    @callflow(next="*")
+    getConsumerUsageMask(handle bufferHandle)
+              generates (Error error,
+                         uint64_t usageMask);
 
     /*
      * Gets a value that uniquely identifies the backing store of the given
@@ -190,9 +160,10 @@
      *                  BAD_BUFFER when the buffer handle is invalid.
      * @return store is the backing store identifier for this buffer.
      */
-    typedef Error (*getBackingStore)(Device* device,
-                                     const native_handle_t* bufferHandle,
-                                     BackingStore* outStore);
+    @callflow(next="*")
+    getBackingStore(handle bufferHandle)
+         generates (Error error,
+                    BackingStore store);
 
     /*
      * Gets the stride of the buffer in pixels.
@@ -209,31 +180,10 @@
      *                            meaningful for the buffer format.
      * @return store is the stride in pixels.
      */
-    typedef Error (*getStride)(Device* device,
-                               const native_handle_t* bufferHandle,
-                               uint32_t* outStride);
-
-    /*
-     * Returns the number of flex layout planes which are needed to represent
-     * the given buffer. This may be used to efficiently allocate only as many
-     * plane structures as necessary before calling into lockFlex.
-     *
-     * If the given buffer cannot be locked as a flex format, this function
-     * may return UNSUPPORTED (as lockFlex would).
-     *
-     * @param device is the mapper device.
-     * @param bufferHandle is the buffer for which the number of planes should
-     *        be queried.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     *                  UNSUPPORTED when the buffer's format cannot be
-     *                              represented in a flex layout.
-     * @return numPlanes is the number of flex planes required to describe the
-     *         given buffer.
-     */
-    typedef Error (*getNumFlexPlanes)(Device* device,
-                                      const native_handle_t* bufferHandle,
-                                      uint32_t* outNumPlanes);
+    @callflow(next="*")
+    getStride(handle bufferHandle)
+        generates (Error error,
+                   uint32_t stride);
 
     /*
      * Locks the given buffer for the specified CPU usage.
@@ -264,7 +214,6 @@
      * the contents of the buffer (prior to locking). If it is already safe to
      * access the buffer contents, -1 may be passed instead.
      *
-     * @param device is the mapper device.
      * @param bufferHandle is the buffer to lock.
      * @param producerUsageMask contains the producer usage flags to request;
      *        either this or consumerUsagemask must be 0, and the other must
@@ -289,13 +238,14 @@
      * @return data will be filled with a CPU-accessible pointer to the buffer
      *         data.
      */
-    typedef Error (*lock)(Device* device,
-                          const native_handle_t* bufferHandle,
-                          uint64_t producerUsageMask,
-                          uint64_t consumerUsageMask,
-                          const Rect* accessRegion,
-                          int32_t acquireFence,
-                          void** outData);
+    @callflow(next="unlock")
+    lock(handle bufferHandle,
+         uint64_t producerUsageMask,
+         uint64_t consumerUsageMask,
+         Rect accessRegion,
+         handle acquireFence)
+        generates (Error error,
+                   pointer data);
 
     /*
      * This is largely the same as lock(), except that instead of returning a
@@ -337,13 +287,14 @@
      * @return flexLayout will be filled with the description of the planes in
      *         the buffer.
      */
-    typedef Error (*lockFlex)(Device* device,
-                              const native_handle_t* bufferHandle,
-                              uint64_t producerUsageMask,
-                              uint64_t consumerUsageMask,
-                              const Rect* accessRegion,
-                              int32_t acquireFence,
-                              FlexLayout* outFlexLayout);
+    @callflow(next="unlock")
+    lockFlex(handle bufferHandle,
+             uint64_t producerUsageMask,
+             uint64_t consumerUsageMask,
+             Rect accessRegion,
+             handle acquireFence)
+        generates (Error error,
+                   FlexLayout layout);
 
     /*
      * This function indicates to the device that the client will be done with
@@ -365,40 +316,8 @@
      * @return releaseFence is a sync fence file descriptor as described
      *         above.
      */
-    typedef Error (*unlock)(Device* device,
-                            const native_handle_t* bufferHandle,
-                            int32_t* outReleaseFence);
+    @callflow(next="*")
+    unlock(handle bufferHandle)
+        generates (Error error,
+                   handle releaseFence);
 };
-static_assert(std::is_pod<Device>::value, "Device is not POD");
-
-struct IMapper {
-    Device::createDevice createDevice;
-    Device::destroyDevice destroyDevice;
-
-    Device::retain retain;
-    Device::release release;
-    Device::getDimensions getDimensions;
-    Device::getFormat getFormat;
-    Device::getLayerCount getLayerCount;
-    Device::getProducerUsageMask getProducerUsageMask;
-    Device::getConsumerUsageMask getConsumerUsageMask;
-    Device::getBackingStore getBackingStore;
-    Device::getStride getStride;
-    Device::getNumFlexPlanes getNumFlexPlanes;
-    Device::lock lock;
-    Device::lockFlex lockFlex;
-    Device::unlock unlock;
-};
-static_assert(std::is_pod<IMapper>::value, "IMapper is not POD");
-
-} // namespace V2_0
-} // namespace mapper
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-const void* HALLIB_FETCH_Interface(const char* name);
-
-} // extern "C"
-
-#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H */
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 7da6eb1..02ed877 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -1,3 +1,4 @@
+//
 // Copyright (C) 2016 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,17 +14,19 @@
 // limitations under the License.
 
 cc_library_shared {
-    name: "android.hardware.graphics.mapper.hallib",
+    name: "android.hardware.graphics.mapper@2.0-impl",
     relative_install_path: "hw",
     srcs: ["GrallocMapper.cpp"],
     cppflags: ["-Wall", "-Wextra"],
-    static_libs: ["android.hardware.graphics.mapper@2.0"],
     shared_libs: [
-        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.mapper@2.0",
+        "libbase",
+        "libcutils",
         "libhardware",
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
         "liblog",
+        "libutils",
     ],
 }
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index 2af1d2c..cd9db38 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -15,13 +15,15 @@
 
 #define LOG_TAG "GrallocMapperPassthrough"
 
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include "GrallocMapper.h"
+
+#include <vector>
+
+#include <string.h>
+
 #include <hardware/gralloc1.h>
 #include <log/log.h>
 
-#include <unordered_set>
-
 namespace android {
 namespace hardware {
 namespace graphics {
@@ -29,50 +31,59 @@
 namespace V2_0 {
 namespace implementation {
 
-using Capability = allocator::V2_0::IAllocator::Capability;
+namespace {
 
-class GrallocDevice : public Device {
+using android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+class GrallocMapperHal : public IMapper {
 public:
-    GrallocDevice();
-    ~GrallocDevice();
+    GrallocMapperHal(const hw_module_t* module);
+    ~GrallocMapperHal();
 
     // IMapper interface
-    Error retain(const native_handle_t* bufferHandle);
-    Error release(const native_handle_t* bufferHandle);
-    Error getDimensions(const native_handle_t* bufferHandle,
-            uint32_t* outWidth, uint32_t* outHeight);
-    Error getFormat(const native_handle_t* bufferHandle,
-            PixelFormat* outFormat);
-    Error getLayerCount(const native_handle_t* bufferHandle,
-            uint32_t* outLayerCount);
-    Error getProducerUsageMask(const native_handle_t* bufferHandle,
-            uint64_t* outUsageMask);
-    Error getConsumerUsageMask(const native_handle_t* bufferHandle,
-            uint64_t* outUsageMask);
-    Error getBackingStore(const native_handle_t* bufferHandle,
-            BackingStore* outStore);
-    Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride);
-    Error getNumFlexPlanes(const native_handle_t* bufferHandle,
-            uint32_t* outNumPlanes);
-    Error lock(const native_handle_t* bufferHandle,
+    Return<Error> retain(const hidl_handle& bufferHandle) override;
+    Return<Error> release(const hidl_handle& bufferHandle) override;
+    Return<void> getDimensions(const hidl_handle& bufferHandle,
+            getDimensions_cb hidl_cb) override;
+    Return<void> getFormat(const hidl_handle& bufferHandle,
+            getFormat_cb hidl_cb) override;
+    Return<void> getLayerCount(const hidl_handle& bufferHandle,
+            getLayerCount_cb hidl_cb) override;
+    Return<void> getProducerUsageMask(const hidl_handle& bufferHandle,
+            getProducerUsageMask_cb hidl_cb) override;
+    Return<void> getConsumerUsageMask(const hidl_handle& bufferHandle,
+            getConsumerUsageMask_cb hidl_cb) override;
+    Return<void> getBackingStore(const hidl_handle& bufferHandle,
+            getBackingStore_cb hidl_cb) override;
+    Return<void> getStride(const hidl_handle& bufferHandle,
+            getStride_cb hidl_cb) override;
+    Return<void> lock(const hidl_handle& bufferHandle,
             uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const Rect* accessRegion, int32_t acquireFence, void** outData);
-    Error lockFlex(const native_handle_t* bufferHandle,
+            const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+            lock_cb hidl_cb) override;
+    Return<void> lockFlex(const hidl_handle& bufferHandle,
             uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const Rect* accessRegion, int32_t acquireFence,
-            FlexLayout* outFlexLayout);
-    Error unlock(const native_handle_t* bufferHandle,
-            int32_t* outReleaseFence);
+            const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+            lockFlex_cb hidl_cb) override;
+    Return<void> unlock(const hidl_handle& bufferHandle,
+            unlock_cb hidl_cb) override;
 
 private:
     void initCapabilities();
 
+    template<typename T>
+    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
     void initDispatch();
-    bool hasCapability(Capability capability) const;
+
+    static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
+    static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
 
     gralloc1_device_t* mDevice;
 
-    std::unordered_set<Capability> mCapabilities;
+    struct {
+        bool layeredBuffers;
+    } mCapabilities;
 
     struct {
         GRALLOC1_PFN_RETAIN retain;
@@ -91,333 +102,293 @@
     } mDispatch;
 };
 
-GrallocDevice::GrallocDevice()
+GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
+    : mDevice(nullptr), mCapabilities(), mDispatch()
 {
-    const hw_module_t* module;
-    int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    int status = gralloc1_open(module, &mDevice);
     if (status) {
-        LOG_ALWAYS_FATAL("failed to get gralloc module");
-    }
-
-    uint8_t major = (module->module_api_version >> 8) & 0xff;
-    if (major != 1) {
-        LOG_ALWAYS_FATAL("unknown gralloc module major version %d", major);
-    }
-
-    status = gralloc1_open(module, &mDevice);
-    if (status) {
-        LOG_ALWAYS_FATAL("failed to open gralloc1 device");
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+                strerror(-status));
     }
 
     initCapabilities();
     initDispatch();
 }
 
-GrallocDevice::~GrallocDevice()
+GrallocMapperHal::~GrallocMapperHal()
 {
     gralloc1_close(mDevice);
 }
 
-void GrallocDevice::initCapabilities()
+void GrallocMapperHal::initCapabilities()
 {
     uint32_t count;
     mDevice->getCapabilities(mDevice, &count, nullptr);
 
-    std::vector<Capability> caps(count);
-    mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
-              std::underlying_type<Capability>::type*>(caps.data()));
+    std::vector<int32_t> caps(count);
+    mDevice->getCapabilities(mDevice, &count, caps.data());
     caps.resize(count);
 
-    mCapabilities.insert(caps.cbegin(), caps.cend());
-}
-
-void GrallocDevice::initDispatch()
-{
-#define CHECK_FUNC(func, desc) do {                                   \
-    mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>(      \
-        mDevice->getFunction(mDevice, desc));                         \
-    if (!mDispatch.func) {                                            \
-        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \
-    }                                                                 \
-} while (0)
-
-    CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN);
-    CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
-    CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
-    CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
-    if (hasCapability(Capability::LAYERED_BUFFERS)) {
-        CHECK_FUNC(getLayerCount, GRALLOC1_FUNCTION_GET_LAYER_COUNT);
+    for (auto cap : caps) {
+        switch (cap) {
+        case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
+            mCapabilities.layeredBuffers = true;
+            break;
+        default:
+            break;
+        }
     }
-    CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
-    CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
-    CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
-    CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE);
-    CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
-    CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK);
-    CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX);
-    CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK);
-
-#undef CHECK_FUNC
 }
 
-bool GrallocDevice::hasCapability(Capability capability) const
+template<typename T>
+void GrallocMapperHal::initDispatch(gralloc1_function_descriptor_t desc,
+        T* outPfn)
 {
-    return (mCapabilities.count(capability) > 0);
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+    }
+
+    *outPfn = reinterpret_cast<T>(pfn);
 }
 
-Error GrallocDevice::retain(const native_handle_t* bufferHandle)
+void GrallocMapperHal::initDispatch()
 {
-    int32_t error = mDispatch.retain(mDevice, bufferHandle);
-    return static_cast<Error>(error);
+    initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
+    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+    initDispatch(GRALLOC1_FUNCTION_GET_DIMENSIONS, &mDispatch.getDimensions);
+    initDispatch(GRALLOC1_FUNCTION_GET_FORMAT, &mDispatch.getFormat);
+    if (mCapabilities.layeredBuffers) {
+        initDispatch(GRALLOC1_FUNCTION_GET_LAYER_COUNT,
+                &mDispatch.getLayerCount);
+    }
+    initDispatch(GRALLOC1_FUNCTION_GET_PRODUCER_USAGE,
+            &mDispatch.getProducerUsage);
+    initDispatch(GRALLOC1_FUNCTION_GET_CONSUMER_USAGE,
+            &mDispatch.getConsumerUsage);
+    initDispatch(GRALLOC1_FUNCTION_GET_BACKING_STORE,
+            &mDispatch.getBackingStore);
+    initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
+    initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
+            &mDispatch.getNumFlexPlanes);
+    initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
+    initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
+    initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
 }
 
-Error GrallocDevice::release(const native_handle_t* bufferHandle)
+gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
 {
-    int32_t error = mDispatch.release(mDevice, bufferHandle);
-    return static_cast<Error>(error);
+    return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
 }
 
-Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle,
-        uint32_t* outWidth, uint32_t* outHeight)
+bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
 {
-    int32_t error = mDispatch.getDimensions(mDevice, bufferHandle,
-            outWidth, outHeight);
-    return static_cast<Error>(error);
+    auto handle = fenceHandle.getNativeHandle();
+    if (!handle || handle->numFds == 0) {
+        *outFd = -1;
+        return true;
+    }
+
+    if (handle->numFds > 1) {
+        ALOGE("invalid fence handle with %d fds", handle->numFds);
+        return false;
+    }
+
+    *outFd = dup(handle->data[0]);
+    return (*outFd >= 0);
 }
 
-Error GrallocDevice::getFormat(const native_handle_t* bufferHandle,
-        PixelFormat* outFormat)
+Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
 {
-    int32_t error = mDispatch.getFormat(mDevice, bufferHandle,
-            reinterpret_cast<int32_t*>(outFormat));
-    return static_cast<Error>(error);
+    int32_t err = mDispatch.retain(mDevice, bufferHandle);
+    return static_cast<Error>(err);
 }
 
-Error GrallocDevice::getLayerCount(const native_handle_t* bufferHandle,
-        uint32_t* outLayerCount)
+Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
 {
-    if (hasCapability(Capability::LAYERED_BUFFERS)) {
-        int32_t error = mDispatch.getLayerCount(mDevice, bufferHandle,
-                outLayerCount);
-        return static_cast<Error>(error);
+    int32_t err = mDispatch.release(mDevice, bufferHandle);
+    return static_cast<Error>(err);
+}
+
+Return<void> GrallocMapperHal::getDimensions(const hidl_handle& bufferHandle,
+        getDimensions_cb hidl_cb)
+{
+    uint32_t width = 0;
+    uint32_t height = 0;
+    int32_t err = mDispatch.getDimensions(mDevice, bufferHandle,
+            &width, &height);
+
+    hidl_cb(static_cast<Error>(err), width, height);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getFormat(const hidl_handle& bufferHandle,
+        getFormat_cb hidl_cb)
+{
+    int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    int32_t err = mDispatch.getFormat(mDevice, bufferHandle, &format);
+
+    hidl_cb(static_cast<Error>(err), static_cast<PixelFormat>(format));
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getLayerCount(const hidl_handle& bufferHandle,
+        getLayerCount_cb hidl_cb)
+{
+    int32_t err = GRALLOC1_ERROR_NONE;
+    uint32_t count = 1;
+    if (mCapabilities.layeredBuffers) {
+        err = mDispatch.getLayerCount(mDevice, bufferHandle, &count);
+    }
+
+    hidl_cb(static_cast<Error>(err), count);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getProducerUsageMask(
+        const hidl_handle& bufferHandle, getProducerUsageMask_cb hidl_cb)
+{
+    uint64_t mask = 0x0;
+    int32_t err = mDispatch.getProducerUsage(mDevice, bufferHandle, &mask);
+
+    hidl_cb(static_cast<Error>(err), mask);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getConsumerUsageMask(
+        const hidl_handle& bufferHandle, getConsumerUsageMask_cb hidl_cb)
+{
+    uint64_t mask = 0x0;
+    int32_t err = mDispatch.getConsumerUsage(mDevice, bufferHandle, &mask);
+
+    hidl_cb(static_cast<Error>(err), mask);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getBackingStore(
+        const hidl_handle& bufferHandle, getBackingStore_cb hidl_cb)
+{
+    uint64_t store = 0;
+    int32_t err = mDispatch.getBackingStore(mDevice, bufferHandle, &store);
+
+    hidl_cb(static_cast<Error>(err), store);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::getStride(const hidl_handle& bufferHandle,
+        getStride_cb hidl_cb)
+{
+    uint32_t stride = 0;
+    int32_t err = mDispatch.getStride(mDevice, bufferHandle, &stride);
+
+    hidl_cb(static_cast<Error>(err), stride);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::lock(const hidl_handle& bufferHandle,
+        uint64_t producerUsageMask, uint64_t consumerUsageMask,
+        const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+        lock_cb hidl_cb)
+{
+    gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
+
+    int fence = -1;
+    if (!dupFence(acquireFence, &fence)) {
+        hidl_cb(Error::NO_RESOURCES, nullptr);
+        return Void();
+    }
+
+    void* data = nullptr;
+    int32_t err = mDispatch.lock(mDevice, bufferHandle, producerUsageMask,
+            consumerUsageMask, &rect, &data, fence);
+    if (err != GRALLOC1_ERROR_NONE) {
+        close(fence);
+    }
+
+    hidl_cb(static_cast<Error>(err), data);
+    return Void();
+}
+
+Return<void> GrallocMapperHal::lockFlex(const hidl_handle& bufferHandle,
+        uint64_t producerUsageMask, uint64_t consumerUsageMask,
+        const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
+        lockFlex_cb hidl_cb)
+{
+    FlexLayout layout_reply{};
+
+    uint32_t planeCount = 0;
+    int32_t err = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
+            &planeCount);
+    if (err != GRALLOC1_ERROR_NONE) {
+        hidl_cb(static_cast<Error>(err), layout_reply);
+        return Void();
+    }
+
+    gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
+
+    int fence = -1;
+    if (!dupFence(acquireFence, &fence)) {
+        hidl_cb(Error::NO_RESOURCES, layout_reply);
+        return Void();
+    }
+
+    std::vector<android_flex_plane_t> planes(planeCount);
+    android_flex_layout_t layout{};
+    layout.num_planes = planes.size();
+    layout.planes = planes.data();
+
+    err = mDispatch.lockFlex(mDevice, bufferHandle, producerUsageMask,
+            consumerUsageMask, &rect, &layout, fence);
+    if (err == GRALLOC1_ERROR_NONE) {
+        layout_reply.format = static_cast<FlexFormat>(layout.format);
+
+        planes.resize(layout.num_planes);
+        layout_reply.planes.setToExternal(
+                reinterpret_cast<FlexPlane*>(planes.data()), planes.size());
     } else {
-        *outLayerCount = 1;
-        return Error::NONE;
+        close(fence);
     }
+
+    hidl_cb(static_cast<Error>(err), layout_reply);
+    return Void();
 }
 
-Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
-        uint64_t* outUsageMask)
+Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
+        unlock_cb hidl_cb)
 {
-    int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle,
-            outUsageMask);
-    return static_cast<Error>(error);
+    int32_t fence = -1;
+    int32_t err = mDispatch.unlock(mDevice, bufferHandle, &fence);
+
+    NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+    hidl_handle fenceHandle;
+    if (err == GRALLOC1_ERROR_NONE && fence >= 0) {
+        auto nativeHandle = native_handle_init(fenceStorage, 1, 0);
+        nativeHandle->data[0] = fence;
+
+        fenceHandle = nativeHandle;
+    }
+
+    hidl_cb(static_cast<Error>(err), fenceHandle);
+    return Void();
 }
 
-Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle,
-        uint64_t* outUsageMask)
-{
-    int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle,
-            outUsageMask);
-    return static_cast<Error>(error);
-}
+} // anonymous namespace
 
-Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle,
-        BackingStore* outStore)
-{
-    int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle,
-            outStore);
-    return static_cast<Error>(error);
-}
-
-Error GrallocDevice::getStride(const native_handle_t* bufferHandle,
-        uint32_t* outStride)
-{
-    int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride);
-    return static_cast<Error>(error);
-}
-
-Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle,
-        uint32_t* outNumPlanes)
-{
-    int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
-            outNumPlanes);
-    return static_cast<Error>(error);
-}
-
-Error GrallocDevice::lock(const native_handle_t* bufferHandle,
-        uint64_t producerUsageMask, uint64_t consumerUsageMask,
-        const Rect* accessRegion, int32_t acquireFence,
-        void** outData)
-{
-    int32_t error = mDispatch.lock(mDevice, bufferHandle,
-            producerUsageMask, consumerUsageMask,
-            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
-            outData, acquireFence);
-    return static_cast<Error>(error);
-}
-
-Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle,
-        uint64_t producerUsageMask, uint64_t consumerUsageMask,
-        const Rect* accessRegion, int32_t acquireFence,
-        FlexLayout* outFlexLayout)
-{
-    int32_t error = mDispatch.lockFlex(mDevice, bufferHandle,
-            producerUsageMask, consumerUsageMask,
-            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
-            reinterpret_cast<android_flex_layout_t*>(outFlexLayout),
-            acquireFence);
-    return static_cast<Error>(error);
-}
-
-Error GrallocDevice::unlock(const native_handle_t* bufferHandle,
-        int32_t* outReleaseFence)
-{
-    int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence);
-    return static_cast<Error>(error);
-}
-
-class GrallocMapper : public IMapper {
-public:
-    GrallocMapper() : IMapper{
-        .createDevice = createDevice,
-        .destroyDevice = destroyDevice,
-        .retain = retain,
-        .release = release,
-        .getDimensions = getDimensions,
-        .getFormat = getFormat,
-        .getLayerCount = getLayerCount,
-        .getProducerUsageMask = getProducerUsageMask,
-        .getConsumerUsageMask = getConsumerUsageMask,
-        .getBackingStore = getBackingStore,
-        .getStride = getStride,
-        .getNumFlexPlanes = getNumFlexPlanes,
-        .lock = lock,
-        .lockFlex = lockFlex,
-        .unlock = unlock,
-    } {}
-
-    const IMapper* getInterface() const
-    {
-        return static_cast<const IMapper*>(this);
+IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
+    const hw_module_t* module = nullptr;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    if (err) {
+        ALOGE("failed to get gralloc module");
+        return nullptr;
     }
 
-private:
-    static GrallocDevice* cast(Device* device)
-    {
-        return reinterpret_cast<GrallocDevice*>(device);
+    uint8_t major = (module->module_api_version >> 8) & 0xff;
+    if (major != 1) {
+        ALOGE("unknown gralloc module major version %d", major);
+        return nullptr;
     }
 
-    static Error createDevice(Device** outDevice)
-    {
-        *outDevice = new GrallocDevice;
-        return Error::NONE;
-    }
-
-    static Error destroyDevice(Device* device)
-    {
-        delete cast(device);
-        return Error::NONE;
-    }
-
-    static Error retain(Device* device,
-            const native_handle_t* bufferHandle)
-    {
-        return cast(device)->retain(bufferHandle);
-    }
-
-    static Error release(Device* device,
-            const native_handle_t* bufferHandle)
-    {
-        return cast(device)->release(bufferHandle);
-    }
-
-    static Error getDimensions(Device* device,
-            const native_handle_t* bufferHandle,
-            uint32_t* outWidth, uint32_t* outHeight)
-    {
-        return cast(device)->getDimensions(bufferHandle, outWidth, outHeight);
-    }
-
-    static Error getFormat(Device* device,
-            const native_handle_t* bufferHandle, PixelFormat* outFormat)
-    {
-        return cast(device)->getFormat(bufferHandle, outFormat);
-    }
-
-    static Error getLayerCount(Device* device,
-            const native_handle_t* bufferHandle, uint32_t* outLayerCount)
-    {
-        return cast(device)->getLayerCount(bufferHandle, outLayerCount);
-    }
-
-    static Error getProducerUsageMask(Device* device,
-            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
-    {
-        return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask);
-    }
-
-    static Error getConsumerUsageMask(Device* device,
-            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
-    {
-        return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask);
-    }
-
-    static Error getBackingStore(Device* device,
-            const native_handle_t* bufferHandle, BackingStore* outStore)
-    {
-        return cast(device)->getBackingStore(bufferHandle, outStore);
-    }
-
-    static Error getStride(Device* device,
-            const native_handle_t* bufferHandle, uint32_t* outStride)
-    {
-        return cast(device)->getStride(bufferHandle, outStride);
-    }
-
-    static Error getNumFlexPlanes(Device* device,
-            const native_handle_t* bufferHandle, uint32_t* outNumPlanes)
-    {
-        return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes);
-    }
-
-    static Error lock(Device* device,
-            const native_handle_t* bufferHandle,
-            uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const Device::Rect* accessRegion, int32_t acquireFence,
-            void** outData)
-    {
-        return cast(device)->lock(bufferHandle,
-                producerUsageMask, consumerUsageMask,
-                accessRegion, acquireFence, outData);
-    }
-
-    static Error lockFlex(Device* device,
-            const native_handle_t* bufferHandle,
-            uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const Device::Rect* accessRegion, int32_t acquireFence,
-            FlexLayout* outFlexLayout)
-    {
-        return cast(device)->lockFlex(bufferHandle,
-                producerUsageMask, consumerUsageMask,
-                accessRegion, acquireFence, outFlexLayout);
-    }
-
-    static Error unlock(Device* device,
-            const native_handle_t* bufferHandle, int32_t* outReleaseFence)
-    {
-        return cast(device)->unlock(bufferHandle, outReleaseFence);
-    }
-};
-
-extern "C" const void* HALLIB_FETCH_Interface(const char* name)
-{
-    if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) {
-        static GrallocMapper sGrallocMapper;
-        return sGrallocMapper.getInterface();
-    }
-
-    return nullptr;
+    return new GrallocMapperHal(module);
 }
 
 } // namespace implementation
diff --git a/graphics/mapper/2.0/default/GrallocMapper.h b/graphics/mapper/2.0/default/GrallocMapper.h
new file mode 100644
index 0000000..a2f89d1
--- /dev/null
+++ b/graphics/mapper/2.0/default/GrallocMapper.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
diff --git a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h b/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h
deleted file mode 100644
index 4054b82..0000000
--- a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/types.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 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_GRAPHICS_MAPPER_V2_0_TYPES_H
-#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H
-
-#include <type_traits>
-
-#include <android/hardware/graphics/allocator/2.0/types.h>
-#include <android/hardware/graphics/common/1.0/types.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace mapper {
-namespace V2_0 {
-
-using android::hardware::graphics::allocator::V2_0::Error;
-using android::hardware::graphics::allocator::V2_0::ProducerUsage;
-using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
-using android::hardware::graphics::common::V1_0::PixelFormat;
-
-/*
- * Structures for describing flexible YUVA/RGBA formats for consumption by
- * applications. Such flexible formats contain a plane for each component
- * (e.g.  red, green, blue), where each plane is laid out in a grid-like
- * pattern occupying unique byte addresses and with consistent byte offsets
- * between neighboring pixels.
- *
- * The FlexLayout structure is used with any pixel format that can be
- * represented by it, such as:
- *
- *  - PixelFormat::YCbCr_*_888
- *  - PixelFormat::FLEX_RGB*_888
- *  - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
- *  - PixelFormat::YV12,Y8,Y16,YCbCr_422_SP/I,YCrCb_420_SP
- *  - even implementation defined formats that can be represented by the
- *    structures
- *
- * Vertical increment (aka. row increment or stride) describes the distance in
- * bytes from the first pixel of one row to the first pixel of the next row
- * (below) for the component plane. This can be negative.
- *
- * Horizontal increment (aka. column or pixel increment) describes the
- * distance in bytes from one pixel to the next pixel (to the right) on the
- * same row for the component plane. This can be negative.
- *
- * Each plane can be subsampled either vertically or horizontally by a
- * power-of-two factor.
- *
- * The bit-depth of each component can be arbitrary, as long as the pixels are
- * laid out on whole bytes, in native byte-order, using the most significant
- * bits of each unit.
- */
-
-enum class FlexComponent : int32_t {
-    Y          = 1 << 0,  /* luma */
-    Cb         = 1 << 1,  /* chroma blue */
-    Cr         = 1 << 2,  /* chroma red */
-
-    R          = 1 << 10, /* red */
-    G          = 1 << 11, /* green */
-    B          = 1 << 12, /* blue */
-
-    A          = 1 << 30, /* alpha */
-};
-
-inline FlexComponent operator|(FlexComponent lhs, FlexComponent rhs)
-{
-    return static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
-                                      static_cast<int32_t>(rhs));
-}
-
-inline FlexComponent& operator|=(FlexComponent &lhs, FlexComponent rhs)
-{
-    lhs = static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
-                                     static_cast<int32_t>(rhs));
-    return lhs;
-}
-
-enum class FlexFormat : int32_t {
-    /* not a flexible format */
-    INVALID    = 0x0,
-
-    Y          = static_cast<int32_t>(FlexComponent::Y),
-    YCbCr      = static_cast<int32_t>(FlexComponent::Y) |
-                 static_cast<int32_t>(FlexComponent::Cb) |
-                 static_cast<int32_t>(FlexComponent::Cr),
-    YCbCrA     = static_cast<int32_t>(YCbCr) |
-                 static_cast<int32_t>(FlexComponent::A),
-    RGB        = static_cast<int32_t>(FlexComponent::R) |
-                 static_cast<int32_t>(FlexComponent::G) |
-                 static_cast<int32_t>(FlexComponent::B),
-    RGBA       = static_cast<int32_t>(RGB) |
-                 static_cast<int32_t>(FlexComponent::A),
-};
-
-struct FlexPlane {
-    /* pointer to the first byte of the top-left pixel of the plane. */
-    uint8_t *topLeft;
-
-    FlexComponent component;
-
-    /*
-     * bits allocated for the component in each pixel. Must be a positive
-     * multiple of 8.
-     */
-    int32_t bitsPerComponent;
-
-    /*
-     * number of the most significant bits used in the format for this
-     * component. Must be between 1 and bits_per_component, inclusive.
-     */
-    int32_t bitsUsed;
-
-    /* horizontal increment */
-    int32_t hIncrement;
-    /* vertical increment */
-    int32_t vIncrement;
-
-    /* horizontal subsampling. Must be a positive power of 2. */
-    int32_t hSubsampling;
-    /* vertical subsampling. Must be a positive power of 2. */
-    int32_t vSubsampling;
-};
-static_assert(std::is_pod<FlexPlane>::value, "FlexPlane is not POD");
-
-struct FlexLayout {
-    /* the kind of flexible format */
-    FlexFormat format;
-
-    /* number of planes; 0 for FLEX_FORMAT_INVALID */
-    uint32_t numPlanes;
-
-    /*
-     * a plane for each component; ordered in increasing component value order.
-     * E.g. FLEX_FORMAT_RGBA maps 0 -> R, 1 -> G, etc.
-     * Can be NULL for FLEX_FORMAT_INVALID
-     */
-    FlexPlane* planes;
-};
-static_assert(std::is_pod<FlexLayout>::value, "FlexLayout is not POD");
-
-typedef uint64_t BackingStore;
-
-} // namespace V2_0
-} // namespace mapper
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H */
diff --git a/graphics/mapper/2.0/types.hal b/graphics/mapper/2.0/types.hal
new file mode 100644
index 0000000..aa33141
--- /dev/null
+++ b/graphics/mapper/2.0/types.hal
@@ -0,0 +1,116 @@
+/*
+ * 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.graphics.mapper@2.0;
+
+/*
+ * Structures for describing flexible YUVA/RGBA formats for consumption by
+ * applications. Such flexible formats contain a plane for each component (e.g.
+ * red, green, blue), where each plane is laid out in a grid-like pattern
+ * occupying unique byte addresses and with consistent byte offsets between
+ * neighboring pixels.
+ *
+ * The FlexLayout structure is used with any pixel format that can be
+ * represented by it, such as:
+ *  - PixelFormat::YCBCR_*_888
+ *  - PixelFormat::FLEX_RGB*_888
+ *  - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
+ *  - PixelFormat::YV12,Y8,Y16,YCBCR_422_SP/I,YCRCB_420_SP
+ *  - even implementation defined formats that can be represented by
+ *    the structures
+ *
+ * Vertical increment (aka. row increment or stride) describes the distance in
+ * bytes from the first pixel of one row to the first pixel of the next row
+ * (below) for the component plane. This can be negative.
+ *
+ * Horizontal increment (aka. column or pixel increment) describes the distance
+ * in bytes from one pixel to the next pixel (to the right) on the same row for
+ * the component plane. This can be negative.
+ *
+ * Each plane can be subsampled either vertically or horizontally by
+ * a power-of-two factor.
+ *
+ * The bit-depth of each component can be arbitrary, as long as the pixels are
+ * laid out on whole bytes, in native byte-order, using the most significant
+ * bits of each unit.
+ */
+
+enum FlexComponent : int32_t {
+    Y  = 1 << 0, /* luma */
+    CB = 1 << 1, /* chroma blue */
+    CR = 1 << 2, /* chroma red */
+
+    R  = 1 << 10, /* red */
+    G  = 1 << 11, /* green */
+    B  = 1 << 12, /* blue */
+
+    A  = 1 << 30, /* alpha */
+};
+
+enum FlexFormat : int32_t {
+    /* not a flexible format */
+    INVALID = 0x0,
+
+    Y       = FlexComponent:Y,
+    YCBCR   = Y | FlexComponent:CB | FlexComponent:CR,
+    YCBCRA  = YCBCR | FlexComponent:A,
+
+    RGB     = FlexComponent:R | FlexComponent:G | FlexComponent:B,
+    RGBA    = RGB | FlexComponent:A,
+};
+
+struct FlexPlane {
+    /* Pointer to the first byte of the top-left pixel of the plane. */
+    pointer topLeft;
+
+    FlexComponent component;
+
+    /*
+     * Bits allocated for the component in each pixel. Must be a positive
+     * multiple of 8.
+     */
+    int32_t bitsPerComponent;
+
+    /*
+     * Number of the most significant bits used in the format for this
+     * component. Must be between 1 and bitsPerComponent, inclusive.
+     */
+    int32_t bitsUsed;
+
+    /* Horizontal increment. */
+    int32_t hIncrement;
+    /* Vertical increment. */
+    int32_t vIncrement;
+    /* Horizontal subsampling. Must be a positive power of 2. */
+    int32_t hSubsampling;
+    /* Vertical subsampling. Must be a positive power of 2. */
+    int32_t vSubsampling;
+};
+
+struct FlexLayout {
+    /* The kind of flexible format. */
+    FlexFormat format;
+
+    /*
+     * A plane for each component; ordered in increasing component value
+     * order. E.g. FlexFormat::RGBA maps 0 -> R, 1 -> G, etc.  Can have size 0
+     * for FlexFormat::INVALID.
+     */
+    vec<FlexPlane> planes;
+};
+
+/* Backing store ID of a buffer. See IMapper::getBackingStore. */
+typedef uint64_t BackingStore;
diff --git a/ir/1.0/IConsumerIr.hal b/ir/1.0/IConsumerIr.hal
index f928c0e..f9e6316 100644
--- a/ir/1.0/IConsumerIr.hal
+++ b/ir/1.0/IConsumerIr.hal
@@ -28,7 +28,7 @@
      *
      * returns: true on success, false on error.
      */
-    transmit(int32_t carrierFreq, vec<int32_t> pattern, int32_t patternLen) generates (bool success);
+    transmit(int32_t carrierFreq, vec<int32_t> pattern) generates (bool success);
 
     /*
      * getCarrierFreqs() enumerates which frequencies the IR transmitter supports.
diff --git a/ir/1.0/default/ConsumerIr.cpp b/ir/1.0/default/ConsumerIr.cpp
index 763e09a..8cfb2e8 100644
--- a/ir/1.0/default/ConsumerIr.cpp
+++ b/ir/1.0/default/ConsumerIr.cpp
@@ -32,8 +32,8 @@
 }
 
 // Methods from ::android::hardware::consumerir::V1_0::IConsumerIr follow.
-Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) {
-    return mDevice->transmit(mDevice, carrierFreq, pattern.data(), patternLen) == 0;
+Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) {
+    return mDevice->transmit(mDevice, carrierFreq, pattern.data(), pattern.size()) == 0;
 }
 
 Return<void> ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) {
diff --git a/ir/1.0/default/ConsumerIr.h b/ir/1.0/default/ConsumerIr.h
index 527c577..1532183 100644
--- a/ir/1.0/default/ConsumerIr.h
+++ b/ir/1.0/default/ConsumerIr.h
@@ -40,7 +40,7 @@
 struct ConsumerIr : public IConsumerIr {
     ConsumerIr(consumerir_device_t *device);
     // Methods from ::android::hardware::ir::V1_0::IConsumerIr follow.
-    Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) override;
+    Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) override;
     Return<void> getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override;
 private:
     consumerir_device_t *mDevice;
diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp
new file mode 100644
index 0000000..3c2034b
--- /dev/null
+++ b/keymaster/3.0/Android.bp
@@ -0,0 +1,56 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.keymaster@3.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.keymaster@3.0",
+    srcs: [
+        "types.hal",
+        "IKeymasterDevice.hal",
+    ],
+    out: [
+        "android/hardware/keymaster/3.0/types.cpp",
+        "android/hardware/keymaster/3.0/KeymasterDeviceAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.keymaster@3.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.keymaster@3.0",
+    srcs: [
+        "types.hal",
+        "IKeymasterDevice.hal",
+    ],
+    out: [
+        "android/hardware/keymaster/3.0/types.h",
+        "android/hardware/keymaster/3.0/IKeymasterDevice.h",
+        "android/hardware/keymaster/3.0/IHwKeymasterDevice.h",
+        "android/hardware/keymaster/3.0/BnKeymasterDevice.h",
+        "android/hardware/keymaster/3.0/BpKeymasterDevice.h",
+        "android/hardware/keymaster/3.0/BsKeymasterDevice.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.keymaster@3.0",
+    generated_sources: ["android.hardware.keymaster@3.0_genc++"],
+    generated_headers: ["android.hardware.keymaster@3.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.keymaster@3.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/keymaster/3.0/IKeymasterDevice.hal b/keymaster/3.0/IKeymasterDevice.hal
new file mode 100644
index 0000000..19669c8
--- /dev/null
+++ b/keymaster/3.0/IKeymasterDevice.hal
@@ -0,0 +1,324 @@
+/*
+ * 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.keymaster@3.0;
+
+/**
+ * Keymaster device definition.  For thorough documentation see the implementer's reference, at
+ * https://source.android.com/security/keystore/implementer-ref.html
+ */
+interface IKeymasterDevice {
+
+    /**
+     * Returns information about the underlying keymaster hardware.
+     *
+     * @return isSecure is true if keys are stored and never leave secure hardware (Trusted
+     *             Execution Environment or similar). CDD requires that all devices initially
+     *             launched with Marshmallow or later must have secure hardware.
+     *
+     * @return supportsEllipticCurve is true if the hardware supports Elliptic Curve cryptography
+     *             with the NIST curves (P-224, P-256, P-384, and P-521). CDD requires that all
+     *             devices initially launched with Nougat or later must support Elliptic Curve
+     *             cryptography.
+     *
+     * @return supportsSymmetricCryptography is true if the hardware supports symmetric
+     *             cryptography, including AES and HMAC. CDD requires that all devices initially
+     *             launched with Nougat or later must support hardware enforcement of Keymaster
+     *             authorizations.
+     *
+     * @return supportsAttestation is true if the hardware supports generation of Keymaster public
+     *             key attestation certificates, signed with a key injected in a secure
+     *             environment. CDD requires that all devices initially launched with Android O or
+     *             later must support hardware attestation.
+     */
+    getHardwareFeatures()
+        generates(bool isSecure, bool supportsEllipticCurve,
+                  bool supportsSymmetricCryptography, bool supportsAttestation);
+
+    /**
+     * Adds entropy to the RNG used by keymaster. Entropy added through this method is guaranteed
+     * not to be the only source of entropy used, and the mixing function is required to be secure,
+     * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot
+     * predict (or control), then the RNG output is indistinguishable from random. Thus, if the
+     * entropy from any source is good, the output must be good.
+     *
+     * @param data Bytes to be mixed into the RNG.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     */
+    addRngEntropy(vec<uint8_t> data) generates(ErrorCode error);
+
+    /**
+     * Generates a key, or key pair, returning a key blob and/or a description of the key.
+     *
+     * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+     *             in params. See Tag in types.hal for the full list.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return keyBlob Opaque, encrypted descriptor of the generated key, which generally contains a
+     *             copy of the key material, wrapped in a key unavailable outside secure hardware.
+     *
+     * @return keyCharacteristics Description of the generated key.  See KeyCharacteristis in
+     *             types.hal.
+     */
+    generateKey(vec<KeyParameter> keyParams)
+        generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+    /**
+     * Imports a key, or key pair, returning a key blob and/or a description of the key.
+     *
+     * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+     *             in params.  See Tag for the full list.
+     *
+     * @param keyFormat The format of the key material to import. See KeyFormat in types.hal.
+     *
+     * @pram keyData The key material to import, in the format specifed in keyFormat.
+     *
+     * @return error See the ErrorCode enum.
+     *
+     * @return keyBlob Opaque, encrypted descriptor of the generated key, which will generally
+     *             contain a copy of the key material, wrapped in a key unavailable outside secure
+     *             hardware.
+     *
+     * @return keyCharacteristics Decription of the generated key.  See KeyCharacteristis.
+     *
+     * @return error See the ErrorCode enum.
+     */
+    importKey(vec<KeyParameter> params, KeyFormat keyFormat, vec<uint8_t> keyData)
+        generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+    /**
+     * Returns the characteristics of the specified key, if the keyBlob is valid (implementations
+     * must fully validate the integrity of the key).
+     *
+     * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+     *
+     * @param clientId An opaque byte string identifying the client. This value must match the
+     *             Tag::APPLICATION_ID data provided during key generation/import.  Without the
+     *             correct value it must be cryptographically impossible for the secure hardware to
+     *             obtain the key material.
+     *
+     * @param appData An opaque byte string provided by the application. This value must match the
+     *             Tag::APPLICATION_DATA data provided during key generation/import.  Without the
+     *             correct value it must be cryptographically impossible for the secure hardware to
+     *             obtain the key material.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return keyCharacteristics Decription of the generated key.  See KeyCharacteristis in
+     *             types.hal.
+     */
+    getKeyCharacteristics(vec<uint8_t> keyBlob, vec<uint8_t> clientId, vec<uint8_t> appData)
+        generates(ErrorCode error, KeyCharacteristics keyCharacteristics);
+
+    /**
+     * Exports a public key, returning the key in the specified format.
+     *
+     * @parm keyFormat The format used for export. See KeyFormat in types.hal.
+     *
+     * @param keyBlob The opaque descriptor returned by generateKey() or importKey().  The
+     *             referenced key must be asymmetric.
+     *
+     * @param clientId An opaque byte string identifying the client. This value must match the
+     *             Tag::APPLICATION_ID data provided during key generation/import.  Without the
+     *             correct value it must be cryptographically impossible for the secure hardware to
+     *             obtain the key material.
+     *
+     * @param appData An opaque byte string provided by the application. This value must match the
+     *             Tag::APPLICATION_DATA data provided during key generation/import.  Without the
+     *             correct value it must be cryptographically impossible for the secure hardware to
+     *             obtain the key material.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return keyMaterial The public key material in PKCS#8 format.
+     */
+    exportKey(KeyFormat keyFormat, vec<uint8_t> keyBlob, vec<uint8_t> clientId,
+              vec<uint8_t> appData) generates(ErrorCode error, vec<uint8_t> keyMaterial);
+
+    /**
+     * Generates a signed X.509 certificate chain attesting to the presence of keyToAttest in
+     * keymaster. The certificate will contain an extension with OID 1.3.6.1.4.1.11129.2.1.17 and
+     * value defined in:
+     *
+     *     https://developer.android.com/training/articles/security-key-attestation.html.
+     *
+     * @param keyToAttest The opaque descriptor returned by generateKey() or importKey().  The
+     *             referenced key must be asymmetric.
+     *
+     * @param attestParams Parameters for the attestation, notably Tag::ATTESTATION_CHALLENGE.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     */
+    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
+        generates(ErrorCode error, vec<vec<uint8_t>> certChain);
+
+    /**
+     * Upgrades an old key. Keys can become "old" in two ways: Keymaster can be upgraded to a new
+     * version, or the system can be updated to invalidate the OS version and/or patch level. In
+     * either case, attempts to use an old key with getKeyCharacteristics(), exportKey(),
+     * attestKey() or begin() will result in keymaster returning
+     * ErrorCode::KEY_REQUIRES_UPGRADE. This method must then be called to upgrade the key.
+     *
+     * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+     *
+     * @param upgradeParams A parameter list containing any parameters needed to complete the
+     *             upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
+     *
+     * @return error See the ErrorCode enum.
+     */
+    upgradeKey(vec<uint8_t> keyBlobToUpgrade, vec<KeyParameter> upgradeParams)
+        generates(ErrorCode error, vec<uint8_t> upgradedKeyBlob);
+
+    /**
+     * Deletes the key, or key pair, associated with the key blob. After calling this function it
+     * will be impossible to use the key for any other operations. May be applied to keys from
+     * foreign roots of trust (keys not usable under the current root of trust).
+     *
+     * This is a NOP for keys that don't have rollback protection.
+     *
+     * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+     *
+     * @return error See the ErrorCode enum.
+     */
+    deleteKey(vec<uint8_t> keyBlob) generates(ErrorCode error);
+
+    /**
+     * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
+     * calling this function it will be impossible to use any previously generated or imported key
+     * blobs for any operations.
+     *
+     * This is a NOP if keys don't have rollback protection.
+     *
+     * @return error See the ErrorCode enum.
+     */
+    deleteAllKeys() generates(ErrorCode error);
+
+    /**
+     * Begins a cryptographic operation using the specified key. If all is well, begin() will return
+     * ErrorCode::OK and create an operation handle which must be passed to subsequent calls to
+     * update(), finish() or abort().
+     *
+     * It is critical that each call to begin() be paired with a subsequent call to finish() or
+     * abort(), to allow the keymaster implementation to clean up any internal operation state.
+     * Failure to do this may leak internal state space or other internal resources and may
+     * eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it runs out of space
+     * for operations. Any result other than ErrorCode::OK from begin(), update() or finish()
+     * implicitly aborts the operation, in which case abort() need not be called (and will return
+     * ErrorCode::INVALID_OPERATION_HANDLE if called).
+     *
+     * @param purpose The purpose of the operation, one of KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT,
+     *             KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD modes, encryption and
+     *             decryption imply signing and verification, respectively, but must be specified as
+     *             KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
+     *
+     * @param keyBlob The opaque key descriptor returned by generateKey() or importKey().  The key
+     *             must have a purpose compatible with purpose and all of its usage requirements
+     *             must be satisfied, or begin() will return an appropriate error code.
+     *
+     * @param inParams Additional parameters for the operation. This is typically used to provide
+     *             authentication data, with Tag::AUTH_TOKEN. If Tag::APPLICATION_ID or
+     *             Tag::APPLICATION_DATA were provided during generation, they must be provided
+     *             here, or the operation will fail with ErrorCode::INVALID_KEY_BLOB. For operations
+     *             that require a nonce or IV, on keys that were generated with Tag::CALLER_NONCE,
+     *             inParams may contain a tag Tag::NONCE.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return outParams Output parameters. Used to return additional data from the operation
+     *             initialization, notably to return the IV or nonce from operations that generate
+     *             an IV or nonce.
+     *
+     * @return operationHandle The newly-created operation handle which must be passed to update(),
+     *             finish() or abort().
+     */
+    begin(KeyPurpose purpose, vec<uint8_t> key, vec<KeyParameter> inParams)
+        generates(ErrorCode error, vec<KeyParameter> outParams, OperationHandle operationHandle);
+
+    /**
+     * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
+     * with begin().
+     *
+     * If operationHandle is invalid, update() will return ErrorCode::INVALID_OPERATION_HANDLE.
+     *
+     * update() may not consume all of the data provided in the data buffer. update() will return
+     * the amount consumed in inputConsumed. The caller may provide the unconsumed data in a
+     * subsequent call.
+     *
+     * @param operationHandle The operation handle returned by begin().
+     *
+     * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+     *             specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in
+     *             multiple calls to update(), but only until input data has been provided.
+     *
+     * @param input Data to be processed, per the parameters established in the call to begin().
+     *             Note that update() may or may not consume all of the data provided. See
+     *             inputConsumed.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return inputConsumed Amount of data that was consumed by update(). If this is less than the
+     *             amount provided, the caller may provide the remainder in a subsequent call to
+     *             update() or finish().
+     *
+     * @return outParams Output parameters, used to return additional data from the operation The
+     *             caller takes ownership of the output parameters array and must free it with
+     *             keymaster_free_param_set().
+     *
+     * @return output The output data, if any.
+     */
+    update(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input)
+        generates(ErrorCode error, uint32_t inputConsumed, vec<KeyParameter> outParams,
+                  vec<uint8_t> output);
+
+    /**
+     * Finalizes a cryptographic operation begun with begin() and invalidates operationHandle.
+     *
+     * @param operationHandle The operation handle returned by begin(). This handle will be
+     *             invalid when finish() returns.
+     *
+     * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+     *             specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
+     *
+     * @param input Data to be processed, per the parameters established in the call to
+     *             begin(). finish() must consume all provided data or return
+     *             ErrorCode::INVALID_INPUT_LENGTH.
+     *
+     * @param signature The signature to be verified if the purpose specified in the begin() call
+     *             was KeyPurpose::VERIFY.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     *
+     * @return outParams Any output parameters generated by finish().
+     *
+     * @return output The output data, if any.
+     */
+    finish(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input,
+           vec<uint8_t> signature)
+        generates(ErrorCode error, vec<KeyParameter> outParams, vec<uint8_t> output);
+
+    /**
+     * Aborts a cryptographic operation begun with begin(), freeing all internal resources and
+     * invalidating operationHandle.
+     *
+     * @param operationHandle The operation handle returned by begin(). This handle will be
+     *             invalid when abort() returns.
+     *
+     * @return error See the ErrorCode enum in types.hal.
+     */
+    abort(OperationHandle operationHandle) generates(ErrorCode error);
+};
diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk
new file mode 100644
index 0000000..36d8890
--- /dev/null
+++ b/keymaster/3.0/default/Android.mk
@@ -0,0 +1,43 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.keymaster@3.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    KeymasterDevice.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libsoftkeymasterdevice \
+    libcrypto \
+    libkeymaster1 \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    libutils \
+    libhardware \
+    android.hardware.keymaster@3.0
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.keymaster@3.0-service
+LOCAL_INIT_RC := android.hardware.keymaster@3.0-service.rc
+LOCAL_SRC_FILES := \
+    service.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libhardware_legacy \
+    libhardware \
+    libhwbinder \
+    libhidlbase \
+    libhidltransport \
+    android.hardware.keymaster@3.0
+
+include $(BUILD_EXECUTABLE)
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
new file mode 100644
index 0000000..1208b8d
--- /dev/null
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -0,0 +1,691 @@
+/*
+ **
+ ** Copyright 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.keymaster@3.0-impl"
+
+#include "KeymasterDevice.h"
+
+#include <cutils/log.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymaster/soft_keymaster_device.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V3_0 {
+namespace implementation {
+
+using ::keymaster::SoftKeymasterDevice;
+
+class SoftwareOnlyHidlKeymasterEnforcement : public ::keymaster::KeymasterEnforcement {
+  public:
+    SoftwareOnlyHidlKeymasterEnforcement() : KeymasterEnforcement(64, 64) {}
+
+    uint32_t get_current_time() const override {
+        struct timespec tp;
+        int err = clock_gettime(CLOCK_MONOTONIC, &tp);
+        if (err || tp.tv_sec < 0) return 0;
+        return static_cast<uint32_t>(tp.tv_sec);
+    }
+
+    bool activation_date_valid(uint64_t) const override { return true; }
+    bool expiration_date_passed(uint64_t) const override { return false; }
+    bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const override { return false; }
+    bool ValidateTokenSignature(const hw_auth_token_t&) const override { return true; }
+};
+
+class SoftwareOnlyHidlKeymasterContext : public ::keymaster::SoftKeymasterContext {
+  public:
+    SoftwareOnlyHidlKeymasterContext() : enforcement_(new SoftwareOnlyHidlKeymasterEnforcement) {}
+
+    ::keymaster::KeymasterEnforcement* enforcement_policy() override { return enforcement_.get(); }
+
+  private:
+    std::unique_ptr<::keymaster::KeymasterEnforcement> enforcement_;
+};
+
+static int keymaster0_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+    assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0);
+    ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version);
+
+    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+    keymaster0_device_t* km0_device = NULL;
+    keymaster_error_t error = KM_ERROR_OK;
+
+    int rc = keymaster0_open(mod, &km0_device);
+    if (rc) {
+        ALOGE("Error opening keystore keymaster0 device.");
+        goto err;
+    }
+
+    if (km0_device->flags & KEYMASTER_SOFTWARE_ONLY) {
+        ALOGI("Keymaster0 module is software-only.  Using SoftKeymasterDevice instead.");
+        km0_device->common.close(&km0_device->common);
+        km0_device = NULL;
+        // SoftKeymasterDevice will be deleted by keymaster_device_release()
+        *dev = soft_keymaster.release()->keymaster2_device();
+        return 0;
+    }
+
+    ALOGD("Wrapping keymaster0 module %s with SoftKeymasterDevice", mod->name);
+    error = soft_keymaster->SetHardwareDevice(km0_device);
+    km0_device = NULL;  // SoftKeymasterDevice has taken ownership.
+    if (error != KM_ERROR_OK) {
+        ALOGE("Got error %d from SetHardwareDevice", error);
+        rc = error;
+        goto err;
+    }
+
+    // SoftKeymasterDevice will be deleted by  keymaster_device_release()
+    *dev = soft_keymaster.release()->keymaster2_device();
+    return 0;
+
+err:
+    if (km0_device) km0_device->common.close(&km0_device->common);
+    *dev = NULL;
+    return rc;
+}
+
+static int keymaster1_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+    assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0);
+    ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version);
+
+    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
+    keymaster1_device_t* km1_device = nullptr;
+    keymaster_error_t error = KM_ERROR_OK;
+
+    int rc = keymaster1_open(mod, &km1_device);
+    if (rc) {
+        ALOGE("Error %d opening keystore keymaster1 device", rc);
+        goto err;
+    }
+
+    ALOGD("Wrapping keymaster1 module %s with SofKeymasterDevice", mod->name);
+    error = soft_keymaster->SetHardwareDevice(km1_device);
+    km1_device = nullptr;  // SoftKeymasterDevice has taken ownership.
+    if (error != KM_ERROR_OK) {
+        ALOGE("Got error %d from SetHardwareDevice", error);
+        rc = error;
+        goto err;
+    }
+
+    // SoftKeymasterDevice will be deleted by keymaster_device_release()
+    *dev = soft_keymaster.release()->keymaster2_device();
+    return 0;
+
+err:
+    if (km1_device) km1_device->common.close(&km1_device->common);
+    *dev = NULL;
+    return rc;
+}
+
+static int keymaster2_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
+    assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_2_0);
+    ALOGI("Found keymaster2 module %s, version %x", mod->name, mod->module_api_version);
+
+    keymaster2_device_t* km2_device = nullptr;
+
+    int rc = keymaster2_open(mod, &km2_device);
+    if (rc) {
+        ALOGE("Error %d opening keystore keymaster2 device", rc);
+        goto err;
+    }
+
+    *dev = km2_device;
+    return 0;
+
+err:
+    if (km2_device) km2_device->common.close(&km2_device->common);
+    *dev = nullptr;
+    return rc;
+}
+
+static int keymaster_device_initialize(keymaster2_device_t** dev, uint32_t* version,
+                                       bool* supports_ec) {
+    const hw_module_t* mod;
+
+    *supports_ec = true;
+
+    int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
+    if (rc) {
+        ALOGI("Could not find any keystore module, using software-only implementation.");
+        // SoftKeymasterDevice will be deleted by keymaster_device_release()
+        *dev = (new SoftKeymasterDevice(new SoftwareOnlyHidlKeymasterContext))->keymaster2_device();
+        *version = -1;
+        return 0;
+    }
+
+    if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) {
+        *version = 0;
+        int rc = keymaster0_device_initialize(mod, dev);
+        if (rc == 0 && ((*dev)->flags & KEYMASTER_SUPPORTS_EC) == 0) {
+            *supports_ec = false;
+        }
+        return rc;
+    } else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
+        *version = 1;
+        return keymaster1_device_initialize(mod, dev);
+    } else {
+        *version = 2;
+        return keymaster2_device_initialize(mod, dev);
+    }
+}
+
+KeymasterDevice::~KeymasterDevice() {
+    if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common);
+}
+
+static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
+    return keymaster_tag_get_type(tag);
+}
+
+/**
+ * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a
+ * cast to make the compiler happy. One of two thigs should happen though:
+ * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a
+ *      single point of truth. Then this cast function can go away.
+ */
+inline static keymaster_tag_t legacy_enum_conversion(const Tag value) {
+    return keymaster_tag_t(value);
+}
+inline static Tag legacy_enum_conversion(const keymaster_tag_t value) {
+    return Tag(value);
+}
+inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
+    return keymaster_purpose_t(value);
+}
+inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
+    return keymaster_key_format_t(value);
+}
+inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
+    return ErrorCode(value);
+}
+
+class KmParamSet : public keymaster_key_param_set_t {
+  public:
+    KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
+        params = new keymaster_key_param_t[keyParams.size()];
+        length = keyParams.size();
+        for (size_t i = 0; i < keyParams.size(); ++i) {
+            auto tag = legacy_enum_conversion(keyParams[i].tag);
+            switch (typeFromTag(tag)) {
+            case KM_ENUM:
+            case KM_ENUM_REP:
+                params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
+                break;
+            case KM_UINT:
+            case KM_UINT_REP:
+                params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
+                break;
+            case KM_ULONG:
+            case KM_ULONG_REP:
+                params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
+                break;
+            case KM_DATE:
+                params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
+                break;
+            case KM_BOOL:
+                if (keyParams[i].f.boolValue)
+                    params[i] = keymaster_param_bool(tag);
+                else
+                    params[i].tag = KM_TAG_INVALID;
+                break;
+            case KM_BIGNUM:
+            case KM_BYTES:
+                params[i] =
+                    keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
+                break;
+            case KM_INVALID:
+            default:
+                params[i].tag = KM_TAG_INVALID;
+                /* just skip */
+                break;
+            }
+        }
+    }
+    KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} {
+        other.length = 0;
+        other.params = nullptr;
+    }
+    KmParamSet(const KmParamSet&) = delete;
+    ~KmParamSet() { delete[] params; }
+};
+
+inline static KmParamSet hidlParams2KmParamSet(const hidl_vec<KeyParameter>& params) {
+    return KmParamSet(params);
+}
+
+inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec<uint8_t>& blob) {
+    /* hidl unmarshals funny pointers if the the blob is empty */
+    if (blob.size()) return {&blob[0], blob.size()};
+    return {nullptr, 0};
+}
+
+inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& blob) {
+    /* hidl unmarshals funny pointers if the the blob is empty */
+    if (blob.size()) return {&blob[0], blob.size()};
+    return {nullptr, 0};
+}
+
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
+    return result;
+}
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
+    return result;
+}
+
+inline static hidl_vec<hidl_vec<uint8_t>>
+kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) {
+    hidl_vec<hidl_vec<uint8_t>> result;
+    if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result;
+
+    result.resize(cert_chain->entry_count);
+    for (size_t i = 0; i < cert_chain->entry_count; ++i) {
+        auto& entry = cert_chain->entries[i];
+        result[i] = kmBlob2hidlVec(entry);
+    }
+
+    return result;
+}
+
+static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
+    hidl_vec<KeyParameter> result;
+    if (set.length == 0 || set.params == nullptr) return result;
+
+    result.resize(set.length);
+    keymaster_key_param_t* params = set.params;
+    for (size_t i = 0; i < set.length; ++i) {
+        auto tag = params[i].tag;
+        result[i].tag = legacy_enum_conversion(tag);
+        switch (typeFromTag(tag)) {
+        case KM_ENUM:
+        case KM_ENUM_REP:
+            result[i].f.integer = params[i].enumerated;
+            break;
+        case KM_UINT:
+        case KM_UINT_REP:
+            result[i].f.integer = params[i].integer;
+            break;
+        case KM_ULONG:
+        case KM_ULONG_REP:
+            result[i].f.longInteger = params[i].long_integer;
+            break;
+        case KM_DATE:
+            result[i].f.dateTime = params[i].date_time;
+            break;
+        case KM_BOOL:
+            result[i].f.boolValue = params[i].boolean;
+            break;
+        case KM_BIGNUM:
+        case KM_BYTES:
+            result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
+                                         params[i].blob.data_length);
+            break;
+        case KM_INVALID:
+        default:
+            params[i].tag = KM_TAG_INVALID;
+            /* just skip */
+            break;
+        }
+    }
+    return result;
+}
+
+// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+Return<void> KeymasterDevice::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
+    bool is_secure = false;
+    bool supports_symmetric_cryptography = false;
+    bool supports_attestation = false;
+
+    switch (hardware_version_) {
+    case 2:
+        supports_attestation = true;
+    /* Falls through */
+    case 1:
+        supports_symmetric_cryptography = true;
+    /* Falls through */
+    case 0:
+        is_secure = true;
+        break;
+    };
+
+    _hidl_cb(is_secure, hardware_supports_ec_, supports_symmetric_cryptography,
+             supports_attestation);
+    return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::addRngEntropy(const hidl_vec<uint8_t>& data) {
+    return legacy_enum_conversion(
+        keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
+}
+
+Return<void> KeymasterDevice::generateKey(const hidl_vec<KeyParameter>& keyParams,
+                                          generateKey_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob{nullptr, 0};
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    // convert the parameter set to something our backend understands
+    auto kmParams = hidlParams2KmParamSet(keyParams);
+
+    auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob,
+                                              &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    // send results off to the client
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+    // free buffers that we are responsible for
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                                    const hidl_vec<uint8_t>& clientId,
+                                                    const hidl_vec<uint8_t>& appData,
+                                                    getKeyCharacteristics_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+
+    // result variables the backend understands
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    auto kmClientId = hidlVec2KmBlob(clientId);
+    auto kmAppData = hidlVec2KmBlob(appData);
+
+    auto rc = keymaster_device_->get_key_characteristics(
+        keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr,
+        clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr,
+        &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics);
+
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                                        const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob{nullptr, 0};
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    auto kmParams = hidlParams2KmParamSet(params);
+    auto kmKeyData = hidlVec2KmBlob(keyData);
+
+    auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams,
+                                            legacy_enum_conversion(keyFormat), &kmKeyData,
+                                            &key_blob, &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+    // free buffers that we are responsible for
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                                        const hidl_vec<uint8_t>& clientId,
+                                        const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
+
+    // result variables for the wire
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_blob_t out_blob{nullptr, 0};
+
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    auto kmClientId = hidlVec2KmBlob(clientId);
+    auto kmAppData = hidlVec2KmBlob(appData);
+
+    auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat),
+                                            keyBlob.size() ? &kmKeyBlob : nullptr,
+                                            clientId.size() ? &kmClientId : nullptr,
+                                            appData.size() ? &kmAppData : nullptr, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
+        resultKeyBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+    // free buffers that we are responsible for
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                                        const hidl_vec<KeyParameter>& attestParams,
+                                        attestKey_cb _hidl_cb) {
+
+    hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+
+    keymaster_cert_chain_t cert_chain{nullptr, 0};
+
+    auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
+    auto kmAttestParams = hidlParams2KmParamSet(attestParams);
+
+    auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams,
+                                            &cert_chain);
+
+    if (rc == KM_ERROR_OK) {
+        resultCertChain = kmCertChain2Hidl(&cert_chain);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultCertChain);
+
+    keymaster_free_cert_chain(&cert_chain);
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                                         const hidl_vec<KeyParameter>& upgradeParams,
+                                         upgradeKey_cb _hidl_cb) {
+
+    // result variables for the wire
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob{nullptr, 0};
+
+    auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade);
+    auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams);
+
+    auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade,
+                                             &kmUpgradeParams, &key_blob);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+
+    return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob));
+}
+
+Return<ErrorCode> KeymasterDevice::deleteAllKeys() {
+    return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
+}
+
+Return<void> KeymasterDevice::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                                    const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) {
+
+    // result variables for the wire
+    hidl_vec<KeyParameter> resultParams;
+    uint64_t resultOpHandle = 0;
+
+    // result variables the backend understands
+    keymaster_key_param_set_t out_params{nullptr, 0};
+    keymaster_operation_handle_t& operation_handle = resultOpHandle;
+
+    auto kmKey = hidlVec2KmKeyBlob(key);
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+
+    auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey,
+                                       &kmInParams, &out_params, &operation_handle);
+
+    if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params);
+
+    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle);
+
+    keymaster_free_param_set(&out_params);
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::update(uint64_t operationHandle,
+                                     const hidl_vec<KeyParameter>& inParams,
+                                     const hidl_vec<uint8_t>& input, update_cb _hidl_cb) {
+    // result variables for the wire
+    uint32_t resultConsumed = 0;
+    hidl_vec<KeyParameter> resultParams;
+    hidl_vec<uint8_t> resultBlob;
+
+    // result variables the backend understands
+    size_t consumed = 0;
+    keymaster_key_param_set_t out_params{nullptr, 0};
+    keymaster_blob_t out_blob{nullptr, 0};
+
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+    auto kmInput = hidlVec2KmBlob(input);
+
+    auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+                                        &consumed, &out_params, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        resultConsumed = consumed;
+        resultParams = kmParamSet2Hidl(out_params);
+        resultBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob);
+
+    keymaster_free_param_set(&out_params);
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<void> KeymasterDevice::finish(uint64_t operationHandle,
+                                     const hidl_vec<KeyParameter>& inParams,
+                                     const hidl_vec<uint8_t>& input,
+                                     const hidl_vec<uint8_t>& signature, finish_cb _hidl_cb) {
+    // result variables for the wire
+    hidl_vec<KeyParameter> resultParams;
+    hidl_vec<uint8_t> resultBlob;
+
+    // result variables the backend understands
+    keymaster_key_param_set_t out_params{nullptr, 0};
+    keymaster_blob_t out_blob{nullptr, 0};
+
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+    auto kmInput = hidlVec2KmBlob(input);
+    auto kmSignature = hidlVec2KmBlob(signature);
+
+    auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+                                        &kmSignature, &out_params, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        resultParams = kmParamSet2Hidl(out_params);
+        resultBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob);
+
+    keymaster_free_param_set(&out_params);
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<ErrorCode> KeymasterDevice::abort(uint64_t operationHandle) {
+    return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle));
+}
+
+IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) {
+    keymaster2_device_t* dev = nullptr;
+
+    uint32_t version;
+    bool supports_ec;
+    auto rc = keymaster_device_initialize(&dev, &version, &supports_ec);
+    if (rc) return nullptr;
+
+    auto kmrc = ::keymaster::ConfigureDevice(dev);
+    if (kmrc != KM_ERROR_OK) {
+        dev->common.close(&dev->common);
+        return nullptr;
+    }
+
+    return new KeymasterDevice(dev, version, supports_ec);
+}
+
+}  // namespace implementation
+}  // namespace V3_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
diff --git a/keymaster/3.0/default/KeymasterDevice.h b/keymaster/3.0/default/KeymasterDevice.h
new file mode 100644
index 0000000..23767ef
--- /dev/null
+++ b/keymaster/3.0/default/KeymasterDevice.h
@@ -0,0 +1,97 @@
+/*
+ **
+ ** Copyright 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 HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
+#define HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
+
+#include <hardware/keymaster2.h>
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hidl/Status.h>
+
+#include <hidl/MQDescriptor.h>
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V3_0 {
+namespace implementation {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
+using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
+using ::android::hardware::keymaster::V3_0::KeyFormat;
+using ::android::hardware::keymaster::V3_0::KeyParameter;
+using ::android::hardware::keymaster::V3_0::KeyPurpose;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class KeymasterDevice : public IKeymasterDevice {
+  public:
+    KeymasterDevice(keymaster2_device_t* dev, uint32_t hardware_version, bool hardware_supports_ec)
+        : keymaster_device_(dev), hardware_version_(hardware_version),
+          hardware_supports_ec_(hardware_supports_ec) {}
+    virtual ~KeymasterDevice();
+
+    // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+    Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
+    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
+    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+                             generateKey_cb _hidl_cb) override;
+    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                       const hidl_vec<uint8_t>& clientId,
+                                       const hidl_vec<uint8_t>& appData,
+                                       getKeyCharacteristics_cb _hidl_cb) override;
+    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
+    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+                           exportKey_cb _hidl_cb) override;
+    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                           const hidl_vec<KeyParameter>& attestParams,
+                           attestKey_cb _hidl_cb) override;
+    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                            const hidl_vec<KeyParameter>& upgradeParams,
+                            upgradeKey_cb _hidl_cb) override;
+    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
+    Return<ErrorCode> deleteAllKeys() override;
+    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                       const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
+    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override;
+    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+                        finish_cb _hidl_cb) override;
+    Return<ErrorCode> abort(uint64_t operationHandle) override;
+
+  private:
+    keymaster2_device_t* keymaster_device_;
+    uint32_t hardware_version_;
+    bool hardware_supports_ec_;
+};
+
+extern "C" IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* name);
+
+}  // namespace implementation
+}  // namespace V3_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_
diff --git a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
new file mode 100644
index 0000000..86ed1e7
--- /dev/null
+++ b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
@@ -0,0 +1,4 @@
+service keymaster-3-0 /system/bin/hw/android.hardware.keymaster@3.0-service
+    class hal
+    user system
+    group system drmrpc
diff --git a/keymaster/3.0/default/service.cpp b/keymaster/3.0/default/service.cpp
new file mode 100644
index 0000000..dd8c0b2
--- /dev/null
+++ b/keymaster/3.0/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+**
+** Copyright 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.keymaster@3.0-service"
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+using android::hardware::keymaster::V3_0::IKeymasterDevice;
+using android::hardware::registerPassthroughServiceImplementation;
+
+int main() {
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
+    registerPassthroughServiceImplementation<IKeymasterDevice>("keymaster");
+    joinRpcThreadpool();
+}
diff --git a/keymaster/3.0/types.hal b/keymaster/3.0/types.hal
new file mode 100644
index 0000000..e99e9c8
--- /dev/null
+++ b/keymaster/3.0/types.hal
@@ -0,0 +1,414 @@
+/*
+ * 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.keymaster@3.0;
+
+enum TagType : uint32_t {
+    INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
+    ENUM = 1 << 28,
+    ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
+    UINT = 3 << 28,
+    UINT_REP = 4 << 28, /* Repeatable integer value */
+    ULONG = 5 << 28,
+    DATE = 6 << 28,
+    BOOL = 7 << 28,
+    BIGNUM = 8 << 28,
+    BYTES = 9 << 28,
+    ULONG_REP = 10 << 28, /* Repeatable long value */
+};
+
+enum Tag : uint32_t {
+    INVALID = TagType:INVALID | 0,
+
+    /*
+     * Tags that must be semantically enforced by hardware and software implementations.
+     */
+
+    /* Crypto parameters */
+    PURPOSE = TagType:ENUM_REP | 1,    /* KeyPurpose. */
+    ALGORITHM = TagType:ENUM | 2,      /* Algorithm. */
+    KEY_SIZE = TagType:UINT | 3,       /* Key size in bits. */
+    BLOCK_MODE = TagType:ENUM_REP | 4, /* BlockMode. */
+    DIGEST = TagType:ENUM_REP | 5,     /* Digest. */
+    PADDING = TagType:ENUM_REP | 6,    /* PaddingMode. */
+    CALLER_NONCE = TagType:BOOL | 7,   /* Allow caller to specify nonce or IV. */
+    MIN_MAC_LENGTH = TagType:UINT | 8, /* Minimum length of MAC or AEAD authentication tag in
+                                        * bits. */
+    KDF = TagType:ENUM_REP | 9,        /* KeyDerivationFunction. */
+    EC_CURVE = TagType:ENUM | 10,      /* EcCurve. */
+
+    /* Algorithm-specific. */
+    RSA_PUBLIC_EXPONENT = TagType:ULONG | 200,
+    ECIES_SINGLE_HASH_MODE = TagType:BOOL | 201, /* Whether the ephemeral public key is fed into the
+                                                  * KDF. */
+    INCLUDE_UNIQUE_ID = TagType:BOOL | 202,      /* If true, attestation certificates for this key
+                                                  * will contain an application-scoped and
+                                                  * time-bounded device-unique ID.*/
+
+    /* Other hardware-enforced. */
+    BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301, /* KeyBlobUsageRequirements. */
+    BOOTLOADER_ONLY = TagType:BOOL | 302,         /* Usable only by bootloader. */
+
+    /*
+     * Tags that should be semantically enforced by hardware if possible and will otherwise be
+     * enforced by software (keystore).
+     */
+
+    /* Key validity period */
+    ACTIVE_DATETIME = TagType:DATE | 400,             /* Start of validity. */
+    ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401, /* Date when new "messages" should no longer
+                                                       * be created. */
+    USAGE_EXPIRE_DATETIME = TagType:DATE | 402,       /* Date when existing "messages" should no
+                                                       * longer be trusted. */
+    MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403,     /* Minimum elapsed time between
+                                                       * cryptographic operations with the key. */
+    MAX_USES_PER_BOOT = TagType:UINT | 404,           /* Number of times the key can be used per
+                                                       * boot. */
+
+    /* User authentication */
+    ALL_USERS = TagType:BOOL | 500,           /* Reserved for future use -- ignore. */
+    USER_ID = TagType:UINT | 501,             /* Reserved for future use -- ignore. */
+    USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
+                                               * Disallowed if ALL_USERS or NO_AUTH_REQUIRED is
+                                               * present. */
+    NO_AUTH_REQUIRED = TagType:BOOL | 503,    /* If key is usable without authentication. */
+    USER_AUTH_TYPE = TagType:ENUM | 504,      /* Bitmask of authenticator types allowed when
+                                               * USER_SECURE_ID contains a secure user ID, rather
+                                               * than a secure authenticator ID.  Defined in
+                                               * HardwareAuthenticatorType. */
+    AUTH_TIMEOUT = TagType:UINT | 505,        /* Required freshness of user authentication for
+                                               * private/secret key operations, in seconds.  Public
+                                               * key operations require no authentication.  If
+                                               * absent, authentication is required for every use.
+                                               * Authentication state is lost when the device is
+                                               * powered off. */
+    ALLOW_WHILE_ON_BODY = TagType:BOOL | 506, /* Allow key to be used after authentication timeout
+                                               * if device is still on-body (requires secure on-body
+                                               * sensor. */
+
+    /* Application access control */
+    ALL_APPLICATIONS = TagType:BOOL | 600, /* Specified to indicate key is usable by all
+                                            * applications. */
+    APPLICATION_ID = TagType:BYTES | 601,  /* Byte string identifying the authorized application. */
+    EXPORTABLE = TagType:BOOL | 602,       /* If true, private/secret key can be exported, but only
+                                            * if all access control requirements for use are
+                                            * met. (keymaster2) */
+
+    /*
+     * Semantically unenforceable tags, either because they have no specific meaning or because
+     * they're informational only.
+     */
+    APPLICATION_DATA = TagType:BYTES | 700,      /* Data provided by authorized application. */
+    CREATION_DATETIME = TagType:DATE | 701,      /* Key creation time */
+    ORIGIN = TagType:ENUM | 702,                 /* keymaster_key_origin_t. */
+    ROLLBACK_RESISTANT = TagType:BOOL | 703,     /* Whether key is rollback-resistant. */
+    ROOT_OF_TRUST = TagType:BYTES | 704,         /* Root of trust ID. */
+    OS_VERSION = TagType:UINT | 705,             /* Version of system (keymaster2) */
+    OS_PATCHLEVEL = TagType:UINT | 706,          /* Patch level of system (keymaster2) */
+    UNIQUE_ID = TagType:BYTES | 707,             /* Used to provide unique ID in attestation */
+    ATTESTATION_CHALLENGE = TagType:BYTES | 708, /* Used to provide challenge in attestation */
+    ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
+                                                       * applications of which one has initiated a
+                                                       * key attestation */
+
+    /* Tags used only to provide data to or receive data from operations */
+    ASSOCIATED_DATA = TagType:BYTES | 1000, /* Used to provide associated data for AEAD modes. */
+    NONCE = TagType:BYTES | 1001,           /* Nonce or Initialization Vector */
+    AUTH_TOKEN = TagType:BYTES | 1002,      /* Authentication token that proves secure user
+                                             * authentication has been performed.  Structure defined
+                                             * in hw_auth_token_t in hw_auth_token.h. */
+    MAC_LENGTH = TagType:UINT | 1003,       /* MAC or AEAD authentication tag length in bits. */
+
+    RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004, /* Whether the device has beeen factory reset
+                                                    * since the last unique ID rotation.  Used for
+                                                    * key attestation. */
+};
+
+enum Algorithm : uint32_t {
+    /* Asymmetric algorithms. */
+    RSA = 1,
+    // DSA = 2, -- Removed, do not re-use value 2.
+    EC = 3,
+
+    /* Block ciphers algorithms */
+    AES = 32,
+
+    /* MAC algorithms */
+    HMAC = 128,
+};
+
+/**
+ * Symmetric block cipher modes provided by keymaster implementations.
+ */
+enum BlockMode : uint32_t {
+    /* Unauthenticated modes, usable only for encryption/decryption and not generally recommended
+     * except for compatibility with existing other protocols. */
+    ECB = 1,
+    CBC = 2,
+    CTR = 3,
+
+    /* Authenticated modes, usable for encryption/decryption and signing/verification.  Recommended
+     * over unauthenticated modes for all purposes. */
+    GCM = 32,
+};
+
+/**
+ * Padding modes that may be applied to plaintext for encryption operations.  This list includes
+ * padding modes for both symmetric and asymmetric algorithms.  Note that implementations should not
+ * provide all possible combinations of algorithm and padding, only the
+ * cryptographically-appropriate pairs.
+ */
+enum PaddingMode : uint32_t {
+    NONE = 1, /* deprecated */
+    RSA_OAEP = 2,
+    RSA_PSS = 3,
+    RSA_PKCS1_1_5_ENCRYPT = 4,
+    RSA_PKCS1_1_5_SIGN = 5,
+    PKCS7 = 64,
+};
+
+/**
+ * Digests provided by keymaster implementations.
+ */
+enum Digest : uint32_t {
+    NONE = 0,
+    MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software if
+              * needed. */
+    SHA1 = 2,
+    SHA_2_224 = 3,
+    SHA_2_256 = 4,
+    SHA_2_384 = 5,
+    SHA_2_512 = 6,
+};
+
+/**
+ * Supported EC curves, used in ECDSA
+ */
+enum EcCurve : uint32_t {
+    P_224 = 0,
+    P_256 = 1,
+    P_384 = 2,
+    P_521 = 3,
+};
+
+/**
+ * The origin of a key (or pair), i.e. where it was generated.  Note that ORIGIN can be found in
+ * either the hardware-enforced or software-enforced list for a key, indicating whether the key is
+ * hardware or software-based.  Specifically, a key with GENERATED in the hardware-enforced list is
+ * guaranteed never to have existed outide the secure hardware.
+ */
+enum KeyOrigin : uint32_t {
+    GENERATED = 0, /* Generated in keymaster.  Should not exist outside the TEE. */
+    DERIVED = 1,   /* Derived inside keymaster.  Likely exists off-device. */
+    IMPORTED = 2,  /* Imported into keymaster.  Existed as cleartext in Android. */
+    UNKNOWN = 3,   /* Keymaster did not record origin.  This value can only be seen on keys in a
+                    * keymaster0 implementation.  The keymaster0 adapter uses this value to document
+                    * the fact that it is unkown whether the key was generated inside or imported
+                    * into keymaster. */
+};
+
+/**
+ * Usability requirements of key blobs.  This defines what system functionality must be available
+ * for the key to function.  For example, key "blobs" which are actually handles referencing
+ * encrypted key material stored in the file system cannot be used until the file system is
+ * available, and should have BLOB_REQUIRES_FILE_SYSTEM.  Other requirements entries will be added
+ * as needed for implementations.
+ */
+enum KeyBlobUsageRequirements : uint32_t {
+    STANDALONE = 0,
+    REQUIRES_FILE_SYSTEM = 1,
+};
+
+/**
+ * Possible purposes of a key (or pair).
+ */
+enum KeyPurpose : uint32_t {
+    ENCRYPT = 0,    /* Usable with RSA, EC and AES keys. */
+    DECRYPT = 1,    /* Usable with RSA, EC and AES keys. */
+    SIGN = 2,       /* Usable with RSA, EC and HMAC keys. */
+    VERIFY = 3,     /* Usable with RSA, EC and HMAC keys. */
+    DERIVE_KEY = 4, /* Usable with EC keys. */
+};
+
+/**
+ * Keymaster error codes.
+ */
+enum ErrorCode : uint32_t {
+    OK = 0,
+    ROOT_OF_TRUST_ALREADY_SET = -1,
+    UNSUPPORTED_PURPOSE = -2,
+    INCOMPATIBLE_PURPOSE = -3,
+    UNSUPPORTED_ALGORITHM = -4,
+    INCOMPATIBLE_ALGORITHM = -5,
+    UNSUPPORTED_KEY_SIZE = -6,
+    UNSUPPORTED_BLOCK_MODE = -7,
+    INCOMPATIBLE_BLOCK_MODE = -8,
+    UNSUPPORTED_MAC_LENGTH = -9,
+    UNSUPPORTED_PADDING_MODE = -10,
+    INCOMPATIBLE_PADDING_MODE = -11,
+    UNSUPPORTED_DIGEST = -12,
+    INCOMPATIBLE_DIGEST = -13,
+    INVALID_EXPIRATION_TIME = -14,
+    INVALID_USER_ID = -15,
+    INVALID_AUTHORIZATION_TIMEOUT = -16,
+    UNSUPPORTED_KEY_FORMAT = -17,
+    INCOMPATIBLE_KEY_FORMAT = -18,
+    UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19,   /* For PKCS8 & PKCS12 */
+    UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /* For PKCS8 & PKCS12 */
+    INVALID_INPUT_LENGTH = -21,
+    KEY_EXPORT_OPTIONS_INVALID = -22,
+    DELEGATION_NOT_ALLOWED = -23,
+    KEY_NOT_YET_VALID = -24,
+    KEY_EXPIRED = -25,
+    KEY_USER_NOT_AUTHENTICATED = -26,
+    OUTPUT_PARAMETER_NULL = -27,
+    INVALID_OPERATION_HANDLE = -28,
+    INSUFFICIENT_BUFFER_SPACE = -29,
+    VERIFICATION_FAILED = -30,
+    TOO_MANY_OPERATIONS = -31,
+    UNEXPECTED_NULL_POINTER = -32,
+    INVALID_KEY_BLOB = -33,
+    IMPORTED_KEY_NOT_ENCRYPTED = -34,
+    IMPORTED_KEY_DECRYPTION_FAILED = -35,
+    IMPORTED_KEY_NOT_SIGNED = -36,
+    IMPORTED_KEY_VERIFICATION_FAILED = -37,
+    INVALID_ARGUMENT = -38,
+    UNSUPPORTED_TAG = -39,
+    INVALID_TAG = -40,
+    MEMORY_ALLOCATION_FAILED = -41,
+    IMPORT_PARAMETER_MISMATCH = -44,
+    SECURE_HW_ACCESS_DENIED = -45,
+    OPERATION_CANCELLED = -46,
+    CONCURRENT_ACCESS_CONFLICT = -47,
+    SECURE_HW_BUSY = -48,
+    SECURE_HW_COMMUNICATION_FAILED = -49,
+    UNSUPPORTED_EC_FIELD = -50,
+    MISSING_NONCE = -51,
+    INVALID_NONCE = -52,
+    MISSING_MAC_LENGTH = -53,
+    KEY_RATE_LIMIT_EXCEEDED = -54,
+    CALLER_NONCE_PROHIBITED = -55,
+    KEY_MAX_OPS_EXCEEDED = -56,
+    INVALID_MAC_LENGTH = -57,
+    MISSING_MIN_MAC_LENGTH = -58,
+    UNSUPPORTED_MIN_MAC_LENGTH = -59,
+    UNSUPPORTED_KDF = -60,
+    UNSUPPORTED_EC_CURVE = -61,
+    KEY_REQUIRES_UPGRADE = -62,
+    ATTESTATION_CHALLENGE_MISSING = -63,
+    KEYMASTER_NOT_CONFIGURED = -64,
+    ATTESTATION_APPLICATION_ID_MISSING = -65,
+
+    UNIMPLEMENTED = -100,
+    VERSION_MISMATCH = -101,
+
+    UNKNOWN_ERROR = -1000,
+};
+
+/**
+ * Key derivation functions, mostly used in ECIES.
+ */
+enum KeyDerivationFunction : uint32_t {
+    /* Do not apply a key derivation function; use the raw agreed key */
+    NONE = 0,
+    /* HKDF defined in RFC 5869 with SHA256 */
+    RFC5869_SHA256 = 1,
+    /* KDF1 defined in ISO 18033-2 with SHA1 */
+    ISO18033_2_KDF1_SHA1 = 2,
+    /* KDF1 defined in ISO 18033-2 with SHA256 */
+    ISO18033_2_KDF1_SHA256 = 3,
+    /* KDF2 defined in ISO 18033-2 with SHA1 */
+    ISO18033_2_KDF2_SHA1 = 4,
+    /* KDF2 defined in ISO 18033-2 with SHA256 */
+    ISO18033_2_KDF2_SHA256 = 5,
+};
+
+/**
+ * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
+ * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
+ * authenticating to activate a key.
+ */
+enum HardwareAuthenticatorType : uint32_t {
+    NONE = 0,
+    PASSWORD = 1 << 0,
+    FINGERPRINT = 1 << 1,
+    // Additional entries must be powers of 2.
+    ANY = 0xFFFFFFFF,
+};
+
+struct KeyParameter {
+    /* Discriminates the uinon/blob field used.  The blob cannot be coincided with the union, but
+     * only one of "f" and "blob" is ever used at a time. */
+    Tag tag;
+    union IntegerParams {
+        /* Enum types */
+        Algorithm algorithm;
+        BlockMode blockMode;
+        PaddingMode paddingMode;
+        Digest digest;
+        EcCurve ecCurve;
+        KeyOrigin origin;
+        KeyBlobUsageRequirements keyBlobUsageRequirements;
+        KeyPurpose purpose;
+        KeyDerivationFunction keyDerivationFunction;
+        HardwareAuthenticatorType hardwareAuthenticatorType;
+
+        /* Other types */
+        bool boolValue;  // Always true, if a boolean tag is present.
+        uint32_t integer;
+        uint64_t longInteger;
+        uint64_t dateTime;
+    };
+    IntegerParams f;  // Hidl does not support anonymous unions, so we have to name it.
+    vec<uint8_t> blob;
+};
+
+struct KeyCharacteristics {
+    vec<KeyParameter> softwareEnforced;
+    vec<KeyParameter> teeEnforced;
+};
+
+/**
+ * Data used to prove successful authentication.
+ */
+struct HardwareAuthToken {
+    uint64_t challenge;
+    uint64_t userId;             // Secure User ID, not Android user ID.
+    uint64_t authenticatorId;    // Secure authenticator ID.
+    uint32_t authenticatorType;  // HardwareAuthenticatorType, in network order.
+    uint64_t timestamp;          // In network order.
+    uint8_t[32] hmac;            // HMAC is computed over 0 || challenge || user_id ||
+                                 // authenticator_id || authenticator_type || timestamp, with a
+                                 // prefixed 0 byte (which was a version field in Keymaster1 and
+                                 // Keymaster2) and the fields packed (no padding; so you probably
+                                 // can't just compute over the bytes of the struct).
+};
+
+enum SecurityLevel : uint32_t {
+    SOFTWARE = 0,
+    TRUSTED_ENVIRONMENT = 1,
+};
+
+/**
+ * Formats for key import and export.
+ */
+enum KeyFormat : uint32_t {
+    X509 = 0,  /* for public key export */
+    PKCS8 = 1, /* for asymmetric key pair import */
+    RAW = 3,   /* for symmetric key import and export*/
+};
+
+typedef uint64_t OperationHandle;
diff --git a/keymaster/Android.bp b/keymaster/Android.bp
new file mode 100644
index 0000000..09b8cb2
--- /dev/null
+++ b/keymaster/Android.bp
@@ -0,0 +1,4 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "3.0",
+]
diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp
index a98801c..0ad131c 100644
--- a/light/2.0/Android.bp
+++ b/light/2.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.light@2.0-ILight-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+    srcs: [
+        "ILight.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/Light.vts.cpp",
+        "android/hardware/light/2.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.light@2.0-ILight-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/light/2.0/ $(genDir)/android/hardware/light/2.0/",
+    srcs: [
+        "ILight.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/Light.vts.h",
+        "android/hardware/light/2.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.light@2.0-ILight-vts.profiler",
+    generated_sources: ["android.hardware.light@2.0-ILight-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.light@2.0-ILight-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.light@2.0-ILight-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.light@2.0",
+    ],
+}
diff --git a/light/2.0/types.hal b/light/2.0/types.hal
index f065ce0..cc2ec32 100644
--- a/light/2.0/types.hal
+++ b/light/2.0/types.hal
@@ -57,7 +57,7 @@
      * When set, the device driver must switch to a mode optimized for low display
      * persistence that is intended to be used when the device is being treated as a
      * head mounted display (HMD). The actual display brightness in this mode is
-     * implementation dependent, and any value set for color in light_state may be
+     * implementation dependent, and any value set for color in LightState may be
      * overridden by the HAL implementation.
      *
      * For an optimal HMD viewing experience, the display must meet the following
diff --git a/light/2.0/vts/functional/light_hidl_hal_test.cpp b/light/2.0/vts/functional/light_hidl_hal_test.cpp
index 7c081e9..9912079 100644
--- a/light/2.0/vts/functional/light_hidl_hal_test.cpp
+++ b/light/2.0/vts/functional/light_hidl_hal_test.cpp
@@ -20,6 +20,7 @@
 #include <android/hardware/light/2.0/ILight.h>
 #include <android/hardware/light/2.0/types.h>
 #include <gtest/gtest.h>
+#include <set>
 #include <unistd.h>
 
 using ::android::hardware::light::V2_0::Brightness;
@@ -35,9 +36,9 @@
 
 #define LIGHT_SERVICE_NAME "light"
 
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.getStatus().isOk())
 #define EXPECT_OK(ret) EXPECT_TRUE(ret.getStatus().isOk())
 
-// The main test class for VIBRATOR HIDL HAL.
 class LightHidlTest : public ::testing::Test {
 public:
     virtual void SetUp() override {
@@ -45,20 +46,22 @@
 
         ASSERT_NE(light, nullptr);
         LOG(INFO) << "Test is remote " << light->isRemote();
+
+        ASSERT_OK(light->getSupportedTypes([this](const hidl_vec<Type> &types) {
+            supportedTypes = types;
+        }));
     }
 
     virtual void TearDown() override {}
 
     sp<ILight> light;
+    std::vector<Type> supportedTypes;
 };
 
-// A class for test environment setup (kept since this file is a template).
 class LightHidlEnvironment : public ::testing::Environment {
 public:
     virtual void SetUp() {}
     virtual void TearDown() {}
-
-private:
 };
 
 const static LightState kWhite = {
@@ -69,6 +72,14 @@
     .brightnessMode = Brightness::USER,
 };
 
+const static LightState kLowPersistance = {
+    .color = 0xFF123456,
+    .flashMode = Flash::TIMED,
+    .flashOnMs = 100,
+    .flashOffMs = 50,
+    .brightnessMode = Brightness::LOW_PERSISTENCE,
+};
+
 const static LightState kOff = {
     .color = 0x00000000,
     .flashMode = Flash::NONE,
@@ -77,21 +88,68 @@
     .brightnessMode = Brightness::USER,
 };
 
+const static std::set<Type> kAllTypes = {
+    Type::BACKLIGHT,
+    Type::KEYBOARD,
+    Type::BUTTONS,
+    Type::BATTERY,
+    Type::NOTIFICATIONS,
+    Type::ATTENTION,
+    Type::BLUETOOTH,
+    Type::WIFI
+};
+
 /**
  * Ensure all lights which are reported as supported work.
  */
 TEST_F(LightHidlTest, TestSupported) {
-    EXPECT_OK(light->getSupportedTypes([this](const hidl_vec<Type> &supportedTypes) {
-        for (size_t i = 0; i < supportedTypes.size(); i++) {
-            EXPECT_OK(light->setLight(supportedTypes[i], kWhite));
-        }
+    for (const Type& type: supportedTypes) {
+        Return<Status> ret = light->setLight(type, kWhite);
+        EXPECT_OK(ret);
+        EXPECT_EQ(Status::SUCCESS, static_cast<Status>(ret));
+    }
 
-        usleep(500000);
+    for (const Type& type: supportedTypes) {
+        Return<Status> ret = light->setLight(type, kOff);
+        EXPECT_OK(ret);
+        EXPECT_EQ(Status::SUCCESS, static_cast<Status>(ret));
+    }
+}
 
-        for (size_t i = 0; i < supportedTypes.size(); i++) {
-            EXPECT_OK(light->setLight(supportedTypes[i], kOff));
-        }
-    }));
+/**
+ * Ensure BRIGHTNESS_NOT_SUPPORTED is returned if LOW_PERSISTANCE is not supported.
+ */
+TEST_F(LightHidlTest, TestLowPersistance) {
+    for (const Type& type: supportedTypes) {
+        Return<Status> ret = light->setLight(type, kLowPersistance);
+        EXPECT_OK(ret);
+
+        Status status = ret;
+        EXPECT_TRUE(Status::SUCCESS == status ||
+                    Status::BRIGHTNESS_NOT_SUPPORTED == status);
+    }
+
+    for (const Type& type: supportedTypes) {
+        Return<Status> ret = light->setLight(type, kOff);
+        EXPECT_OK(ret);
+        EXPECT_EQ(Status::SUCCESS, static_cast<Status>(ret));
+    }
+}
+
+/**
+ * Ensure lights which are not supported return LIGHT_NOT_SUPPORTED
+ */
+TEST_F(LightHidlTest, TestUnsupported) {
+    std::set<Type> unsupportedTypes = kAllTypes;
+    for (const Type& type: supportedTypes) {
+        unsupportedTypes.erase(type);
+    }
+
+    for (const Type& type: unsupportedTypes) {
+        Return<Status> ret = light->setLight(type, kWhite);
+        EXPECT_OK(ret);
+        EXPECT_EQ(Status::LIGHT_NOT_SUPPORTED, static_cast<Status>(ret));
+    }
 }
 
 int main(int argc, char **argv) {
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
index 98dfe14..89b7fa2 100644
--- a/media/1.0/types.hal
+++ b/media/1.0/types.hal
@@ -27,28 +27,28 @@
 
 /**
  * Ref: frameworks/native/include/ui/GraphicBuffer.h
- * Ref: system/core/include/system/window.h
+ * Ref: system/core/include/system/window.h: ANativeWindowBuffer
  */
 
 /**
  * This struct contains attributes for a gralloc buffer that can be put into a
  * union.
  */
-struct GraphicBufferAttributes {
+struct AnwBufferAttributes {
     uint32_t width;
     uint32_t height;
     uint32_t stride;
     PixelFormat format;
     uint32_t usage; // TODO: convert to an enum
-    uint32_t generationNumber;
+    uint64_t layerCount;
 };
 
 /**
- * A GraphicBuffer is simply GraphicBufferAttributes plus a native handle.
+ * An AnwBuffer is simply AnwBufferAttributes plus a native handle.
  */
-struct GraphicBuffer {
+struct AnwBuffer {
     handle nativeHandle;
-    GraphicBufferAttributes attr;
+    AnwBufferAttributes attr;
 };
 
 /**
diff --git a/media/omx/1.0/IGraphicBufferSource.hal b/media/omx/1.0/IGraphicBufferSource.hal
index a5b5813..9b3ab0c 100644
--- a/media/omx/1.0/IGraphicBufferSource.hal
+++ b/media/omx/1.0/IGraphicBufferSource.hal
@@ -29,32 +29,23 @@
  */
 interface IGraphicBufferSource {
 
-    configure(IOmxNode omxNode, Dataspace dataspace)
-        generates (Status status);
+    configure(IOmxNode omxNode, Dataspace dataspace);
 
-    setSuspend(bool suspend)
-        generates (Status status);
+    setSuspend(bool suspend);
 
-    setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)
-        generates (Status status);
+    setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
 
-    setMaxFps(float maxFps)
-        generates (Status status);
+    setMaxFps(float maxFps);
 
-    setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs)
-        generates (Status status);
+    setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs);
 
-    setStartTimeUs(int64_t startTimeUs)
-        generates (Status status);
+    setStartTimeUs(int64_t startTimeUs);
 
-    setColorAspects(ColorAspects aspects)
-        generates (Status status);
+    setColorAspects(ColorAspects aspects);
 
-    setTimeOffsetUs(int64_t timeOffsetUs)
-        generates (Status status);
+    setTimeOffsetUs(int64_t timeOffsetUs);
 
-    signalEndOfInputStream()
-        generates (Status status);
+    signalEndOfInputStream();
 
 };
 
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
index 9483be4..5945b44 100644
--- a/media/omx/1.0/IOmxNode.hal
+++ b/media/omx/1.0/IOmxNode.hal
@@ -46,14 +46,14 @@
      * Invoke a command on the node.
      *
      * @param[in] cmd indicates the type of the command.
-     * @param[in] info holds information about the command.
+     * @param[in] param is a parameter for the command.
      * @param[out] status will be the status of the call.
      *
      * @see OMX_SendCommand() in the OpenMax IL standard.
      */
     sendCommand(
             uint32_t cmd,
-            Bytes info // TODO: describe structure better or point at standard
+            int32_t param
         ) generates (
             Status status
         );
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
index 79c3a44..ccb2ddf 100644
--- a/media/omx/1.0/types.hal
+++ b/media/omx/1.0/types.hal
@@ -34,6 +34,7 @@
 
     NAME_NOT_FOUND          = -2,
     NO_MEMORY               = -12,
+    BAD_VALUE               = -22,
     ERROR_UNSUPPORTED       = -1010,
     UNKNOWN_ERROR           = -2147483648,
 };
@@ -149,7 +150,7 @@
         SharedMemoryAttributes sharedMem;
 
         // if bufferType == ANW_BUFFER
-        GraphicBufferAttributes anwBuffer;
+        AnwBufferAttributes anwBuffer;
 
         // if bufferType == NATIVE_HANDLE
         // No additional attributes.
diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp
index c80ebf8..87342ef 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.memtrack@1.0-IMemtrack-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+    srcs: [
+        "IMemtrack.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/memtrack/1.0/Memtrack.vts.cpp",
+        "android/hardware/memtrack/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.memtrack@1.0-IMemtrack-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/memtrack/1.0/ $(genDir)/android/hardware/memtrack/1.0/",
+    srcs: [
+        "IMemtrack.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/memtrack/1.0/Memtrack.vts.h",
+        "android/hardware/memtrack/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.memtrack@1.0-IMemtrack-vts.profiler",
+    generated_sources: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.memtrack@1.0-IMemtrack-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.memtrack@1.0",
+    ],
+}
diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk
index 4a5ca4f..397f946 100644
--- a/memtrack/1.0/vts/Android.mk
+++ b/memtrack/1.0/vts/Android.mk
@@ -16,35 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for memtrack.
-include $(CLEAR_VARS)
+include $(call all-subdir-makefiles)
 
-LOCAL_MODULE := libvts_profiler_hidl_memtrack@1.0
-
-LOCAL_SRC_FILES := \
-  Memtrack.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.memtrack@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
+include $(LOCAL_PATH)/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..b3e560a
--- /dev/null
+++ b/memtrack/1.0/vts/functional/Android.bp
@@ -0,0 +1,40 @@
+//
+// 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: "memtrack_hidl_hal_test",
+    gtest: true,
+    srcs: ["memtrack_hidl_hal_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.memtrack@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "--coverage",
+        "-O0",
+        "-g",
+    ],
+    ldflags: [
+        "--coverage"
+    ]
+}
diff --git a/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
new file mode 100644
index 0000000..597b5da
--- /dev/null
+++ b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
@@ -0,0 +1,198 @@
+/*
+ * 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 "memtrack_hidl_hal_test"
+#include <android-base/logging.h>
+#include <android/hardware/memtrack/1.0/IMemtrack.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <vector>
+
+using ::android::hardware::memtrack::V1_0::IMemtrack;
+using ::android::hardware::memtrack::V1_0::MemtrackRecord;
+using ::android::hardware::memtrack::V1_0::MemtrackFlag;
+using ::android::hardware::memtrack::V1_0::MemtrackType;
+using ::android::hardware::memtrack::V1_0::MemtrackStatus;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::sp;
+using std::vector;
+using std::count_if;
+
+class MemtrackHidlTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    memtrack = IMemtrack::getService("memtrack");
+    ASSERT_NE(memtrack, nullptr);
+  }
+
+  virtual void TearDown() override {}
+
+  sp<IMemtrack> memtrack;
+};
+
+/* Returns true if flags contains at least min, and no more than max,
+ * of the flags in flagSet. Returns false otherwise.
+ */
+bool rightFlagCount(uint32_t flags, vector<MemtrackFlag> flagSet, uint32_t min,
+                    uint32_t max) {
+  uint32_t count =
+      count_if(flagSet.begin(), flagSet.end(),
+               [&](MemtrackFlag f) { return flags & (uint32_t)f; });
+  return (min <= count && count <= max);
+}
+
+/* Returns true when passed a valid, defined status, false otherwise.
+ */
+bool validStatus(MemtrackStatus s) {
+  vector<MemtrackStatus> statusVec = {
+      MemtrackStatus::SUCCESS, MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED,
+      MemtrackStatus::TYPE_NOT_SUPPORTED};
+  return std::find(statusVec.begin(), statusVec.end(), s) != statusVec.end();
+}
+
+/* Returns a pid found in /proc for which the string read from
+ * /proc/[pid]/cmdline matches cmd, or -1 if no such pid exists.
+ */
+pid_t getPidFromCmd(const char cmd[], uint32_t len) {
+  const char procs[] = "/proc/";
+  DIR *dir = opendir(procs);
+  if (!dir) {
+    return -1;
+  }
+
+  struct dirent *proc;
+  while ((proc = readdir(dir)) != NULL) {
+    if (!isdigit(proc->d_name[0])) {
+      continue;
+    }
+    char line[len];
+    char fname[PATH_MAX];
+    snprintf(fname, PATH_MAX, "/proc/%s/cmdline", proc->d_name);
+
+    FILE *file = fopen(fname, "r");
+    if (!file) {
+      continue;
+    }
+    char *str = fgets(line, len, file);
+    fclose(file);
+    if (!str || strcmp(str, cmd)) {
+      continue;
+    } else {
+      closedir(dir);
+      return atoi(proc->d_name);
+    }
+  }
+  closedir(dir);
+  return -1;
+}
+
+auto generate_cb(MemtrackStatus *s, hidl_vec<MemtrackRecord> *v) {
+  return [=](MemtrackStatus status, hidl_vec<MemtrackRecord> vec) {
+    *s = status;
+    *v = vec;
+  };
+}
+
+/* Sanity check results when getMemory() is passed a negative PID
+ */
+TEST_F(MemtrackHidlTest, BadPidTest) {
+  MemtrackStatus s;
+  hidl_vec<MemtrackRecord> v;
+  auto cb = generate_cb(&s, &v);
+  for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES);
+       i++) {
+    Return<void> ret =
+        memtrack->getMemory(-1, static_cast<MemtrackType>(i), cb);
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_TRUE(validStatus(s));
+  }
+}
+
+/* Sanity check results when getMemory() is passed a bad memory usage type
+ */
+TEST_F(MemtrackHidlTest, BadTypeTest) {
+  MemtrackStatus s;
+  hidl_vec<MemtrackRecord> v;
+  auto cb = generate_cb(&s, &v);
+  Return<void> ret = memtrack->getMemory(getpid(), MemtrackType::NUM_TYPES, cb);
+  ASSERT_TRUE(ret.isOk());
+  ASSERT_TRUE(validStatus(s));
+}
+
+/* Call memtrack on the surfaceflinger process and check that the results are
+ * reasonable for all memory types, including valid flag combinations for
+ * every MemtrackRecord returned.
+ */
+TEST_F(MemtrackHidlTest, SurfaceflingerTest) {
+  const char cmd[] = "/system/bin/surfaceflinger";
+  const uint32_t len = sizeof(cmd);
+  pid_t pid = getPidFromCmd(cmd, len);
+  ASSERT_LE(0, pid) << "Surfaceflinger process not found";
+
+  MemtrackStatus s;
+  hidl_vec<MemtrackRecord> v;
+  auto cb = generate_cb(&s, &v);
+  uint32_t unsupportedCount = 0;
+  for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES);
+       i++) {
+    Return<void> ret =
+        memtrack->getMemory(pid, static_cast<MemtrackType>(i), cb);
+    ASSERT_TRUE(ret.isOk());
+
+    switch (s) {
+      case MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED:
+        unsupportedCount++;
+        break;
+      case MemtrackStatus::TYPE_NOT_SUPPORTED:
+        break;
+      case MemtrackStatus::SUCCESS: {
+        for (uint32_t j = 0; j < v.size(); j++) {
+          // Enforce flag constraints
+          vector<MemtrackFlag> smapFlags = {MemtrackFlag::SMAPS_ACCOUNTED,
+                                            MemtrackFlag::SMAPS_UNACCOUNTED};
+          EXPECT_TRUE(rightFlagCount(v[j].flags, smapFlags, 1, 1));
+          vector<MemtrackFlag> shareFlags = {MemtrackFlag::SHARED,
+                                             MemtrackFlag::SHARED_PSS,
+                                             MemtrackFlag::PRIVATE};
+          EXPECT_TRUE(rightFlagCount(v[j].flags, shareFlags, 0, 1));
+          vector<MemtrackFlag> systemFlags = {MemtrackFlag::SYSTEM,
+                                              MemtrackFlag::DEDICATED};
+          EXPECT_TRUE(rightFlagCount(v[j].flags, systemFlags, 0, 1));
+          vector<MemtrackFlag> secureFlags = {MemtrackFlag::SECURE,
+                                              MemtrackFlag::NONSECURE};
+          EXPECT_TRUE(rightFlagCount(v[j].flags, secureFlags, 0, 1));
+        }
+        break;
+      }
+      default:
+        FAIL();
+    }
+  }
+  // If tracking is not supported this should be returned for all types.
+  ASSERT_TRUE(unsupportedCount == 0 ||
+              unsupportedCount ==
+                  static_cast<uint32_t>(MemtrackType::NUM_TYPES));
+}
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
new file mode 100644
index 0000000..8dcaabb
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/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 := HalMemtrackHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/memtrack/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..7fb286b
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/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 Memtrack 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="HalMemtrackHidlTargetTest"/>
+        <option name="binary-test-sources" value="
+            _32bit::DATA/nativetest/memtrack_hidl_hal_test/memtrack_hidl_hal_test,
+            _64bit::DATA/nativetest64/memtrack_hidl_hal_test/memtrack_hidl_hal_test,
+            "/>
+        <option name="test-config-path" value="vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config" />
+        <option name="binary-test-type" value="gtest" />
+        <option name="test-timeout" value="5m" />
+    </test>
+</configuration>
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config
new file mode 100644
index 0000000..d2597a2
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/target/HalMemtrackHidlTargetTest.config
@@ -0,0 +1,20 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [
+        {
+            "module_name": "system/lib64/hw/memtrack.msm8992",
+            "git_project": {
+                "name": "platform/hardware/qcom/display",
+                "path": "hardware/qcom/display"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/android.hardware.memtrack@1.0-impl",
+            "git_project": {
+                "name": "platform/hardware/interfaces",
+                "path": "hardware/interfaces"
+            }
+        }
+    ]
+}
diff --git a/memtrack/Android.bp b/memtrack/Android.bp
index ba90f2c..ed19a37 100644
--- a/memtrack/Android.bp
+++ b/memtrack/Android.bp
@@ -2,4 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/vts/functional",
 ]
diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp
index 930fb14..af571f3 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -124,3 +124,93 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.nfc@1.0-INfc-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "INfc.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/Nfc.vts.cpp",
+        "android/hardware/nfc/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.nfc@1.0-INfc-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "INfc.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/Nfc.vts.h",
+        "android/hardware/nfc/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.nfc@1.0-INfc-vts.profiler",
+    generated_sources: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.nfc@1.0-INfc-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.nfc@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "INfcClientCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/NfcClientCallback.vts.cpp",
+        "android/hardware/nfc/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/nfc/1.0/ $(genDir)/android/hardware/nfc/1.0/",
+    srcs: [
+        "INfcClientCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/nfc/1.0/NfcClientCallback.vts.h",
+        "android/hardware/nfc/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.nfc@1.0-INfcClientCallback-vts.profiler",
+    generated_sources: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.nfc@1.0-INfcClientCallback-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.nfc@1.0",
+    ],
+}
diff --git a/nfc/1.0/vts/Android.mk b/nfc/1.0/vts/Android.mk
index e7dec14..f9e3276 100644
--- a/nfc/1.0/vts/Android.mk
+++ b/nfc/1.0/vts/Android.mk
@@ -16,68 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for Nfc.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_nfc@1.0
-
-LOCAL_SRC_FILES := \
-   Nfc.vts \
-   types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.nfc@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-# build profiler for NfcClientCallback.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_nfc_client_callback_@1.0
-
-LOCAL_SRC_FILES := \
-   NfcClientCallback.vts \
-   types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.nfc@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
diff --git a/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp b/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
index 3e40a9c..f5ed4d7 100644
--- a/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
+++ b/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
@@ -21,14 +21,12 @@
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
 #include <android/hardware/nfc/1.0/types.h>
 #include <hardware/nfc.h>
-#include <hwbinder/ProcessState.h>
 
 #include <gtest/gtest.h>
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
 
-using ::android::hardware::ProcessState;
 using ::android::hardware::nfc::V1_0::INfc;
 using ::android::hardware::nfc::V1_0::INfcClientCallback;
 using ::android::hardware::nfc::V1_0::NfcEvent;
@@ -66,12 +64,6 @@
     nfc_ = INfc::getService(NFC_NCI_SERVICE_NAME, passthrough);
     ASSERT_NE(nfc_, nullptr);
 
-    // TODO:b/31748996
-    if (nfc_->isRemote()) {
-      ProcessState::self()->setThreadPoolMaxThreadCount(1);
-      ProcessState::self()->startThreadPool();
-    }
-
     nfc_cb_ = new NfcClientCallback(*this);
     ASSERT_NE(nfc_cb_, nullptr);
 
diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp
index 2eb9e34..8643139 100644
--- a/power/1.0/Android.bp
+++ b/power/1.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.power@1.0-IPower-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+    srcs: [
+        "IPower.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/power/1.0/Power.vts.cpp",
+        "android/hardware/power/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.power@1.0-IPower-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/power/1.0/ $(genDir)/android/hardware/power/1.0/",
+    srcs: [
+        "IPower.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/power/1.0/Power.vts.h",
+        "android/hardware/power/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.power@1.0-IPower-vts.profiler",
+    generated_sources: ["android.hardware.power@1.0-IPower-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.power@1.0-IPower-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.power@1.0-IPower-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.power@1.0",
+    ],
+}
diff --git a/power/1.0/vts/Android.mk b/power/1.0/vts/Android.mk
index db7e98e..df5dac8 100644
--- a/power/1.0/vts/Android.mk
+++ b/power/1.0/vts/Android.mk
@@ -16,36 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for power.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_power@1.0
-
-LOCAL_SRC_FILES := \
-   Power.vts \
-   types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.power@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/power/1.0/vts/functional/power_hidl_hal_test.cpp b/power/1.0/vts/functional/power_hidl_hal_test.cpp
index 8833c04..045a34b 100644
--- a/power/1.0/vts/functional/power_hidl_hal_test.cpp
+++ b/power/1.0/vts/functional/power_hidl_hal_test.cpp
@@ -35,18 +35,8 @@
 class PowerHidlTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    // TODO(b/33385836) Delete copied code
-    bool getStub = false;
-    char getSubProperty[PROPERTY_VALUE_MAX];
-    if (property_get("vts.hidl.get_stub", getSubProperty, "") > 0) {
-        if (!strcmp(getSubProperty, "true") || !strcmp(getSubProperty, "True") ||
-            !strcmp(getSubProperty, "1")) {
-            getStub = true;
-        }
-    }
-    power = IPower::getService("power", getStub);
+    power = IPower::getService("power");
     ASSERT_NE(power, nullptr);
-    ASSERT_EQ(!getStub, power->isRemote());
   }
 
   virtual void TearDown() override {}
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
index bb80de2..0eb2142 100644
--- a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
             _32bit::DATA/nativetest/power_hidl_hal_test/power_hidl_hal_test,
             _64bit::DATA/nativetest64/power_hidl_hal_test/power_hidl_hal_test,
             "/>
+        <option name="test-config-path" value="vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config" />
         <option name="binary-test-type" value="gtest" />
         <option name="test-timeout" value="1m" />
     </test>
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
new file mode 100644
index 0000000..54c0175
--- /dev/null
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
@@ -0,0 +1,34 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [
+        {
+            "module_name": "system/lib64/hw/power.bullhead",
+            "git_project": {
+                "name": "device/lge/bullhead",
+                "path": "device/lge/bullhead"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/power.marlin",
+            "git_project": {
+                "name": "device/google/marlin",
+                "path": "device/google/marlin"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/power.sailfish",
+            "git_project": {
+                "name": "device/google/marlin",
+                "path": "device/google/marlin"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/android.hardware.power@1.0-impl",
+            "git_project": {
+                "name": "platform/hardware/interfaces",
+                "path": "hardware/interfaces"
+            }
+        }
+    ]
+}
diff --git a/radio/1.0/Android.mk b/radio/1.0/Android.mk
index c645657..059ebcb 100644
--- a/radio/1.0/Android.mk
+++ b/radio/1.0/Android.mk
@@ -1556,6 +1556,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (LastCallFailCauseInfo)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_0/LastCallFailCauseInfo.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.radio@1.0::types.LastCallFailCauseInfo
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (LceDataInfo)
 #
 GEN := $(intermediates)/android/hardware/radio/V1_0/LceDataInfo.java
@@ -4476,6 +4495,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (LastCallFailCauseInfo)
+#
+GEN := $(intermediates)/android/hardware/radio/V1_0/LastCallFailCauseInfo.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.radio@1.0::types.LastCallFailCauseInfo
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (LceDataInfo)
 #
 GEN := $(intermediates)/android/hardware/radio/V1_0/LceDataInfo.java
diff --git a/radio/1.0/IRadio.hal b/radio/1.0/IRadio.hal
index 62bc840..1cb7040 100644
--- a/radio/1.0/IRadio.hal
+++ b/radio/1.0/IRadio.hal
@@ -1037,7 +1037,7 @@
      *
      * Response callback is IRadioCallback.setGsmBroadcastConfigResponse()
      */
-    oneway setGsmBroadcastConfig(int32_t serial, GsmBroadcastSmsConfigInfo configInfo);
+    oneway setGsmBroadcastConfig(int32_t serial, vec<GsmBroadcastSmsConfigInfo> configInfo);
 
     /*
      * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS
@@ -1067,7 +1067,7 @@
      *
      * Response callback is IRadioCallback.setCdmaBroadcastConfigResponse()
      */
-    oneway setCdmaBroadcastConfig(int32_t serial, CdmaBroadcastSmsConfigInfo configInfo);
+    oneway setCdmaBroadcastConfig(int32_t serial, vec<CdmaBroadcastSmsConfigInfo> configInfo);
 
     /*
      * Enable or disable the reception of CDMA Cell Broadcast SMS
@@ -1564,4 +1564,4 @@
      *
      */
     oneway responseAcknowledgement();
-};
\ No newline at end of file
+};
diff --git a/radio/1.0/IRadioIndication.hal b/radio/1.0/IRadioIndication.hal
index 4dbae17..79ebf30 100644
--- a/radio/1.0/IRadioIndication.hal
+++ b/radio/1.0/IRadioIndication.hal
@@ -81,8 +81,9 @@
      * Indicates when new SMS has been stored on SIM card
      *
      * @param type Type of radio indication
+     * @param recordNumber Record number on the sim
      */
-    oneway newSmsOnSim(RadioIndicationType type);
+    oneway newSmsOnSim(RadioIndicationType type, int32_t recordNumber);
 
     /*
      * Indicates when a new USSD message is received.
@@ -91,8 +92,9 @@
      *
      * @param type Type of radio indication
      * @param modeType USSD type code
+     * @param msg Message string in UTF-8, if applicable
      */
-    oneway onUssd(RadioIndicationType type, UssdModeType modeType);
+    oneway onUssd(RadioIndicationType type, UssdModeType modeType, string msg);
 
     /*
      * Indicates when radio has received a NITZ time message.
@@ -146,7 +148,7 @@
      * @param cmd SAT/USAT proactive represented as byte array starting with command tag.
      *        Refer ETSI TS 102.223 section 9.4 for command types
      */
-    oneway stkProactiveCommand(RadioIndicationType type, vec<uint8_t> cmd);
+    oneway stkProactiveCommand(RadioIndicationType type, string cmd);
 
     /*
      * Indicates when SIM notifies applcations some event happens.
@@ -157,7 +159,7 @@
      *        starting with first byte of response data for command tag. Refer
      *        ETSI TS 102.223 section 9.4 for command types
      */
-    oneway stkEventNotify(RadioIndicationType type, vec<uint8_t> cmd);
+    oneway stkEventNotify(RadioIndicationType type, string cmd);
 
     /*
      * Indicates when SIM wants application to setup a voice call.
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index e25a30c..8ff2e24 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -23,17 +23,17 @@
  */
 interface IRadioResponse {
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param cardStatus ICC card status as defined by CardStatus in types.hal
      *
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:INVALID_ARGUMENTS
      */
-    oneway iccCardStatusResponse(RadioResponseInfo info, CardStatus cardStatus);
+    oneway getIccCardStatusResponse(RadioResponseInfo info, CardStatus cardStatus);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -46,7 +46,7 @@
     oneway supplyIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -59,7 +59,7 @@
     oneway supplyIccPukForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -72,7 +72,7 @@
     oneway supplyIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      * Valid errors returned:
      *   RadioError:NONE
@@ -84,7 +84,7 @@
     oneway supplyIccPuk2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -97,7 +97,7 @@
     oneway changeIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -110,7 +110,7 @@
     oneway changeIccPin2ForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown.
      *
      * Valid errors returned:
@@ -123,7 +123,7 @@
     oneway supplyNetworkDepersonalizationResponse(RadioResponseInfo info, int32_t remainingRetries);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param calls Current call list
      *
      * Valid errors returned:
@@ -136,7 +136,7 @@
     oneway getCurrentCallsResponse(RadioResponseInfo info, vec<Call> calls);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -162,7 +162,7 @@
     oneway dialResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param imsi String containing the IMSI
      *
      * Valid errors returned:
@@ -174,7 +174,7 @@
     oneway getIMSIForAppResponse(RadioResponseInfo info, string imsi);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -190,7 +190,7 @@
     oneway hangupConnectionResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -208,7 +208,7 @@
     oneway hangupWaitingOrBackgroundResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -226,7 +226,7 @@
     oneway hangupForegroundResumeBackgroundResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -244,7 +244,7 @@
     oneway switchWaitingOrHoldingAndActiveResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -261,7 +261,7 @@
     oneway conferenceResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -279,9 +279,9 @@
     oneway rejectCallResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
-     * @param failCause failCause is LastCallFailCause. GSM failure reasons are
-     *        mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA
+     * @param info Response info struct containing response type, serial no. and error
+     * @param failCauseInfo Contains LastCallFailCause and vendor cause code. GSM failure reasons
+     *        are mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA
      *        failure reasons are derived from the possible call failure scenarios
      *        described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
      *
@@ -300,10 +300,11 @@
      *   RadioError:NO_MEMORY
      *   RadioError:GENERIC_FAILURE
      */
-    oneway getLastCallFailCauseResponse(RadioResponseInfo info, LastCallFailCause failCause);
+    oneway getLastCallFailCauseResponse(RadioResponseInfo info,
+            LastCallFailCauseInfo failCauseinfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param sigStrength Current signal strength
      *
      * Valid errors returned:
@@ -314,7 +315,7 @@
     oneway getSignalStrengthResponse(RadioResponseInfo info, SignalStrength sigStrength);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param voiceRegResponse Current Voice registration response as defined by VoiceRegStateResult
      *        in types.hal
      *
@@ -328,7 +329,7 @@
             VoiceRegStateResult voiceRegResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param dataRegResponse Current Data registration response as defined by DataRegStateResult in
      *        types.hal
      *
@@ -342,7 +343,7 @@
             DataRegStateResult dataRegResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param longName is long alpha ONS or EONS or empty string if unregistered
      * @param shortName is short alpha ONS or EONS or empty string if unregistered
      * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered
@@ -357,7 +358,7 @@
             string numeric);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -369,7 +370,7 @@
     oneway setRadioPowerResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -384,7 +385,7 @@
     oneway sendDtmfResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param sms Response to sms sent as defined by SendSmsResult in types.hal
      *
      * Valid errors returned:
@@ -408,7 +409,7 @@
     oneway sendSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param sms Response to sms sent as defined by SendSmsResult in types.hal
      *
      * Valid errors returned:
@@ -433,7 +434,7 @@
     oneway sendSMSExpectMoreResponse(RadioResponseInfo info, SendSmsResult sms);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param dcResponse SetupDataCallResult defined in types.hal
      *
      * Valid errors returned:
@@ -450,7 +451,7 @@
     oneway setupDataCallResponse(RadioResponseInfo info, SetupDataCallResult dcResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param iccIo ICC io operation response as defined by IccIoResult in types.hal
      *
      * Valid errors returned:
@@ -461,10 +462,10 @@
      *   RadioError:SIM_PUK2
      *   RadioError:GENERIC_FAILURE
      */
-    oneway iccIOForApp(RadioResponseInfo info, IccIoResult iccIo);
+    oneway iccIOForAppResponse(RadioResponseInfo info, IccIoResult iccIo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -487,7 +488,7 @@
     oneway sendUssdResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -504,7 +505,7 @@
     oneway cancelPendingUssdResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param n is "n" parameter from TS 27.007 7.7
      * @param m is "m" parameter from TS 27.007 7.7
      *
@@ -525,7 +526,7 @@
     oneway getClirResponse(RadioResponseInfo info, int32_t n, int32_t m);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -541,7 +542,7 @@
     oneway setClirResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param callForwardInfos points to a vector of CallForwardInfo, one for
      *        each distinct registered phone number.
      *
@@ -570,7 +571,7 @@
             vec<CallForwardInfo> callForwardInfos);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -590,7 +591,7 @@
     oneway setCallForwardResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param enable If current call waiting state is disabled, enable = false else true
      * @param serviceClass If enable, then callWaitingResp[1]
      *        must follow, with the TS 27.007 service class bit vector of services
@@ -615,7 +616,7 @@
     oneway getCallWaitingResponse(RadioResponseInfo info, bool enable, int32_t serviceClass);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -634,7 +635,7 @@
     oneway setCallWaitingResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -645,7 +646,7 @@
     oneway acknowledgeLastIncomingGsmSmsResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -662,7 +663,7 @@
     oneway acceptCallResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -673,7 +674,7 @@
     oneway deactivateDataCallResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param response 0 is the TS 27.007 service class bit vector of
      *        services for which the specified barring facility
      *        is active. "0" means "disabled for all"
@@ -695,7 +696,7 @@
     oneway getFacilityLockForAppResponse(RadioResponseInfo info, int32_t response);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param retry 0 is the number of retries remaining, or -1 if unknown
      *
      * Valid errors returned:
@@ -715,7 +716,7 @@
     oneway setFacilityLockForAppResponse(RadioResponseInfo info, int32_t retry);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -734,7 +735,7 @@
     oneway setBarringPasswordResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param selection false for automatic selection, true for manual selection
      *
      * Valid errors returned:
@@ -746,7 +747,7 @@
     oneway getNetworkSelectionModeResponse(RadioResponseInfo info, bool manual);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -763,7 +764,7 @@
     oneway setNetworkSelectionModeAutomaticResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -780,7 +781,7 @@
     oneway setNetworkSelectionModeManualResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param networkInfos List of network operator information as OperatorInfos defined in
      *         types.hal
      *
@@ -795,7 +796,7 @@
             vec<OperatorInfo> networkInfos);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -812,7 +813,7 @@
     oneway startDtmfResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -830,7 +831,7 @@
     oneway stopDtmfResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param version string containing version string for log reporting
      *
      * Valid errors returned:
@@ -843,7 +844,7 @@
     oneway getBasebandVersionResponse(RadioResponseInfo info, string version);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -862,7 +863,7 @@
     oneway separateConnectionResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -875,8 +876,8 @@
     oneway setMuteResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
-     * @param enable true for "mute enabled" & false for "mute disabled"
+     * @param info Response info struct containing response type, serial no. and error
+     * @param enable true for "mute enabled" and false for "mute disabled"
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -892,7 +893,7 @@
     oneway getMuteResponse(RadioResponseInfo info, bool enable);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param status indicates CLIP status
      *
      * Valid errors returned:
@@ -909,7 +910,7 @@
     oneway getClipResponse(RadioResponseInfo info, ClipStatus status);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param dcResponse List of DataCallResult as defined in types.hal
      *
      * Valid errors returned:
@@ -921,7 +922,7 @@
     oneway getDataCallListResponse(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param data data returned by oem
      *
      * Valid errors returned:
@@ -933,7 +934,7 @@
     oneway sendOemRilRequestRawResponse(RadioResponseInfo info, vec<uint8_t> data);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param data data returned by oem
      *
      * Valid errors returned:
@@ -945,7 +946,7 @@
     oneway sendOemRilRequestStringsResponse(RadioResponseInfo info, vec<string> data);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -956,7 +957,7 @@
     oneway sendScreenStateResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -972,7 +973,7 @@
     oneway setSuppServiceNotificationsResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param index record index where the message is stored
      *
      * Valid errors returned:
@@ -993,7 +994,7 @@
     oneway writeSmsToSimResponse(RadioResponseInfo info, int32_t index);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1009,7 +1010,7 @@
     oneway deleteSmsOnSimResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1021,7 +1022,7 @@
     oneway setBandModeResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param bandModes List of RadioBandMode listing supported modes
      *
      * Valid errors returned:
@@ -1033,7 +1034,7 @@
     oneway getAvailableBandModesResponse(RadioResponseInfo info, vec<RadioBandMode> bandModes);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param commandResponse SAT/USAT response in hexadecimal format
      *        string starting with first byte of response
      *
@@ -1048,7 +1049,7 @@
     oneway sendEnvelopeResponse(RadioResponseInfo info, string commandResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1060,7 +1061,7 @@
     oneway sendTerminalResponseToSimResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1072,7 +1073,7 @@
     oneway handleStkCallSetupRequestFromSimResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1091,7 +1092,7 @@
     oneway explicitCallTransferResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1104,7 +1105,7 @@
     oneway setPreferredNetworkTypeResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param nwType RadioPreferredNetworkType defined in types.hal
      *
      * Valid errors returned:
@@ -1117,8 +1118,8 @@
             PreferredNetworkType nwType);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
-     * @param cell RadioNeighboringCell defined in types.hal
+     * @param info Response info struct containing response type, serial no. and error
+     * @param cells Vector of neighboring radio cell
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1126,10 +1127,10 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:GENERIC_FAILURE
      */
-    oneway getNeighboringCidsResponse(RadioResponseInfo info, NeighboringCell cell);
+    oneway getNeighboringCidsResponse(RadioResponseInfo info, vec<NeighboringCell> cells);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1140,7 +1141,7 @@
     oneway setLocationUpdatesResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1153,7 +1154,7 @@
     oneway setCdmaSubscriptionSourceResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1164,7 +1165,7 @@
     oneway setCdmaRoamingPreferenceResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param type CdmaRoamingType defined in types.hal
      *
      * Valid errors returned:
@@ -1176,7 +1177,7 @@
     oneway getCdmaRoamingPreferenceResponse(RadioResponseInfo info, CdmaRoamingType type);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1190,7 +1191,7 @@
     oneway setTTYModeResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param mode TtyMode
      *
      * Valid errors returned:
@@ -1205,7 +1206,7 @@
     oneway getTTYModeResponse(RadioResponseInfo info, TtyMode mode);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1219,7 +1220,7 @@
     oneway setPreferredVoicePrivacyResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param enable false for Standard Privacy Mode (Public Long Code Mask)
      *        true for Enhanced Privacy Mode (Private Long Code Mask)
      *
@@ -1237,7 +1238,7 @@
     /*
      * Response callback for IRadio.sendCDMAFeatureCode()
      *
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1254,7 +1255,7 @@
     oneway sendCDMAFeatureCodeResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1271,7 +1272,7 @@
     oneway sendBurstDtmfResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param sms Sms result struct as defined by SendSmsResult in types.hal
      *
      * Valid errors returned:
@@ -1296,7 +1297,7 @@
     oneway sendCdmaSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1316,8 +1317,8 @@
     oneway acknowledgeLastIncomingCdmaSmsResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
-     * @param configInfo Setting of GSM/WCDMA Cell broadcast config
+     * @param info Response info struct containing response type, serial no. and error
+     * @param configs Vector of GSM/WCDMA Cell broadcast configs
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1331,10 +1332,11 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:GENERIC_FAILURE
      */
-    oneway getGsmBroadcastConfigResponse(RadioResponseInfo info, GsmBroadcastSmsConfigInfo configInfo);
+    oneway getGsmBroadcastConfigResponse(RadioResponseInfo info,
+            vec<GsmBroadcastSmsConfigInfo> configs);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1350,7 +1352,7 @@
     oneway setGsmBroadcastConfigResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1366,8 +1368,8 @@
     oneway setGsmBroadcastActivationResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
-     * @param configInfo CDMA Broadcast SMS config.
+     * @param info Response info struct containing response type, serial no. and error
+     * @param configs Vector of CDMA Broadcast SMS configs.
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1381,10 +1383,11 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:GENERIC_FAILURE
      */
-    oneway getCdmaBroadcastConfigResponse(RadioResponseInfo info, CdmaBroadcastSmsConfigInfo configInfo);
+    oneway getCdmaBroadcastConfigResponse(RadioResponseInfo info,
+            vec<CdmaBroadcastSmsConfigInfo> configs);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1400,7 +1403,7 @@
     oneway setCdmaBroadcastConfigResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1416,7 +1419,7 @@
     oneway setCdmaBroadcastActivationResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param mdn MDN if CDMA subscription is available
      * @param hSid is a comma separated list of H_SID (Home SID) if
      *        CDMA subscription is available, in decimal format
@@ -1436,7 +1439,7 @@
             string hNid, string min, string prl);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param index record index where the cmda sms message is stored
      *
      * Valid errors returned:
@@ -1458,7 +1461,7 @@
     oneway writeSmsToRuimResponse(RadioResponseInfo info, uint32_t index);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1474,7 +1477,7 @@
     oneway deleteSmsOnRuimResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param imei IMEI if GSM subscription is available
      * @param imeisv IMEISV if GSM subscription is available
      * @param esn ESN if CDMA subscription is available
@@ -1494,7 +1497,7 @@
             string esn, string meid);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1506,7 +1509,7 @@
     oneway exitEmergencyCallbackModeResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param smsc Short Message Service Center address on the device
      *
      * Valid errors returned:
@@ -1525,7 +1528,7 @@
     oneway getSmscAddressResponse(RadioResponseInfo info, string smsc);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1542,7 +1545,7 @@
     oneway setSmscAddressResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1558,7 +1561,7 @@
     oneway reportSmsMemoryStatusResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param source CDMA subscription source
      *
      * Valid errors returned:
@@ -1570,7 +1573,7 @@
     oneway getCdmaSubscriptionSourceResponse(RadioResponseInfo info, CdmaSubscriptionSource source);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param response response string of the challenge/response algo for ISIM auth in base64 format
      *
      * Valid errors returned:
@@ -1581,7 +1584,7 @@
     oneway requestIsimAuthenticationResponse(RadioResponseInfo info, string response);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1591,7 +1594,7 @@
     oneway acknowledgeIncomingGsmSmsWithPduResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param iccIo IccIoResult as defined in types.hal corresponding to ICC IO response
      *
      * Valid errors returned:
@@ -1604,7 +1607,7 @@
     oneway sendEnvelopeWithStatusResponse(RadioResponseInfo info, IccIoResult iccIo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param rat Current voice RAT
      *
      * Valid errors returned:
@@ -1615,7 +1618,7 @@
     oneway getVoiceRadioTechnologyResponse(RadioResponseInfo info, RadioTechnology rat);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param cellInfo List of current cell information known to radio
      *
      * Valid errors returned:
@@ -1626,7 +1629,7 @@
     oneway getCellInfoListResponse(RadioResponseInfo info, vec<CellInfo> cellInfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1636,7 +1639,7 @@
     oneway setCellInfoListRateResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1647,7 +1650,7 @@
     oneway setInitialAttachApnResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param isRegistered false = not registered, true = registered
      * @param ratFamily RadioTechnologyFamily as defined in types.hal. This value is valid only if
      *        isRegistered is true.
@@ -1661,7 +1664,7 @@
             RadioTechnologyFamily ratFamily);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param sms Response to sms sent as defined by SendSmsResult in types.hal
      *
      * Valid errors returned:
@@ -1685,7 +1688,7 @@
     oneway sendImsSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      *
      * Valid errors returned:
@@ -1696,7 +1699,7 @@
     oneway iccTransmitApduBasicChannelResponse(RadioResponseInfo info, IccIoResult result);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param channelId session id of the logical channel.
      * @param selectResponse Contains the select response for the open channel command with one
      *        byte per integer
@@ -1712,7 +1715,7 @@
             vec<int8_t> selectResponse);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1722,7 +1725,7 @@
     oneway iccCloseLogicalChannelResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      *
      * Valid errors returned:
@@ -1733,7 +1736,7 @@
     oneway iccTransmitApduLogicalChannelResponse(RadioResponseInfo info, IccIoResult result);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param result string containing the contents of the NV item
      *
      * Valid errors returned:
@@ -1744,7 +1747,7 @@
     oneway nvReadItemResponse(RadioResponseInfo info, string result);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1754,7 +1757,7 @@
     oneway nvWriteItemResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1764,7 +1767,7 @@
     oneway nvWriteCdmaPrlResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1774,7 +1777,7 @@
     oneway nvResetConfigResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1785,7 +1788,7 @@
     oneway setUiccSubscriptionResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1795,7 +1798,7 @@
     oneway setDataAllowedResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param config Array of HardwareConfig of the radio.
      *
      * Valid errors returned:
@@ -1805,7 +1808,7 @@
     oneway getHardwareConfigResponse(RadioResponseInfo info, vec<HardwareConfig> config);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      *
      * Valid errors returned:
@@ -1815,7 +1818,7 @@
     oneway requestIccSimAuthenticationResponse(RadioResponseInfo info, IccIoResult result);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1825,7 +1828,7 @@
     oneway setDataProfileResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
@@ -1836,7 +1839,7 @@
     oneway requestShutdownResponse(RadioResponseInfo info);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param rc Radio capability as defined by RadioCapability in types.hal
      *
      * Valid errors returned:
@@ -1848,7 +1851,7 @@
     oneway getRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param rc Radio capability as defined by RadioCapability in types.hal used to
      *        feedback return status
      *
@@ -1861,7 +1864,7 @@
     oneway setRadioCapabilityResponse(RadioResponseInfo info, RadioCapability rc);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param statusInfo LceStatusInfo indicating LCE status
      *
      * Valid errors returned:
@@ -1872,7 +1875,7 @@
     oneway startLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param statusInfo LceStatusInfo indicating LCE status
      *
      * Valid errors returned:
@@ -1883,7 +1886,7 @@
     oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param lceInfo LceDataInfo indicating LCE data as defined in types.hal
      *
      * Valid errors returned:
@@ -1894,7 +1897,7 @@
     oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param activityInfo modem activity information
      *
      * Valid errors returned:
@@ -1905,7 +1908,7 @@
     oneway getModemActivityInfoResponse(RadioResponseInfo info, ActivityStatsInfo activityInfo);
 
     /*
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param numAllowed number of allowed carriers which have been set correctly.
      *        On success, it must match the length of list Carriers->allowedCarriers.
      *        if Length of allowed carriers list is 0, numAllowed = 0.
@@ -1922,7 +1925,7 @@
      * Expected modem behavior:
      *  Return list of allowed carriers, and if all carriers are allowed.
      *
-     * @param info Response info struct containing response type, serial no. & error
+     * @param info Response info struct containing response type, serial no. and error
      * @param allAllowed true only when all carriers are allowed. Ignore "carriers" struct.
      *        If false, consider "carriers" struct
      * @param carriers Carrier restriction information.
@@ -1942,5 +1945,5 @@
      *
      * @param serial Serial no. of the request whose acknowledgement is sent.
      */
-    oneway requestAcknowledgement(int32_t serial);
+    oneway acknowledgeRequest(int32_t serial);
 };
diff --git a/radio/1.0/ISapCallback.hal b/radio/1.0/ISapCallback.hal
index 5129648..6d80d6c 100644
--- a/radio/1.0/ISapCallback.hal
+++ b/radio/1.0/ISapCallback.hal
@@ -46,7 +46,6 @@
      * TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7
      *
      * @param token Id to match req-resp. Value must match the one in req.
-     * @param type APDU command type
      * @param resultCode ResultCode to indicate if command was processed correctly
      *        Possible values:
      *        SapResultCode:SUCCESS,
@@ -58,7 +57,6 @@
      *        occurred.
      */
     oneway apduResponse(int32_t token,
-                        SapApduType type,
                         SapResultCode resultCode,
                         vec<uint8_t> apduRsp);
 
@@ -123,7 +121,7 @@
      *        Possible values:
      *        SapResultCode:SUCCESS,
      *        SapResultCode:GENERIC_FAILURE
-     *        SapResultCode:CARD_ALREADY_POWERED_ON
+     *        SapResultCode:DATA_NOT_AVAILABLE
      * @param cardReaderStatus Card Reader Status coded as described in 3GPP TS 11.14 Section 12.33
      *        and TS 31.111 Section 8.33
      */
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 5b853b4..6475b4f 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -51,7 +51,6 @@
 };
 
 enum RadioError : int32_t {
-    INVALID_RESPONSE = -1,                // Response from vendor had invalid data
     NONE = 0,                             // Success
     RADIO_NOT_AVAILABLE = 1,              // If radio did not start or is resetting
     GENERIC_FAILURE = 2,
@@ -115,7 +114,8 @@
     NO_NETWORK_FOUND = 63,                // Network cannot be found
     DEVICE_IN_USE = 64,                   // Operation cannot be performed because the device
                                           // is currently in use
-    RIL_E_ABORTED = 65,                   // Operation aborted
+    ABORTED = 65,                         // Operation aborted
+    INVALID_RESPONSE = 66,                // Response from vendor had invalid data
 
     // TODO(May be moved to vendor HAL extension)
     // OEM specific error codes. To be used by OEM when they don't want to reveal
@@ -562,8 +562,6 @@
 };
 
 enum CallForwardInfoStatus : int32_t {
-    ACTIVE,
-    INACTIVE,
     DISABLE,
     ENABLE,
     INTERROGATE,
@@ -1080,7 +1078,7 @@
     string aidPtr;                        // e.g., from 0xA0, 0x00 -> 0x41,
                                           // 0x30, 0x30, 0x30
     string appLabelPtr;
-    int32_t pin1Replaced;                 // applicable to USIM, CSIM & ISIM
+    int32_t pin1Replaced;                 // applicable to USIM, CSIM and ISIM
     PinState pin1;
     PinState pin2;
 };
@@ -1126,6 +1124,11 @@
     vec<UusInfo> uusInfo;                 // Vector of User-User Signaling Information
 };
 
+struct LastCallFailCauseInfo {
+    LastCallFailCause causeCode;
+    string vendorCause;
+};
+
 struct GsmSignalStrength {
     uint32_t signalStrength;              // Valid values are (0-61, 99) as defined in
                                           // TS 27.007 8.69
@@ -1262,16 +1265,16 @@
 
 struct IccIo {
     int32_t command;                      // one of the commands listed for TS 27.007 +CRSM
-    int32_t fileid;                       // EF id
+    int32_t fileId;                       // EF id
     string path;                          // "pathid" from TS 27.007 +CRSM command.
                                           // Path is in hex asciii format eg "7f205f70"
                                           // Path must always be provided.
-    int32_t p1;                           // Values of p1, p2 & p3 defined as per 3GPP TS 51.011
+    int32_t p1;                           // Values of p1, p2 and p3 defined as per 3GPP TS 51.011
     int32_t p2;
     int32_t p3;
     string data;                          // information to be written to the SIM
     string pin2;
-    string aidPtr;                        // AID value, See ETSI 102.221 8.1 and 101.220 4, empty
+    string aid;                           // AID value, See ETSI 102.221 8.1 and 101.220 4, empty
                                           // string if no value.
 };
 
@@ -1405,7 +1408,7 @@
 // See also com.android.internal.telephony.gsm.CallForwardInfo
 struct CallForwardInfo {
     CallForwardInfoStatus status;         // For queryCallForwardStatus()
-                                          // status must be ACTIVE, INACTIVE
+                                          // status is DISABLE (Not used by vendor code currently)
                                           // For setCallForward():
                                           // status must be
                                           // DISABLE, ENABLE, INTERROGATE, REGISTRATION, ERASURE
@@ -1437,7 +1440,7 @@
 };
 
 struct CdmaSmsAddress {
-    CdmaSmsDigitMode digitMode;          // CdmaSmsDigitMode is of two types : 4 bit & 8 bit.
+    CdmaSmsDigitMode digitMode;          // CdmaSmsDigitMode is of two types : 4 bit and 8 bit.
                                          // For 4-bit type, only "digits" field defined below in
                                          // this struct is used.
     CdmaSmsNumberMode numberMode;        // Used only when digitMode is 8-bit
@@ -1613,7 +1616,7 @@
     bool registered;                     // true if this cell is registered false if not registered
     TimeStampType timeStampType;         // type of time stamp represented by timeStamp
     uint64_t timeStamp;                  // Time in nanos as returned by ril_nano_time
-    // Only one of the below vectors must be of size 1 based on the CellInfoType & others must be
+    // Only one of the below vectors must be of size 1 based on the CellInfoType and others must be
     // of size 0
     vec<CellInfoGsm> gsm;                // Valid only if type = gsm and size = 1 else must be empty
     vec<CellInfoCdma> cdma;              // Valid only if type = cdma and size = 1 else must be
@@ -1640,7 +1643,7 @@
     int32_t messageRef;                  // Valid field if retry is set to true.
                                          // Contains messageRef from SendSmsResult stuct
                                          // corresponding to failed MO SMS.
-    // Only one of the below vectors must be of size 1 based on the RadioTechnologyFamily & others
+    // Only one of the below vectors must be of size 1 based on the RadioTechnologyFamily and others
     // must be of size 0
     vec<CdmaSmsMessage> cdmaMessage;     // Valid field if tech is 3GPP2 and size = 1 else must be
                                          // empty
@@ -1649,7 +1652,7 @@
 };
 
 struct SimApdu {
-    int32_t sessionid;                   // "sessionid" from TS 27.007 +CGLA command. Must be
+    int32_t sessionId;                   // "sessionid" from TS 27.007 +CGLA command. Must be
                                          // ignored for +CSIM command.
     // Following fields are used to derive the APDU ("command" and "length"
     // values in TS 27.007 +CSIM and +CGLA commands).
@@ -1662,7 +1665,7 @@
 };
 
 struct NvWriteItem {
-    NvItem itemID;
+    NvItem itemId;
     string value;
 };
 
@@ -1786,9 +1789,7 @@
     bool isMT;                             // notification type
                                            // false = MO intermediate result code
                                            // true = MT unsolicited result code
-    bool isCode1;                          // See 27.007 7.17
-                                           // true = "code1" for MO
-                                           // false = "code2" for MT
+    int32_t code;                          // result code. See 27.007 7.17.
     int32_t index;                         // CUG index. See 27.007 7.17.
     int32_t type;                          // "type" from 27.007 7.17 (MT only).
     string number;                         // "number" from 27.007 7.17
@@ -1933,4 +1934,4 @@
                                          // to send all of them.
     vec<uint8_t> contents;               // Carrier-defined content. It is binary, opaque and
                                          // loosely defined in LTE Layer 3 spec 24.008
-};
\ No newline at end of file
+};
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
index ed65265..b5ee36a 100644
--- a/sensors/1.0/Android.bp
+++ b/sensors/1.0/Android.bp
@@ -54,3 +54,106 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.sensors.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.sensors@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+    srcs: [
+        "types.hal",
+        "ISensors.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/types.vts.cpp",
+        "android/hardware/sensors/1.0/Sensors.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.sensors.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.sensors@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+    srcs: [
+        "types.hal",
+        "ISensors.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/types.vts.h",
+        "android/hardware/sensors/1.0/Sensors.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.sensors.vts.driver@1.0",
+    generated_sources: ["android.hardware.sensors.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.sensors.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.sensors.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.sensors@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.sensors@1.0-ISensors-vts.profiler_genc++",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.sensors@1.0 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+    srcs: [
+        "ISensors.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/Sensors.vts.cpp",
+        "android/hardware/sensors/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.sensors@1.0-ISensors-vts.profiler_genc++_headers",
+    tools: ["hidl-gen", "vtsc"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.sensors@1.0 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/sensors/1.0/ $(genDir)/android/hardware/sensors/1.0/",
+    srcs: [
+        "ISensors.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/Sensors.vts.h",
+        "android/hardware/sensors/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.sensors@1.0-ISensors-vts.profiler",
+    generated_sources: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.sensors@1.0-ISensors-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.sensors@1.0",
+    ],
+}
diff --git a/sensors/1.0/vts/Android.mk b/sensors/1.0/vts/Android.mk
index df8d66f..e22fba7 100644
--- a/sensors/1.0/vts/Android.mk
+++ b/sensors/1.0/vts/Android.mk
@@ -16,68 +16,5 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Sensors v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_sensors@1.0
-
-LOCAL_SRC_FILES := \
-  Sensors.vts \
-  types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.sensors@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 sensors.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_sensors@1.0
-
-LOCAL_SRC_FILES := \
-  Sensors.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.sensors@1.0 \
-   libbase \
-   libutils \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
 # include hidl test makefiles
 include $(LOCAL_PATH)/functional/vts/testcases/hal/sensors/hidl/Android.mk
-
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml
index 66317f0..6329d5d 100644
--- a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml
@@ -25,6 +25,7 @@
             _64bit::DATA/nativetest64/sensors_hidl_hal_test/sensors_hidl_hal_test,
             "/>
         <option name="binary-test-type" value="gtest" />
+        <option name="binary-test-disable-framework" value="true" />
         <option name="test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index 6ef8ac2..e4c79fa 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -6,10 +6,12 @@
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
     srcs: [
         "IBar.hal",
+        "IComplicated.hal",
         "IImportTypes.hal",
     ],
     out: [
         "android/hardware/tests/bar/1.0/BarAll.cpp",
+        "android/hardware/tests/bar/1.0/ComplicatedAll.cpp",
         "android/hardware/tests/bar/1.0/ImportTypesAll.cpp",
     ],
 }
@@ -20,6 +22,7 @@
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
     srcs: [
         "IBar.hal",
+        "IComplicated.hal",
         "IImportTypes.hal",
     ],
     out: [
@@ -28,6 +31,11 @@
         "android/hardware/tests/bar/1.0/BnBar.h",
         "android/hardware/tests/bar/1.0/BpBar.h",
         "android/hardware/tests/bar/1.0/BsBar.h",
+        "android/hardware/tests/bar/1.0/IComplicated.h",
+        "android/hardware/tests/bar/1.0/IHwComplicated.h",
+        "android/hardware/tests/bar/1.0/BnComplicated.h",
+        "android/hardware/tests/bar/1.0/BpComplicated.h",
+        "android/hardware/tests/bar/1.0/BsComplicated.h",
         "android/hardware/tests/bar/1.0/IImportTypes.h",
         "android/hardware/tests/bar/1.0/IHwImportTypes.h",
         "android/hardware/tests/bar/1.0/BnImportTypes.h",
diff --git a/tests/bar/1.0/IBar.hal b/tests/bar/1.0/IBar.hal
index 21c3473..5f94d07 100644
--- a/tests/bar/1.0/IBar.hal
+++ b/tests/bar/1.0/IBar.hal
@@ -17,9 +17,12 @@
 package android.hardware.tests.bar@1.0;
 
 import android.hardware.tests.foo@1.0::IFoo;
+import android.hardware.tests.foo@1.0::ISimple;
 import android.hardware.tests.foo@1.0::Abc;
 import android.hardware.tests.foo@1.0::Unrelated;
 
+import IComplicated;
+
 interface IBar extends android.hardware.tests.foo@1.0::IFoo {
 
     typedef android.hardware.tests.foo@1.0::IFoo FunkyAlias;
@@ -33,4 +36,6 @@
     expectNullHandle(handle h, Abc xyz) generates (bool hIsNull, bool xyzHasNull);
     takeAMask(BitField bf, bitfield<BitField> first, MyMask second, Mask third)
             generates (BitField bf, uint8_t first, uint8_t second, uint8_t third);
+
+    haveAInterface(ISimple i) generates (ISimple i);
 };
diff --git a/tests/bar/1.0/IComplicated.hal b/tests/bar/1.0/IComplicated.hal
new file mode 100644
index 0000000..deaef8d
--- /dev/null
+++ b/tests/bar/1.0/IComplicated.hal
@@ -0,0 +1,22 @@
+/*
+ * 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.tests.bar@1.0;
+
+import android.hardware.tests.foo@1.0::ISimple;
+
+interface IComplicated extends ISimple {
+};
diff --git a/tests/bar/1.0/default/Bar.cpp b/tests/bar/1.0/default/Bar.cpp
index a750fe4..4152bb9 100644
--- a/tests/bar/1.0/default/Bar.cpp
+++ b/tests/bar/1.0/default/Bar.cpp
@@ -165,6 +165,13 @@
     return Void();
 }
 
+Return<void> Bar::haveAInterface(const sp<ISimple> &in,
+            haveAInterface_cb _hidl_cb) {
+    _hidl_cb(in);
+    return Void();
+}
+
+
 IBar* HIDL_FETCH_IBar(const char* /* name */) {
     return new Bar();
 }
diff --git a/tests/bar/1.0/default/Bar.h b/tests/bar/1.0/default/Bar.h
index 71737fe..70bffe7 100644
--- a/tests/bar/1.0/default/Bar.h
+++ b/tests/bar/1.0/default/Bar.h
@@ -71,6 +71,8 @@
 
     Return<void> takeAMask(BitField bf, uint8_t first, const MyMask& second, uint8_t third,
             takeAMask_cb _hidl_cb) override;
+    Return<void> haveAInterface(const sp<ISimple> &in,
+            haveAInterface_cb _hidl_cb) override;
 
 private:
     sp<IFoo> mFoo;
diff --git a/tests/baz/1.0/IBaz.hal b/tests/baz/1.0/IBaz.hal
index 3e1e2b9..a2d961a 100644
--- a/tests/baz/1.0/IBaz.hal
+++ b/tests/baz/1.0/IBaz.hal
@@ -49,6 +49,11 @@
     doStuffAndReturnAString() generates (string something);
     mapThisVector(vec<int32_t> param) generates (vec<int32_t> something);
     callMe(IBazCallback cb);
+
+    callMeLater(IBazCallback cb);
+    iAmFreeNow();
+    dieNow();
+
     useAnEnum(SomeEnum zzz) generates (SomeEnum kkk);
 
     haveSomeStrings(string[3] array) generates (string[2] result);
diff --git a/tests/baz/1.0/IBazCallback.hal b/tests/baz/1.0/IBazCallback.hal
index b59a107..503b970 100644
--- a/tests/baz/1.0/IBazCallback.hal
+++ b/tests/baz/1.0/IBazCallback.hal
@@ -18,4 +18,5 @@
 
 interface IBazCallback {
     heyItsMe(IBazCallback cb);
+    hey();
 };
diff --git a/tests/foo/1.0/ISimple.hal b/tests/foo/1.0/ISimple.hal
index 92e9d95..0d45835 100644
--- a/tests/foo/1.0/ISimple.hal
+++ b/tests/foo/1.0/ISimple.hal
@@ -18,4 +18,8 @@
 
 interface ISimple {
     getCookie() generates (int32_t cookie);
+    customVecInt() generates (vec<int32_t> chain);
+    customVecStr() generates (vec<string> chain);
+    mystr() generates (string str);
+    myhandle() generates (handle str);
 };
diff --git a/tests/msgq/1.0/ITestMsgQ.hal b/tests/msgq/1.0/ITestMsgQ.hal
index dcdc74a..933e39b 100644
--- a/tests/msgq/1.0/ITestMsgQ.hal
+++ b/tests/msgq/1.0/ITestMsgQ.hal
@@ -17,6 +17,11 @@
 package android.hardware.tests.msgq@1.0;
 
 interface ITestMsgQ {
+    enum EventFlagBits : uint32_t {
+        FMQ_NOT_EMPTY = 1 << 0,
+        FMQ_NOT_FULL  = 1 << 1,
+    };
+
     /*
      * This method requests the service to set up a synchronous read/write
      * wait-free FMQ with the client as reader.
@@ -26,7 +31,7 @@
      * set up by the service. Client can use it to set up the FMQ at its end.
      */
     configureFmqSyncReadWrite()
-        generates(bool ret, MQDescriptorSync mqDesc);
+        generates(bool ret, fmq_sync<uint16_t> mqDesc);
 
     /*
      * This method requests the service to set up an unsynchronized write
@@ -37,7 +42,7 @@
      * set up by the service. Client can use it to set up the FMQ at its end.
      */
     configureFmqUnsyncWrite()
-        generates(bool ret, MQDescriptorUnsync mqDesc);
+        generates(bool ret, fmq_unsync<uint16_t> mqDesc);
 
     /*
      * This method request the service to write into the synchronized read/write
@@ -79,4 +84,11 @@
      */
     requestReadFmqUnsync(int32_t count) generates(bool ret);
 
+    /*
+     * This method requests the service to trigger a blocking read.
+     *
+     * @param count Number of messages to read.
+     *
+     */
+    oneway requestBlockingRead(int32_t count);
 };
diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp
index c73ab42..f2c60da 100644
--- a/thermal/1.0/Android.bp
+++ b/thermal/1.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.thermal@1.0-IThermal-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+    srcs: [
+        "IThermal.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.0/Thermal.vts.cpp",
+        "android/hardware/thermal/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.thermal@1.0-IThermal-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/thermal/1.0/ $(genDir)/android/hardware/thermal/1.0/",
+    srcs: [
+        "IThermal.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.0/Thermal.vts.h",
+        "android/hardware/thermal/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.thermal@1.0-IThermal-vts.profiler",
+    generated_sources: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.thermal@1.0-IThermal-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.thermal@1.0",
+    ],
+}
diff --git a/thermal/1.0/vts/Android.mk b/thermal/1.0/vts/Android.mk
index ef926fe..60cc723 100644
--- a/thermal/1.0/vts/Android.mk
+++ b/thermal/1.0/vts/Android.mk
@@ -16,73 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for Thermal v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_thermal@1.0
-
-LOCAL_SRC_FILES := \
-  Thermal.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES := \
-  android.hardware.thermal@1.0 \
-  system/core/base/include \
-  system/core/include \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.thermal@1.0 \
-  libbase \
-  libutils \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_datatype \
-  libvts_measurement \
-  libvts_multidevice_proto \
-
-LOCAL_STATIC_LIBRARIES := \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-# build profiler for thermal.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_thermal@1.0
-
-LOCAL_SRC_FILES := \
-   Thermal.vts \
-   types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.thermal@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
diff --git a/thermal/1.0/vts/functional/Android.bp b/thermal/1.0/vts/functional/Android.bp
index fedb760..bef7bc2 100644
--- a/thermal/1.0/vts/functional/Android.bp
+++ b/thermal/1.0/vts/functional/Android.bp
@@ -31,8 +31,12 @@
     ],
     static_libs: ["libgtest"],
     cflags: [
+        "--coverage",
         "-O0",
         "-g",
     ],
+    ldflags: [
+        "--coverage"
+    ]
 }
 
diff --git a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
index 169264d..3594745 100644
--- a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
+++ b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/AndroidTest.xml
@@ -26,6 +26,8 @@
             "/>
         <option name="binary-test-type" value="gtest" />
         <option name="test-timeout" value="5m" />
+        <option name="test-config-path"
+            value="vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config" />
     </test>
 </configuration>
 
diff --git a/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config
new file mode 100644
index 0000000..0d19619
--- /dev/null
+++ b/thermal/1.0/vts/functional/vts/testcases/hal/thermal/hidl/target/ThermalHidlBasicTest.config
@@ -0,0 +1,25 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [{
+                    "module_name": "system/lib64/hw/thermal.bullhead",
+                    "git_project": {
+                        "name": "device/lge/bullhead",
+                        "path": "device/lge/bullhead"
+                    }
+                },
+                {
+                    "module_name": "system/lib64/hw/thermal.marlin",
+                    "git_project": {
+                        "name": "device/google/marlin",
+                        "path": "device/google/marlin"
+                    }
+                },
+                {
+                    "module_name": "system/lib64/hw/android.hardware.thermal@1.0-impl",
+                    "git_project": {
+                        "name": "platform/hardware/interfaces",
+                        "path": "hardware/interfaces"
+                    }
+                }]
+}
diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp
index b6dc3b1..4c98cb9 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -124,3 +124,93 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "IHdmiCec.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/HdmiCec.vts.cpp",
+        "android/hardware/tv/cec/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "IHdmiCec.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/HdmiCec.vts.h",
+        "android/hardware/tv/cec/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler",
+    generated_sources: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCec-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.tv.cec@1.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "IHdmiCecCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.cpp",
+        "android/hardware/tv/cec/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/tv/cec/1.0/ $(genDir)/android/hardware/tv/cec/1.0/",
+    srcs: [
+        "IHdmiCecCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/tv/cec/1.0/HdmiCecCallback.vts.h",
+        "android/hardware/tv/cec/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler",
+    generated_sources: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.tv.cec@1.0-IHdmiCecCallback-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.tv.cec@1.0",
+    ],
+}
diff --git a/tv/cec/1.0/vts/Android.mk b/tv/cec/1.0/vts/Android.mk
index a7eeb33..60cc723 100644
--- a/tv/cec/1.0/vts/Android.mk
+++ b/tv/cec/1.0/vts/Android.mk
@@ -16,73 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS profiler for HdmiCec
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_cec@1.0
-
-LOCAL_SRC_FILES := \
-  HdmiCec.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.cec@1.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# build VTS profiler for HdmiCecCallback
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_cec_callback_@1.0
-
-LOCAL_SRC_FILES := \
-  HdmiCecCallback.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.cec@1.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
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
index ba062d9..cd2374a 100644
--- 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
@@ -34,11 +34,15 @@
         self.dut.shell.InvokeTerminal("one")
         self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
 
+        self.dut.shell.one.Execute(
+            "setprop vts.hal.vts.hidl.get_stub true")
+
         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",
+                                 hw_binder_service_name="tv.cec",
                                  bits=64)
 
     def testGetCecVersion1(self):
diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp
index 21d8893..94dcdc9 100644
--- a/tv/input/1.0/Android.bp
+++ b/tv/input/1.0/Android.bp
@@ -64,3 +64,67 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.tv.input.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.input@1.0 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/tv/input/1.0/ $(genDir)/android/hardware/tv/input/1.0/",
+    srcs: [
+        "types.hal",
+        "ITvInput.hal",
+        "ITvInputCallback.hal",
+    ],
+    out: [
+        "android/hardware/tv/input/1.0/types.vts.cpp",
+        "android/hardware/tv/input/1.0/TvInput.vts.cpp",
+        "android/hardware/tv/input/1.0/TvInputCallback.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.tv.input.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.input@1.0 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/tv/input/1.0/ $(genDir)/android/hardware/tv/input/1.0/",
+    srcs: [
+        "types.hal",
+        "ITvInput.hal",
+        "ITvInputCallback.hal",
+    ],
+    out: [
+        "android/hardware/tv/input/1.0/types.vts.h",
+        "android/hardware/tv/input/1.0/TvInput.vts.h",
+        "android/hardware/tv/input/1.0/TvInputCallback.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.tv.input.vts.driver@1.0",
+    generated_sources: ["android.hardware.tv.input.vts.driver@1.0_genc++"],
+    generated_headers: ["android.hardware.tv.input.vts.driver@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.tv.input.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.hardware.audio.common@2.0",
+        "android.hidl.base@1.0",
+        "android.hardware.tv.input@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.audio.common@2.0",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/tv/input/1.0/Android.mk b/tv/input/1.0/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/input/1.0/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/input/1.0/vts/Android.mk b/tv/input/1.0/vts/Android.mk
index f8610dd..040cfce 100644
--- a/tv/input/1.0/vts/Android.mk
+++ b/tv/input/1.0/vts/Android.mk
@@ -16,107 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build VTS driver for TvInput v1.0.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_driver_hidl_tv_input@1.0
-
-LOCAL_SRC_FILES := \
-  TvInput.vts \
-  TvInputCallback.vts \
-  types.vts \
-  ../../../../audio/common/2.0/vts/types.vts \
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.input@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 TvInput
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_input@1.0
-
-LOCAL_SRC_FILES := \
-  TvInput.vts \
-  types.vts \
-  ../../../../audio/common/2.0/vts/types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.input@1.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# build VTS profiler for TvInputCallback
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_tv_input_callback_@1.0
-
-LOCAL_SRC_FILES := \
-  TvInputCallback.vts \
-  types.vts \
-  ../../../../audio/common/2.0/vts/types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES += \
-  android.hardware.tv.input@1.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
+include $(LOCAL_PATH)/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk
diff --git a/tv/input/1.0/vts/TvInput.vts b/tv/input/1.0/vts/TvInput.vts
index 638fd08..73b322a 100644
--- a/tv/input/1.0/vts/TvInput.vts
+++ b/tv/input/1.0/vts/TvInput.vts
@@ -57,6 +57,7 @@
             predefined_type: "::android::hardware::tv::input::V1_0::Result"
         }
         return_type_hidl: {
+            type: TYPE_HANDLE
         }
         arg: {
             type: TYPE_SCALAR
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/__init__.py b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/__init__.py
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/Android.mk b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/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/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/__init__.py b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/__init__.py
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk
new file mode 100644
index 0000000..2703d8c
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/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 := TvInputHidlTest
+VTS_CONFIG_SRC_DIR := testcases/hal/tv_input/hidl/host
+include test/vts/tools/build/Android.host_config.mk
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/AndroidTest.xml b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/AndroidTest.xml
new file mode 100644
index 0000000..8fdd72d
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/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/input/1.0/vts/TvInput.vts->/data/local/tmp/spec/TvInput.vts" />
+        <option name="push" value="spec/hardware/interfaces/tv/input/1.0/vts/TvInputCallback.vts->/data/local/tmp/spec/TvInputCallback.vts" />
+        <option name="push" value="spec/hardware/interfaces/tv/input/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="TvInputHidlTest" />
+        <option name="test-case-path" value="vts/testcases/hal/tv_input/hidl/host/TvInputHidlTest" />
+    </test>
+</configuration>
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/TvInputHidlTest.py b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/TvInputHidlTest.py
new file mode 100644
index 0000000..c99c82c
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/TvInputHidlTest.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 TvInputHidlTest(base_test_with_webdb.BaseTestWithWebDbClass):
+    """Two hello world test cases which use the shell driver."""
+
+    def setUpClass(self):
+        """Creates a mirror and init tv input hal."""
+        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_input",
+                                 target_basepaths=["/system/lib64"],
+                                 target_version=1.0,
+                                 target_package="android.hardware.tv.input",
+                                 target_component_name="ITvInput",
+                                 bits=64)
+
+        self.dut.shell.InvokeTerminal("one")
+
+    def testGetStreamConfigurations(self):
+        configs = self.dut.hal.tv_input.getStreamConfigurations(0)
+        logging.info('tv input configs: %s', configs)
+
+
+if __name__ == "__main__":
+    test_runner.main()
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/__init__.py b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/__init__.py
diff --git a/tv/input/1.0/vts/types.vts b/tv/input/1.0/vts/types.vts
index 67d84db..d03e065 100644
--- a/tv/input/1.0/vts/types.vts
+++ b/tv/input/1.0/vts/types.vts
@@ -133,7 +133,7 @@
         }
         enumerator: "PUBLIC_CNT"
         scalar_value: {
-            int32_t: 10
+            int32_t: 11
         }
         enumerator: "FOR_POLICY_CNT"
         scalar_value: {
@@ -310,6 +310,82 @@
         scalar_value: {
             uint32_t: 234881024
         }
+        enumerator: "EVRC"
+        scalar_value: {
+            uint32_t: 268435456
+        }
+        enumerator: "EVRCB"
+        scalar_value: {
+            uint32_t: 285212672
+        }
+        enumerator: "EVRCWB"
+        scalar_value: {
+            uint32_t: 301989888
+        }
+        enumerator: "EVRCNW"
+        scalar_value: {
+            uint32_t: 318767104
+        }
+        enumerator: "AAC_ADIF"
+        scalar_value: {
+            uint32_t: 335544320
+        }
+        enumerator: "WMA"
+        scalar_value: {
+            uint32_t: 352321536
+        }
+        enumerator: "WMA_PRO"
+        scalar_value: {
+            uint32_t: 369098752
+        }
+        enumerator: "AMR_WB_PLUS"
+        scalar_value: {
+            uint32_t: 385875968
+        }
+        enumerator: "MP2"
+        scalar_value: {
+            uint32_t: 402653184
+        }
+        enumerator: "QCELP"
+        scalar_value: {
+            uint32_t: 419430400
+        }
+        enumerator: "DSD"
+        scalar_value: {
+            uint32_t: 436207616
+        }
+        enumerator: "FLAC"
+        scalar_value: {
+            uint32_t: 452984832
+        }
+        enumerator: "ALAC"
+        scalar_value: {
+            uint32_t: 469762048
+        }
+        enumerator: "APE"
+        scalar_value: {
+            uint32_t: 486539264
+        }
+        enumerator: "AAC_ADTS"
+        scalar_value: {
+            uint32_t: 503316480
+        }
+        enumerator: "SBC"
+        scalar_value: {
+            uint32_t: 520093696
+        }
+        enumerator: "APTX"
+        scalar_value: {
+            uint32_t: 536870912
+        }
+        enumerator: "APTX_HD"
+        scalar_value: {
+            uint32_t: 553648128
+        }
+        enumerator: "LDAC"
+        scalar_value: {
+            uint32_t: 570425344
+        }
         enumerator: "MAIN_MASK"
         scalar_value: {
             uint32_t: 4278190080
@@ -458,6 +534,46 @@
         scalar_value: {
             uint32_t: 67109376
         }
+        enumerator: "AAC_ADTS_MAIN"
+        scalar_value: {
+            uint32_t: 503316481
+        }
+        enumerator: "AAC_ADTS_LC"
+        scalar_value: {
+            uint32_t: 503316482
+        }
+        enumerator: "AAC_ADTS_SSR"
+        scalar_value: {
+            uint32_t: 503316484
+        }
+        enumerator: "AAC_ADTS_LTP"
+        scalar_value: {
+            uint32_t: 503316488
+        }
+        enumerator: "AAC_ADTS_HE_V1"
+        scalar_value: {
+            uint32_t: 503316496
+        }
+        enumerator: "AAC_ADTS_SCALABLE"
+        scalar_value: {
+            uint32_t: 503316512
+        }
+        enumerator: "AAC_ADTS_ERLC"
+        scalar_value: {
+            uint32_t: 503316544
+        }
+        enumerator: "AAC_ADTS_LD"
+        scalar_value: {
+            uint32_t: 503316608
+        }
+        enumerator: "AAC_ADTS_HE_V2"
+        scalar_value: {
+            uint32_t: 503316736
+        }
+        enumerator: "AAC_ADTS_ELD"
+        scalar_value: {
+            uint32_t: 503316992
+        }
     }
 }
 
@@ -580,6 +696,10 @@
         scalar_value: {
             uint32_t: 3
         }
+        enumerator: "OUT_2POINT1"
+        scalar_value: {
+            uint32_t: 11
+        }
         enumerator: "OUT_QUAD"
         scalar_value: {
             uint32_t: 51
@@ -592,6 +712,14 @@
         scalar_value: {
             uint32_t: 1539
         }
+        enumerator: "OUT_SURROUND"
+        scalar_value: {
+            uint32_t: 263
+        }
+        enumerator: "OUT_PENTA"
+        scalar_value: {
+            uint32_t: 55
+        }
         enumerator: "OUT_5POINT1"
         scalar_value: {
             uint32_t: 63
@@ -604,6 +732,10 @@
         scalar_value: {
             uint32_t: 1551
         }
+        enumerator: "OUT_6POINT1"
+        scalar_value: {
+            uint32_t: 319
+        }
         enumerator: "OUT_7POINT1"
         scalar_value: {
             uint32_t: 1599
@@ -680,6 +812,18 @@
         scalar_value: {
             uint32_t: 48
         }
+        enumerator: "IN_VOICE_UPLINK_MONO"
+        scalar_value: {
+            uint32_t: 16400
+        }
+        enumerator: "IN_VOICE_DNLINK_MONO"
+        scalar_value: {
+            uint32_t: 32784
+        }
+        enumerator: "IN_VOICE_CALL_MONO"
+        scalar_value: {
+            uint32_t: 49168
+        }
         enumerator: "IN_ALL"
         scalar_value: {
             uint32_t: 65532
@@ -907,13 +1051,17 @@
         scalar_value: {
             uint32_t: 16777216
         }
+        enumerator: "OUT_PROXY"
+        scalar_value: {
+            uint32_t: 33554432
+        }
         enumerator: "OUT_DEFAULT"
         scalar_value: {
             uint32_t: 1073741824
         }
         enumerator: "OUT_ALL"
         scalar_value: {
-            uint32_t: 1107296255
+            uint32_t: 1140850687
         }
         enumerator: "OUT_ALL_A2DP"
         scalar_value: {
@@ -1019,13 +1167,17 @@
         scalar_value: {
             uint32_t: 2148532224
         }
+        enumerator: "IN_PROXY"
+        scalar_value: {
+            uint32_t: 2164260864
+        }
         enumerator: "IN_DEFAULT"
         scalar_value: {
             uint32_t: 3221225472
         }
         enumerator: "IN_ALL"
         scalar_value: {
-            uint32_t: 3223322623
+            uint32_t: 3240099839
         }
         enumerator: "IN_ALL_SCO"
         scalar_value: {
@@ -1092,6 +1244,14 @@
         scalar_value: {
             int32_t: 1024
         }
+        enumerator: "DIRECT_PCM"
+        scalar_value: {
+            int32_t: 8192
+        }
+        enumerator: "MMAP_NOIRQ"
+        scalar_value: {
+            int32_t: 16384
+        }
     }
 }
 
@@ -1121,6 +1281,91 @@
         scalar_value: {
             int32_t: 8
         }
+        enumerator: "MMAP_NOIRQ"
+        scalar_value: {
+            int32_t: 16
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::audio::common::V2_0::AudioUsage"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "UNKNOWN"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "MEDIA"
+        scalar_value: {
+            int32_t: 1
+        }
+        enumerator: "VOICE_COMMUNICATION"
+        scalar_value: {
+            int32_t: 2
+        }
+        enumerator: "VOICE_COMMUNICATION_SIGNALLING"
+        scalar_value: {
+            int32_t: 3
+        }
+        enumerator: "ALARM"
+        scalar_value: {
+            int32_t: 4
+        }
+        enumerator: "NOTIFICATION"
+        scalar_value: {
+            int32_t: 5
+        }
+        enumerator: "NOTIFICATION_TELEPHONY_RINGTONE"
+        scalar_value: {
+            int32_t: 6
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_REQUEST"
+        scalar_value: {
+            int32_t: 7
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_INSTANT"
+        scalar_value: {
+            int32_t: 8
+        }
+        enumerator: "NOTIFICATION_COMMUNICATION_DELAYED"
+        scalar_value: {
+            int32_t: 9
+        }
+        enumerator: "NOTIFICATION_EVENT"
+        scalar_value: {
+            int32_t: 10
+        }
+        enumerator: "ASSISTANCE_ACCESSIBILITY"
+        scalar_value: {
+            int32_t: 11
+        }
+        enumerator: "ASSISTANCE_NAVIGATION_GUIDANCE"
+        scalar_value: {
+            int32_t: 12
+        }
+        enumerator: "ASSISTANCE_SONIFICATION"
+        scalar_value: {
+            int32_t: 13
+        }
+        enumerator: "GAME"
+        scalar_value: {
+            int32_t: 14
+        }
+        enumerator: "VIRTUAL_SOURCE"
+        scalar_value: {
+            int32_t: 15
+        }
+        enumerator: "CNT"
+        scalar_value: {
+            int32_t: 16
+        }
+        enumerator: "MAX"
+        scalar_value: {
+            int32_t: 15
+        }
     }
 }
 
@@ -1167,6 +1412,21 @@
         type: TYPE_SCALAR
         scalar_type: "bool_t"
     }
+    struct_value: {
+        name: "bitWidth"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "bufferSize"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "usage"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::audio::common::V2_0::AudioUsage"
+    }
 }
 
 attribute: {
diff --git a/update-makefiles.sh b/update-makefiles.sh
index f153a84..d0cb91c 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -20,7 +20,9 @@
 for p in $packages; do
   echo "Updating $p";
   hidl-gen -Lmakefile -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
+  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
   hidl-gen -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
+  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
 done
 
 # subdirectories of hardware/interfaces which contain an Android.bp file
diff --git a/vehicle/2.0/Android.bp b/vehicle/2.0/Android.bp
index 571ef2b..04dfd5a 100644
--- a/vehicle/2.0/Android.bp
+++ b/vehicle/2.0/Android.bp
@@ -124,3 +124,93 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vehicle@2.0-IVehicle-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "IVehicle.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/Vehicle.vts.cpp",
+        "android/hardware/vehicle/2.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vehicle@2.0-IVehicle-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "IVehicle.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/Vehicle.vts.h",
+        "android/hardware/vehicle/2.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vehicle@2.0-IVehicle-vts.profiler",
+    generated_sources: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.vehicle@2.0-IVehicle-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vehicle@2.0",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "IVehicleCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/VehicleCallback.vts.cpp",
+        "android/hardware/vehicle/2.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/vehicle/2.0/ $(genDir)/android/hardware/vehicle/2.0/",
+    srcs: [
+        "IVehicleCallback.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vehicle/2.0/VehicleCallback.vts.h",
+        "android/hardware/vehicle/2.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler",
+    generated_sources: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.vehicle@2.0-IVehicleCallback-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vehicle@2.0",
+    ],
+}
diff --git a/vehicle/2.0/Android.mk b/vehicle/2.0/Android.mk
index dc4d25c..9544960 100644
--- a/vehicle/2.0/Android.mk
+++ b/vehicle/2.0/Android.mk
@@ -17,6 +17,177 @@
 
 
 #
+# Build types.hal (CommonIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/CommonIgnitionMonitors.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.vehicle@2.0::types.CommonIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (CompressionIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/CompressionIgnitionMonitors.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.vehicle@2.0::types.CompressionIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (FuelSystemStatus)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/FuelSystemStatus.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.vehicle@2.0::types.FuelSystemStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (FuelType)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/FuelType.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.vehicle@2.0::types.FuelType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (IgnitionMonitorKind)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/IgnitionMonitorKind.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.vehicle@2.0::types.IgnitionMonitorKind
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Obd2FloatSensorIndex)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Obd2FloatSensorIndex.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.vehicle@2.0::types.Obd2FloatSensorIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Obd2IntegerSensorIndex)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Obd2IntegerSensorIndex.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.vehicle@2.0::types.Obd2IntegerSensorIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SecondaryAirStatus)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/SecondaryAirStatus.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.vehicle@2.0::types.SecondaryAirStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SparkIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/SparkIgnitionMonitors.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.vehicle@2.0::types.SparkIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (StatusCode)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/StatusCode.java
@@ -663,6 +834,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VehicleIgnitionState)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleIgnitionState.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.vehicle@2.0::types.VehicleIgnitionState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VehicleInstrumentClusterType)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleInstrumentClusterType.java
@@ -682,25 +872,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VehiclePermissionModel)
-#
-GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePermissionModel.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.vehicle@2.0::types.VehiclePermissionModel
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (VehiclePropConfig)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePropConfig.java
@@ -970,6 +1141,177 @@
 
 
 #
+# Build types.hal (CommonIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/CommonIgnitionMonitors.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.vehicle@2.0::types.CommonIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (CompressionIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/CompressionIgnitionMonitors.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.vehicle@2.0::types.CompressionIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (FuelSystemStatus)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/FuelSystemStatus.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.vehicle@2.0::types.FuelSystemStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (FuelType)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/FuelType.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.vehicle@2.0::types.FuelType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (IgnitionMonitorKind)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/IgnitionMonitorKind.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.vehicle@2.0::types.IgnitionMonitorKind
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Obd2FloatSensorIndex)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Obd2FloatSensorIndex.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.vehicle@2.0::types.Obd2FloatSensorIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Obd2IntegerSensorIndex)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Obd2IntegerSensorIndex.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.vehicle@2.0::types.Obd2IntegerSensorIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SecondaryAirStatus)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/SecondaryAirStatus.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.vehicle@2.0::types.SecondaryAirStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SparkIgnitionMonitors)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/SparkIgnitionMonitors.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.vehicle@2.0::types.SparkIgnitionMonitors
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (StatusCode)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/StatusCode.java
@@ -1616,6 +1958,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VehicleIgnitionState)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleIgnitionState.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.vehicle@2.0::types.VehicleIgnitionState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VehicleInstrumentClusterType)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehicleInstrumentClusterType.java
@@ -1635,25 +1996,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VehiclePermissionModel)
-#
-GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePermissionModel.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.vehicle@2.0::types.VehiclePermissionModel
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (VehiclePropConfig)
 #
 GEN := $(intermediates)/android/hardware/vehicle/V2_0/VehiclePropConfig.java
diff --git a/vehicle/2.0/default/VehicleService.cpp b/vehicle/2.0/default/VehicleService.cpp
index 651a2ad..493df74 100644
--- a/vehicle/2.0/default/VehicleService.cpp
+++ b/vehicle/2.0/default/VehicleService.cpp
@@ -16,10 +16,10 @@
 
 #define LOG_TAG "android.hardware.vehicle@2.0-service"
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 
 #include <iostream>
 
-#include <hwbinder/IPCThreadState.h>
 
 #include <vehicle_hal_manager/VehicleHalManager.h>
 #include <impl/DefaultVehicleHal.h>
@@ -32,11 +32,11 @@
     auto hal = std::make_unique<impl::DefaultVehicleHal>();
     auto service = std::make_unique<VehicleHalManager>(hal.get());
 
+    configureRpcThreadpool(1, true /* callerWillJoin */);
+
     ALOGI("Registering as service...");
     service->registerAsService("Vehicle");
 
     ALOGI("Ready");
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
+    joinRpcThreadpool();
 }
diff --git a/vehicle/2.0/default/impl/DefaultConfig.h b/vehicle/2.0/default/impl/DefaultConfig.h
index e4ca5ca..77ee9d4 100644
--- a/vehicle/2.0/default/impl/DefaultConfig.h
+++ b/vehicle/2.0/default/impl/DefaultConfig.h
@@ -32,14 +32,12 @@
         .prop = VehicleProperty::INFO_MAKE,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::STATIC,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
     },
 
     {
         .prop = VehicleProperty::HVAC_POWER_ON,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1)
     },
 
@@ -47,7 +45,6 @@
         .prop = VehicleProperty::HVAC_DEFROSTER,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas =
                 VehicleAreaWindow::FRONT_WINDSHIELD
                 | VehicleAreaWindow::REAR_WINDSHIELD
@@ -57,7 +54,6 @@
         .prop = VehicleProperty::HVAC_RECIRC_ON,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1)
     },
 
@@ -65,7 +61,6 @@
         .prop = VehicleProperty::HVAC_AC_ON,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1)
     },
 
@@ -73,7 +68,6 @@
         .prop = VehicleProperty::HVAC_AUTO_ON,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1)
     },
 
@@ -81,7 +75,6 @@
         .prop = VehicleProperty::HVAC_FAN_SPEED,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1),
         .areaConfigs = {
             VehicleAreaConfig {
@@ -96,7 +89,6 @@
         .prop = VehicleProperty::HVAC_FAN_DIRECTION,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = toInt(VehicleAreaZone::ROW_1),
     },
 
@@ -104,7 +96,6 @@
         .prop = VehicleProperty::HVAC_TEMPERATURE_SET,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas =
                 VehicleAreaZone::ROW_1_LEFT
                 | VehicleAreaZone::ROW_1_RIGHT,
@@ -126,28 +117,24 @@
         .prop = VehicleProperty::NIGHT_MODE,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
     },
 
     {
         .prop = VehicleProperty::DRIVING_STATUS,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
     },
 
     {
         .prop = VehicleProperty::GEAR_SELECTION,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
     },
 
     {
         .prop = VehicleProperty::INFO_FUEL_CAPACITY,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
         .areaConfigs = {
             VehicleAreaConfig {
                 .minFloatValue = 0,
@@ -160,13 +147,18 @@
         .prop = VehicleProperty::DISPLAY_BRIGHTNESS,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
         .areaConfigs = {
             VehicleAreaConfig {
                 .minInt32Value = 0,
                 .maxInt32Value = 10
             }
         }
+    },
+
+    {
+        .prop = VehicleProperty::IGNITION_STATE,
+        .access = VehiclePropertyAccess::READ,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
     }
 };
 
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
index 4e27bdc..6cbcfe3 100644
--- a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
@@ -87,6 +87,9 @@
         case VehicleProperty::DRIVING_STATUS:
             v = pool.obtainInt32(toInt(VehicleDrivingStatus::UNRESTRICTED));
             break;
+        case VehicleProperty::IGNITION_STATE:
+            v = pool.obtainInt32(toInt(VehicleIgnitionState::ACC));
+            break;
         default:
             *outStatus = StatusCode::INVALID_ARG;
     }
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 964c7c8..dffcfbb 100644
--- a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -67,6 +67,14 @@
                     pValue = getValuePool()->obtainFloat(42.42);
                 }
                 break;
+            case VehicleProperty::VEHICLE_MAPS_DATA_SERVICE:
+                pValue = getValuePool()->obtainComplex();
+                pValue->value.int32Values = hidl_vec<int32_t> { 10, 20 };
+                pValue->value.int64Values = hidl_vec<int64_t> { 30, 40 };
+                pValue->value.floatValues = hidl_vec<float_t> { 1.1, 2.2 };
+                pValue->value.bytes = hidl_vec<uint8_t> { 1, 2, 3 };
+                pValue->value.stringValue = kCarMake;
+                break;
             default:
                 auto key = makeKey(property, areaId);
                 if (mValues.count(key) == 0) {
@@ -308,6 +316,32 @@
     ASSERT_EQ(StatusCode::OK, res);
 }
 
+TEST_F(VehicleHalManagerTest, get_Complex) {
+    invokeGet(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, 0);
+
+    ASSERT_EQ(StatusCode::OK, actualStatusCode);
+    ASSERT_EQ(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, actualValue.prop);
+
+    ASSERT_EQ(3, actualValue.value.bytes.size());
+    ASSERT_EQ(1, actualValue.value.bytes[0]);
+    ASSERT_EQ(2, actualValue.value.bytes[1]);
+    ASSERT_EQ(3, actualValue.value.bytes[2]);
+
+    ASSERT_EQ(2, actualValue.value.int32Values.size());
+    ASSERT_EQ(10, actualValue.value.int32Values[0]);
+    ASSERT_EQ(20, actualValue.value.int32Values[1]);
+
+    ASSERT_EQ(2, actualValue.value.floatValues.size());
+    ASSERT_FLOAT_EQ(1.1, actualValue.value.floatValues[0]);
+    ASSERT_FLOAT_EQ(2.2, actualValue.value.floatValues[1]);
+
+    ASSERT_EQ(2, actualValue.value.int64Values.size());
+    ASSERT_FLOAT_EQ(30, actualValue.value.int64Values[0]);
+    ASSERT_FLOAT_EQ(40, actualValue.value.int64Values[1]);
+
+    ASSERT_STREQ(kCarMake, actualValue.value.stringValue.c_str());
+}
+
 TEST_F(VehicleHalManagerTest, get_StaticString) {
     invokeGet(VehicleProperty::INFO_MAKE, 0);
 
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index 586b5ab..e1e355e 100644
--- a/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -32,7 +32,6 @@
         .prop = VehicleProperty::INFO_MAKE,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::STATIC,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
         .configString = "Some=config,options=if,you=have_any",
     },
 
@@ -40,7 +39,6 @@
         .prop = VehicleProperty::HVAC_FAN_SPEED,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = static_cast<int32_t>(
             VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
         .areaConfigs = {
@@ -61,7 +59,6 @@
         .prop = VehicleProperty::HVAC_SEAT_TEMPERATURE,
         .access = VehiclePropertyAccess::WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_SET,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
         .supportedAreas = static_cast<int32_t>(
             VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
         .areaConfigs = {
@@ -81,7 +78,6 @@
         .prop = VehicleProperty::INFO_FUEL_CAPACITY,
         .access = VehiclePropertyAccess::READ,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
         .areaConfigs = {
             VehicleAreaConfig {
                 .minFloatValue = 0,
@@ -94,7 +90,6 @@
         .prop = VehicleProperty::DISPLAY_BRIGHTNESS,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
         .areaConfigs = {
             VehicleAreaConfig {
                 .minInt32Value = 0,
@@ -107,8 +102,14 @@
         .prop = VehicleProperty::MIRROR_FOLD,
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
 
+    },
+
+    // Complex data type.
+    {
+        .prop = VehicleProperty::VEHICLE_MAPS_DATA_SERVICE,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE
     }
 };
 
@@ -238,7 +239,6 @@
        << "  prop: " << enumToHexString(config.prop) << ",\n"
        << "  supportedAreas: " << hexString(config.supportedAreas) << ",\n"
        << "  access: " << enumToHexString(config.access) << ",\n"
-       << "  permissionModel: " << enumToHexString(config.permissionModel) << ",\n"
        << "  changeMode: " << enumToHexString(config.changeMode) << ",\n"
        << "  configFlags: " << hexString(config.configFlags) << ",\n"
        << "  minSampleRate: " << config.minSampleRate << ",\n"
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
index 70b93e7..463b333 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.cpp
@@ -80,6 +80,10 @@
     return val;
 }
 
+VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
+    return obtain(VehiclePropertyType::COMPLEX);
+}
+
 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
         VehiclePropertyType type, size_t vecSize) {
     // VehiclePropertyType is not overlapping with vectorSize.
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
index 1ca9211..d9231c3 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
@@ -184,13 +184,15 @@
     RecyclableType obtainInt64(int64_t value);
     RecyclableType obtainFloat(float value);
     RecyclableType obtainString(const char* cstr);
+    RecyclableType obtainComplex();
 
     VehiclePropValuePool(VehiclePropValuePool& ) = delete;
     VehiclePropValuePool& operator=(VehiclePropValuePool&) = delete;
 private:
     bool isDisposable(VehiclePropertyType type, size_t vecSize) const {
         return vecSize > mMaxRecyclableVectorSize ||
-               VehiclePropertyType::STRING == type;
+               VehiclePropertyType::STRING == type ||
+               VehiclePropertyType::COMPLEX == type;
     }
 
     RecyclableType obtainDisposable(VehiclePropertyType valueType,
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
index c461833..ab1d908 100644
--- a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.cpp
@@ -47,6 +47,7 @@
             val->value.bytes.resize(vecSize);
             break;
         case VehiclePropertyType::STRING:
+        case VehiclePropertyType::COMPLEX:
             break; // Valid, but nothing to do.
         default:
             ALOGE("createVehiclePropValue: unknown type: %d", type);
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index 72fa554..d98a982 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -31,6 +31,12 @@
     FLOAT_VEC      = 0x00610000,
     BYTES          = 0x00700000,
 
+    /*
+     * Any combination of scalar or vector types. The exact format must be
+     * provided in the description of the property.
+     */
+    COMPLEX        = 0x00e00000,
+
     MASK           = 0x00ff0000
 };
 
@@ -310,6 +316,18 @@
         | VehicleArea:GLOBAL),
 
     /*
+     * Represents ignition state
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ
+     */
+    IGNITION_STATE = (
+        0x0409
+            | VehiclePropertyGroup:SYSTEM
+            | VehiclePropertyType:INT32
+            | VehicleArea:GLOBAL),
+
+    /*
      * Fan speed setting
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
@@ -1614,6 +1632,18 @@
         | VehiclePropertyGroup:SYSTEM
         | VehiclePropertyType:BOOLEAN
         | VehicleArea:GLOBAL),
+
+    /*
+     * Vehicle Maps Data Service (VMDS) message
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    VEHICLE_MAPS_DATA_SERVICE = (
+        0x0C00
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:COMPLEX
+        | VehicleArea:GLOBAL),
 };
 
 /*
@@ -2144,30 +2174,6 @@
 };
 
 /*
- * These permissions define how the OEMs want to distribute their information
- * and security they want to apply. On top of these restrictions, android will
- * have additional 'app-level' permissions that the apps will need to ask the
- * user before the apps have the information.
- * This information must be kept in VehiclePropConfig#permissionModel.
- */
-enum VehiclePermissionModel : int32_t {
-  /*
-   * No special restriction, but each property can still require specific
-   * android app-level permission.
-   */
-  NO_RESTRICTION = 0,
-
-  /* Signature only. Only APKs signed with OEM keys are allowed. */
-  OEM_ONLY = 0x1,
-
-  /* System only. APKs built-in to system  can access the property. */
-  SYSTEM_APP_ONLY = 0x2,
-
-  /* Equivalent to “system|signature” */
-  OEM_OR_SYSTEM_APP = 0x3,
-};
-
-/*
  * Car states.
  *
  * The driving states determine what features of the UI will be accessible.
@@ -2311,11 +2317,6 @@
     VehiclePropertyChangeMode changeMode;
 
     /*
-     * Defines permission model to access the data.
-     */
-    VehiclePermissionModel permissionModel;
-
-    /*
      * Some of the properties may have associated areas (for example, some hvac
      * properties are associated with VehicleAreaZone), in these
      * cases the config may contain an ORed value for the associated areas.
@@ -2405,6 +2406,35 @@
     RawValue value;
 };
 
+enum VehicleIgnitionState : int32_t {
+    UNDEFINED = 0,
+
+    /* Steering wheel is locked */
+    LOCK = 1,
+
+     /*
+      * Steering wheel is not locked, engine and all accessories are OFF. If
+      * car can be in LOCK and OFF state at the same time than HAL must report
+      * LOCK state.
+      */
+    OFF,
+
+    /*
+     * Typically in this state accessories become available (e.g. radio).
+     * Instrument cluster and engine are turned off
+     */
+    ACC,
+
+    /*
+     * Ignition is in state ON. Accessories and instrument cluster available,
+     * engine might be running or ready to be started.
+     */
+    ON,
+
+    /* Typically in this state engine is starting (cranking). */
+    START
+};
+
 
 /*
  * Represent the operation where the current error has happened.
@@ -2501,3 +2531,383 @@
   /* Something unexpected has happened in Vehicle HAL */
   INTERNAL_ERROR = 5,
 };
+
+/* The status of a fuel system as described by the OBD2 specification. */
+enum FuelSystemStatus : int32_t {
+  OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 1,
+
+  CLOSED_LOOP = 2,
+
+  OPEN_ENGINE_LOAD_OR_DECELERATION = 4,
+
+  OPEN_SYSTEM_FAILURE = 8,
+
+  CLOSED_LOOP_BUT_FEEDBACK_FAULT = 16,
+};
+
+/* Defines which ignition monitors are available to be read. */
+enum IgnitionMonitorKind : int32_t {
+  SPARK = 0,
+
+  COMPRESSION = 1,
+};
+
+/* These ignition monitors are common to both SPARK and COMPRESSION. */
+enum CommonIgnitionMonitors : int32_t {
+  COMPONENTS_AVAILABLE = 0x1 << 0,
+  COMPONENTS_INCOMPLETE = 0x1 << 1,
+
+  FUEL_SYSTEM_AVAILABLE = 0x1 << 2,
+  FUEL_SYSTEM_INCOMPLETE = 0x1 << 3,
+
+  MISFIRE_AVAILABLE = 0x1 << 4,
+  MISFIRE_INCOMPLETE = 0x1 << 5,
+};
+
+/* Ignition monitors available for SPARK vehicles. */
+enum SparkIgnitionMonitors : CommonIgnitionMonitors {
+  EGR_AVAILABLE = 0x1 << 6,
+  EGR_INCOMPLETE = 0x1 << 7,
+
+  OXYGEN_SENSOR_HEATER_AVAILABLE = 0x1 << 8,
+  OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x1 << 9,
+
+  OXYGEN_SENSOR_AVAILABLE = 0x1 << 10,
+  OXYGEN_SENSOR_INCOMPLETE = 0x1 << 11,
+
+  AC_REFRIGERANT_AVAILABLE = 0x1 << 12,
+  AC_REFRIGERANT_INCOMPLETE = 0x1 << 13,
+
+  SECONDARY_AIR_SYSTEM_AVAILABLE = 0x1 << 14,
+  SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x1 << 15,
+
+  EVAPORATIVE_SYSTEM_AVAILABLE = 0x1 << 16,
+  EVAPORATIVE_SYSTEM_INCOMPLETE = 0x1 << 17,
+
+  HEATED_CATALYST_AVAILABLE = 0x1 << 18,
+  HEATED_CATALYST_INCOMPLETE = 0x1 << 19,
+
+  CATALYST_AVAILABLE = 0x1 << 20,
+  CATALYST_INCOMPLETE = 0x1 << 21,
+};
+
+/* Ignition monitors only available for COMPRESSION vehicles. */
+enum CompressionIgnitionMonitors : CommonIgnitionMonitors {
+  EGR_OR_VVT_AVAILABLE = 0x1 << 6,
+  EGR_OR_VVT_INCOMPLETE = 0x1 << 7,
+
+  PM_FILTER_AVAILABLE = 0x1 << 8,
+  PM_FILTER_INCOMPLETE = 0x1 << 9,
+
+  EXHAUST_GAS_SENSOR_AVAILABLE = 0x1 << 10,
+  EXHAUST_GAS_SENSOR_INCOMPLETE = 0x1 << 11,
+
+  BOOST_PRESSURE_AVAILABLE = 0x1 << 12,
+  BOOST_PRESSURE_INCOMPLETE = 0x1 << 13,
+
+  NOx_SCR__AVAILABLE = 0x1 << 14,
+  NOx_SCR_INCOMPLETE = 0x1 << 15,
+
+  NMHC_CATALYST_AVAILABLE = 0x1 << 16,
+  NMHC_CATALYST_INCOMPLETE = 0x1 << 17,
+};
+
+enum SecondaryAirStatus : int32_t {
+  UPSTREAM = 1,
+
+  DOWNSTREAM_OF_CATALYCIC_CONVERTER = 2,
+
+  FROM_OUTSIDE_OR_OFF = 4,
+
+  PUMP_ON_FOR_DIAGNOSTICS = 8,
+};
+
+enum FuelType : int32_t {
+  NOT_AVAILABLE = 0,
+
+  GASOLINE = 1,
+
+  METHANOL = 2,
+
+  ETHANOL = 3,
+
+  DIESEL = 4,
+
+  LPG = 5,
+
+  CNG = 6,
+
+  PROPANE = 7,
+
+  ELECTRIC = 8,
+
+  BIFUEL_RUNNING_GASOLINE = 9,
+
+  BIFUEL_RUNNING_METHANOL = 10,
+
+  BIFUEL_RUNNING_ETHANOL = 11,
+
+  BIFUEL_RUNNING_LPG = 12,
+
+  BIFUEL_RUNNING_CNG = 13,
+
+  BIFUEL_RUNNING_PROPANE = 14,
+
+  BIFUEL_RUNNING_ELECTRIC = 15,
+
+  BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION = 16,
+
+  HYBRID_GASOLINE = 17,
+
+  HYBRID_ETHANOL = 18,
+
+  HYBRID_DIESEL = 19,
+
+  HYBRID_ELECTRIC = 20,
+
+  HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION = 21,
+
+  HYBRID_REGENERATIVE = 22,
+
+  BIFUEL_RUNNING_DIESEL = 23,
+};
+
+/*
+ * This enum provides the canonical mapping for sensor properties that have an integer value.
+ * The ordering of the values is taken from the OBD2 specification.
+ * Some of the properties are represented as an integer mapping to another enum. In those cases
+ * expect a comment by the property definition describing the enum to look at for the mapping.
+ * Any value greater than the last reserved index is available to vendors to map their extensions.
+ */
+enum Obd2IntegerSensorIndex : int32_t {
+  /* refer to FuelSystemStatus for a description of this value. */
+  FUEL_SYSTEM_STATUS = 0,
+
+  MALFUNCTION_INDICATOR_LIGHT_ON = 1,
+
+  /* refer to IgnitionMonitorKind for a description of this value. */
+  IGNITION_MONITORS_SUPPORTED = 2,
+
+  /*
+   * The value of this sensor is a bitmask that specifies whether ignition-specific
+   * tests are available and whether they are complete. The semantics of the individual
+   * bits in this value are given by, respectively, SparkIgnitionMonitors and
+   * CompressionIgnitionMonitors depending on the value of IGNITION_MONITORS_SUPPORTED.
+  /*
+  IGNITION_SPECIFIC_MONITORS = 3,
+
+  INTAKE_AIR_TEMPERATURE = 4,
+
+  /* refer to SecondaryAirStatus for a description of this value. */
+  COMMANDED_SECONDARY_AIR_STATUS = 5,
+
+  NUM_OXYGEN_SENSORS_PRESENT = 6,
+
+  RUNTIME_SINCE_ENGINE_START = 7,
+
+  DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 8,
+
+  WARMUPS_SINCE_CODES_CLEARED = 9,
+
+  DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 10,
+
+  ABSOLUTE_BAROMETRIC_PRESSURE = 11,
+
+  CONTROL_MODULE_VOLTAGE = 12,
+
+  AMBIENT_AIR_TEMPERATURE = 13,
+
+  TIME_WITH_MALFUNCTION_LIGHT_ON = 14,
+
+  TIME_SINCE_TROUBLE_CODES_CLEARED = 15,
+
+  MAX_FUEL_AIR_EQUIVALENCE_RATIO = 16,
+
+  MAX_OXYGEN_SENSOR_VOLTAGE = 17,
+
+  MAX_OXYGEN_SENSOR_CURRENT = 18,
+
+  MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 19,
+
+  MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 20,
+
+  /* refer to FuelType for a description of this value. */
+  FUEL_TYPE = 21,
+
+  FUEL_RAIL_ABSOLUTE_PRESSURE = 22,
+
+  ENGINE_OIL_TEMPERATURE = 23,
+
+  DRIVER_DEMAND_PERCENT_TORQUE = 24,
+
+  ENGINE_ACTUAL_PERCENT_TORQUE = 25,
+
+  ENGINE_REFERENCE_PERCENT_TORQUE = 26,
+
+  ENGINE_PERCENT_TORQUE_DATA_IDLE = 27,
+
+  ENGINE_PERCENT_TORQUE_DATA_POINT1 = 28,
+
+  ENGINE_PERCENT_TORQUE_DATA_POINT2 = 29,
+
+  ENGINE_PERCENT_TORQUE_DATA_POINT3 = 30,
+
+  ENGINE_PERCENT_TORQUE_DATA_POINT4 = 31,
+
+  LAST_SYSTEM_INDEX = ENGINE_PERCENT_TORQUE_DATA_POINT4,
+
+  VENDOR_START_INDEX = LAST_SYSTEM_INDEX + 1,
+};
+
+/*
+ * This enum provides the canonical mapping for sensor properties that have a floating-point value.
+ * The ordering of the values is taken from the OBD2 specification.
+ * Any value greater than the last reserved index is available to vendors to map their extensions.
+ */
+enum Obd2FloatSensorIndex : int32_t {
+  CALCULATED_ENGINE_LOAD = 0,
+
+  ENGINE_COOLANT_TEMPERATURE = 1,
+
+  SHORT_TERM_FUEL_TRIM_BANK1 = 2,
+
+  LONG_TERM_FUEL_TRIM_BANK1 = 3,
+
+  SHORT_TERM_FUEL_TRIM_BANK2 = 4,
+
+  LONG_TERM_FUEL_TRIM_BANK2 = 5,
+
+  FUEL_PRESSURE = 6,
+
+  INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 7,
+
+  ENGINE_RPM = 8,
+
+  VEHICLE_SPEED = 9,
+
+  TIMING_ADVANCE = 10,
+
+  MAF_AIR_FLOW_RATE = 11,
+
+  THROTTLE_POSITION = 12,
+
+  OXYGEN_SENSOR1_VOLTAGE = 13,
+
+  OXYGEN_SENSOR1_SHORT_TERM_FUEL_TRIM = 14,
+
+  OXYGEN_SENSOR1_FUEL_AIR_EQUIVALENCE_RATIO = 15,
+
+  OXYGEN_SENSOR2_VOLTAGE = 16,
+
+  OXYGEN_SENSOR2_SHORT_TERM_FUEL_TRIM = 17,
+
+  OXYGEN_SENSOR2_FUEL_AIR_EQUIVALENCE_RATIO = 18,
+
+  OXYGEN_SENSOR3_VOLTAGE = 19,
+
+  OXYGEN_SENSOR3_SHORT_TERM_FUEL_TRIM = 20,
+
+  OXYGEN_SENSOR3_FUEL_AIR_EQUIVALENCE_RATIO = 21,
+
+  OXYGEN_SENSOR4_VOLTAGE = 22,
+
+  OXYGEN_SENSOR4_SHORT_TERM_FUEL_TRIM = 23,
+
+  OXYGEN_SENSOR4_FUEL_AIR_EQUIVALENCE_RATIO = 24,
+
+  OXYGEN_SENSOR5_VOLTAGE = 25,
+
+  OXYGEN_SENSOR5_SHORT_TERM_FUEL_TRIM = 26,
+
+  OXYGEN_SENSOR5_FUEL_AIR_EQUIVALENCE_RATIO = 27,
+
+  OXYGEN_SENSOR6_VOLTAGE = 28,
+
+  OXYGEN_SENSOR6_SHORT_TERM_FUEL_TRIM = 29,
+
+  OXYGEN_SENSOR6_FUEL_AIR_EQUIVALENCE_RATIO = 30,
+
+  OXYGEN_SENSOR7_VOLTAGE = 31,
+
+  OXYGEN_SENSOR7_SHORT_TERM_FUEL_TRIM = 32,
+
+  OXYGEN_SENSOR7_FUEL_AIR_EQUIVALENCE_RATIO = 33,
+
+  OXYGEN_SENSOR8_VOLTAGE = 34,
+
+  OXYGEN_SENSOR8_SHORT_TERM_FUEL_TRIM = 35,
+
+  OXYGEN_SENSOR8_FUEL_AIR_EQUIVALENCE_RATIO = 36,
+
+  FUEL_RAIL_PRESSURE = 37,
+
+  FUEL_RAIL_GAUGE_PRESSURE = 38,
+
+  COMMANDED_EXHAUST_GAS_RECIRCULATION = 39,
+
+  EXHAUST_GAS_RECIRCULATION_ERROR = 40,
+
+  COMMANDED_EVAPORATIVE_PURGE = 41,
+
+  FUEL_TANK_LEVEL_INPUT = 42,
+
+  EVAPORATION_SYSTEM_VAPOR_PRESSURE = 43,
+
+  CATALYST_TEMPERATURE_BANK1_SENSOR1 = 44,
+
+  CATALYST_TEMPERATURE_BANK2_SENSOR1 = 45,
+
+  CATALYST_TEMPERATURE_BANK1_SENSOR2 = 46,
+
+  CATALYST_TEMPERATURE_BANK2_SENSOR2 = 47,
+
+  ABSOLUTE_LOAD_VALUE = 48,
+
+  FUEL_AIR_COMMANDED_EQUIVALENCE_RATIO = 49,
+
+  RELATIVE_THROTTLE_POSITION = 50,
+
+  ABSOLUTE_THROTTLE_POSITION_B = 51,
+
+  ABSOLUTE_THROTTLE_POSITION_C = 52,
+
+  ACCELERATOR_PEDAL_POSITION_D = 53,
+
+  ACCELERATOR_PEDAL_POSITION_E = 54,
+
+  ACCELERATOR_PEDAL_POSITION_F = 55,
+
+  COMMANDED_THROTTLE_ACTUATOR = 56,
+
+  ETHANOL_FUEL_PERCENTAGE = 57,
+
+  ABSOLUTE_EVAPORATION_SYSTEM_VAPOR_PRESSURE = 58,
+
+  SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1 = 59,
+
+  SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2 = 60,
+
+  SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3 = 61,
+
+  SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4 = 62,
+
+  LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1 = 63,
+
+  LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2 = 64,
+
+  LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3 = 65,
+
+  LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4 = 66,
+
+  RELATIVE_ACCELERATOR_PEDAL_POSITION = 67,
+
+  HYBRID_BATTERY_PACK_REMAINING_LIFE = 68,
+
+  FUEL_INJECTION_TIMING = 69,
+
+  ENGINE_FUEL_RATE = 70,
+
+  LAST_SYSTEM_INDEX = ENGINE_FUEL_RATE,
+
+  VENDOR_START_INDEX = LAST_SYSTEM_INDEX + 1,
+};
diff --git a/vehicle/2.0/vts/Android.mk b/vehicle/2.0/vts/Android.mk
index b7f185d..df5dac8 100644
--- a/vehicle/2.0/vts/Android.mk
+++ b/vehicle/2.0/vts/Android.mk
@@ -16,73 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for Vehicle.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vehicle@2.0
-
-LOCAL_SRC_FILES := \
-  Vehicle.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-  android.hardware.vehicle@2.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# build profiler for VehicleCallback.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vehicle_callback_@2.0
-
-LOCAL_SRC_FILES := \
-  Vehicle.vts \
-  types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-  android.hardware.vehicle@2.0 \
-  libbase \
-  libcutils \
-  liblog \
-  libhidlbase \
-  libhidltransport \
-  libhwbinder \
-  libprotobuf-cpp-full \
-  libvts_common \
-  libvts_multidevice_proto \
-  libvts_profiling \
-  libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
index bc37e59..8da36d1 100644
--- a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
+++ b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
@@ -33,6 +33,7 @@
         self.dut = self.registerController(android_device)[0]
 
         self.dut.shell.InvokeTerminal("one")
+        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
 
         if self.enable_profiling:
             profiling_utils.EnableVTSProfiling(self.dut.shell.one)
@@ -55,25 +56,13 @@
             self.ProcessAndUploadTraceData(self.dut, profiling_trace_path)
             profiling_utils.DisableVTSProfiling(self.dut.shell.one)
 
-    def testEcho1(self):
-        """A simple testcase which sends a command."""
-        self.dut.shell.InvokeTerminal("my_shell1")  # creates a remote shell instance.
-        results = self.dut.shell.my_shell1.Execute("echo hello_world")  # runs a shell command.
-        logging.info(str(results[const.STDOUT]))  # prints the stdout
-        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello_world")  # checks the stdout
-        asserts.assertEqual(results[const.EXIT_CODE][0], 0)  # checks the exit code
+    def testListProperties(self):
+        logging.info("vehicle_types")
+        vehicle_types = self.dut.hal.vehicle.GetHidlTypeInterface("types")
+        logging.info("vehicle_types: %s", vehicle_types)
 
-    def testEcho2(self):
-        """A simple testcase which sends two commands."""
-        self.dut.shell.InvokeTerminal("my_shell2")
-        my_shell = getattr(self.dut.shell, "my_shell2")
-        results = my_shell.Execute(["echo hello", "echo world"])
-        logging.info(str(results[const.STDOUT]))
-        asserts.assertEqual(len(results[const.STDOUT]), 2)  # check the number of processed commands
-        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello")
-        asserts.assertEqual(results[const.STDOUT][1].strip(), "world")
-        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
-        asserts.assertEqual(results[const.EXIT_CODE][1], 0)
+        allConfigs = self.dut.hal.vehicle.getAllPropConfigs()
+        logging.info("all supported properties: %s", allConfigs)
 
 if __name__ == "__main__":
     test_runner.main()
diff --git a/vehicle/2.0/vts/types.vts b/vehicle/2.0/vts/types.vts
index fc63add..99fa6e7 100644
--- a/vehicle/2.0/vts/types.vts
+++ b/vehicle/2.0/vts/types.vts
@@ -1149,6 +1149,10 @@
     enum_value: {
         scalar_type: "int32_t"
 
+        enumerator: "NONE"
+        scalar_value: {
+            int32_t: 0
+        }
         enumerator: "READ"
         scalar_value: {
             int32_t: 1
@@ -1165,31 +1169,6 @@
 }
 
 attribute: {
-    name: "::android::hardware::vehicle::V2_0::VehiclePermissionModel"
-    type: TYPE_ENUM
-    enum_value: {
-        scalar_type: "int32_t"
-
-        enumerator: "NO_RESTRICTION"
-        scalar_value: {
-            int32_t: 0
-        }
-        enumerator: "OEM_ONLY"
-        scalar_value: {
-            int32_t: 1
-        }
-        enumerator: "SYSTEM_APP_ONLY"
-        scalar_value: {
-            int32_t: 2
-        }
-        enumerator: "OEM_OR_SYSTEM_APP"
-        scalar_value: {
-            int32_t: 3
-        }
-    }
-}
-
-attribute: {
     name: "::android::hardware::vehicle::V2_0::VehicleDrivingStatus"
     type: TYPE_ENUM
     enum_value: {
@@ -1600,11 +1579,6 @@
         predefined_type: "::android::hardware::vehicle::V2_0::VehiclePropertyChangeMode"
     }
     struct_value: {
-        name: "permissionModel"
-        type: TYPE_ENUM
-        predefined_type: "::android::hardware::vehicle::V2_0::VehiclePermissionModel"
-    }
-    struct_value: {
         name: "supportedAreas"
         type: TYPE_SCALAR
         scalar_type: "int32_t"
diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp
index ec97cfb..cea74bb 100644
--- a/vibrator/1.0/Android.bp
+++ b/vibrator/1.0/Android.bp
@@ -112,3 +112,48 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vibrator@1.0-IVibrator-vts.profiler_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) -mPROFILER -tSOURCE -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+    srcs: [
+        "IVibrator.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.0/Vibrator.vts.cpp",
+        "android/hardware/vibrator/1.0/types.vts.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.vibrator@1.0-IVibrator-vts.profiler_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) -mPROFILER -tHEADER -b$(genDir) android/hardware/vibrator/1.0/ $(genDir)/android/hardware/vibrator/1.0/",
+    srcs: [
+        "IVibrator.hal",
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/vibrator/1.0/Vibrator.vts.h",
+        "android/hardware/vibrator/1.0/types.vts.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.vibrator@1.0-IVibrator-vts.profiler",
+    generated_sources: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.vibrator@1.0-IVibrator-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vibrator@1.0",
+    ],
+}
diff --git a/vibrator/1.0/vts/Android.mk b/vibrator/1.0/vts/Android.mk
index 084dcf7..df5dac8 100644
--- a/vibrator/1.0/vts/Android.mk
+++ b/vibrator/1.0/vts/Android.mk
@@ -16,36 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for vibrator.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vibrator@1.0
-
-LOCAL_SRC_FILES := \
-   Vibrator.vts \
-   types.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.vibrator@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp
index 240b7ad..3397bff 100644
--- a/vr/1.0/Android.bp
+++ b/vr/1.0/Android.bp
@@ -104,3 +104,44 @@
         "android.hidl.base@1.0",
     ],
 }
+
+genrule {
+    name: "android.hardware.vr@1.0-IVr-vts.profiler_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) -mPROFILER -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@1.0-IVr-vts.profiler_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) -mPROFILER -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@1.0-IVr-vts.profiler",
+    generated_sources: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++"],
+    generated_headers: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++_headers"],
+    export_generated_headers: ["android.hardware.vr@1.0-IVr-vts.profiler_genc++_headers"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libvts_profiling",
+        "libvts_multidevice_proto",
+        "libprotobuf-cpp-full",
+        "android.hidl.base@1.0",
+        "android.hardware.vr@1.0",
+    ],
+}
diff --git a/vr/1.0/vts/Android.mk b/vr/1.0/vts/Android.mk
index ac1cad5..e8afa86 100644
--- a/vr/1.0/vts/Android.mk
+++ b/vr/1.0/vts/Android.mk
@@ -16,36 +16,5 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# build profiler for Vr.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvts_profiler_hidl_vr@1.0
-
-LOCAL_SRC_FILES := \
-   Vr.vts \
-
-LOCAL_C_INCLUDES += \
-  test/vts/drivers/libprofiling \
-
-LOCAL_VTS_MODE := PROFILER
-
-LOCAL_SHARED_LIBRARIES := \
-   android.hardware.vr@1.0 \
-   libbase \
-   libcutils \
-   liblog \
-   libhidlbase \
-   libhidltransport \
-   libhwbinder \
-   libprotobuf-cpp-full \
-   libvts_common \
-   libvts_multidevice_proto \
-   libvts_profiling \
-   libutils \
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-include $(BUILD_SHARED_LIBRARY)
-
 # include hidl test makefiles
 include $(LOCAL_PATH)/functional/vts/testcases/hal/vr/hidl/Android.mk
diff --git a/wifi/1.0/default/service.cpp b/wifi/1.0/default/service.cpp
index 751e8f6..40e8b12 100644
--- a/wifi/1.0/default/service.cpp
+++ b/wifi/1.0/default/service.cpp
@@ -15,42 +15,21 @@
  */
 
 #include <android-base/logging.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
 #include <utils/Looper.h>
 #include <utils/StrongPointer.h>
 
 #include "wifi.h"
 
-using android::hardware::hidl_version;
-using android::hardware::IPCThreadState;
-using android::hardware::ProcessState;
-using android::Looper;
-
-namespace {
-int OnBinderReadReady(int /*fd*/, int /*events*/, void* /*data*/) {
-  IPCThreadState::self()->handlePolledCommands();
-  return 1;  // continue receiving events
-}
-}
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
 
 int main(int /*argc*/, char** argv) {
   android::base::InitLogging(argv,
                              android::base::LogdLogger(android::base::SYSTEM));
   LOG(INFO) << "wifi_hal_legacy is starting up...";
 
-  // Setup binder
-  int binder_fd = -1;
-  ProcessState::self()->setThreadPoolMaxThreadCount(0);
-  CHECK_EQ(IPCThreadState::self()->setupPolling(&binder_fd), android::NO_ERROR)
-      << "Failed to initialize binder polling";
-  CHECK_GE(binder_fd, 0) << "Invalid binder FD: " << binder_fd;
-
-  // Setup looper
-  android::sp<Looper> looper = Looper::prepare(0 /* no options */);
-  CHECK(looper->addFd(
-      binder_fd, 0, Looper::EVENT_INPUT, OnBinderReadReady, nullptr))
-      << "Failed to watch binder FD";
+  configureRpcThreadpool(1, true /* callerWillJoin */);
 
   // Setup hwbinder service
   android::sp<android::hardware::wifi::V1_0::IWifi> service =
@@ -58,10 +37,7 @@
   CHECK_EQ(service->registerAsService("wifi"), android::NO_ERROR)
       << "Failed to register wifi HAL";
 
-  // Loop
-  while (looper->pollAll(-1) != Looper::POLL_ERROR) {
-    // Keep polling until failure.
-  }
+  joinRpcThreadpool();
 
   LOG(INFO) << "wifi_hal_legacy is terminating...";
   return 0;
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..422eec5
--- /dev/null
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -0,0 +1,50 @@
+//
+// 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: "wifi_hidl_test",
+    gtest: true,
+    srcs: [
+        "main.cpp",
+        "wifi_ap_iface_hidl_test.cpp",
+        "wifi_chip_hidl_test.cpp",
+        "wifi_hidl_test.cpp",
+        "wifi_hidl_test_utils.cpp",
+        "wifi_nan_iface_hidl_test.cpp",
+        "wifi_p2p_iface_hidl_test.cpp",
+        "wifi_rtt_controller_hidl_test.cpp",
+        "wifi_sta_iface_hidl_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "--coverage",
+        "-O0",
+        "-g",
+    ],
+    ldflags: [
+        "--coverage"
+    ]
+}
diff --git a/wifi/1.0/vts/functional/Android.mk b/wifi/1.0/vts/functional/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/wifi/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/wifi/1.0/vts/functional/main.cpp b/wifi/1.0/vts/functional/main.cpp
new file mode 100644
index 0000000..b33b5eb
--- /dev/null
+++ b/wifi/1.0/vts/functional/main.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+class WifiHidlEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() override { stopFramework(); }
+    virtual void TearDown() override { startFramework(); }
+
+   private:
+};
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
new file mode 100644
index 0000000..dc7b0b9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all AP Iface HIDL interface tests.
+ */
+class WifiApIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiApIface proxy object is
+ * successfully created.
+ */
+TEST(WifiApIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiApIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..b6ecd8b
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::sp;
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiChip proxy object is
+ * successfully created.
+ */
+TEST(WifiChipHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiChip().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
new file mode 100644
index 0000000..3e350e5
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::sp;
+
+/**
+ * Fixture to use for all root Wifi HIDL interface tests.
+ */
+class WifiHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifi proxy object is
+ * successfully created.
+ */
+TEST(WifiHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifi().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
new file mode 100644
index 0000000..f88b866
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::ChipId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+const char kWifiServiceName[] = "wifi";
+
+void stopFramework() {
+    ASSERT_EQ(std::system("svc wifi disable"), 0);
+    sleep(5);
+}
+
+void startFramework() { ASSERT_EQ(std::system("svc wifi enable"), 0); }
+
+sp<IWifi> getWifi() {
+    sp<IWifi> wifi = IWifi::getService(kWifiServiceName);
+    return wifi;
+}
+
+sp<IWifiChip> getWifiChip() {
+    sp<IWifi> wifi = getWifi();
+    if (!wifi.get()) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    wifi->start([&](WifiStatus status) {
+        if (status.code != WifiStatusCode::SUCCESS) {
+            operation_failed = true;
+        }
+    });
+    if (operation_failed) {
+        return nullptr;
+    }
+
+    std::vector<ChipId> wifi_chip_ids;
+    wifi->getChipIds(
+        [&](const WifiStatus& status, const hidl_vec<ChipId>& chip_ids) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_chip_ids = chip_ids;
+        });
+    // We don't expect more than 1 chip currently.
+    if (operation_failed || wifi_chip_ids.size() != 1) {
+        return nullptr;
+    }
+
+    sp<IWifiChip> wifi_chip;
+    wifi->getChip(wifi_chip_ids[0],
+                  [&](const WifiStatus& status, const sp<IWifiChip>& chip) {
+                      if (status.code != WifiStatusCode::SUCCESS) {
+                          operation_failed = true;
+                      }
+                      wifi_chip = chip;
+                  });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_chip;
+}
+
+// Since we currently only support one iface of each type. Just iterate thru the
+// modes of operation and find the mode ID to use for that iface type.
+bool findModeToSupportIfaceType(IfaceType type,
+                                const std::vector<IWifiChip::ChipMode>& modes,
+                                ChipModeId* mode_id) {
+    for (const auto& mode : modes) {
+        std::vector<IWifiChip::ChipIfaceCombination> combinations =
+            mode.availableCombinations;
+        for (const auto& combination : combinations) {
+            std::vector<IWifiChip::ChipIfaceCombinationLimit> iface_limits =
+                combination.limits;
+            for (const auto& iface_limit : iface_limits) {
+                std::vector<IfaceType> iface_types = iface_limit.types;
+                for (const auto& iface_type : iface_types) {
+                    if (iface_type == type) {
+                        *mode_id = mode.id;
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip,
+                                     IfaceType type) {
+    bool operation_failed = false;
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    wifi_chip->getAvailableModes(
+        [&](WifiStatus status, const hidl_vec<IWifiChip::ChipMode>& modes) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            chip_modes = modes;
+        });
+    if (operation_failed) {
+        return false;
+    }
+
+    ChipModeId mode_id;
+    if (!findModeToSupportIfaceType(type, chip_modes, &mode_id)) {
+        return false;
+    }
+
+    wifi_chip->configureChip(mode_id, [&](WifiStatus status) {
+        if (status.code != WifiStatusCode::SUCCESS) {
+            operation_failed = true;
+        }
+    });
+    if (operation_failed) {
+        return false;
+    }
+    return true;
+}
+
+sp<IWifiApIface> getWifiApIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::AP)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiApIface> wifi_ap_iface;
+    wifi_chip->createApIface(
+        [&](const WifiStatus& status, const sp<IWifiApIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_ap_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_ap_iface;
+}
+
+sp<IWifiNanIface> getWifiNanIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::NAN)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiNanIface> wifi_nan_iface;
+    wifi_chip->createNanIface(
+        [&](const WifiStatus& status, const sp<IWifiNanIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_nan_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_nan_iface;
+}
+
+sp<IWifiP2pIface> getWifiP2pIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::P2P)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiP2pIface> wifi_p2p_iface;
+    wifi_chip->createP2pIface(
+        [&](const WifiStatus& status, const sp<IWifiP2pIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_p2p_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_p2p_iface;
+}
+
+sp<IWifiStaIface> getWifiStaIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::STA)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiStaIface> wifi_sta_iface;
+    wifi_chip->createStaIface(
+        [&](const WifiStatus& status, const sp<IWifiStaIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_sta_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_sta_iface;
+}
+
+sp<IWifiRttController> getWifiRttController() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface();
+    if (!wifi_sta_iface.get()) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiRttController> wifi_rtt_controller;
+    wifi_chip->createRttController(
+        wifi_sta_iface, [&](const WifiStatus& status,
+                            const sp<IWifiRttController>& controller) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_rtt_controller = controller;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_rtt_controller;
+}
+
+void stopWifi() {
+    sp<IWifi> wifi = getWifi();
+    ASSERT_NE(wifi, nullptr);
+    wifi->stop([](const WifiStatus& status) {
+        ASSERT_EQ(status.code, WifiStatusCode::SUCCESS);
+    });
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
new file mode 100644
index 0000000..08933d9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+// Used to stop the android framework (wifi service) before every
+// test.
+void stopFramework();
+void startFramework();
+
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::V1_0::IWifi> getWifi();
+android::sp<android::hardware::wifi::V1_0::IWifiChip> getWifiChip();
+android::sp<android::hardware::wifi::V1_0::IWifiApIface> getWifiApIface();
+android::sp<android::hardware::wifi::V1_0::IWifiNanIface> getWifiNanIface();
+android::sp<android::hardware::wifi::V1_0::IWifiP2pIface> getWifiP2pIface();
+android::sp<android::hardware::wifi::V1_0::IWifiStaIface> getWifiStaIface();
+android::sp<android::hardware::wifi::V1_0::IWifiRttController>
+getWifiRttController();
+// Used to trigger IWifi.stop() at the end of every test.
+void stopWifi();
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..a8be48c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Nanache 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST(WifiNanIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiNanIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
new file mode 100644
index 0000000..e29226d
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the P2pache 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all P2P Iface HIDL interface tests.
+ */
+class WifiP2pIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiP2pIface proxy object is
+ * successfully created.
+ */
+TEST(WifiP2pIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiP2pIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
new file mode 100644
index 0000000..7aee761
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::sp;
+
+/**
+ * Fixture to use for all RTT controller HIDL interface tests.
+ */
+class WifiRttControllerHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiRttController proxy object is
+ * successfully created.
+ */
+TEST(WifiRttControllerHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiRttController().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
new file mode 100644
index 0000000..770763c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Staache 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all STA Iface HIDL interface tests.
+ */
+class WifiStaIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiStaIface proxy object is
+ * successfully created.
+ */
+TEST(WifiStaIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiStaIface().get());
+    stopWifi();
+}
diff --git a/wifi/Android.bp b/wifi/Android.bp
index ea43db4..d4e0fda 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -1,5 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/vts/functional",
     "supplicant/1.0",
 ]
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIface.hal b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
index cd5a7c5..0fa19c8 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
@@ -357,8 +357,7 @@
    *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
    *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
    */
-  configureExtListen(bool enable,
-                     uint32_t periodInMillis,
+  configureExtListen(uint32_t periodInMillis,
                      uint32_t intervalInMillis)
       generates (SupplicantStatus status);
 
@@ -492,8 +491,7 @@
    *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
    *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
    */
-  flushServices(uint32_t version, string serviceName)
-      generates (SupplicantStatus status);
+  flushServices() generates (SupplicantStatus status);
 
   /**
    * Schedule a P2P service discovery request. The parameters for this command