Merge "audioflinger: add standby() method to MmapStreamInterface"
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 3512730..0771fc8 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -54,6 +54,22 @@
     void beginConfigure();
 
     /**
+     * The standard operating mode for a camera device; all API guarantees are in force
+     */
+    const int NORMAL_MODE = 0;
+
+    /**
+     * High-speed recording mode; only two outputs targeting preview and video recording may be
+     * used, and requests must be batched.
+     */
+    const int CONSTRAINED_HIGH_SPEED_MODE = 1;
+
+    /**
+     * Start of custom vendor modes
+     */
+    const int VENDOR_MODE_START = 0x8000;
+
+    /**
      * End the device configuration.
      *
      * <p>
@@ -61,8 +77,10 @@
      * a call to beginConfigure and subsequent createStream/deleteStream calls).  This
      * must be called before any requests can be submitted.
      * <p>
+     * @param operatingMode The kind of session to create; either NORMAL_MODE or
+     *     CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
      */
-    void endConfigure(boolean isConstrainedHighSpeed);
+    void endConfigure(int operatingMode);
 
     void deleteStream(int streamId);
 
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index ad70470..ff5e5d3 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -12,7 +12,6 @@
         libjpeg libgui libcutils liblog \
         libhidlmemory \
         android.hardware.media.omx@1.0 \
-        android.hardware.media.omx@1.0-utils \
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index ffa09eb..4d8dd3c 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -65,7 +65,7 @@
 #include <gui/SurfaceComposerClient.h>
 
 #include <android/hardware/media/omx/1.0/IOmx.h>
-#include <omx/hal/1.0/utils/WOmx.h>
+#include <media/omx/1.0/WOmx.h>
 
 using namespace android;
 
diff --git a/drm/libmediadrm/Android.mk b/drm/libmediadrm/Android.mk
index a57fafa..590622e 100644
--- a/drm/libmediadrm/Android.mk
+++ b/drm/libmediadrm/Android.mk
@@ -48,7 +48,8 @@
     android.hidl.base@1.0 \
     android.hardware.drm@1.0 \
     libhidlbase \
-    libhidlmemory
+    libhidlmemory \
+    libhidltransport
 endif
 
 LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 5732613..1fda06c 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -17,10 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CryptoHal"
 #include <utils/Log.h>
-#include <dirent.h>
-#include <dlfcn.h>
 
 #include <android/hardware/drm/1.0/types.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 
 #include <binder/IMemory.h>
 #include <cutils/native_handle.h>
@@ -47,6 +46,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hidl::manager::V1_0::IServiceManager;
 using ::android::sp;
 
 
@@ -101,31 +101,52 @@
 
 
 CryptoHal::CryptoHal()
-    : mFactory(makeCryptoFactory()),
-      mInitCheck((mFactory == NULL) ? ERROR_UNSUPPORTED : NO_INIT),
+    : mFactories(makeCryptoFactories()),
+      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
       mNextBufferId(0) {
 }
 
 CryptoHal::~CryptoHal() {
 }
 
+Vector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
+    Vector<sp<ICryptoFactory>> factories;
 
-sp<ICryptoFactory> CryptoHal::makeCryptoFactory() {
-    sp<ICryptoFactory> factory = ICryptoFactory::getService("crypto");
-    if (factory == NULL) {
-        ALOGE("Failed to make crypto factory");
+    auto manager = ::IServiceManager::getService("manager");
+    if (manager != NULL) {
+        manager->listByInterface(ICryptoFactory::descriptor,
+                [&factories](const hidl_vec<hidl_string> &registered) {
+                    for (const auto &instance : registered) {
+                        auto factory = ICryptoFactory::getService(instance);
+                        if (factory != NULL) {
+                            factories.push_back(factory);
+                            ALOGI("makeCryptoFactories: factory instance %s is %s",
+                                    instance.c_str(),
+                                    factory->isRemote() ? "Remote" : "Not Remote");
+                        }
+                    }
+                }
+            );
     }
-    return factory;
+
+    if (factories.size() == 0) {
+        // must be in passthrough mode, load the default passthrough service
+        auto passthrough = ICryptoFactory::getService("crypto");
+        if (passthrough != NULL) {
+            ALOGI("makeCryptoFactories: using default crypto instance");
+            factories.push_back(passthrough);
+        } else {
+            ALOGE("Failed to find any crypto factories");
+        }
+    }
+    return factories;
 }
 
-sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const uint8_t uuid[16],
-        const void *initData, size_t initDataSize) {
-    if (mFactory == NULL){
-        return NULL;
-    }
+sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
+        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
 
     sp<ICryptoPlugin> plugin;
-    Return<void> hResult = mFactory->createPlugin(toHidlArray16(uuid),
+    Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
             toHidlVec(initData, initDataSize),
             [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
                 if (status != Status::OK) {
@@ -146,17 +167,24 @@
 
 bool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
     Mutex::Autolock autoLock(mLock);
-    if (mFactory != NULL) {
-        return mFactory->isCryptoSchemeSupported(uuid);
+
+    for (size_t i = 0; i < mFactories.size(); i++) {
+        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
+            return true;
+        }
     }
     return false;
 }
 
-status_t CryptoHal::createPlugin(
-        const uint8_t uuid[16], const void *data, size_t size) {
+status_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
+        size_t size) {
     Mutex::Autolock autoLock(mLock);
 
-    mPlugin = makeCryptoPlugin(uuid, data, size);
+    for (size_t i = 0; i < mFactories.size(); i++) {
+        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
+            mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
+        }
+    }
 
     if (mPlugin == NULL) {
         mInitCheck = ERROR_UNSUPPORTED;
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 8200d55..595b895 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -20,12 +20,11 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <dirent.h>
-#include <dlfcn.h>
 
 #include <android/hardware/drm/1.0/IDrmFactory.h>
 #include <android/hardware/drm/1.0/IDrmPlugin.h>
 #include <android/hardware/drm/1.0/types.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 
 #include <media/DrmHal.h>
 #include <media/DrmSessionClientInterface.h>
@@ -52,6 +51,7 @@
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hidl::manager::V1_0::IServiceManager;
 using ::android::sp;
 
 namespace android {
@@ -110,9 +110,9 @@
     return keyedVector;
 }
 
-static List<Vector<uint8_t> > toSecureStops(const hidl_vec<SecureStop>&
+static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
         hSecureStops) {
-    List<Vector<uint8_t> > secureStops;
+    List<Vector<uint8_t>> secureStops;
     for (size_t i = 0; i < hSecureStops.size(); i++) {
         secureStops.push_back(toVector(hSecureStops[i].opaqueData));
     }
@@ -189,43 +189,61 @@
 
 DrmHal::DrmHal()
    : mDrmSessionClient(new DrmSessionClient(this)),
-     mFactory(makeDrmFactory()),
-     mInitCheck((mFactory == NULL) ? ERROR_UNSUPPORTED : NO_INIT) {
+     mFactories(makeDrmFactories()),
+     mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
 }
 
 DrmHal::~DrmHal() {
     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
 }
 
-sp<IDrmFactory> DrmHal::makeDrmFactory() {
-    sp<IDrmFactory> factory = IDrmFactory::getService("drm");
-    if (factory == NULL) {
-        ALOGE("Failed to make drm factory");
-        return NULL;
+Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
+    Vector<sp<IDrmFactory>> factories;
+
+    auto manager = ::IServiceManager::getService("manager");
+
+    if (manager != NULL) {
+        manager->listByInterface(IDrmFactory::descriptor,
+                [&factories](const hidl_vec<hidl_string> &registered) {
+                    for (const auto &instance : registered) {
+                        auto factory = IDrmFactory::getService(instance);
+                        if (factory != NULL) {
+                            factories.push_back(factory);
+                            ALOGI("makeDrmFactories: factory instance %s is %s",
+                                    instance.c_str(),
+                                    factory->isRemote() ? "Remote" : "Not Remote");
+                        }
+                    }
+                }
+            );
     }
 
-    ALOGD("makeDrmFactory: service is %s",
-            factory->isRemote() ? "Remote" : "Not Remote");
-
-    return factory;
+    if (factories.size() == 0) {
+        // must be in passthrough mode, load the default passthrough service
+        auto passthrough = IDrmFactory::getService("drm");
+        if (passthrough != NULL) {
+            ALOGI("makeDrmFactories: using default drm instance");
+            factories.push_back(passthrough);
+        } else {
+            ALOGE("Failed to find any drm factories");
+        }
+    }
+    return factories;
 }
 
-sp<IDrmPlugin> DrmHal::makeDrmPlugin(const uint8_t uuid[16],
-        const String8& appPackageName) {
-    if (mFactory == NULL){
-        return NULL;
-    }
+sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
+        const uint8_t uuid[16], const String8& appPackageName) {
 
     sp<IDrmPlugin> plugin;
-    Return<void> hResult = mFactory->createPlugin(uuid, appPackageName.string(),
+    Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
             [&](Status status, const sp<IDrmPlugin>& hPlugin) {
-      if (status != Status::OK) {
-        ALOGD("Failed to make drm plugin");
-        return;
-      }
-      plugin = hPlugin;
-    }
-    );
+                if (status != Status::OK) {
+                    ALOGE("Failed to make drm plugin");
+                    return;
+                }
+                plugin = hPlugin;
+            }
+        );
     return plugin;
 }
 
@@ -346,22 +364,30 @@
 
 bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
     Mutex::Autolock autoLock(mLock);
-    bool result = false;
 
-    if (mFactory != NULL && mFactory->isCryptoSchemeSupported(uuid)) {
-        result = true;
-        if (mimeType != "") {
-            result = mFactory->isContentTypeSupported(mimeType.string());
+    for (size_t i = 0; i < mFactories.size(); i++) {
+        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
+            if (mimeType != "") {
+                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
+                    return true;
+                }
+            } else {
+                return true;
+            }
         }
     }
-    return result;
+    return false;
 }
 
 status_t DrmHal::createPlugin(const uint8_t uuid[16],
         const String8& appPackageName) {
     Mutex::Autolock autoLock(mLock);
 
-    mPlugin = makeDrmPlugin(uuid, appPackageName);
+    for (size_t i = 0; i < mFactories.size(); i++) {
+        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
+            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
+        }
+    }
 
     if (mPlugin == NULL) {
         mInitCheck = ERROR_UNSUPPORTED;
@@ -628,7 +654,7 @@
     return hResult.isOk() ? err : DEAD_OBJECT;
 }
 
-status_t DrmHal::getSecureStops(List<Vector<uint8_t> > &secureStops) {
+status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/include/media/omx/1.0/Conversion.h
similarity index 98%
rename from media/libstagefright/omx/hal/1.0/utils/Conversion.h
rename to include/media/omx/1.0/Conversion.h
index c4876ac..f3f8441 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/include/media/omx/1.0/Conversion.h
@@ -29,12 +29,12 @@
 #include <binder/Binder.h>
 #include <binder/Status.h>
 #include <ui/FenceTime.h>
-#include <media/OMXFenceParcelable.h>
 #include <cutils/native_handle.h>
 #include <gui/IGraphicBufferProducer.h>
 
+#include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
-#include <VideoAPI.h>
+#include <media/hardware/VideoAPI.h>
 
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <android/hardware/media/omx/1.0/types.h>
@@ -191,6 +191,19 @@
 }
 
 /**
+ * \brief Convert `Return<Status>` to `binder::Status`.
+ *
+ * \param[in] t The source `Return<Status>`.
+ * \return The corresponding `binder::Status`.
+ */
+// convert: Return<Status> -> ::android::binder::Status
+inline ::android::binder::Status toBinderStatus(
+        Return<Status> const& t) {
+    return ::android::binder::Status::fromStatusT(
+            t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR);
+}
+
+/**
  * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
  * calls.
  *
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h b/include/media/omx/1.0/WGraphicBufferSource.h
similarity index 62%
rename from media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
rename to include/media/omx/1.0/WGraphicBufferSource.h
index 1090d52..0ca5f44 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
+++ b/include/media/omx/1.0/WGraphicBufferSource.h
@@ -20,8 +20,8 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
-#include <media/IOMX.h>
 #include <binder/Binder.h>
+#include <media/IOMX.h>
 
 #include <android/hardware/graphics/common/1.0/types.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
@@ -48,7 +48,6 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::sp;
-
 using ::android::IOMXNode;
 
 /**
@@ -60,7 +59,7 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-typedef ::android::IGraphicBufferSource LGraphicBufferSource;
+typedef ::android::binder::Status BnStatus;
 typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
 typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
         TGraphicBufferSource;
@@ -68,36 +67,19 @@
 struct LWGraphicBufferSource : public BnGraphicBufferSource {
     sp<TGraphicBufferSource> mBase;
     LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
-    ::android::binder::Status configure(
+    BnStatus configure(
             const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
-    ::android::binder::Status setSuspend(bool suspend, int64_t timeUs) override;
-    ::android::binder::Status setRepeatPreviousFrameDelayUs(
+    BnStatus setSuspend(bool suspend, int64_t timeUs) override;
+    BnStatus setRepeatPreviousFrameDelayUs(
             int64_t repeatAfterUs) override;
-    ::android::binder::Status setMaxFps(float maxFps) override;
-    ::android::binder::Status setTimeLapseConfig(
+    BnStatus setMaxFps(float maxFps) override;
+    BnStatus setTimeLapseConfig(
             int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
-    ::android::binder::Status setStartTimeUs(int64_t startTimeUs) override;
-    ::android::binder::Status setStopTimeUs(int64_t stopTimeUs) override;
-    ::android::binder::Status setColorAspects(int32_t aspects) override;
-    ::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
-    ::android::binder::Status signalEndOfInputStream() override;
-};
-
-struct TWGraphicBufferSource : public TGraphicBufferSource {
-    sp<LGraphicBufferSource> mBase;
-    TWGraphicBufferSource(sp<LGraphicBufferSource> const& base);
-    Return<void> configure(
-            const sp<IOmxNode>& omxNode, Dataspace dataspace) override;
-    Return<void> setSuspend(bool suspend, int64_t timeUs) override;
-    Return<void> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
-    Return<void> setMaxFps(float maxFps) override;
-    Return<void> setTimeLapseConfig(
-            int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
-    Return<void> setStartTimeUs(int64_t startTimeUs) override;
-    Return<void> setStopTimeUs(int64_t stopTimeUs) override;
-    Return<void> setColorAspects(const ColorAspects& aspects) override;
-    Return<void> setTimeOffsetUs(int64_t timeOffsetUs) override;
-    Return<void> signalEndOfInputStream() override;
+    BnStatus setStartTimeUs(int64_t startTimeUs) override;
+    BnStatus setStopTimeUs(int64_t stopTimeUs) override;
+    BnStatus setColorAspects(int32_t aspects) override;
+    BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override;
+    BnStatus signalEndOfInputStream() override;
 };
 
 }  // namespace utils
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.h b/include/media/omx/1.0/WOmx.h
similarity index 84%
rename from media/libstagefright/omx/hal/1.0/utils/WOmx.h
rename to include/media/omx/1.0/WOmx.h
index 7860f46..9268bd6 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.h
+++ b/include/media/omx/1.0/WOmx.h
@@ -20,7 +20,7 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
-#include "../../../../include/OMXNodeInstance.h"
+#include <media/IOMX.h>
 
 #include <android/hardware/media/omx/1.0/IOmx.h>
 
@@ -70,18 +70,6 @@
             sp<::android::IGraphicBufferSource>* bufferSource) override;
 };
 
-struct TWOmx : public IOmx {
-    sp<IOMX> mBase;
-    TWOmx(sp<IOMX> const& base);
-    Return<void> listNodes(listNodes_cb _hidl_cb) override;
-    Return<void> allocateNode(
-            const hidl_string& name,
-            const sp<IOmxObserver>& observer,
-            allocateNode_cb _hidl_cb) override;
-    Return<void> createInputSurface(createInputSurface_cb _hidl_cb) override;
-
-};
-
 }  // namespace utils
 }  // namespace V1_0
 }  // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h b/include/media/omx/1.0/WOmxBufferProducer.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
rename to include/media/omx/1.0/WOmxBufferProducer.h
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h b/include/media/omx/1.0/WOmxBufferSource.h
similarity index 98%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
rename to include/media/omx/1.0/WOmxBufferSource.h
index 086f648..86322da 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
+++ b/include/media/omx/1.0/WOmxBufferSource.h
@@ -21,7 +21,7 @@
 #include <hidl/Status.h>
 
 #include <binder/Binder.h>
-#include <media/OMXFenceParcelable.h>
+#include <OMXFenceParcelable.h>
 
 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
 #include <android/BnOMXBufferSource.h>
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h b/include/media/omx/1.0/WOmxNode.h
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
rename to include/media/omx/1.0/WOmxNode.h
index 46dfb49..3176a65 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
+++ b/include/media/omx/1.0/WOmxNode.h
@@ -20,9 +20,9 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
+#include <binder/HalToken.h>
 #include <utils/Errors.h>
-
-#include "../../../../include/OMXNodeInstance.h"
+#include <media/IOMX.h>
 
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -59,9 +59,8 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-struct LWOmxNode : public BnOMXNode {
-    sp<IOmxNode> mBase;
-    LWOmxNode(sp<IOmxNode> const& base);
+struct LWOmxNode : public H2BConverter<IOmxNode, IOMXNode, BnOMXNode> {
+    LWOmxNode(sp<IOmxNode> const& base) : CBase(base) {}
     status_t freeNode() override;
     status_t sendCommand(
             OMX_COMMANDTYPE cmd, OMX_S32 param) override;
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h b/include/media/omx/1.0/WOmxObserver.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
rename to include/media/omx/1.0/WOmxObserver.h
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h b/include/media/omx/1.0/WOmxProducerListener.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
rename to include/media/omx/1.0/WOmxProducerListener.h
diff --git a/include/ndk/NdkImage.h b/include/ndk/NdkImage.h
index 9a99287..15eae40 100644
--- a/include/ndk/NdkImage.h
+++ b/include/ndk/NdkImage.h
@@ -54,6 +54,97 @@
 // Formats not listed here will not be supported by AImageReader
 enum AIMAGE_FORMATS {
     /**
+     * 32 bits RGBA format, 8 bits for each of the four channels.
+     *
+     * <p>
+     * Corresponding formats:
+     * <ul>
+     * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM</li>
+     * <li>Vulkan: VK_FORMAT_R8G8B8A8_UNORM</li>
+     * <li>OpenGL ES: GL_RGBA8</li>
+     * </ul>
+     * </p>
+     *
+     * @see AImage
+     * @see AImageReader
+     * @see AHardwareBuffer
+     */
+    AIMAGE_FORMAT_RGBA_8888         = 0x1,
+
+    /**
+     * 32 bits RGBX format, 8 bits for each of the four channels.
+     *
+     * <p>
+     * Corresponding formats:
+     * <ul>
+     * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM</li>
+     * <li>Vulkan: VK_FORMAT_R8G8B8A8_UNORM</li>
+     * <li>OpenGL ES: GL_RGBA8</li>
+     * </ul>
+     * </p>
+     *
+     * @see AImage
+     * @see AImageReader
+     * @see AHardwareBuffer
+     */
+    AIMAGE_FORMAT_RGBX_8888         = 0x2,
+
+    /**
+     * 24 bits RGB format, 8 bits for each of the three channels.
+     *
+     * <p>
+     * Corresponding formats:
+     * <ul>
+     * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM</li>
+     * <li>Vulkan: VK_FORMAT_R8G8B8_UNORM</li>
+     * <li>OpenGL ES: GL_RGB8</li>
+     * </ul>
+     * </p>
+     *
+     * @see AImage
+     * @see AImageReader
+     * @see AHardwareBuffer
+     */
+    AIMAGE_FORMAT_RGB_888           = 0x3,
+
+    /**
+     * 16 bits RGB format, 5 bits for Red channel, 6 bits for Green channel,
+     * and 5 bits for Blue channel.
+     *
+     * <p>
+     * Corresponding formats:
+     * <ul>
+     * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM</li>
+     * <li>Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16</li>
+     * <li>OpenGL ES: GL_RGB565</li>
+     * </ul>
+     * </p>
+     *
+     * @see AImage
+     * @see AImageReader
+     * @see AHardwareBuffer
+     */
+    AIMAGE_FORMAT_RGB_565           = 0x4,
+
+    /**
+     * 64 bits RGBA format, 16 bits for each of the four channels.
+     *
+     * <p>
+     * Corresponding formats:
+     * <ul>
+     * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT</li>
+     * <li>Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT</li>
+     * <li>OpenGL ES: GL_RGBA16F</li>
+     * </ul>
+     * </p>
+     *
+     * @see AImage
+     * @see AImageReader
+     * @see AHardwareBuffer
+     */
+    AIMAGE_FORMAT_RGBA_FP16         = 0x16,
+
+    /**
      * Multi-plane Android YUV 420 format.
      *
      * <p>This format is a generic YCbCr format, capable of describing any 4:2:0
diff --git a/media/libaudiohal/EffectHalHidl.cpp b/media/libaudiohal/EffectHalHidl.cpp
index db115ef..539558d 100644
--- a/media/libaudiohal/EffectHalHidl.cpp
+++ b/media/libaudiohal/EffectHalHidl.cpp
@@ -194,8 +194,8 @@
         }
         return analyzeResult(retval);
     }
-    if (ret == -EAGAIN) {
-        // This normally retries no more than once.
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
         goto retry;
     }
     return ret;
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 77ba716..5b06b73 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -360,8 +360,8 @@
         }
         return ret;
     }
-    if (ret == -EAGAIN) {
-        // This normally retries no more than once.
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
         goto retry;
     }
     return ret;
@@ -620,8 +620,8 @@
         }
         return ret;
     }
-    if (ret == -EAGAIN) {
-        // This normally retries no more than once.
+    if (ret == -EAGAIN || ret == -EINTR) {
+        // Spurious wakeup. This normally retries no more than once.
         goto retry;
     }
     return ret;
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index eac532b..c057cf5 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -55,15 +55,36 @@
     OMXBuffer.cpp \
     Visualizer.cpp \
     StringArray.cpp \
+    omx/1.0/WGraphicBufferSource.cpp \
+    omx/1.0/WOmx.cpp \
+    omx/1.0/WOmxBufferProducer.cpp \
+    omx/1.0/WOmxBufferSource.cpp \
+    omx/1.0/WOmxNode.cpp \
+    omx/1.0/WOmxObserver.cpp \
+    omx/1.0/WOmxProducerListener.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
         libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
         libcamera_client libstagefright_foundation \
         libgui libdl libaudioutils libaudioclient \
         libmedia_helper libmediadrm \
+        libbase \
         libhidlbase \
+        libhidltransport \
+        libhwbinder \
+        libhidlmemory \
+        android.hidl.base@1.0 \
+        android.hidl.memory@1.0 \
+        android.hardware.graphics.common@1.0 \
+        android.hardware.media@1.0 \
+        android.hardware.media.omx@1.0 \
 
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libsonivox libmediadrm
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+        libbinder \
+        libsonivox \
+        libmediadrm \
+        android.hardware.media.omx@1.0 \
+        android.hidl.memory@1.0 \
 
 # for memory heap analysis
 LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
@@ -76,8 +97,9 @@
     $(TOP)/system/libhidl/base/include \
     $(TOP)/frameworks/native/include/media/openmax \
     $(TOP)/frameworks/av/include/media/ \
-    $(TOP)/frameworks/av/media/libstagefright \
     $(TOP)/frameworks/av/media/libmedia/aidl \
+    $(TOP)/frameworks/av/include \
+    $(TOP)/frameworks/native/include \
     $(call include-path-for, audio-utils)
 
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
diff --git a/media/libmedia/IDataSource.cpp b/media/libmedia/IDataSource.cpp
index 7df3b65..31c85af 100644
--- a/media/libmedia/IDataSource.cpp
+++ b/media/libmedia/IDataSource.cpp
@@ -55,8 +55,16 @@
         data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
         data.writeInt64(offset);
         data.writeInt64(size);
-        remote()->transact(READ_AT, data, &reply);
-        return reply.readInt64();
+        status_t err = remote()->transact(READ_AT, data, &reply);
+        if (err != OK) {
+            return err;
+        }
+        int64_t value = 0;
+        err = reply.readInt64(&value);
+        if (err != OK) {
+            return err;
+        }
+        return (ssize_t)value;
     }
 
     virtual status_t getSize(off64_t* size) {
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 67939b2..223ca6b 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -29,6 +29,7 @@
 #include <utils/NativeHandle.h>
 #include <gui/IGraphicBufferProducer.h>
 
+#include <omx/1.0/WOmxNode.h>
 #include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 
@@ -448,8 +449,115 @@
     }
 };
 
+using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
+class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> {
+public:
+    HpOMXNode(const sp<IBinder>& base) : PBase(base) {}
+
+    virtual status_t freeNode() {
+        return mBase->freeNode();
+    }
+
+    virtual status_t sendCommand(
+            OMX_COMMANDTYPE cmd, OMX_S32 param) {
+        return mBase->sendCommand(cmd, param);
+    }
+
+    virtual status_t getParameter(
+            OMX_INDEXTYPE index, void *params, size_t size) {
+        return mBase->getParameter(index, params, size);
+    }
+
+    virtual status_t setParameter(
+            OMX_INDEXTYPE index, const void *params, size_t size) {
+        return mBase->setParameter(index, params, size);
+    }
+
+    virtual status_t getConfig(
+            OMX_INDEXTYPE index, void *params, size_t size) {
+        return mBase->getConfig(index, params, size);
+    }
+
+    virtual status_t setConfig(
+            OMX_INDEXTYPE index, const void *params, size_t size) {
+        return mBase->setConfig(index, params, size);
+    }
+
+    virtual status_t setPortMode(
+            OMX_U32 port_index, IOMX::PortMode mode) {
+        return mBase->setPortMode(port_index, mode);
+    }
+
+    virtual status_t prepareForAdaptivePlayback(
+            OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+        return mBase->prepareForAdaptivePlayback(
+                portIndex, enable, maxFrameWidth, maxFrameHeight);
+    }
+
+    virtual status_t configureVideoTunnelMode(
+            OMX_U32 portIndex, OMX_BOOL tunneled,
+            OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
+        return mBase->configureVideoTunnelMode(
+                portIndex, tunneled, audioHwSync, sidebandHandle);
+    }
+
+    virtual status_t getGraphicBufferUsage(
+            OMX_U32 port_index, OMX_U32* usage) {
+        return mBase->getGraphicBufferUsage(port_index, usage);
+    }
+
+    virtual status_t setInputSurface(
+            const sp<IOMXBufferSource> &bufferSource) {
+        return mBase->setInputSurface(bufferSource);
+    }
+
+    virtual status_t allocateSecureBuffer(
+            OMX_U32 port_index, size_t size, buffer_id *buffer,
+            void **buffer_data, sp<NativeHandle> *native_handle) {
+        return mBase->allocateSecureBuffer(
+                port_index, size, buffer, buffer_data, native_handle);
+    }
+
+    virtual status_t useBuffer(
+            OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
+        return mBase->useBuffer(port_index, omxBuf, buffer);
+    }
+
+    virtual status_t freeBuffer(
+            OMX_U32 port_index, buffer_id buffer) {
+        return mBase->freeBuffer(port_index, buffer);
+    }
+
+    virtual status_t fillBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) {
+        return mBase->fillBuffer(buffer, omxBuf, fenceFd);
+    }
+
+    virtual status_t emptyBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf,
+            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) {
+        return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
+    }
+
+    virtual status_t getExtensionIndex(
+            const char *parameter_name,
+            OMX_INDEXTYPE *index) {
+        return mBase->getExtensionIndex(parameter_name, index);
+    }
+
+    virtual status_t dispatchMessage(const omx_message &msg) {
+        return mBase->dispatchMessage(msg);
+    }
+
+    // TODO: this is temporary, will be removed when quirks move to OMX side
+    virtual status_t setQuirks(OMX_U32 quirks) {
+        return mBase->setQuirks(quirks);
+    }
+};
+
 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
-IMPLEMENT_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
+IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
 
 ////////////////////////////////////////////////////////////////////////////////
 
diff --git a/media/libmedia/include/CryptoHal.h b/media/libmedia/include/CryptoHal.h
index 9d0c3e4..28ade20 100644
--- a/media/libmedia/include/CryptoHal.h
+++ b/media/libmedia/include/CryptoHal.h
@@ -20,11 +20,14 @@
 
 #include <android/hardware/drm/1.0/ICryptoFactory.h>
 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
+
 #include <media/ICrypto.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 
-#include "SharedLibrary.h"
+using ::android::hardware::drm::V1_0::ICryptoFactory;
+using ::android::hardware::drm::V1_0::ICryptoPlugin;
+using ::android::hardware::drm::V1_0::SharedBuffer;
 
 class IMemoryHeap;
 
@@ -60,9 +63,8 @@
 private:
     mutable Mutex mLock;
 
-    sp<SharedLibrary> mLibrary;
-    sp<::android::hardware::drm::V1_0::ICryptoFactory> mFactory;
-    sp<::android::hardware::drm::V1_0::ICryptoPlugin> mPlugin;
+    const Vector<sp<ICryptoFactory>> mFactories;
+    sp<ICryptoPlugin> mPlugin;
 
     /**
      * mInitCheck is:
@@ -75,16 +77,13 @@
     KeyedVector<void *, uint32_t> mHeapBases;
     uint32_t mNextBufferId;
 
-    sp<::android::hardware::drm::V1_0::ICryptoFactory>
-            makeCryptoFactory();
-    sp<::android::hardware::drm::V1_0::ICryptoPlugin>
-            makeCryptoPlugin(const uint8_t uuid[16], const void *initData,
-                size_t size);
+    Vector<sp<ICryptoFactory>> makeCryptoFactories();
+    sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory,
+            const uint8_t uuid[16], const void *initData, size_t size);
 
     void setHeapBase(const sp<IMemoryHeap>& heap);
 
-    status_t toSharedBuffer(const sp<IMemory>& memory,
-            ::android::hardware::drm::V1_0::SharedBuffer* buffer);
+    status_t toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer);
 
     DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
 };
diff --git a/media/libmedia/include/DrmHal.h b/media/libmedia/include/DrmHal.h
index 82d2555..e031765 100644
--- a/media/libmedia/include/DrmHal.h
+++ b/media/libmedia/include/DrmHal.h
@@ -87,7 +87,7 @@
                                               Vector<uint8_t> &certificate,
                                               Vector<uint8_t> &wrappedKey);
 
-    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops);
+    virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops);
     virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
 
     virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
@@ -158,7 +158,7 @@
     mutable Mutex mEventLock;
     mutable Mutex mNotifyLock;
 
-    sp<IDrmFactory> mFactory;
+    const Vector<sp<IDrmFactory>> mFactories;
     sp<IDrmPlugin> mPlugin;
 
     /**
@@ -169,9 +169,9 @@
      */
     status_t mInitCheck;
 
-    sp<IDrmFactory> makeDrmFactory();
-    sp<IDrmPlugin> makeDrmPlugin(const uint8_t uuid[16],
-                                 const String8 &appPackageName);
+    Vector<sp<IDrmFactory>> makeDrmFactories();
+    sp<IDrmPlugin> makeDrmPlugin(const sp<IDrmFactory>& factory,
+            const uint8_t uuid[16], const String8& appPackageName);
 
     void writeByteArray(Parcel &obj, const hidl_vec<uint8_t>& array);
 
diff --git a/media/libmedia/include/IMediaCodecService.h b/media/libmedia/include/IMediaCodecService.h
index 984a0fd..da3c5a03 100644
--- a/media/libmedia/include/IMediaCodecService.h
+++ b/media/libmedia/include/IMediaCodecService.h
@@ -21,7 +21,7 @@
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
 #include <media/IDataSource.h>
-#include <include/OMX.h>
+#include <media/IOMX.h>
 
 namespace android {
 
diff --git a/media/libmedia/include/IOMX.h b/media/libmedia/include/IOMX.h
index 39b9ad4..b4fc04c 100644
--- a/media/libmedia/include/IOMX.h
+++ b/media/libmedia/include/IOMX.h
@@ -19,6 +19,7 @@
 #define ANDROID_IOMX_H_
 
 #include <binder/IInterface.h>
+#include <binder/HalToken.h>
 #include <utils/List.h>
 #include <utils/String8.h>
 #include <cutils/native_handle.h>
@@ -26,6 +27,7 @@
 #include <list>
 
 #include <media/hardware/MetadataBufferType.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
 
 #include <OMX_Core.h>
 #include <OMX_Video.h>
@@ -42,6 +44,8 @@
 class OMXBuffer;
 struct omx_message;
 
+using hardware::media::omx::V1_0::IOmxNode;
+
 class IOMX : public IInterface {
 public:
     DECLARE_META_INTERFACE(OMX);
@@ -83,7 +87,7 @@
 
 class IOMXNode : public IInterface {
 public:
-    DECLARE_META_INTERFACE(OMXNode);
+    DECLARE_HYBRID_META_INTERFACE(OMXNode, IOmxNode);
 
     typedef IOMX::buffer_id buffer_id;
 
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
new file mode 100644
index 0000000..b4e2975
--- /dev/null
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/Conversion.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+namespace utils {
+
+// LWGraphicBufferSource
+LWGraphicBufferSource::LWGraphicBufferSource(
+        sp<TGraphicBufferSource> const& base) : mBase(base) {
+}
+
+BnStatus LWGraphicBufferSource::configure(
+        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+    sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
+    return toBinderStatus(mBase->configure(
+            hOmxNode == nullptr ? new TWOmxNode(omxNode) : hOmxNode,
+            toHardwareDataspace(dataSpace)));
+}
+
+BnStatus LWGraphicBufferSource::setSuspend(
+        bool suspend, int64_t timeUs) {
+    return toBinderStatus(mBase->setSuspend(suspend, timeUs));
+}
+
+BnStatus LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+        int64_t repeatAfterUs) {
+    return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+BnStatus LWGraphicBufferSource::setMaxFps(float maxFps) {
+    return toBinderStatus(mBase->setMaxFps(maxFps));
+}
+
+BnStatus LWGraphicBufferSource::setTimeLapseConfig(
+        int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+    return toBinderStatus(mBase->setTimeLapseConfig(
+            timePerFrameUs, timePerCaptureUs));
+}
+
+BnStatus LWGraphicBufferSource::setStartTimeUs(
+        int64_t startTimeUs) {
+    return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
+}
+
+BnStatus LWGraphicBufferSource::setStopTimeUs(
+        int64_t stopTimeUs) {
+    return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
+}
+
+BnStatus LWGraphicBufferSource::setColorAspects(
+        int32_t aspects) {
+    return toBinderStatus(mBase->setColorAspects(
+            toHardwareColorAspects(aspects)));
+}
+
+BnStatus LWGraphicBufferSource::setTimeOffsetUs(
+        int64_t timeOffsetsUs) {
+    return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
+}
+
+BnStatus LWGraphicBufferSource::signalEndOfInputStream() {
+    return toBinderStatus(mBase->signalEndOfInputStream());
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace omx
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp b/media/libmedia/omx/1.0/WOmx.cpp
similarity index 67%
rename from media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
rename to media/libmedia/omx/1.0/WOmx.cpp
index 00f40cd..8e4e147 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
+++ b/media/libmedia/omx/1.0/WOmx.cpp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#include "WOmx.h"
-#include "WOmxNode.h"
-#include "WOmxObserver.h"
-#include "WOmxBufferProducer.h"
-#include "WGraphicBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmx.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxObserver.h>
+#include <media/omx/1.0/WOmxBufferProducer.h>
+#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
@@ -79,45 +79,6 @@
     return transStatus == NO_ERROR ? fnStatus : transStatus;
 }
 
-// TWOmx
-TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
-}
-
-Return<void> TWOmx::listNodes(listNodes_cb _hidl_cb) {
-    List<IOMX::ComponentInfo> lList;
-    Status status = toStatus(mBase->listNodes(&lList));
-
-    hidl_vec<IOmx::ComponentInfo> tList;
-    tList.resize(lList.size());
-    size_t i = 0;
-    for (auto const& lInfo : lList) {
-        convertTo(&(tList[i++]), lInfo);
-    }
-    _hidl_cb(status, tList);
-    return Void();
-}
-
-Return<void> TWOmx::allocateNode(
-        const hidl_string& name,
-        const sp<IOmxObserver>& observer,
-        allocateNode_cb _hidl_cb) {
-    sp<IOMXNode> omxNode;
-    Status status = toStatus(mBase->allocateNode(
-            name, new LWOmxObserver(observer), &omxNode));
-    _hidl_cb(status, new TWOmxNode(omxNode));
-    return Void();
-}
-
-Return<void> TWOmx::createInputSurface(createInputSurface_cb _hidl_cb) {
-    sp<::android::IGraphicBufferProducer> lProducer;
-    sp<::android::IGraphicBufferSource> lSource;
-    status_t status = mBase->createInputSurface(&lProducer, &lSource);
-    _hidl_cb(toStatus(status),
-             new TWOmxBufferProducer(lProducer),
-             new TWGraphicBufferSource(lSource));
-    return Void();
-}
-
 }  // namespace utils
 }  // namespace V1_0
 }  // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp b/media/libmedia/omx/1.0/WOmxBufferProducer.cpp
similarity index 88%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
rename to media/libmedia/omx/1.0/WOmxBufferProducer.cpp
index e9a93b9..03499f2 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
+++ b/media/libmedia/omx/1.0/WOmxBufferProducer.cpp
@@ -16,11 +16,11 @@
 
 #define LOG_TAG "WOmxBufferProducer-utils"
 
-#include <android-base/logging.h>
+#include <utils/Log.h>
 
-#include "WOmxBufferProducer.h"
-#include "WOmxProducerListener.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxBufferProducer.h>
+#include <media/omx/1.0/WOmxProducerListener.h>
+#include <media/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
@@ -72,8 +72,7 @@
 
     native_handle_t* nh = nullptr;
     if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
-        LOG(ERROR) << "TWOmxBufferProducer::dequeueBuffer - "
-                "Invalid output fence";
+        ALOGE("TWOmxBufferProducer::dequeueBuffer - Invalid output fence");
         _hidl_cb(toStatus(status),
                  static_cast<int32_t>(slot),
                  tFence,
@@ -82,8 +81,7 @@
     }
     std::vector<std::vector<native_handle_t*> > nhAA;
     if (getFrameTimestamps && !wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
-        LOG(ERROR) << "TWOmxBufferProducer::dequeueBuffer - "
-                "Invalid output timestamps";
+        ALOGE("TWOmxBufferProducer::dequeueBuffer - Invalid output timestamps");
         _hidl_cb(toStatus(status),
                  static_cast<int32_t>(slot),
                  tFence,
@@ -120,16 +118,14 @@
     hidl_handle tFence;
 
     if (outBuffer == nullptr) {
-        LOG(ERROR) << "TWOmxBufferProducer::detachNextBuffer - "
-                "Invalid output buffer";
+        ALOGE("TWOmxBufferProducer::detachNextBuffer - Invalid output buffer");
         _hidl_cb(toStatus(status), tBuffer, tFence);
         return Void();
     }
     wrapAs(&tBuffer, *outBuffer);
     native_handle_t* nh = nullptr;
     if ((outFence != nullptr) && !wrapAs(&tFence, &nh, *outFence)) {
-        LOG(ERROR) << "TWOmxBufferProducer::detachNextBuffer - "
-                "Invalid output fence";
+        ALOGE("TWOmxBufferProducer::detachNextBuffer - Invalid output fence");
         _hidl_cb(toStatus(status), tBuffer, tFence);
         return Void();
     }
@@ -145,8 +141,8 @@
     int outSlot;
     sp<GraphicBuffer> lBuffer = new GraphicBuffer();
     if (!convertTo(lBuffer.get(), buffer)) {
-        LOG(ERROR) << "TWOmxBufferProducer::attachBuffer - "
-                "Invalid input native window buffer";
+        ALOGE("TWOmxBufferProducer::attachBuffer - "
+                "Invalid input native window buffer");
         _hidl_cb(toStatus(BAD_VALUE), -1);
         return Void();
     }
@@ -166,8 +162,7 @@
             NATIVE_WINDOW_SCALING_MODE_FREEZE,
             0, ::android::Fence::NO_FENCE);
     if (!convertTo(&lInput, input)) {
-        LOG(ERROR) << "TWOmxBufferProducer::queueBuffer - "
-                "Invalid input";
+        ALOGE("TWOmxBufferProducer::queueBuffer - Invalid input");
         _hidl_cb(toStatus(BAD_VALUE), tOutput);
         return Void();
     }
@@ -177,8 +172,7 @@
 
     std::vector<std::vector<native_handle_t*> > nhAA;
     if (!wrapAs(&tOutput, &nhAA, lOutput)) {
-        LOG(ERROR) << "TWOmxBufferProducer::queueBuffer - "
-                "Invalid output";
+        ALOGE("TWOmxBufferProducer::queueBuffer - Invalid output");
         _hidl_cb(toStatus(BAD_VALUE), tOutput);
         return Void();
     }
@@ -196,8 +190,7 @@
         int32_t slot, const hidl_handle& fence) {
     sp<Fence> lFence = new Fence();
     if (!convertTo(lFence.get(), fence)) {
-        LOG(ERROR) << "TWOmxBufferProducer::cancelBuffer - "
-                "Invalid input fence";
+        ALOGE("TWOmxBufferProducer::cancelBuffer - Invalid input fence");
         return toStatus(BAD_VALUE);
     }
     return toStatus(mBase->cancelBuffer(static_cast<int>(slot), lFence));
@@ -224,8 +217,7 @@
     QueueBufferOutput tOutput;
     std::vector<std::vector<native_handle_t*> > nhAA;
     if (!wrapAs(&tOutput, &nhAA, lOutput)) {
-        LOG(ERROR) << "TWOmxBufferProducer::connect - "
-                "Invalid output";
+        ALOGE("TWOmxBufferProducer::connect - Invalid output");
         _hidl_cb(toStatus(status), tOutput);
         return Void();
     }
@@ -300,8 +292,8 @@
     hidl_handle tOutFence;
     native_handle_t* nh = nullptr;
     if ((lOutFence == nullptr) || !wrapAs(&tOutFence, &nh, *lOutFence)) {
-        LOG(ERROR) << "TWOmxBufferProducer::getLastQueuedBuffer - "
-                "Invalid output fence";
+        ALOGE("TWOmxBufferProducer::getLastQueuedBuffer - "
+                "Invalid output fence");
         _hidl_cb(toStatus(status),
                 tOutBuffer,
                 tOutFence,
@@ -323,8 +315,8 @@
     FrameEventHistoryDelta tDelta;
     std::vector<std::vector<native_handle_t*> > nhAA;
     if (!wrapAs(&tDelta, &nhAA, lDelta)) {
-        LOG(ERROR) << "TWOmxBufferProducer::getFrameTimestamps - "
-                "Invalid output frame timestamps";
+        ALOGE("TWOmxBufferProducer::getFrameTimestamps - "
+                "Invalid output frame timestamps");
         _hidl_cb(tDelta);
         return Void();
     }
@@ -392,13 +384,13 @@
                 fnStatus = toStatusT(status);
                 *slot = tSlot;
                 if (!convertTo(fence->get(), tFence)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::dequeueBuffer - "
-                            "Invalid output fence";
+                    ALOGE("LWOmxBufferProducer::dequeueBuffer - "
+                            "Invalid output fence");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
                 if (outTimestamps && !convertTo(outTimestamps, tTs)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::dequeueBuffer - "
-                            "Invalid output timestamps";
+                    ALOGE("LWOmxBufferProducer::dequeueBuffer - "
+                            "Invalid output timestamps");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
             }));
@@ -421,13 +413,13 @@
                     hidl_handle const& tFence) {
                 fnStatus = toStatusT(status);
                 if (!convertTo(outFence->get(), tFence)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::detachNextBuffer - "
-                            "Invalid output fence";
+                    ALOGE("LWOmxBufferProducer::detachNextBuffer - "
+                            "Invalid output fence");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
                 if (!convertTo(outBuffer->get(), tBuffer)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::detachNextBuffer - "
-                            "Invalid output buffer";
+                    ALOGE("LWOmxBufferProducer::detachNextBuffer - "
+                            "Invalid output buffer");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
             }));
@@ -454,8 +446,7 @@
     IOmxBufferProducer::QueueBufferInput tInput;
     native_handle_t* nh;
     if (!wrapAs(&tInput, &nh, input)) {
-        LOG(ERROR) << "LWOmxBufferProducer::queueBuffer - "
-                "Invalid input";
+        ALOGE("LWOmxBufferProducer::queueBuffer - Invalid input");
         return BAD_VALUE;
     }
     status_t fnStatus;
@@ -465,8 +456,8 @@
                     IOmxBufferProducer::QueueBufferOutput const& tOutput) {
                 fnStatus = toStatusT(status);
                 if (!convertTo(output, tOutput)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::queueBuffer - "
-                            "Invalid output";
+                    ALOGE("LWOmxBufferProducer::queueBuffer - "
+                            "Invalid output");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
             }));
@@ -478,8 +469,7 @@
     hidl_handle tFence;
     native_handle_t* nh = nullptr;
     if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
-        LOG(ERROR) << "LWOmxBufferProducer::cancelBuffer - "
-                "Invalid input fence";
+        ALOGE("LWOmxBufferProducer::cancelBuffer - Invalid input fence");
         return BAD_VALUE;
     }
 
@@ -513,8 +503,7 @@
                     IOmxBufferProducer::QueueBufferOutput const& tOutput) {
                 fnStatus = toStatusT(status);
                 if (!convertTo(output, tOutput)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::connect - "
-                            "Invalid output";
+                    ALOGE("LWOmxBufferProducer::connect - Invalid output");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
             }));
@@ -579,14 +568,14 @@
                 fnStatus = toStatusT(status);
                 *outBuffer = new GraphicBuffer();
                 if (!convertTo(outBuffer->get(), buffer)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::getLastQueuedBuffer - "
-                            "Invalid output buffer";
+                    ALOGE("LWOmxBufferProducer::getLastQueuedBuffer - "
+                            "Invalid output buffer");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
                 *outFence = new Fence();
                 if (!convertTo(outFence->get(), fence)) {
-                    LOG(ERROR) << "LWOmxBufferProducer::getLastQueuedBuffer - "
-                            "Invalid output fence";
+                    ALOGE("LWOmxBufferProducer::getLastQueuedBuffer - "
+                            "Invalid output fence");
                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
                 }
                 std::copy(transformMatrix.data(),
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp b/media/libmedia/omx/1.0/WOmxBufferSource.cpp
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
rename to media/libmedia/omx/1.0/WOmxBufferSource.cpp
index fe565e6..7cca5bd 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WOmxBufferSource.cpp
@@ -16,8 +16,8 @@
 
 #include <utils/String8.h>
 
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libmedia/omx/1.0/WOmxNode.cpp
similarity index 98%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
rename to media/libmedia/omx/1.0/WOmxNode.cpp
index df191c7..b5186b5 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
+++ b/media/libmedia/omx/1.0/WOmxNode.cpp
@@ -16,9 +16,9 @@
 
 #include <algorithm>
 
-#include "WOmxNode.h"
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
@@ -30,9 +30,6 @@
 using ::android::hardware::Void;
 
 // LWOmxNode
-LWOmxNode::LWOmxNode(sp<IOmxNode> const& base) : mBase(base) {
-}
-
 status_t LWOmxNode::freeNode() {
     return toStatusT(mBase->freeNode());
 }
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libmedia/omx/1.0/WOmxObserver.cpp
similarity index 92%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
rename to media/libmedia/omx/1.0/WOmxObserver.cpp
index 05ec37e..fa0407f 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
+++ b/media/libmedia/omx/1.0/WOmxObserver.cpp
@@ -18,12 +18,12 @@
 
 #include <vector>
 
-#include <android-base/logging.h>
+#include <utils/Log.h>
 #include <cutils/native_handle.h>
 #include <binder/Binder.h>
 
-#include "WOmxObserver.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxObserver.h>
+#include <media/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
@@ -47,7 +47,7 @@
     }
     auto transResult = mBase->onMessages(tMessages);
     if (!transResult.isOk()) {
-        LOG(ERROR) << "LWOmxObserver::onMessages - Transaction failed";
+        ALOGE("LWOmxObserver::onMessages - Transaction failed");
     }
     for (auto& handle : handles) {
         native_handle_close(handle);
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp b/media/libmedia/omx/1.0/WOmxProducerListener.cpp
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
rename to media/libmedia/omx/1.0/WOmxProducerListener.cpp
index 80b0f71..3ee381f 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
+++ b/media/libmedia/omx/1.0/WOmxProducerListener.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "WOmxProducerListener.h"
+#include <media/omx/1.0/WOmxProducerListener.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 05e6201..ad4c223 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -258,7 +258,11 @@
 }
 
 status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
-    return mLiveSession->seekTo(seekTimeUs, mode);
+    if (mLiveSession->isSeekable()) {
+        return mLiveSession->seekTo(seekTimeUs, mode);
+    } else {
+        return INVALID_OPERATION;
+    }
 }
 
 void NuPlayer::HTTPLiveSource::pollForRawData(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index abea5bc..19c4d85 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -49,6 +49,7 @@
       mSeekInProgress(false),
       mPlayingTimeUs(0),
       mLooper(new ALooper),
+      mPlayer(new NuPlayer(pid)),
       mPlayerFlags(0),
       mAnalyticsItem(NULL),
       mAtEOS(false),
@@ -66,7 +67,6 @@
             true,  /* canCallJava */
             PRIORITY_AUDIO);
 
-    mPlayer = new NuPlayer(pid);
     mLooper->registerHandler(mPlayer);
 
     mPlayer->setDriver(this);
@@ -206,9 +206,11 @@
 
 status_t NuPlayerDriver::getDefaultBufferingSettings(BufferingSettings* buffering) {
     ALOGV("getDefaultBufferingSettings(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-    if (mState == STATE_IDLE) {
-        return INVALID_OPERATION;
+    {
+        Mutex::Autolock autoLock(mLock);
+        if (mState == STATE_IDLE) {
+            return INVALID_OPERATION;
+        }
     }
 
     return mPlayer->getDefaultBufferingSettings(buffering);
@@ -216,9 +218,11 @@
 
 status_t NuPlayerDriver::setBufferingSettings(const BufferingSettings& buffering) {
     ALOGV("setBufferingSettings(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-    if (mState == STATE_IDLE) {
-        return INVALID_OPERATION;
+    {
+        Mutex::Autolock autoLock(mLock);
+        if (mState == STATE_IDLE) {
+            return INVALID_OPERATION;
+        }
     }
 
     return mPlayer->setBufferingSettings(buffering);
@@ -994,8 +998,6 @@
 {
     ALOGV("prepareDrm(%p) state: %d", this, mState);
 
-    Mutex::Autolock autoLock(mLock);
-
     // leaving the state verification for mediaplayer.cpp
     status_t ret = mPlayer->prepareDrm(uuid, drmSessionId);
 
@@ -1008,8 +1010,6 @@
 {
     ALOGV("releaseDrm(%p) state: %d", this, mState);
 
-    Mutex::Autolock autoLock(mLock);
-
     // leaving the state verification for mediaplayer.cpp
     status_t ret = mPlayer->releaseDrm();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 972a348..082f71a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -127,7 +127,7 @@
     // <<<
 
     sp<ALooper> mLooper;
-    sp<NuPlayer> mPlayer;
+    const sp<NuPlayer> mPlayer;
     sp<AudioSink> mAudioSink;
     uint32_t mPlayerFlags;
 
diff --git a/media/libnbaio/PipeReader.cpp b/media/libnbaio/PipeReader.cpp
index bd468a6..be5c0c1 100644
--- a/media/libnbaio/PipeReader.cpp
+++ b/media/libnbaio/PipeReader.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/compiler.h>
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <media/nbaio/PipeReader.h>
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 78f28ae..81eecaf 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -45,6 +45,7 @@
 #include <media/stagefright/SurfaceUtils.h>
 #include <media/hardware/HardwareAPI.h>
 #include <media/OMXBuffer.h>
+#include <media/omx/1.0/WOmxNode.h>
 
 #include <hidlmemory/mapping.h>
 
@@ -63,7 +64,6 @@
 
 #include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
-#include "omx/hal/1.0/utils/WOmxNode.h"
 
 namespace android {
 
@@ -6133,10 +6133,7 @@
     if (mDeathNotifier != NULL) {
         if (mCodec->mOMXNode != NULL) {
             if (mCodec->getTrebleFlag()) {
-                auto tOmxNode =
-                        (static_cast<
-                        ::android::hardware::media::omx::V1_0::utils::
-                        LWOmxNode*>(mCodec->mOMXNode.get()))->mBase;
+                auto tOmxNode = mCodec->mOMXNode->getHalInterface();
                 tOmxNode->unlinkToDeath(mDeathNotifier);
             } else {
                 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
@@ -6304,8 +6301,7 @@
 
     mDeathNotifier = new DeathNotifier(notify);
     if (mCodec->getTrebleFlag()) {
-        auto tOmxNode = (static_cast<::android::hardware::media::omx::V1_0::
-                utils::LWOmxNode*>(omxNode.get()))->mBase;
+        auto tOmxNode = omxNode->getHalInterface();
         if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
             mDeathNotifier.clear();
         }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 140ceb1..18cfc0e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -120,7 +120,6 @@
         android.hidl.allocator@1.0 \
         android.hidl.memory@1.0 \
         android.hardware.media.omx@1.0 \
-        android.hardware.media.omx@1.0-utils \
 
 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libmedia
 
@@ -131,7 +130,8 @@
 LOCAL_CFLAGS += -DENABLE_STAGEFRIGHT_EXPERIMENTS
 endif
 
-LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_MODULE:= libstagefright
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 70916dc..a017737 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -72,6 +72,7 @@
                 Vector<SidxEntry> &sidx,
                 const Trex *trex,
                 off64_t firstMoofOffset);
+    virtual status_t init();
 
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop();
@@ -2175,7 +2176,10 @@
             *offset += chunk_size;
 
             if (underQTMetaPath(mPath, 3)) {
-                parseQTMetaKey(data_offset, chunk_data_size);
+                status_t err = parseQTMetaKey(data_offset, chunk_data_size);
+                if (err != OK) {
+                    return err;
+                }
             }
             break;
         }
@@ -2334,7 +2338,10 @@
 
         case FOURCC('s', 'i', 'd', 'x'):
         {
-            parseSegmentIndex(data_offset, chunk_data_size);
+            status_t err = parseSegmentIndex(data_offset, chunk_data_size);
+            if (err != OK) {
+                return err;
+            }
             *offset += chunk_size;
             return UNKNOWN_ERROR; // stop parsing after sidx
         }
@@ -2382,7 +2389,10 @@
             // check if we're parsing 'ilst' for meta keys
             // if so, treat type as a number (key-id).
             if (underQTMetaPath(mPath, 3)) {
-                parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
+                status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
+                if (err != OK) {
+                    return err;
+                }
             }
 
             *offset += chunk_size;
@@ -3302,9 +3312,13 @@
         }
     }
 
-    return new MPEG4Source(this,
+    sp<MPEG4Source> source =  new MPEG4Source(this,
             track->meta, mDataSource, track->timescale, track->sampleTable,
             mSidxEntries, trex, mMoofOffset);
+    if (source->init() != OK) {
+        return NULL;
+    }
+    return source;
 }
 
 // static
@@ -3701,6 +3715,7 @@
       mTrex(trex),
       mFirstMoofOffset(firstMoofOffset),
       mCurrentMoofOffset(firstMoofOffset),
+      mNextMoofOffset(-1),
       mCurrentTime(0),
       mCurrentSampleInfoAllocSize(0),
       mCurrentSampleInfoSizes(NULL),
@@ -3765,10 +3780,14 @@
 
     CHECK(format->findInt32(kKeyTrackID, &mTrackId));
 
+}
+
+status_t MPEG4Source::init() {
     if (mFirstMoofOffset != 0) {
         off64_t offset = mFirstMoofOffset;
-        parseChunk(&offset);
+        return parseChunk(&offset);
     }
+    return OK;
 }
 
 MPEG4Source::~MPEG4Source() {
@@ -3899,9 +3918,30 @@
                     }
                     chunk_size = ntohl(hdr[0]);
                     chunk_type = ntohl(hdr[1]);
+                    if (chunk_size == 1) {
+                        // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
+                        // which is defined in 4.2 Object Structure.
+                        // When chunk_size==1, 8 bytes follows as "largesize".
+                        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
+                            return ERROR_IO;
+                        }
+                        chunk_size = ntoh64(chunk_size);
+                        if (chunk_size < 16) {
+                            // The smallest valid chunk is 16 bytes long in this case.
+                            return ERROR_MALFORMED;
+                        }
+                    } else if (chunk_size == 0) {
+                        // next box extends to end of file.
+                    } else if (chunk_size < 8) {
+                        // The smallest valid chunk is 8 bytes long in this case.
+                        return ERROR_MALFORMED;
+                    }
+
                     if (chunk_type == FOURCC('m', 'o', 'o', 'f')) {
                         mNextMoofOffset = *offset;
                         break;
+                    } else if (chunk_size == 0) {
+                        break;
                     }
                     *offset += chunk_size;
                 }
@@ -4785,17 +4825,25 @@
                 totalOffset += se->mSize;
             }
             mCurrentMoofOffset = totalOffset;
+            mNextMoofOffset = -1;
             mCurrentSamples.clear();
             mCurrentSampleIndex = 0;
-            parseChunk(&totalOffset);
+            status_t err = parseChunk(&totalOffset);
+            if (err != OK) {
+                return err;
+            }
             mCurrentTime = totalTime * mTimescale / 1000000ll;
         } else {
             // without sidx boxes, we can only seek to 0
             mCurrentMoofOffset = mFirstMoofOffset;
+            mNextMoofOffset = -1;
             mCurrentSamples.clear();
             mCurrentSampleIndex = 0;
             off64_t tmp = mCurrentMoofOffset;
-            parseChunk(&tmp);
+            status_t err = parseChunk(&tmp);
+            if (err != OK) {
+                return err;
+            }
             mCurrentTime = 0;
         }
 
@@ -4824,7 +4872,10 @@
             mCurrentMoofOffset = nextMoof;
             mCurrentSamples.clear();
             mCurrentSampleIndex = 0;
-            parseChunk(&nextMoof);
+            status_t err = parseChunk(&nextMoof);
+            if (err != OK) {
+                return err;
+            }
             if (mCurrentSampleIndex >= mCurrentSamples.size()) {
                 return ERROR_END_OF_STREAM;
             }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index d46ef3c..cafedba 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -3669,11 +3669,19 @@
 
     mOwner->beginBox("ctts");
     mOwner->writeInt32(0);  // version=0, flags=0
-    uint32_t delta = mMinCttsOffsetTimeUs - getStartTimeOffsetScaledTime();
+    int64_t delta = mMinCttsOffsetTimeUs - getStartTimeOffsetScaledTime();
     mCttsTableEntries->adjustEntries([delta](size_t /* ix */, uint32_t (&value)[2]) {
         // entries are <count, ctts> pairs; adjust only ctts
         uint32_t duration = htonl(value[1]); // back to host byte order
-        value[1] = htonl(duration - delta);
+        // Prevent overflow and underflow
+        if (delta > duration) {
+            duration = 0;
+        } else if (delta < 0 && UINT32_MAX + delta < duration) {
+            duration = UINT32_MAX;
+        } else {
+            duration -= delta;
+        }
+        value[1] = htonl(duration);
     });
     mCttsTableEntries->write(mOwner);
     mOwner->endBox();  // ctts
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index b77ee1d..1706221 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -28,9 +28,9 @@
 #include <media/IMediaCodecService.h>
 #include <media/stagefright/OMXClient.h>
 
-#include "include/OMX.h"
+#include <media/IOMX.h>
 
-#include "omx/hal/1.0/utils/WOmx.h"
+#include <media/omx/1.0/WOmx.h>
 
 namespace android {
 
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index de5ea9c..1d2a931 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -701,7 +701,13 @@
             }
 
             ++sampleIndex;
-            sampleTime += delta;
+            if (sampleTime > UINT32_MAX - delta) {
+                ALOGE("%u + %u would overflow, clamping",
+                    sampleTime, delta);
+                sampleTime = UINT32_MAX;
+            } else {
+                sampleTime += delta;
+            }
         }
     }
 
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 4d763d0..e75b48f 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -20,6 +20,10 @@
 
 *******************************************************************************/
 
+#define LOG_TAG "NoiselessCoder"
+
+#include "log/log.h"
+
 #include "aac_rom.h"
 #include "dyn_bits.h"
 #include "bit_cnt.h"
@@ -296,6 +300,9 @@
     case SHORT_WINDOW:
       sideInfoTab = sideInfoTabShort;
       break;
+    default:
+      ALOGE("invalid blockType: %d", blockType);
+      return;
   }
 
 
diff --git a/media/libstagefright/colorconversion/Android.mk b/media/libstagefright/colorconversion/Android.mk
index 1e82727..1e7a4cc 100644
--- a/media/libstagefright/colorconversion/Android.mk
+++ b/media/libstagefright/colorconversion/Android.mk
@@ -17,7 +17,8 @@
         libyuv_static \
 
 LOCAL_CFLAGS += -Werror
-LOCAL_SANITIZE := signed-integer-overflow
+LOCAL_SANITIZE := signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_MODULE:= libstagefright_color_conversion
 
diff --git a/media/libstagefright/filters/Android.mk b/media/libstagefright/filters/Android.mk
index 07b2eb8..d4ecfcc 100644
--- a/media/libstagefright/filters/Android.mk
+++ b/media/libstagefright/filters/Android.mk
@@ -29,4 +29,7 @@
 
 LOCAL_MODULE:= libstagefright_mediafilter
 
+LOCAL_SANITIZE := cfi
+LOCAL_SANITIZE_DIAG := cfi
+
 include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/id3/Android.mk b/media/libstagefright/id3/Android.mk
index 19ada73..827703e 100644
--- a/media/libstagefright/id3/Android.mk
+++ b/media/libstagefright/id3/Android.mk
@@ -5,7 +5,8 @@
 	ID3.cpp
 
 LOCAL_CFLAGS += -Werror -Wall
-LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_SHARED_LIBRARIES := libmedia
 
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index 7dd0863..7de5dbe 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -10,7 +10,8 @@
         $(TOP)/frameworks/av/media/libstagefright/include \
 
 LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_SHARED_LIBRARIES := libmedia
 
diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk
index de3d4f4..5140e66 100644
--- a/media/libstagefright/mpeg2ts/Android.mk
+++ b/media/libstagefright/mpeg2ts/Android.mk
@@ -15,7 +15,8 @@
 	$(TOP)/frameworks/native/include/media/openmax
 
 LOCAL_CFLAGS += -Werror -Wall
-LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_SHARED_LIBRARIES := libmedia
 
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 82b8143..9cba3d0 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES:=                     \
         FrameDropper.cpp              \
         GraphicBufferSource.cpp       \
+        BWGraphicBufferSource.cpp      \
         OMX.cpp                       \
         OMXMaster.cpp                 \
         OMXNodeInstance.cpp           \
@@ -34,6 +35,9 @@
         libhidlmemory                   \
         android.hidl.memory@1.0         \
 
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+        android.hidl.memory@1.0
+
 LOCAL_MODULE:= libstagefright_omx
 LOCAL_CFLAGS += -Werror -Wall
 LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.cpp b/media/libstagefright/omx/BWGraphicBufferSource.cpp
new file mode 100644
index 0000000..4e0f6dd
--- /dev/null
+++ b/media/libstagefright/omx/BWGraphicBufferSource.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2017, 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_NDEBUG 0
+#define LOG_TAG "BWGraphicBufferSource"
+
+#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
+
+#include <media/OMXBuffer.h>
+#include <IOMX.h>
+
+#include "OMXUtils.h"
+#include "BWGraphicBufferSource.h"
+
+namespace android {
+
+static const OMX_U32 kPortIndexInput = 0;
+
+struct BWGraphicBufferSource::BWOmxNodeWrapper : public IOmxNodeWrapper {
+    sp<IOMXNode> mOMXNode;
+
+    BWOmxNodeWrapper(const sp<IOMXNode> &omxNode): mOMXNode(omxNode) {
+    }
+
+    virtual status_t emptyBuffer(
+            int32_t bufferId, uint32_t flags,
+            const sp<GraphicBuffer> &buffer,
+            int64_t timestamp, int fenceFd) override {
+        return mOMXNode->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
+    }
+
+    virtual void dispatchDataSpaceChanged(
+            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+        omx_message msg;
+        msg.type = omx_message::EVENT;
+        msg.fenceFd = -1;
+        msg.u.event_data.event = OMX_EventDataSpaceChanged;
+        msg.u.event_data.data1 = dataSpace;
+        msg.u.event_data.data2 = aspects;
+        msg.u.event_data.data3 = pixelFormat;
+        mOMXNode->dispatchMessage(msg);
+    }
+};
+
+struct BWGraphicBufferSource::BWOMXBufferSource : public BnOMXBufferSource {
+    sp<GraphicBufferSource> mSource;
+
+    BWOMXBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
+    }
+
+    Status onOmxExecuting() override {
+        return mSource->onOmxExecuting();
+    }
+
+    Status onOmxIdle() override {
+        return mSource->onOmxIdle();
+    }
+
+    Status onOmxLoaded() override {
+        return mSource->onOmxLoaded();
+    }
+
+    Status onInputBufferAdded(int bufferId) override {
+        return mSource->onInputBufferAdded(bufferId);
+    }
+
+    Status onInputBufferEmptied(
+            int bufferId, const OMXFenceParcelable& fenceParcel) override {
+        return mSource->onInputBufferEmptied(bufferId, fenceParcel.get());
+    }
+};
+
+BWGraphicBufferSource::BWGraphicBufferSource(
+        sp<GraphicBufferSource> const& base) :
+    mBase(base),
+    mOMXBufferSource(new BWOMXBufferSource(base)) {
+}
+
+::android::binder::Status BWGraphicBufferSource::configure(
+        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+    // Do setInputSurface() first, the node will try to enable metadata
+    // mode on input, and does necessary error checking. If this fails,
+    // we can't use this input surface on the node.
+    status_t err = omxNode->setInputSurface(mOMXBufferSource);
+    if (err != NO_ERROR) {
+        ALOGE("Unable to set input surface: %d", err);
+        return Status::fromStatusT(err);
+    }
+
+    // use consumer usage bits queried from encoder, but always add
+    // HW_VIDEO_ENCODER for backward compatibility.
+    uint32_t consumerUsage;
+    if (omxNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+            &consumerUsage, sizeof(consumerUsage)) != OK) {
+        consumerUsage = 0;
+    }
+
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = kPortIndexInput;
+
+    err = omxNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
+    if (err != NO_ERROR) {
+        ALOGE("Failed to get port definition: %d", err);
+        return Status::fromStatusT(UNKNOWN_ERROR);
+    }
+
+    return Status::fromStatusT(mBase->configure(
+              new BWOmxNodeWrapper(omxNode),
+              dataSpace,
+              def.nBufferCountActual,
+              def.format.video.nFrameWidth,
+              def.format.video.nFrameHeight,
+              consumerUsage));
+}
+
+::android::binder::Status BWGraphicBufferSource::setSuspend(
+        bool suspend, int64_t timeUs) {
+    return Status::fromStatusT(mBase->setSuspend(suspend, timeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+        int64_t repeatAfterUs) {
+    return Status::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setMaxFps(float maxFps) {
+    return Status::fromStatusT(mBase->setMaxFps(maxFps));
+}
+
+::android::binder::Status BWGraphicBufferSource::setTimeLapseConfig(
+        int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+    return Status::fromStatusT(mBase->setTimeLapseConfig(
+            timePerFrameUs, timePerCaptureUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setStartTimeUs(
+        int64_t startTimeUs) {
+    return Status::fromStatusT(mBase->setStartTimeUs(startTimeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setStopTimeUs(
+        int64_t stopTimeUs) {
+    return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setColorAspects(
+        int32_t aspects) {
+    return Status::fromStatusT(mBase->setColorAspects(aspects));
+}
+
+::android::binder::Status BWGraphicBufferSource::setTimeOffsetUs(
+        int64_t timeOffsetsUs) {
+    return Status::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::signalEndOfInputStream() {
+    return Status::fromStatusT(mBase->signalEndOfInputStream());
+}
+
+}  // namespace android
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.h b/media/libstagefright/omx/BWGraphicBufferSource.h
new file mode 100644
index 0000000..f1ce2af
--- /dev/null
+++ b/media/libstagefright/omx/BWGraphicBufferSource.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017, 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 BWGRAPHIC_BUFFER_SOURCE_H_
+#define BWGRAPHIC_BUFFER_SOURCE_H_
+
+#include <binder/Binder.h>
+#include <binder/Status.h>
+#include <android/BnGraphicBufferSource.h>
+#include <android/BnOMXBufferSource.h>
+#include <IOMX.h>
+
+#include "GraphicBufferSource.h"
+#include "IOmxNodeWrapper.h"
+
+namespace android {
+
+using ::android::binder::Status;
+using ::android::BnGraphicBufferSource;
+using ::android::GraphicBufferSource;
+using ::android::IOMXNode;
+using ::android::sp;
+
+struct BWGraphicBufferSource : public BnGraphicBufferSource {
+    struct BWOMXBufferSource;
+    struct BWOmxNodeWrapper;
+
+    sp<GraphicBufferSource> mBase;
+    sp<IOMXBufferSource> mOMXBufferSource;
+
+    BWGraphicBufferSource(sp<GraphicBufferSource> const &base);
+
+    Status configure(
+            const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+    Status setSuspend(bool suspend, int64_t timeUs) override;
+    Status setRepeatPreviousFrameDelayUs(
+            int64_t repeatAfterUs) override;
+    Status setMaxFps(float maxFps) override;
+    Status setTimeLapseConfig(
+            int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+    Status setStartTimeUs(int64_t startTimeUs) override;
+    Status setStopTimeUs(int64_t stopTimeUs) override;
+    Status setColorAspects(int32_t aspects) override;
+    Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
+    Status signalEndOfInputStream() override;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 2f457ac..793ecb8 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -41,37 +41,6 @@
 
 namespace android {
 
-static const OMX_U32 kPortIndexInput = 0;
-
-class GraphicBufferSource::OmxBufferSource : public BnOMXBufferSource {
-public:
-    GraphicBufferSource* mSource;
-
-    OmxBufferSource(GraphicBufferSource* source): mSource(source) {
-    }
-
-    Status onOmxExecuting() override {
-        return mSource->onOmxExecuting();
-    }
-
-    Status onOmxIdle() override {
-        return mSource->onOmxIdle();
-    }
-
-    Status onOmxLoaded() override {
-        return mSource->onOmxLoaded();
-    }
-
-    Status onInputBufferAdded(int bufferId) override {
-        return mSource->onInputBufferAdded(bufferId);
-    }
-
-    Status onInputBufferEmptied(
-            int bufferId, const OMXFenceParcelable& fenceParcel) override {
-        return mSource->onInputBufferEmptied(bufferId, fenceParcel);
-    }
-};
-
 GraphicBufferSource::GraphicBufferSource() :
     mInitCheck(UNKNOWN_ERROR),
     mExecuting(false),
@@ -97,8 +66,7 @@
     mTimePerFrameUs(-1ll),
     mPrevCaptureUs(-1ll),
     mPrevFrameUs(-1ll),
-    mInputBufferTimeOffsetUs(0ll),
-    mOmxBufferSource(new OmxBufferSource(this)) {
+    mInputBufferTimeOffsetUs(0ll) {
     ALOGV("GraphicBufferSource");
 
     String8 name("GraphicBufferSource");
@@ -122,7 +90,7 @@
         return;
     }
 
-    memset(&mColorAspects, 0, sizeof(mColorAspects));
+    memset(&mColorAspectsPacked, 0, sizeof(mColorAspectsPacked));
 
     CHECK(mInitCheck == NO_ERROR);
 }
@@ -273,9 +241,7 @@
 }
 
 Status GraphicBufferSource::onInputBufferEmptied(
-        int32_t bufferID, const OMXFenceParcelable &fenceParcel) {
-    int fenceFd = fenceParcel.get();
-
+        int32_t bufferID, int fenceFd) {
     Mutex::Autolock autoLock(mMutex);
     if (!mExecuting) {
         if (fenceFd >= 0) {
@@ -374,15 +340,7 @@
     mLastDataSpace = dataSpace;
 
     if (ColorUtils::convertDataSpaceToV0(dataSpace)) {
-        omx_message msg;
-        msg.type = omx_message::EVENT;
-        msg.fenceFd = -1;
-        msg.u.event_data.event = OMX_EventDataSpaceChanged;
-        msg.u.event_data.data1 = mLastDataSpace;
-        msg.u.event_data.data2 = ColorUtils::packToU32(mColorAspects);
-        msg.u.event_data.data3 = pixelFormat;
-
-        mOMXNode->dispatchMessage(msg);
+        mOMXNode->dispatchDataSpaceChanged(mLastDataSpace, mColorAspectsPacked, pixelFormat);
     }
 }
 
@@ -689,7 +647,7 @@
     int fenceID = item.mFence->isValid() ? item.mFence->dup() : -1;
 
     status_t err = mOMXNode->emptyBuffer(
-            bufferID, buffer, OMX_BUFFERFLAG_ENDOFFRAME, codecTimeUs, fenceID);
+            bufferID, OMX_BUFFERFLAG_ENDOFFRAME, buffer, codecTimeUs, fenceID);
 
     if (err != OK) {
         ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
@@ -721,10 +679,8 @@
     CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
     IOMX::buffer_id bufferID = codecBuffer.mBufferID;
 
-    status_t err = mOMXNode->emptyBuffer(
-            bufferID, (sp<GraphicBuffer>)NULL,
-            OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
-            0 /* timestamp */, -1 /* fenceFd */);
+    status_t err = mOMXNode->emptyBuffer(bufferID,
+            OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
     if (err != OK) {
         ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
     } else {
@@ -865,65 +821,38 @@
     ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
 }
 
-Status GraphicBufferSource::configure(
-        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+status_t GraphicBufferSource::configure(
+        const sp<IOmxNodeWrapper>& omxNode,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
+        uint32_t consumerUsage) {
     if (omxNode == NULL) {
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        return BAD_VALUE;
     }
 
-    // Do setInputSurface() first, the node will try to enable metadata
-    // mode on input, and does necessary error checking. If this fails,
-    // we can't use this input surface on the node.
-    status_t err = omxNode->setInputSurface(mOmxBufferSource);
-    if (err != NO_ERROR) {
-        ALOGE("Unable to set input surface: %d", err);
-        return Status::fromServiceSpecificError(err);
-    }
-
-    // use consumer usage bits queried from encoder, but always add
-    // HW_VIDEO_ENCODER for backward compatibility.
-    uint32_t consumerUsage;
-    if (omxNode->getParameter(
-            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
-            &consumerUsage, sizeof(consumerUsage)) != OK) {
-        consumerUsage = 0;
-    }
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    err = omxNode->getParameter(
-            OMX_IndexParamPortDefinition, &def, sizeof(def));
-    if (err != NO_ERROR) {
-        ALOGE("Failed to get port definition: %d", err);
-        return Status::fromServiceSpecificError(UNKNOWN_ERROR);
-    }
 
     // Call setMaxAcquiredBufferCount without lock.
     // setMaxAcquiredBufferCount could call back to onBuffersReleased
     // if the buffer count change results in releasing of existing buffers,
     // which would lead to deadlock.
-    err = mConsumer->setMaxAcquiredBufferCount(def.nBufferCountActual);
+    status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
     if (err != NO_ERROR) {
         ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
-                def.nBufferCountActual, err);
-        return Status::fromServiceSpecificError(err);
+                bufferCount, err);
+        return err;
     }
 
     {
         Mutex::Autolock autoLock(mMutex);
         mOMXNode = omxNode;
 
-        err = mConsumer->setDefaultBufferSize(
-                def.format.video.nFrameWidth,
-                def.format.video.nFrameHeight);
+        err = mConsumer->setDefaultBufferSize(frameWidth, frameHeight);
         if (err != NO_ERROR) {
             ALOGE("Unable to set BQ default buffer size to %ux%u: %d",
-                    def.format.video.nFrameWidth,
-                    def.format.video.nFrameHeight,
-                    err);
-            return Status::fromServiceSpecificError(err);
+                    frameWidth, frameHeight, err);
+            return err;
         }
 
         consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
@@ -957,17 +886,17 @@
         mActionQueue.clear();
     }
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
+status_t GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
     ALOGV("setSuspend=%d at time %lld us", suspend, (long long)suspendStartTimeUs);
 
     Mutex::Autolock autoLock(mMutex);
 
     if (mStopTimeUs != -1) {
         ALOGE("setSuspend failed as STOP action is pending");
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     // Push the action to the queue.
@@ -977,12 +906,12 @@
         if (suspendStartTimeUs > currentSystemTimeUs) {
             ALOGE("setSuspend failed. %lld is larger than current system time %lld us",
                     (long long)suspendStartTimeUs, (long long)currentSystemTimeUs);
-            return Status::fromServiceSpecificError(INVALID_OPERATION);
+            return INVALID_OPERATION;
         }
         if (mLastActionTimeUs != -1 && suspendStartTimeUs < mLastActionTimeUs) {
             ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
                     (long long)suspendStartTimeUs, (long long)mLastActionTimeUs);
-            return Status::fromServiceSpecificError(INVALID_OPERATION);
+            return INVALID_OPERATION;
         }
         mLastActionTimeUs = suspendStartTimeUs;
         ActionItem action;
@@ -1007,7 +936,7 @@
 
                 releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
             }
-            return Status::ok();
+            return OK;
         } else {
 
             mSuspended = false;
@@ -1023,54 +952,54 @@
             }
         }
     }
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
+status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
     ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
 
     Mutex::Autolock autoLock(mMutex);
 
     if (mExecuting || repeatAfterUs <= 0ll) {
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     mRepeatAfterUs = repeatAfterUs;
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+status_t GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
     Mutex::Autolock autoLock(mMutex);
 
     // timeOffsetUs must be negative for adjustment.
     if (timeOffsetUs >= 0ll) {
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     mInputBufferTimeOffsetUs = timeOffsetUs;
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setMaxFps(float maxFps) {
+status_t GraphicBufferSource::setMaxFps(float maxFps) {
     ALOGV("setMaxFps: maxFps=%lld", (long long)maxFps);
 
     Mutex::Autolock autoLock(mMutex);
 
     if (mExecuting) {
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     mFrameDropper = new FrameDropper();
     status_t err = mFrameDropper->setMaxFrameRate(maxFps);
     if (err != OK) {
         mFrameDropper.clear();
-        return Status::fromServiceSpecificError(err);
+        return err;
     }
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
+status_t GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
     ALOGV("setStartTimeUs: skipFramesBeforeUs=%lld", (long long)skipFramesBeforeUs);
 
     Mutex::Autolock autoLock(mMutex);
@@ -1078,16 +1007,16 @@
     mSkipFramesBeforeNs =
             (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
+status_t GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
     ALOGV("setStopTimeUs: %lld us", (long long)stopTimeUs);
     Mutex::Autolock autoLock(mMutex);
 
     if (mStopTimeUs != -1) {
         // Ignore if stop time has already been set
-        return Status::ok();
+        return OK;
     }
 
     // stopTimeUs must be smaller or equal to current systemTime.
@@ -1095,12 +1024,12 @@
     if (stopTimeUs > currentSystemTimeUs) {
         ALOGE("setStopTimeUs failed. %lld is larger than current system time %lld us",
             (long long)stopTimeUs, (long long)currentSystemTimeUs);
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
     if (mLastActionTimeUs != -1 && stopTimeUs < mLastActionTimeUs) {
         ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
             (long long)stopTimeUs, (long long)mLastActionTimeUs);
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
     mLastActionTimeUs = stopTimeUs;
     ActionItem action;
@@ -1108,45 +1037,46 @@
     action.mActionTimeUs = stopTimeUs;
     mActionQueue.push_back(action);
     mStopTimeUs = stopTimeUs;
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+status_t GraphicBufferSource::setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) {
     ALOGV("setTimeLapseConfig: timePerFrameUs=%lld, timePerCaptureUs=%lld",
             (long long)timePerFrameUs, (long long)timePerCaptureUs);
 
     Mutex::Autolock autoLock(mMutex);
 
     if (mExecuting || timePerFrameUs <= 0ll || timePerCaptureUs <= 0ll) {
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     mTimePerFrameUs = timePerFrameUs;
     mTimePerCaptureUs = timePerCaptureUs;
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
+status_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
     Mutex::Autolock autoLock(mMutex);
-    mColorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
+    mColorAspectsPacked = aspectsPacked;
+    ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
     ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
-            mColorAspects.mRange, asString(mColorAspects.mRange),
-            mColorAspects.mPrimaries, asString(mColorAspects.mPrimaries),
-            mColorAspects.mMatrixCoeffs, asString(mColorAspects.mMatrixCoeffs),
-            mColorAspects.mTransfer, asString(mColorAspects.mTransfer));
+            colorAspects.mRange, asString(colorAspects.mRange),
+            colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
+            colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
+            colorAspects.mTransfer, asString(colorAspects.mTransfer));
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::signalEndOfInputStream() {
+status_t GraphicBufferSource::signalEndOfInputStream() {
     Mutex::Autolock autoLock(mMutex);
     ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d",
             mExecuting, mNumFramesAvailable, mEndOfStream);
 
     if (mEndOfStream) {
         ALOGE("EOS was already signaled");
-        return Status::fromStatusT(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     // Set the end-of-stream flag.  If no frames are pending from the
@@ -1163,7 +1093,7 @@
         submitEndOfInputStream_l();
     }
 
-    return Status::ok();
+    return OK;
 }
 
 void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 475548e..371c5ed 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -32,6 +32,8 @@
 #include <android/BnGraphicBufferSource.h>
 #include <android/BnOMXBufferSource.h>
 
+#include "IOmxNodeWrapper.h"
+
 namespace android {
 
 using ::android::binder::Status;
@@ -54,8 +56,7 @@
  * before the codec is in the "executing" state, so we need to queue
  * things up until we're ready to go.
  */
-class GraphicBufferSource : public BnGraphicBufferSource,
-                            public BufferQueue::ConsumerListener {
+class GraphicBufferSource : public BufferQueue::ConsumerListener {
 public:
     GraphicBufferSource();
 
@@ -95,24 +96,30 @@
     // Called from OnEmptyBufferDone.  If we have a BQ buffer available,
     // fill it with a new frame of data; otherwise, just mark it as available.
     Status onInputBufferEmptied(
-            int32_t bufferID, const OMXFenceParcelable& fenceParcel);
+            int32_t bufferID, int fenceFd);
 
     // Configure the buffer source to be used with an OMX node with the default
     // data space.
-    Status configure(const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+    status_t configure(
+        const sp<IOmxNodeWrapper> &omxNode,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
+        uint32_t consumerUsage);
 
     // This is called after the last input frame has been submitted or buffer
     // timestamp is greater or equal than stopTimeUs. We need to submit an empty
     // buffer with the EOS flag set.  If we don't have a codec buffer ready,
     // we just set the mEndOfStream flag.
-    Status signalEndOfInputStream() override;
+    status_t signalEndOfInputStream();
 
     // If suspend is true, all incoming buffers (including those currently
     // in the BufferQueue) with timestamp larger than timeUs will be discarded
     // until the suspension is lifted. If suspend is false, all incoming buffers
     // including those currently in the BufferQueue) with timestamp larger than
     // timeUs will be processed. timeUs uses SYSTEM_TIME_MONOTONIC time base.
-    Status setSuspend(bool suspend, int64_t timeUs) override;
+    status_t setSuspend(bool suspend, int64_t timeUs);
 
     // Specifies the interval after which we requeue the buffer previously
     // queued to the encoder. This is useful in the case of surface flinger
@@ -121,30 +128,30 @@
     // the decoder on the remote end would be unable to decode the latest frame.
     // This API must be called before transitioning the encoder to "executing"
     // state and once this behaviour is specified it cannot be reset.
-    Status setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+    status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
 
     // Sets the input buffer timestamp offset.
     // When set, the sample's timestamp will be adjusted with the timeOffsetUs.
-    Status setTimeOffsetUs(int64_t timeOffsetUs) override;
+    status_t setTimeOffsetUs(int64_t timeOffsetUs);
 
     // When set, the max frame rate fed to the encoder will be capped at maxFps.
-    Status setMaxFps(float maxFps) override;
+    status_t setMaxFps(float maxFps);
 
     // Sets the time lapse (or slow motion) parameters.
     // When set, the sample's timestamp will be modified to playback framerate,
     // and capture timestamp will be modified to capture rate.
-    Status setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+    status_t setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs);
 
     // Sets the start time us (in system time), samples before which should
     // be dropped and not submitted to encoder
-    Status setStartTimeUs(int64_t startTimeUs) override;
+    status_t setStartTimeUs(int64_t startTimeUs);
 
     // Sets the stop time us (in system time), samples after which should be dropped
     // and not submitted to encoder. timeUs uses SYSTEM_TIME_MONOTONIC time base.
-    Status setStopTimeUs(int64_t stopTimeUs) override;
+    status_t setStopTimeUs(int64_t stopTimeUs);
 
     // Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace.
-    Status setColorAspects(int32_t aspectsPacked) override;
+    status_t setColorAspects(int32_t aspectsPacked);
 
 protected:
     // BufferQueue::ConsumerListener interface, called when a new frame of
@@ -229,8 +236,8 @@
     // Used to report constructor failure.
     status_t mInitCheck;
 
-    // Pointer back to the IOMXNode that created us.  We send buffers here.
-    sp<IOMXNode> mOMXNode;
+    // Pointer back to the Omx node that created us.  We send buffers here.
+    sp<IOmxNodeWrapper> mOMXNode;
 
     // Set by omxExecuting() / omxIdling().
     bool mExecuting;
@@ -328,10 +335,7 @@
 
     int64_t mInputBufferTimeOffsetUs;
 
-    ColorAspects mColorAspects;
-
-    class OmxBufferSource;
-    sp<OmxBufferSource> mOmxBufferSource;
+    int32_t mColorAspectsPacked;
 
     void onMessageReceived(const sp<AMessage> &msg);
 
diff --git a/media/libstagefright/omx/IOmxNodeWrapper.h b/media/libstagefright/omx/IOmxNodeWrapper.h
new file mode 100644
index 0000000..cd44e67
--- /dev/null
+++ b/media/libstagefright/omx/IOmxNodeWrapper.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017, 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 IOMX_NODE_WRAPPER_SOURCE_H_
+#define IOMX_NODE_WRAPPER_SOURCE_H_
+
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <stdint.h>
+
+namespace android {
+
+struct IOmxNodeWrapper : public RefBase {
+    virtual status_t emptyBuffer(
+            int32_t bufferId, uint32_t flags,
+            const sp<GraphicBuffer> &buffer = nullptr,
+            int64_t timestamp = 0, int fenceFd = -1) = 0;
+    virtual void dispatchDataSpaceChanged(
+            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) = 0;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 80c125c..bf1418f 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -27,7 +27,7 @@
 #include "../include/OMXNodeInstance.h"
 
 #include <media/stagefright/foundation/ADebug.h>
-#include "GraphicBufferSource.h"
+#include "BWGraphicBufferSource.h"
 
 #include "OMXMaster.h"
 #include "OMXUtils.h"
@@ -174,7 +174,7 @@
     }
 
     *bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
-    *bufferSource = graphicBufferSource;
+    *bufferSource = new BWGraphicBufferSource(graphicBufferSource);
 
     return OK;
 }
diff --git a/media/libstagefright/omx/hal/1.0/impl/Android.mk b/media/libstagefright/omx/hal/1.0/impl/Android.mk
index 09424b5..79cb1fa 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Android.mk
+++ b/media/libstagefright/omx/hal/1.0/impl/Android.mk
@@ -4,7 +4,6 @@
 LOCAL_MODULE := android.hardware.media.omx@1.0-impl
 LOCAL_SRC_FILES := \
     WGraphicBufferSource.cpp \
-    WOmx.cpp \
     WOmxBufferProducer.cpp \
     WOmxBufferSource.cpp \
     WOmxNode.cpp \
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 117d1c8..a6fed2e 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -611,6 +611,37 @@
 }
 
 /**
+ * \brief Wrap `GraphicBuffer` in `CodecBuffer`.
+ *
+ * \param[out] t The wrapper of type `CodecBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: OMXBuffer -> CodecBuffer
+inline CodecBuffer *wrapAs(CodecBuffer *t, sp<GraphicBuffer> const& graphicBuffer) {
+    t->sharedMemory = hidl_memory();
+    t->nativeHandle = hidl_handle();
+    t->type = CodecBuffer::Type::ANW_BUFFER;
+    if (graphicBuffer == nullptr) {
+        t->attr.anwBuffer.width = 0;
+        t->attr.anwBuffer.height = 0;
+        t->attr.anwBuffer.stride = 0;
+        t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
+        t->attr.anwBuffer.layerCount = 0;
+        t->attr.anwBuffer.usage = 0;
+        return t;
+    }
+    t->attr.anwBuffer.width = graphicBuffer->getWidth();
+    t->attr.anwBuffer.height = graphicBuffer->getHeight();
+    t->attr.anwBuffer.stride = graphicBuffer->getStride();
+    t->attr.anwBuffer.format = static_cast<PixelFormat>(
+            graphicBuffer->getPixelFormat());
+    t->attr.anwBuffer.layerCount = graphicBuffer->getLayerCount();
+    t->attr.anwBuffer.usage = graphicBuffer->getUsage();
+    t->nativeHandle = graphicBuffer->handle;
+    return t;
+}
+
+/**
  * \brief Wrap `OMXBuffer` in `CodecBuffer`.
  *
  * \param[out] t The wrapper of type `CodecBuffer`.
@@ -642,24 +673,7 @@
             return false;
         }
         case OMXBuffer::kBufferTypeANWBuffer: {
-            t->type = CodecBuffer::Type::ANW_BUFFER;
-            if (l.mGraphicBuffer == nullptr) {
-                t->attr.anwBuffer.width = 0;
-                t->attr.anwBuffer.height = 0;
-                t->attr.anwBuffer.stride = 0;
-                t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
-                t->attr.anwBuffer.layerCount = 0;
-                t->attr.anwBuffer.usage = 0;
-                return true;
-            }
-            t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
-            t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
-            t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
-            t->attr.anwBuffer.format = static_cast<PixelFormat>(
-                    l.mGraphicBuffer->getPixelFormat());
-            t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
-            t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
-            t->nativeHandle = l.mGraphicBuffer->handle;
+            wrapAs(t, l.mGraphicBuffer);
             return true;
         }
         case OMXBuffer::kBufferTypeNativeHandle: {
diff --git a/media/libstagefright/omx/hal/1.0/impl/Omx.cpp b/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
index a9f29e9..0ef7c8c 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
@@ -123,7 +123,6 @@
 
 Return<void> Omx::createInputSurface(createInputSurface_cb _hidl_cb) {
     sp<::android::IGraphicBufferProducer> bufferProducer;
-    sp<::android::IGraphicBufferSource> bufferSource;
 
     sp<GraphicBufferSource> graphicBufferSource = new GraphicBufferSource();
     status_t err = graphicBufferSource->initCheck();
@@ -135,11 +134,10 @@
         return Void();
     }
     bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
-    bufferSource = graphicBufferSource;
 
     _hidl_cb(toStatus(OK),
             new TWOmxBufferProducer(bufferProducer),
-            new TWGraphicBufferSource(bufferSource));
+            new TWGraphicBufferSource(graphicBufferSource));
     return Void();
 }
 
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
index 884e87b..13e1f2f 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
@@ -14,8 +14,15 @@
  * limitations under the License.
  */
 
-#include <stagefright/foundation/ColorUtils.h>
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TWGraphicBufferSource"
 
+#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
+
+#include "omx/OMXUtils.h"
 #include "WGraphicBufferSource.h"
 #include "WOmxNode.h"
 #include "Conversion.h"
@@ -27,122 +34,183 @@
 namespace V1_0 {
 namespace implementation {
 
-using android::ColorUtils;
+static const OMX_U32 kPortIndexInput = 0;
 
-// LWGraphicBufferSource
-LWGraphicBufferSource::LWGraphicBufferSource(
-        sp<TGraphicBufferSource> const& base) : mBase(base) {
-}
+struct TWGraphicBufferSource::TWOmxNodeWrapper : public IOmxNodeWrapper {
+    sp<IOmxNode> mOmxNode;
 
-::android::binder::Status LWGraphicBufferSource::configure(
-        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
-    return toBinderStatus(mBase->configure(
-            new TWOmxNode(omxNode), toHardwareDataspace(dataSpace)));
-}
+    TWOmxNodeWrapper(const sp<IOmxNode> &omxNode): mOmxNode(omxNode) {
+    }
 
-::android::binder::Status LWGraphicBufferSource::setSuspend(
-        bool suspend, int64_t timeUs) {
-    return toBinderStatus(mBase->setSuspend(suspend, timeUs));
-}
+    virtual status_t emptyBuffer(
+            int32_t bufferId, uint32_t flags,
+            const sp<GraphicBuffer> &buffer,
+            int64_t timestamp, int fenceFd) override {
+        CodecBuffer tBuffer;
+        return toStatusT(mOmxNode->emptyBuffer(
+              bufferId,
+              *wrapAs(&tBuffer, buffer),
+              flags,
+              toRawTicks(timestamp),
+              native_handle_create_from_fd(fenceFd)));
+    }
 
-::android::binder::Status LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
-        int64_t repeatAfterUs) {
-    return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
-}
+    virtual void dispatchDataSpaceChanged(
+            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+        Message tMsg;
+        tMsg.type = Message::Type::EVENT;
+        tMsg.fence = native_handle_create(0, 0);
+        tMsg.data.eventData.event = uint32_t(OMX_EventDataSpaceChanged);
+        tMsg.data.eventData.data1 = dataSpace;
+        tMsg.data.eventData.data2 = aspects;
+        tMsg.data.eventData.data3 = pixelFormat;
+        mOmxNode->dispatchMessage(tMsg);
+    }
+};
 
-::android::binder::Status LWGraphicBufferSource::setMaxFps(float maxFps) {
-    return toBinderStatus(mBase->setMaxFps(maxFps));
-}
+struct TWGraphicBufferSource::TWOmxBufferSource : public IOmxBufferSource {
+    sp<GraphicBufferSource> mSource;
 
-::android::binder::Status LWGraphicBufferSource::setTimeLapseConfig(
-        int64_t timePerFrameUs, int64_t timePerCaptureUs) {
-    return toBinderStatus(mBase->setTimeLapseConfig(
-            timePerFrameUs, timePerCaptureUs));
-}
+    TWOmxBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
+    }
 
-::android::binder::Status LWGraphicBufferSource::setStartTimeUs(
-        int64_t startTimeUs) {
-    return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
-}
+    Return<void> onOmxExecuting() override {
+        mSource->onOmxExecuting();
+        return Void();
+    }
 
-::android::binder::Status LWGraphicBufferSource::setStopTimeUs(
-        int64_t stopTimeUs) {
-    return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
-}
+    Return<void> onOmxIdle() override {
+        mSource->onOmxIdle();
+        return Void();
+    }
 
-::android::binder::Status LWGraphicBufferSource::setColorAspects(
-        int32_t aspects) {
-    return toBinderStatus(mBase->setColorAspects(
-            toHardwareColorAspects(aspects)));
-}
+    Return<void> onOmxLoaded() override {
+        mSource->onOmxLoaded();
+        return Void();
+    }
 
-::android::binder::Status LWGraphicBufferSource::setTimeOffsetUs(
-        int64_t timeOffsetsUs) {
-    return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
-}
+    Return<void> onInputBufferAdded(uint32_t bufferId) override {
+        mSource->onInputBufferAdded(static_cast<int32_t>(bufferId));
+        return Void();
+    }
 
-::android::binder::Status LWGraphicBufferSource::signalEndOfInputStream() {
-    return toBinderStatus(mBase->signalEndOfInputStream());
-}
+    Return<void> onInputBufferEmptied(
+            uint32_t bufferId, hidl_handle const& tFence) override {
+        mSource->onInputBufferEmptied(
+                static_cast<int32_t>(bufferId),
+                native_handle_read_fd(tFence));
+        return Void();
+    }
+};
 
 // TWGraphicBufferSource
 TWGraphicBufferSource::TWGraphicBufferSource(
-        sp<LGraphicBufferSource> const& base) : mBase(base) {
+        sp<GraphicBufferSource> const& base) :
+    mBase(base),
+    mOmxBufferSource(new TWOmxBufferSource(base)) {
 }
 
-Return<void> TWGraphicBufferSource::configure(
+Return<Status> TWGraphicBufferSource::configure(
         const sp<IOmxNode>& omxNode, Dataspace dataspace) {
-    mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
-    return Void();
+    if (omxNode == NULL) {
+        return toStatus(BAD_VALUE);
+    }
+
+    // Do setInputSurface() first, the node will try to enable metadata
+    // mode on input, and does necessary error checking. If this fails,
+    // we can't use this input surface on the node.
+    Return<Status> err(omxNode->setInputSurface(mOmxBufferSource));
+    status_t fnStatus = toStatusT(err);
+    if (fnStatus != NO_ERROR) {
+        ALOGE("Unable to set input surface: %d", fnStatus);
+        return err;
+    }
+
+    // use consumer usage bits queried from encoder, but always add
+    // HW_VIDEO_ENCODER for backward compatibility.
+    uint32_t  consumerUsage;
+    void *_params = &consumerUsage;
+    uint8_t *params = static_cast<uint8_t*>(_params);
+    fnStatus = UNKNOWN_ERROR;
+    IOmxNode::getParameter_cb _hidl_cb(
+            [&fnStatus, &params](Status status, hidl_vec<uint8_t> const& outParams) {
+                fnStatus = toStatusT(status);
+                std::copy(
+                        outParams.data(),
+                        outParams.data() + outParams.size(),
+                        params);
+            });
+    omxNode->getParameter(
+            static_cast<uint32_t>(OMX_IndexParamConsumerUsageBits),
+            inHidlBytes(&consumerUsage, sizeof(consumerUsage)),
+            _hidl_cb);
+    if (fnStatus != OK) {
+        consumerUsage = 0;
+    }
+
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = kPortIndexInput;
+
+    _params = &def;
+    params = static_cast<uint8_t*>(_params);
+    omxNode->getParameter(
+            static_cast<uint32_t>(OMX_IndexParamPortDefinition),
+            inHidlBytes(&def, sizeof(def)),
+            _hidl_cb);
+    if (fnStatus != NO_ERROR) {
+        ALOGE("Failed to get port definition: %d", fnStatus);
+        return toStatus(fnStatus);
+    }
+
+
+    return toStatus(mBase->configure(
+            new TWOmxNodeWrapper(omxNode),
+            toRawDataspace(dataspace),
+            def.nBufferCountActual,
+            def.format.video.nFrameWidth,
+            def.format.video.nFrameHeight,
+            consumerUsage));
 }
 
-Return<void> TWGraphicBufferSource::setSuspend(
+Return<Status> TWGraphicBufferSource::setSuspend(
         bool suspend, int64_t timeUs) {
-    mBase->setSuspend(suspend, timeUs);
-    return Void();
+    return toStatus(mBase->setSuspend(suspend, timeUs));
 }
 
-Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+Return<Status> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
         int64_t repeatAfterUs) {
-    mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
-    return Void();
+    return toStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
 }
 
-Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
-    mBase->setMaxFps(maxFps);
-    return Void();
+Return<Status> TWGraphicBufferSource::setMaxFps(float maxFps) {
+    return toStatus(mBase->setMaxFps(maxFps));
 }
 
-Return<void> TWGraphicBufferSource::setTimeLapseConfig(
+Return<Status> TWGraphicBufferSource::setTimeLapseConfig(
         int64_t timePerFrameUs, int64_t timePerCaptureUs) {
-    mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
-    return Void();
+    return toStatus(mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs));
 }
 
-Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
-    mBase->setStartTimeUs(startTimeUs);
-    return Void();
+Return<Status> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
+    return toStatus(mBase->setStartTimeUs(startTimeUs));
 }
 
-Return<void> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
-    mBase->setStopTimeUs(stopTimeUs);
-    return Void();
+Return<Status> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
+    return toStatus(mBase->setStopTimeUs(stopTimeUs));
 }
 
-Return<void> TWGraphicBufferSource::setColorAspects(
+Return<Status> TWGraphicBufferSource::setColorAspects(
         const ColorAspects& aspects) {
-    mBase->setColorAspects(toCompactColorAspects(aspects));
-    return Void();
+    return toStatus(mBase->setColorAspects(toCompactColorAspects(aspects)));
 }
 
-Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
-    mBase->setTimeOffsetUs(timeOffsetUs);
-    return Void();
+Return<Status> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+    return toStatus(mBase->setTimeOffsetUs(timeOffsetUs));
 }
 
-Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
-    mBase->signalEndOfInputStream();
-    return Void();
+Return<Status> TWGraphicBufferSource::signalEndOfInputStream() {
+    return toStatus(mBase->signalEndOfInputStream());
 }
 
 }  // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
index bd60c46..8cf11ca 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
@@ -20,15 +20,16 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
-#include <media/IOMX.h>
-#include <binder/Binder.h>
-
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/graphics/common/1.0/types.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 
 #include <android/BnGraphicBufferSource.h>
 
+#include "../../../GraphicBufferSource.h"
+
 namespace android {
 namespace hardware {
 namespace media {
@@ -36,10 +37,12 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::GraphicBufferSource;
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::media::omx::V1_0::ColorAspects;
 using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
 using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Status;
 using ::android::hidl::base::V1_0::IBase;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_memory;
@@ -60,44 +63,28 @@
  * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
  */
 
-typedef ::android::IGraphicBufferSource LGraphicBufferSource;
-typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
 typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
         TGraphicBufferSource;
 
-struct LWGraphicBufferSource : public BnGraphicBufferSource {
-    sp<TGraphicBufferSource> mBase;
-    LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
-    ::android::binder::Status configure(
-            const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
-    ::android::binder::Status setSuspend(bool suspend, int64_t timeUs) override;
-    ::android::binder::Status setRepeatPreviousFrameDelayUs(
-            int64_t repeatAfterUs) override;
-    ::android::binder::Status setMaxFps(float maxFps) override;
-    ::android::binder::Status setTimeLapseConfig(
-            int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
-    ::android::binder::Status setStartTimeUs(int64_t startTimeUs) override;
-    ::android::binder::Status setStopTimeUs(int64_t stopTimeUs) override;
-    ::android::binder::Status setColorAspects(int32_t aspects) override;
-    ::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
-    ::android::binder::Status signalEndOfInputStream() override;
-};
-
 struct TWGraphicBufferSource : public TGraphicBufferSource {
-    sp<LGraphicBufferSource> mBase;
-    TWGraphicBufferSource(sp<LGraphicBufferSource> const& base);
-    Return<void> configure(
+    struct TWOmxNodeWrapper;
+    struct TWOmxBufferSource;
+    sp<GraphicBufferSource> mBase;
+    sp<IOmxBufferSource> mOmxBufferSource;
+
+    TWGraphicBufferSource(sp<GraphicBufferSource> const& base);
+    Return<Status> configure(
             const sp<IOmxNode>& omxNode, Dataspace dataspace) override;
-    Return<void> setSuspend(bool suspend, int64_t timeUs) override;
-    Return<void> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
-    Return<void> setMaxFps(float maxFps) override;
-    Return<void> setTimeLapseConfig(
+    Return<Status> setSuspend(bool suspend, int64_t timeUs) override;
+    Return<Status> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+    Return<Status> setMaxFps(float maxFps) override;
+    Return<Status> setTimeLapseConfig(
             int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
-    Return<void> setStartTimeUs(int64_t startTimeUs) override;
-    Return<void> setStopTimeUs(int64_t stopTimeUs) override;
-    Return<void> setColorAspects(const ColorAspects& aspects) override;
-    Return<void> setTimeOffsetUs(int64_t timeOffsetUs) override;
-    Return<void> signalEndOfInputStream() override;
+    Return<Status> setStartTimeUs(int64_t startTimeUs) override;
+    Return<Status> setStopTimeUs(int64_t stopTimeUs) override;
+    Return<Status> setColorAspects(const ColorAspects& aspects) override;
+    Return<Status> setTimeOffsetUs(int64_t timeOffsetUs) override;
+    Return<Status> signalEndOfInputStream() override;
 };
 
 }  // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
deleted file mode 100644
index da1c23d..0000000
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
+++ /dev/null
@@ -1,126 +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.
- */
-
-#include "WOmx.h"
-#include "WOmxNode.h"
-#include "WOmxObserver.h"
-#include "WOmxBufferProducer.h"
-#include "WGraphicBufferSource.h"
-#include "Conversion.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-// LWOmx
-LWOmx::LWOmx(sp<IOmx> const& base) : mBase(base) {
-}
-
-status_t LWOmx::listNodes(List<IOMX::ComponentInfo>* list) {
-    status_t fnStatus;
-    status_t transStatus = toStatusT(mBase->listNodes(
-            [&fnStatus, list](
-                    Status status,
-                    hidl_vec<IOmx::ComponentInfo> const& nodeList) {
-                fnStatus = toStatusT(status);
-                list->clear();
-                for (size_t i = 0; i < nodeList.size(); ++i) {
-                    auto newInfo = list->insert(
-                            list->end(), IOMX::ComponentInfo());
-                    convertTo(&*newInfo, nodeList[i]);
-                }
-            }));
-    return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-status_t LWOmx::allocateNode(
-        char const* name,
-        sp<IOMXObserver> const& observer,
-        sp<IOMXNode>* omxNode) {
-    status_t fnStatus;
-    status_t transStatus = toStatusT(mBase->allocateNode(
-            name, new TWOmxObserver(observer),
-            [&fnStatus, omxNode](Status status, sp<IOmxNode> const& node) {
-                fnStatus = toStatusT(status);
-                *omxNode = new LWOmxNode(node);
-            }));
-    return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-status_t LWOmx::createInputSurface(
-        sp<::android::IGraphicBufferProducer>* bufferProducer,
-        sp<::android::IGraphicBufferSource>* bufferSource) {
-    status_t fnStatus;
-    status_t transStatus = toStatusT(mBase->createInputSurface(
-            [&fnStatus, bufferProducer, bufferSource] (
-                    Status status,
-                    sp<IOmxBufferProducer> const& tProducer,
-                    sp<IGraphicBufferSource> const& tSource) {
-                fnStatus = toStatusT(status);
-                *bufferProducer = new LWOmxBufferProducer(tProducer);
-                *bufferSource = new LWGraphicBufferSource(tSource);
-            }));
-    return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-// TWOmx
-TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
-}
-
-Return<void> TWOmx::listNodes(listNodes_cb _hidl_cb) {
-    List<IOMX::ComponentInfo> lList;
-    Status status = toStatus(mBase->listNodes(&lList));
-
-    hidl_vec<IOmx::ComponentInfo> tList;
-    tList.resize(lList.size());
-    size_t i = 0;
-    for (auto const& lInfo : lList) {
-        convertTo(&(tList[i++]), lInfo);
-    }
-    _hidl_cb(status, tList);
-    return Void();
-}
-
-Return<void> TWOmx::allocateNode(
-        const hidl_string& name,
-        const sp<IOmxObserver>& observer,
-        allocateNode_cb _hidl_cb) {
-    sp<IOMXNode> omxNode;
-    Status status = toStatus(mBase->allocateNode(
-            name, new LWOmxObserver(observer), &omxNode));
-    _hidl_cb(status, new TWOmxNode(omxNode));
-    return Void();
-}
-
-Return<void> TWOmx::createInputSurface(createInputSurface_cb _hidl_cb) {
-    sp<::android::IGraphicBufferProducer> lProducer;
-    sp<::android::IGraphicBufferSource> lSource;
-    status_t status = mBase->createInputSurface(&lProducer, &lSource);
-    _hidl_cb(toStatus(status),
-             new TWOmxBufferProducer(lProducer),
-             new TWGraphicBufferSource(lSource));
-    return Void();
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace omx
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.h b/media/libstagefright/omx/hal/1.0/impl/WOmx.h
deleted file mode 100644
index 3cb002e..0000000
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.h
+++ /dev/null
@@ -1,92 +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_MEDIA_OMX_V1_0_WOMX_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include "../../../../include/OMXNodeInstance.h"
-
-#include <android/hardware/media/omx/1.0/IOmx.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::media::omx::V1_0::IOmx;
-using ::android::hardware::media::omx::V1_0::IOmxNode;
-using ::android::hardware::media::omx::V1_0::IOmxObserver;
-using ::android::hardware::media::omx::V1_0::Status;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-using ::android::List;
-using ::android::IOMX;
-using ::android::BnOMX;
-
-/**
- * Wrapper classes for conversion
- * ==============================
- *
- * Naming convention:
- * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
- * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
- */
-
-struct LWOmx : public BnOMX {
-    sp<IOmx> mBase;
-    LWOmx(sp<IOmx> const& base);
-    status_t listNodes(List<IOMX::ComponentInfo>* list) override;
-    status_t allocateNode(
-            char const* name,
-            sp<IOMXObserver> const& observer,
-            sp<IOMXNode>* omxNode) override;
-    status_t createInputSurface(
-            sp<::android::IGraphicBufferProducer>* bufferProducer,
-            sp<::android::IGraphicBufferSource>* bufferSource) override;
-};
-
-struct TWOmx : public IOmx {
-    sp<IOMX> mBase;
-    TWOmx(sp<IOMX> const& base);
-    Return<void> listNodes(listNodes_cb _hidl_cb) override;
-    Return<void> allocateNode(
-            const hidl_string& name,
-            const sp<IOmxObserver>& observer,
-            allocateNode_cb _hidl_cb) override;
-    Return<void> createInputSurface(createInputSurface_cb _hidl_cb) override;
-
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace omx
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
diff --git a/media/libstagefright/omx/hal/1.0/utils/Android.mk b/media/libstagefright/omx/hal/1.0/utils/Android.mk
deleted file mode 100644
index c44ce25..0000000
--- a/media/libstagefright/omx/hal/1.0/utils/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.media.omx@1.0-utils
-LOCAL_SRC_FILES := \
-    WGraphicBufferSource.cpp \
-    WOmx.cpp \
-    WOmxBufferProducer.cpp \
-    WOmxBufferSource.cpp \
-    WOmxNode.cpp \
-    WOmxObserver.cpp \
-    WOmxProducerListener.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    libmedia \
-    libstagefright_foundation \
-    libstagefright_omx \
-    libui \
-    libgui \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    libhidlmemory \
-    libutils \
-    libcutils \
-    libbinder \
-    liblog \
-    libbase \
-    android.hardware.media.omx@1.0 \
-    android.hardware.graphics.common@1.0 \
-    android.hardware.media@1.0 \
-    android.hidl.base@1.0 \
-
-LOCAL_C_INCLUDES += \
-        $(TOP)/frameworks/av/include \
-        $(TOP)/frameworks/av/media/libstagefright \
-        $(TOP)/frameworks/native/include \
-        $(TOP)/frameworks/native/include/media/openmax \
-        $(TOP)/frameworks/native/include/media/hardware \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
deleted file mode 100644
index 0ba6060..0000000
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
+++ /dev/null
@@ -1,153 +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.
- */
-
-#include <stagefright/foundation/ColorUtils.h>
-
-#include "WGraphicBufferSource.h"
-#include "WOmxNode.h"
-#include "Conversion.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace utils {
-
-using android::ColorUtils;
-
-// LWGraphicBufferSource
-LWGraphicBufferSource::LWGraphicBufferSource(
-        sp<TGraphicBufferSource> const& base) : mBase(base) {
-}
-
-::android::binder::Status LWGraphicBufferSource::configure(
-        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
-    return toBinderStatus(mBase->configure(
-            new TWOmxNode(omxNode), toHardwareDataspace(dataSpace)));
-}
-
-::android::binder::Status LWGraphicBufferSource::setSuspend(
-        bool suspend, int64_t timeUs) {
-    return toBinderStatus(mBase->setSuspend(suspend, timeUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
-        int64_t repeatAfterUs) {
-    return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::setMaxFps(float maxFps) {
-    return toBinderStatus(mBase->setMaxFps(maxFps));
-}
-
-::android::binder::Status LWGraphicBufferSource::setTimeLapseConfig(
-        int64_t timePerFrameUs, int64_t timePerCaptureUs) {
-    return toBinderStatus(mBase->setTimeLapseConfig(
-            timePerFrameUs, timePerCaptureUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::setStartTimeUs(
-        int64_t startTimeUs) {
-    return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::setStopTimeUs(
-        int64_t stopTimeUs) {
-    return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::setColorAspects(
-        int32_t aspects) {
-    return toBinderStatus(mBase->setColorAspects(
-            toHardwareColorAspects(aspects)));
-}
-
-::android::binder::Status LWGraphicBufferSource::setTimeOffsetUs(
-        int64_t timeOffsetsUs) {
-    return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
-}
-
-::android::binder::Status LWGraphicBufferSource::signalEndOfInputStream() {
-    return toBinderStatus(mBase->signalEndOfInputStream());
-}
-
-// TWGraphicBufferSource
-TWGraphicBufferSource::TWGraphicBufferSource(
-        sp<LGraphicBufferSource> const& base) : mBase(base) {
-}
-
-Return<void> TWGraphicBufferSource::configure(
-        const sp<IOmxNode>& omxNode, Dataspace dataspace) {
-    mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setSuspend(
-        bool suspend, int64_t timeUs) {
-    mBase->setSuspend(suspend, timeUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
-        int64_t repeatAfterUs) {
-    mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
-    mBase->setMaxFps(maxFps);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setTimeLapseConfig(
-        int64_t timePerFrameUs, int64_t timePerCaptureUs) {
-    mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
-    mBase->setStartTimeUs(startTimeUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
-    mBase->setStopTimeUs(stopTimeUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setColorAspects(
-        const ColorAspects& aspects) {
-    mBase->setColorAspects(toCompactColorAspects(aspects));
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
-    mBase->setTimeOffsetUs(timeOffsetUs);
-    return Void();
-}
-
-Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
-    mBase->signalEndOfInputStream();
-    return Void();
-}
-
-}  // namespace utils
-}  // namespace V1_0
-}  // namespace omx
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 6d0f189..5941b94 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -17,7 +17,6 @@
         android.hidl.allocator@1.0 \
         android.hidl.memory@1.0 \
         android.hardware.media.omx@1.0 \
-        android.hardware.media.omx@1.0-utils
 
 LOCAL_C_INCLUDES := \
         $(TOP)/frameworks/av/media/libstagefright \
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index 0b0facf..70ae46b 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -5,7 +5,8 @@
         TextDescriptions.cpp      \
 
 LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-LOCAL_SANITIZE := signed-integer-overflow
+LOCAL_SANITIZE := signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_C_INCLUDES:= \
         $(TOP)/frameworks/av/include/media/stagefright/timedtext \
diff --git a/media/libstagefright/webm/Android.mk b/media/libstagefright/webm/Android.mk
index 096fd07..0d55de9 100644
--- a/media/libstagefright/webm/Android.mk
+++ b/media/libstagefright/webm/Android.mk
@@ -4,7 +4,8 @@
 LOCAL_CPPFLAGS += -D__STDINT_LIMITS
 
 LOCAL_CFLAGS += -Werror -Wall
-LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
+LOCAL_SANITIZE_DIAG := cfi
 
 LOCAL_SRC_FILES:= EbmlUtil.cpp        \
                   WebmElement.cpp     \
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 5a1d6dc..88dabff 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -54,7 +54,7 @@
     MTP_OPERATION_SEND_OBJECT,
 //    MTP_OPERATION_INITIATE_CAPTURE,
 //    MTP_OPERATION_FORMAT_STORE,
-//    MTP_OPERATION_RESET_DEVICE,
+    MTP_OPERATION_RESET_DEVICE,
 //    MTP_OPERATION_SELF_TEST,
 //    MTP_OPERATION_SET_OBJECT_PROTECTION,
 //    MTP_OPERATION_POWER_DOWN,
@@ -362,6 +362,7 @@
         case MTP_OPERATION_OPEN_SESSION:
             response = doOpenSession();
             break;
+        case MTP_OPERATION_RESET_DEVICE:
         case MTP_OPERATION_CLOSE_SESSION:
             response = doCloseSession();
             break;
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 30aa7fb..ab3829e 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -22,6 +22,7 @@
 #include "NdkImagePriv.h"
 #include "NdkImageReaderPriv.h"
 
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <android_runtime/android_view_Surface.h>
 
@@ -41,6 +42,11 @@
 bool
 AImageReader::isSupportedFormat(int32_t format) {
     switch (format) {
+        case AIMAGE_FORMAT_RGBA_8888:
+        case AIMAGE_FORMAT_RGBX_8888:
+        case AIMAGE_FORMAT_RGB_888:
+        case AIMAGE_FORMAT_RGB_565:
+        case AIMAGE_FORMAT_RGBA_FP16:
         case AIMAGE_FORMAT_YUV_420_888:
         case AIMAGE_FORMAT_JPEG:
         case AIMAGE_FORMAT_RAW16:
@@ -60,6 +66,11 @@
     switch (format) {
         case AIMAGE_FORMAT_YUV_420_888:
             return 3;
+        case AIMAGE_FORMAT_RGBA_8888:
+        case AIMAGE_FORMAT_RGBX_8888:
+        case AIMAGE_FORMAT_RGB_888:
+        case AIMAGE_FORMAT_RGB_565:
+        case AIMAGE_FORMAT_RGBA_FP16:
         case AIMAGE_FORMAT_JPEG:
         case AIMAGE_FORMAT_RAW16:
         case AIMAGE_FORMAT_RAW_PRIVATE:
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index dca7bf9..caf7905 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -22,6 +22,7 @@
 #include "Configuration.h"
 #include <linux/futex.h>
 #include <sys/syscall.h>
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include "FastThread.h"
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index c2981a1..32606ea 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -22,6 +22,7 @@
 #include "TypeConverter.h"
 
 #include <log/log.h>
+#include <cutils/atomic.h>
 #include <utils/String8.h>
 
 namespace android {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index aac23b4..6ed2cb7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -21,6 +21,7 @@
 #include "HwModule.h"
 #include "AudioGain.h"
 #include <policy.h>
+#include <cutils/atomic.h>
 
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 31c145e..7634664 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -32,6 +32,7 @@
 
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyEngineInstance.h>
+#include <cutils/atomic.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 0401796..2be9362 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -41,6 +41,7 @@
     api1/client2/CaptureSequencer.cpp \
     api1/client2/ZslProcessor.cpp \
     api2/CameraDeviceClient.cpp \
+    device1/CameraHardwareInterface.cpp \
     device3/Camera3Device.cpp \
     device3/Camera3Stream.cpp \
     device3/Camera3IOStreamBase.cpp \
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index b83d425..ffb657e 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "CameraClient"
 //#define LOG_NDEBUG 0
 
+#include <cutils/atomic.h>
 #include <cutils/properties.h>
 #include <gui/Surface.h>
 #include <media/hardware/HardwareAPI.h>
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 79e7ff0..4428f75 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -321,7 +321,7 @@
     return binder::Status::ok();
 }
 
-binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
+binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
     ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
             __FUNCTION__, mInputStream.configured ? 1 : 0,
             mStreamMap.size());
@@ -335,7 +335,16 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
+    if (operatingMode < 0) {
+        String8 msg = String8::format(
+            "Camera %s: Invalid operating mode %d requested", mCameraIdStr.string(), operatingMode);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                msg.string());
+    }
+
     // Sanitize the high speed session against necessary capability bit.
+    bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
     if (isConstrainedHighSpeed) {
         CameraMetadata staticInfo = mDevice->info();
         camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -357,7 +366,7 @@
         }
     }
 
-    status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
+    status_t err = mDevice->configureStreams(operatingMode);
     if (err == BAD_VALUE) {
         String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
                 mCameraIdStr.string());
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 012beb4..2a95c88 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -70,70 +70,70 @@
             const hardware::camera2::CaptureRequest& request,
             bool streaming = false,
             /*out*/
-            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
     // List of requests are copied.
     virtual binder::Status submitRequestList(
             const std::vector<hardware::camera2::CaptureRequest>& requests,
             bool streaming = false,
             /*out*/
-            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
     virtual binder::Status cancelRequest(int requestId,
             /*out*/
-            int64_t* lastFrameNumber = NULL);
+            int64_t* lastFrameNumber = NULL) override;
 
-    virtual binder::Status beginConfigure();
+    virtual binder::Status beginConfigure() override;
 
-    virtual binder::Status endConfigure(bool isConstrainedHighSpeed = false);
+    virtual binder::Status endConfigure(int operatingMode) override;
 
     // Returns -EBUSY if device is not idle
-    virtual binder::Status deleteStream(int streamId);
+    virtual binder::Status deleteStream(int streamId) override;
 
     virtual binder::Status createStream(
             const hardware::camera2::params::OutputConfiguration &outputConfiguration,
             /*out*/
-            int32_t* newStreamId = NULL);
+            int32_t* newStreamId = NULL) override;
 
     // Create an input stream of width, height, and format.
     virtual binder::Status createInputStream(int width, int height, int format,
             /*out*/
-            int32_t* newStreamId = NULL);
+            int32_t* newStreamId = NULL) override;
 
     // Get the buffer producer of the input stream
     virtual binder::Status getInputSurface(
             /*out*/
-            view::Surface *inputSurface);
+            view::Surface *inputSurface) override;
 
     // Create a request object from a template.
     virtual binder::Status createDefaultRequest(int templateId,
             /*out*/
-            hardware::camera2::impl::CameraMetadataNative* request);
+            hardware::camera2::impl::CameraMetadataNative* request) override;
 
     // Get the static metadata for the camera
     // -- Caller owns the newly allocated metadata
     virtual binder::Status getCameraInfo(
             /*out*/
-            hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics);
+            hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics) override;
 
     // Wait until all the submitted requests have finished processing
-    virtual binder::Status waitUntilIdle();
+    virtual binder::Status waitUntilIdle() override;
 
     // Flush all active and pending requests as fast as possible
     virtual binder::Status flush(
             /*out*/
-            int64_t* lastFrameNumber = NULL);
+            int64_t* lastFrameNumber = NULL) override;
 
     // Prepare stream by preallocating its buffers
-    virtual binder::Status prepare(int32_t streamId);
+    virtual binder::Status prepare(int32_t streamId) override;
 
     // Tear down stream resources by freeing its unused buffers
-    virtual binder::Status tearDown(int32_t streamId);
+    virtual binder::Status tearDown(int32_t streamId) override;
 
     // Prepare stream by preallocating up to maxCount of its buffers
-    virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
+    virtual binder::Status prepare2(int32_t maxCount, int32_t streamId) override;
 
     // Finalize the output configurations with surfaces not added before.
     virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
-            const hardware::camera2::params::OutputConfiguration &outputConfiguration);
+            const hardware::camera2::params::OutputConfiguration &outputConfiguration) override;
 
     /**
      * Interface used by CameraService
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 98a3fcc..f9b062a 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -184,7 +184,7 @@
      * - BAD_VALUE if the set of streams was invalid (e.g. fmts or sizes)
      * - INVALID_OPERATION if the device was in the wrong state
      */
-    virtual status_t configureStreams(bool isConstrainedHighSpeed = false) = 0;
+    virtual status_t configureStreams(int operatingMode = 0) = 0;
 
     // get the buffer producer of the input stream
     virtual status_t getInputBufferProducer(
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
new file mode 100644
index 0000000..3e4e631
--- /dev/null
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (C) 2017 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 "CameraHardwareInterface"
+//#define LOG_NDEBUG 0
+
+#include <inttypes.h>
+#include "CameraHardwareInterface.h"
+
+namespace android {
+
+using namespace hardware::camera::device::V1_0;
+using namespace hardware::camera::common::V1_0;
+using hardware::hidl_handle;
+
+CameraHardwareInterface::~CameraHardwareInterface()
+{
+    ALOGI("Destroying camera %s", mName.string());
+    if (mDevice) {
+        int rc = mDevice->common.close(&mDevice->common);
+        if (rc != OK)
+            ALOGE("Could not close camera %s: %d", mName.string(), rc);
+    }
+    if (mHidlDevice != nullptr) {
+        mHidlDevice->close();
+        mHidlDevice.clear();
+        cleanupCirculatingBuffers();
+    }
+}
+
+status_t CameraHardwareInterface::initialize(CameraModule *module)
+{
+    if (mHidlDevice != nullptr) {
+        ALOGE("%s: camera hardware interface has been initialized to HIDL path!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    ALOGI("Opening camera %s", mName.string());
+    camera_info info;
+    status_t res = module->getCameraInfo(atoi(mName.string()), &info);
+    if (res != OK) {
+        return res;
+    }
+
+    int rc = OK;
+    if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
+        info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
+        // Open higher version camera device as HAL1.0 device.
+        rc = module->openLegacy(mName.string(),
+                                 CAMERA_DEVICE_API_VERSION_1_0,
+                                 (hw_device_t **)&mDevice);
+    } else {
+        rc = module->open(mName.string(), (hw_device_t **)&mDevice);
+    }
+    if (rc != OK) {
+        ALOGE("Could not open camera %s: %d", mName.string(), rc);
+        return rc;
+    }
+    initHalPreviewWindow();
+    return rc;
+}
+
+status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
+    if (mDevice) {
+        ALOGE("%s: camera hardware interface has been initialized to libhardware path!",
+                __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    ALOGI("Opening camera %s", mName.string());
+
+    status_t ret = manager->openSession(String8::std_string(mName), this, &mHidlDevice);
+    if (ret != OK) {
+        ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
+    }
+    return ret;
+}
+
+status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
+{
+    int rc = OK;
+    mPreviewScalingMode = scalingMode;
+    if (mPreviewWindow != nullptr) {
+        rc = native_window_set_scaling_mode(mPreviewWindow.get(),
+                scalingMode);
+    }
+    return rc;
+}
+
+status_t CameraHardwareInterface::setPreviewTransform(int transform) {
+    int rc = OK;
+    mPreviewTransform = transform;
+    if (mPreviewWindow != nullptr) {
+        rc = native_window_set_buffers_transform(mPreviewWindow.get(),
+                mPreviewTransform);
+    }
+    return rc;
+}
+
+/**
+ * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
+ */
+hardware::Return<void> CameraHardwareInterface::notifyCallback(
+        NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
+    sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
+    return hardware::Void();
+}
+
+hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
+        const hardware::hidl_handle& descriptor,
+        uint32_t bufferSize, uint32_t bufferCount) {
+    if (descriptor->numFds != 1) {
+        ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
+                __FUNCTION__, descriptor->numFds);
+        return 0;
+    }
+    if (descriptor->data[0] < 0) {
+        ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
+                __FUNCTION__, descriptor->data[0]);
+        return 0;
+    }
+
+    camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
+    sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
+    int memPoolId = camMem->mHeap->getHeapID();
+    if (memPoolId < 0) {
+        ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
+        return 0;
+    }
+    mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
+    return memPoolId;
+}
+
+hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
+    if (mHidlMemPoolMap.count(memId) == 0) {
+        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
+        return hardware::Void();
+    }
+    camera_memory_t* mem = mHidlMemPoolMap.at(memId);
+    sPutMemory(mem);
+    mHidlMemPoolMap.erase(memId);
+    return hardware::Void();
+}
+
+hardware::Return<void> CameraHardwareInterface::dataCallback(
+        DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
+        const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
+    if (mHidlMemPoolMap.count(data) == 0) {
+        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+        return hardware::Void();
+    }
+    camera_frame_metadata_t md;
+    md.number_of_faces = metadata.faces.size();
+    md.faces = (camera_face_t*) metadata.faces.data();
+    sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
+    return hardware::Void();
+}
+
+hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
+        DataCallbackMsg msgType, uint32_t data,
+        uint32_t bufferIndex, int64_t timestamp) {
+    if (mHidlMemPoolMap.count(data) == 0) {
+        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+        return hardware::Void();
+    }
+    sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
+    return hardware::Void();
+}
+
+hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
+        DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
+        uint32_t bufferIndex, int64_t timestamp) {
+    if (mHidlMemPoolMap.count(data) == 0) {
+        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+        return hardware::Void();
+    }
+    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
+    VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
+            mem->mBuffers[bufferIndex]->pointer();
+    md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
+    sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
+    return hardware::Void();
+}
+
+std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
+        ANativeWindowBuffer* anb) {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+
+    buffer_handle_t& buf = anb->handle;
+    auto it = mBufferIdMap.find(buf);
+    if (it == mBufferIdMap.end()) {
+        uint64_t bufId = mNextBufferId++;
+        mBufferIdMap[buf] = bufId;
+        mReversedBufMap[bufId] = anb;
+        return std::make_pair(true, bufId);
+    } else {
+        return std::make_pair(false, it->second);
+    }
+}
+
+void CameraHardwareInterface::cleanupCirculatingBuffers() {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+    mBufferIdMap.clear();
+    mReversedBufMap.clear();
+}
+
+hardware::Return<void>
+CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return hardware::Void();
+    }
+    ANativeWindowBuffer* anb;
+    int rc = native_window_dequeue_buffer_and_wait(a, &anb);
+    Status s = Status::INTERNAL_ERROR;
+    uint64_t bufferId = 0;
+    uint32_t stride = 0;
+    hidl_handle buf = nullptr;
+    if (rc == OK) {
+        s = Status::OK;
+        auto pair = getBufferId(anb);
+        buf = (pair.first) ? anb->handle : nullptr;
+        bufferId = pair.second;
+        stride = anb->stride;
+    }
+
+    _hidl_cb(s, bufferId, buf, stride);
+    return hardware::Void();
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+    if (mReversedBufMap.count(bufferId) == 0) {
+        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+    int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
+    if (rc == 0) {
+        return Status::OK;
+    }
+    return Status::INTERNAL_ERROR;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+    if (mReversedBufMap.count(bufferId) == 0) {
+        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+    int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
+    if (rc == 0) {
+        return Status::OK;
+    }
+    return Status::INTERNAL_ERROR;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setBufferCount(uint32_t count) {
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a != nullptr) {
+        // Workaround for b/27039775
+        // Previously, setting the buffer count would reset the buffer
+        // queue's flag that allows for all buffers to be dequeued on the
+        // producer side, instead of just the producer's declared max count,
+        // if no filled buffers have yet been queued by the producer.  This
+        // reset no longer happens, but some HALs depend on this behavior,
+        // so it needs to be maintained for HAL backwards compatibility.
+        // Simulate the prior behavior by disconnecting/reconnecting to the
+        // window and setting the values again.  This has the drawback of
+        // actually causing memory reallocation, which may not have happened
+        // in the past.
+        native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
+        native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
+        if (mPreviewScalingMode != NOT_SET) {
+            native_window_set_scaling_mode(a, mPreviewScalingMode);
+        }
+        if (mPreviewTransform != NOT_SET) {
+            native_window_set_buffers_transform(a, mPreviewTransform);
+        }
+        if (mPreviewWidth != NOT_SET) {
+            native_window_set_buffers_dimensions(a,
+                    mPreviewWidth, mPreviewHeight);
+            native_window_set_buffers_format(a, mPreviewFormat);
+        }
+        if (mPreviewUsage != 0) {
+            native_window_set_usage(a, mPreviewUsage);
+        }
+        if (mPreviewSwapInterval != NOT_SET) {
+            a->setSwapInterval(a, mPreviewSwapInterval);
+        }
+        if (mPreviewCrop.left != NOT_SET) {
+            native_window_set_crop(a, &(mPreviewCrop));
+        }
+    }
+    int rc = native_window_set_buffer_count(a, count);
+    if (rc == OK) {
+        cleanupCirculatingBuffers();
+        return Status::OK;
+    }
+    return Status::INTERNAL_ERROR;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setBuffersGeometry(
+        uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
+    Status s = Status::INTERNAL_ERROR;
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return s;
+    }
+    mPreviewWidth = w;
+    mPreviewHeight = h;
+    mPreviewFormat = (int) format;
+    int rc = native_window_set_buffers_dimensions(a, w, h);
+    if (rc == OK) {
+        rc = native_window_set_buffers_format(a, mPreviewFormat);
+    }
+    if (rc == OK) {
+        cleanupCirculatingBuffers();
+        s = Status::OK;
+    }
+    return s;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+    Status s = Status::INTERNAL_ERROR;
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return s;
+    }
+    mPreviewCrop.left = left;
+    mPreviewCrop.top = top;
+    mPreviewCrop.right = right;
+    mPreviewCrop.bottom = bottom;
+    int rc = native_window_set_crop(a, &mPreviewCrop);
+    if (rc == OK) {
+        s = Status::OK;
+    }
+    return s;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setUsage(hardware::graphics::allocator::V2_0::ProducerUsage usage) {
+    Status s = Status::INTERNAL_ERROR;
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return s;
+    }
+    mPreviewUsage = (int) usage;
+    int rc = native_window_set_usage(a, mPreviewUsage);
+    if (rc == OK) {
+        cleanupCirculatingBuffers();
+        s = Status::OK;
+    }
+    return s;
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setSwapInterval(int32_t interval) {
+    Status s = Status::INTERNAL_ERROR;
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return s;
+    }
+    mPreviewSwapInterval = interval;
+    int rc = a->setSwapInterval(a, interval);
+    if (rc == OK) {
+        s = Status::OK;
+    }
+    return s;
+}
+
+hardware::Return<void>
+CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return hardware::Void();
+    }
+    int count = 0;
+    int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
+    Status s = Status::INTERNAL_ERROR;
+    if (rc == OK) {
+        s = Status::OK;
+    }
+    _hidl_cb(s, count);
+    return hardware::Void();
+}
+
+hardware::Return<Status>
+CameraHardwareInterface::setTimestamp(int64_t timestamp) {
+    Status s = Status::INTERNAL_ERROR;
+    ANativeWindow *a = mPreviewWindow.get();
+    if (a == nullptr) {
+        ALOGE("%s: preview window is null", __FUNCTION__);
+        return s;
+    }
+    int rc = native_window_set_buffers_timestamp(a, timestamp);
+    if (rc == OK) {
+        s = Status::OK;
+    }
+    return s;
+}
+
+status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
+{
+    ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mPreviewWindow = buf;
+        if (buf != nullptr) {
+            if (mPreviewScalingMode != NOT_SET) {
+                setPreviewScalingMode(mPreviewScalingMode);
+            }
+            if (mPreviewTransform != NOT_SET) {
+                setPreviewTransform(mPreviewTransform);
+            }
+        }
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
+    } else if (mDevice) {
+        if (mDevice->ops->set_preview_window) {
+            mPreviewWindow = buf;
+            if (buf != nullptr) {
+                if (mPreviewScalingMode != NOT_SET) {
+                    setPreviewScalingMode(mPreviewScalingMode);
+                }
+                if (mPreviewTransform != NOT_SET) {
+                    setPreviewTransform(mPreviewTransform);
+                }
+            }
+            mHalPreviewWindow.user = this;
+            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p",__FUNCTION__,
+                    &mHalPreviewWindow, mHalPreviewWindow.user);
+            return mDevice->ops->set_preview_window(mDevice,
+                    buf.get() ? &mHalPreviewWindow.nw : 0);
+        }
+    }
+    return INVALID_OPERATION;
+}
+
+void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
+        data_callback data_cb,
+        data_callback_timestamp data_cb_timestamp,
+        void* user)
+{
+    mNotifyCb = notify_cb;
+    mDataCb = data_cb;
+    mDataCbTimestamp = data_cb_timestamp;
+    mCbUser = user;
+
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+
+    if (mDevice && mDevice->ops->set_callbacks) {
+        mDevice->ops->set_callbacks(mDevice,
+                               sNotifyCb,
+                               sDataCb,
+                               sDataCbTimestamp,
+                               sGetMemory,
+                               this);
+    }
+}
+
+void CameraHardwareInterface::enableMsgType(int32_t msgType)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mHidlDevice->enableMsgType(msgType);
+    } else if (mDevice && mDevice->ops->enable_msg_type) {
+        mDevice->ops->enable_msg_type(mDevice, msgType);
+    }
+}
+
+void CameraHardwareInterface::disableMsgType(int32_t msgType)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mHidlDevice->disableMsgType(msgType);
+    } else if (mDevice && mDevice->ops->disable_msg_type) {
+        mDevice->ops->disable_msg_type(mDevice, msgType);
+    }
+}
+
+int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return mHidlDevice->msgTypeEnabled(msgType);
+    } else if (mDevice && mDevice->ops->msg_type_enabled) {
+        return mDevice->ops->msg_type_enabled(mDevice, msgType);
+    }
+    return false;
+}
+
+status_t CameraHardwareInterface::startPreview()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->startPreview());
+    } else if (mDevice && mDevice->ops->start_preview) {
+        return mDevice->ops->start_preview(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+void CameraHardwareInterface::stopPreview()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mHidlDevice->stopPreview();
+    } else if (mDevice && mDevice->ops->stop_preview) {
+        mDevice->ops->stop_preview(mDevice);
+    }
+}
+
+int CameraHardwareInterface::previewEnabled()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return mHidlDevice->previewEnabled();
+    } else if (mDevice && mDevice->ops->preview_enabled) {
+        return mDevice->ops->preview_enabled(mDevice);
+    }
+    return false;
+}
+
+status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->storeMetaDataInBuffers(enable));
+    } else if (mDevice && mDevice->ops->store_meta_data_in_buffers) {
+        return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
+    }
+    return enable ? INVALID_OPERATION: OK;
+}
+
+status_t CameraHardwareInterface::startRecording()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->startRecording());
+    } else if (mDevice && mDevice->ops->start_recording) {
+        return mDevice->ops->start_recording(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+/**
+ * Stop a previously started recording.
+ */
+void CameraHardwareInterface::stopRecording()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mHidlDevice->stopRecording();
+    } else if (mDevice && mDevice->ops->stop_recording) {
+        mDevice->ops->stop_recording(mDevice);
+    }
+}
+
+/**
+ * Returns true if recording is enabled.
+ */
+int CameraHardwareInterface::recordingEnabled()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return mHidlDevice->recordingEnabled();
+    } else if (mDevice && mDevice->ops->recording_enabled) {
+        return mDevice->ops->recording_enabled(mDevice);
+    }
+    return false;
+}
+
+void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+    int heapId = heap->getHeapID();
+    int bufferIndex = offset / size;
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        if (size == sizeof(VideoNativeHandleMetadata)) {
+            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
+            // Caching the handle here because md->pHandle will be subject to HAL's edit
+            native_handle_t* nh = md->pHandle;
+            hidl_handle frame = nh;
+            mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
+            native_handle_close(nh);
+            native_handle_delete(nh);
+        } else {
+            mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
+        }
+    } else if (mDevice && mDevice->ops->release_recording_frame) {
+        void *data = ((uint8_t *)heap->base()) + offset;
+        return mDevice->ops->release_recording_frame(mDevice, data);
+    }
+}
+
+status_t CameraHardwareInterface::autoFocus()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->autoFocus());
+    } else if (mDevice && mDevice->ops->auto_focus) {
+        return mDevice->ops->auto_focus(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::cancelAutoFocus()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->cancelAutoFocus());
+    } else if (mDevice && mDevice->ops->cancel_auto_focus) {
+        return mDevice->ops->cancel_auto_focus(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::takePicture()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->takePicture());
+    } else if (mDevice && mDevice->ops->take_picture) {
+        return mDevice->ops->take_picture(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::cancelPicture()
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->cancelPicture());
+    } else if (mDevice && mDevice->ops->cancel_picture) {
+        return mDevice->ops->cancel_picture(mDevice);
+    }
+    return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->setParameters(params.flatten().string()));
+    } else if (mDevice && mDevice->ops->set_parameters) {
+        return mDevice->ops->set_parameters(mDevice, params.flatten().string());
+    }
+    return INVALID_OPERATION;
+}
+
+CameraParameters CameraHardwareInterface::getParameters() const
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    CameraParameters parms;
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        hardware::hidl_string outParam;
+        mHidlDevice->getParameters(
+                [&outParam](const auto& outStr) {
+                    outParam = outStr;
+                });
+        String8 tmp(outParam.c_str());
+        parms.unflatten(tmp);
+    } else if (mDevice && mDevice->ops->get_parameters) {
+        char *temp = mDevice->ops->get_parameters(mDevice);
+        String8 str_parms(temp);
+        if (mDevice->ops->put_parameters)
+            mDevice->ops->put_parameters(mDevice, temp);
+        else
+            free(temp);
+        parms.unflatten(str_parms);
+    }
+    return parms;
+}
+
+status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        return CameraProviderManager::mapToStatusT(
+                mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
+    } else if (mDevice && mDevice->ops->send_command) {
+        return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
+    }
+    return INVALID_OPERATION;
+}
+
+/**
+ * Release the hardware resources owned by this object.  Note that this is
+ * *not* done in the destructor.
+ */
+void CameraHardwareInterface::release() {
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        mHidlDevice->close();
+        mHidlDevice.clear();
+    } else if (mDevice && mDevice->ops->release) {
+        mDevice->ops->release(mDevice);
+    }
+}
+
+/**
+ * Dump state of the camera hardware
+ */
+status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
+{
+    ALOGV("%s(%s)", __FUNCTION__, mName.string());
+    if (CC_LIKELY(mHidlDevice != nullptr)) {
+        native_handle_t* handle = native_handle_create(1,0);
+        handle->data[0] = fd;
+        Status s = mHidlDevice->dumpState(handle);
+        native_handle_delete(handle);
+        return CameraProviderManager::mapToStatusT(s);
+    } else if (mDevice && mDevice->ops->dump) {
+        return mDevice->ops->dump(mDevice, fd);
+    }
+    return OK; // It's fine if the HAL doesn't implement dump()
+}
+
+/**
+ * Methods for legacy (non-HIDL) path follows
+ */
+void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
+                        int32_t ext2, void *user)
+{
+    ALOGV("%s", __FUNCTION__);
+    CameraHardwareInterface *object =
+            static_cast<CameraHardwareInterface *>(user);
+    object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
+}
+
+void CameraHardwareInterface::sDataCb(int32_t msg_type,
+                      const camera_memory_t *data, unsigned int index,
+                      camera_frame_metadata_t *metadata,
+                      void *user)
+{
+    ALOGV("%s", __FUNCTION__);
+    CameraHardwareInterface *object =
+            static_cast<CameraHardwareInterface *>(user);
+    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+    if (index >= mem->mNumBufs) {
+        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+             index, mem->mNumBufs);
+        return;
+    }
+    object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
+}
+
+void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
+                         const camera_memory_t *data, unsigned index,
+                         void *user)
+{
+    ALOGV("%s", __FUNCTION__);
+    CameraHardwareInterface *object =
+            static_cast<CameraHardwareInterface *>(user);
+    // Start refcounting the heap object from here on.  When the clients
+    // drop all references, it will be destroyed (as well as the enclosed
+    // MemoryHeapBase.
+    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+    if (index >= mem->mNumBufs) {
+        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+             index, mem->mNumBufs);
+        return;
+    }
+    object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
+}
+
+camera_memory_t* CameraHardwareInterface::sGetMemory(
+        int fd, size_t buf_size, uint_t num_bufs,
+        void *user __attribute__((unused)))
+{
+    CameraHeapMemory *mem;
+    if (fd < 0) {
+        mem = new CameraHeapMemory(buf_size, num_bufs);
+    } else {
+        mem = new CameraHeapMemory(fd, buf_size, num_bufs);
+    }
+    mem->incStrong(mem);
+    return &mem->handle;
+}
+
+void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
+{
+    if (!data) {
+        return;
+    }
+
+    CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
+    mem->decStrong(mem);
+}
+
+ANativeWindow* CameraHardwareInterface::sToAnw(void *user)
+{
+    CameraHardwareInterface *object =
+            reinterpret_cast<CameraHardwareInterface *>(user);
+    return object->mPreviewWindow.get();
+}
+#define anw(n) sToAnw(((struct camera_preview_window *)(n))->user)
+#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
+    ((struct camera_preview_window *)(n))->user)
+
+int CameraHardwareInterface::sDequeueBuffer(struct preview_stream_ops* w,
+                            buffer_handle_t** buffer, int *stride)
+{
+    int rc;
+    ANativeWindow *a = anw(w);
+    ANativeWindowBuffer* anb;
+    rc = native_window_dequeue_buffer_and_wait(a, &anb);
+    if (rc == OK) {
+        *buffer = &anb->handle;
+        *stride = anb->stride;
+    }
+    return rc;
+}
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({                      \
+    const __typeof__(((type *) 0)->member) *__mptr = (ptr);     \
+    (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
+#endif
+
+int CameraHardwareInterface::sLockBuffer(struct preview_stream_ops* w,
+                  buffer_handle_t* /*buffer*/)
+{
+    ANativeWindow *a = anw(w);
+    (void)a;
+    return 0;
+}
+
+int CameraHardwareInterface::sEnqueueBuffer(struct preview_stream_ops* w,
+                  buffer_handle_t* buffer)
+{
+    ANativeWindow *a = anw(w);
+    return a->queueBuffer(a,
+              container_of(buffer, ANativeWindowBuffer, handle), -1);
+}
+
+int CameraHardwareInterface::sCancelBuffer(struct preview_stream_ops* w,
+                  buffer_handle_t* buffer)
+{
+    ANativeWindow *a = anw(w);
+    return a->cancelBuffer(a,
+              container_of(buffer, ANativeWindowBuffer, handle), -1);
+}
+
+int CameraHardwareInterface::sSetBufferCount(struct preview_stream_ops* w, int count)
+{
+    ANativeWindow *a = anw(w);
+
+    if (a != nullptr) {
+        // Workaround for b/27039775
+        // Previously, setting the buffer count would reset the buffer
+        // queue's flag that allows for all buffers to be dequeued on the
+        // producer side, instead of just the producer's declared max count,
+        // if no filled buffers have yet been queued by the producer.  This
+        // reset no longer happens, but some HALs depend on this behavior,
+        // so it needs to be maintained for HAL backwards compatibility.
+        // Simulate the prior behavior by disconnecting/reconnecting to the
+        // window and setting the values again.  This has the drawback of
+        // actually causing memory reallocation, which may not have happened
+        // in the past.
+        CameraHardwareInterface *hw = hwi(w);
+        native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
+        native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
+        if (hw->mPreviewScalingMode != NOT_SET) {
+            native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
+        }
+        if (hw->mPreviewTransform != NOT_SET) {
+            native_window_set_buffers_transform(a, hw->mPreviewTransform);
+        }
+        if (hw->mPreviewWidth != NOT_SET) {
+            native_window_set_buffers_dimensions(a,
+                    hw->mPreviewWidth, hw->mPreviewHeight);
+            native_window_set_buffers_format(a, hw->mPreviewFormat);
+        }
+        if (hw->mPreviewUsage != 0) {
+            native_window_set_usage(a, hw->mPreviewUsage);
+        }
+        if (hw->mPreviewSwapInterval != NOT_SET) {
+            a->setSwapInterval(a, hw->mPreviewSwapInterval);
+        }
+        if (hw->mPreviewCrop.left != NOT_SET) {
+            native_window_set_crop(a, &(hw->mPreviewCrop));
+        }
+    }
+
+    return native_window_set_buffer_count(a, count);
+}
+
+int CameraHardwareInterface::sSetBuffersGeometry(struct preview_stream_ops* w,
+                  int width, int height, int format)
+{
+    int rc;
+    ANativeWindow *a = anw(w);
+    CameraHardwareInterface *hw = hwi(w);
+    hw->mPreviewWidth = width;
+    hw->mPreviewHeight = height;
+    hw->mPreviewFormat = format;
+    rc = native_window_set_buffers_dimensions(a, width, height);
+    if (rc == OK) {
+        rc = native_window_set_buffers_format(a, format);
+    }
+    return rc;
+}
+
+int CameraHardwareInterface::sSetCrop(struct preview_stream_ops *w,
+                  int left, int top, int right, int bottom)
+{
+    ANativeWindow *a = anw(w);
+    CameraHardwareInterface *hw = hwi(w);
+    hw->mPreviewCrop.left = left;
+    hw->mPreviewCrop.top = top;
+    hw->mPreviewCrop.right = right;
+    hw->mPreviewCrop.bottom = bottom;
+    return native_window_set_crop(a, &(hw->mPreviewCrop));
+}
+
+int CameraHardwareInterface::sSetTimestamp(struct preview_stream_ops *w,
+                           int64_t timestamp) {
+    ANativeWindow *a = anw(w);
+    return native_window_set_buffers_timestamp(a, timestamp);
+}
+
+int CameraHardwareInterface::sSetUsage(struct preview_stream_ops* w, int usage)
+{
+    ANativeWindow *a = anw(w);
+    CameraHardwareInterface *hw = hwi(w);
+    hw->mPreviewUsage = usage;
+    return native_window_set_usage(a, usage);
+}
+
+int CameraHardwareInterface::sSetSwapInterval(struct preview_stream_ops *w, int interval)
+{
+    ANativeWindow *a = anw(w);
+    CameraHardwareInterface *hw = hwi(w);
+    hw->mPreviewSwapInterval = interval;
+    return a->setSwapInterval(a, interval);
+}
+
+int CameraHardwareInterface::sGetMinUndequeuedBufferCount(
+                  const struct preview_stream_ops *w,
+                  int *count)
+{
+    ANativeWindow *a = anw(w);
+    return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
+}
+
+void CameraHardwareInterface::initHalPreviewWindow()
+{
+    mHalPreviewWindow.nw.cancel_buffer = sCancelBuffer;
+    mHalPreviewWindow.nw.lock_buffer = sLockBuffer;
+    mHalPreviewWindow.nw.dequeue_buffer = sDequeueBuffer;
+    mHalPreviewWindow.nw.enqueue_buffer = sEnqueueBuffer;
+    mHalPreviewWindow.nw.set_buffer_count = sSetBufferCount;
+    mHalPreviewWindow.nw.set_buffers_geometry = sSetBuffersGeometry;
+    mHalPreviewWindow.nw.set_crop = sSetCrop;
+    mHalPreviewWindow.nw.set_timestamp = sSetTimestamp;
+    mHalPreviewWindow.nw.set_usage = sSetUsage;
+    mHalPreviewWindow.nw.set_swap_interval = sSetSwapInterval;
+
+    mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
+            sGetMinUndequeuedBufferCount;
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index c8210b7..88ab2e9 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
 #define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
 
+#include <unordered_map>
 #include <binder/IMemory.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
@@ -74,10 +75,15 @@
  * provided in a data callback must be copied if it's needed after returning.
  */
 
-class CameraHardwareInterface : public virtual RefBase {
+class CameraHardwareInterface :
+        public virtual RefBase,
+        public virtual hardware::camera::device::V1_0::ICameraDeviceCallback,
+        public virtual hardware::camera::device::V1_0::ICameraDevicePreviewCallback {
+
 public:
     explicit CameraHardwareInterface(const char *name):
             mDevice(nullptr),
+            mHidlDevice(nullptr),
             mName(name),
             mPreviewScalingMode(NOT_SET),
             mPreviewTransform(NOT_SET),
@@ -90,115 +96,23 @@
     {
     }
 
-    ~CameraHardwareInterface()
-    {
-        ALOGI("Destroying camera %s", mName.string());
-        if(mDevice) {
-            int rc = mDevice->common.close(&mDevice->common);
-            if (rc != OK)
-                ALOGE("Could not close camera %s: %d", mName.string(), rc);
-        }
-    }
+    ~CameraHardwareInterface();
 
-    status_t initialize(CameraModule *module)
-    {
-        ALOGI("Opening camera %s", mName.string());
-        camera_info info;
-        status_t res = module->getCameraInfo(atoi(mName.string()), &info);
-        if (res != OK) {
-            return res;
-        }
-
-        int rc = OK;
-        if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
-            info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
-            // Open higher version camera device as HAL1.0 device.
-            rc = module->openLegacy(mName.string(),
-                                     CAMERA_DEVICE_API_VERSION_1_0,
-                                     (hw_device_t **)&mDevice);
-        } else {
-            rc = module->open(mName.string(), (hw_device_t **)&mDevice);
-        }
-        if (rc != OK) {
-            ALOGE("Could not open camera %s: %d", mName.string(), rc);
-            return rc;
-        }
-        initHalPreviewWindow();
-        return rc;
-    }
-
-    status_t initialize(sp<CameraProviderManager> manager) {
-        (void) manager;
-        ALOGE("%s: Not supported yet", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
+    status_t initialize(CameraModule *module);
+    status_t initialize(sp<CameraProviderManager> manager);
 
     /** Set the ANativeWindow to which preview frames are sent */
-    status_t setPreviewWindow(const sp<ANativeWindow>& buf)
-    {
-        ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
-        if (mDevice->ops->set_preview_window) {
-            mPreviewWindow = buf;
-            if (buf != nullptr) {
-                if (mPreviewScalingMode != NOT_SET) {
-                    setPreviewScalingMode(mPreviewScalingMode);
-                }
-                if (mPreviewTransform != NOT_SET) {
-                    setPreviewTransform(mPreviewTransform);
-                }
-            }
-            mHalPreviewWindow.user = this;
-            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
-                    &mHalPreviewWindow, mHalPreviewWindow.user);
-            return mDevice->ops->set_preview_window(mDevice,
-                    buf.get() ? &mHalPreviewWindow.nw : 0);
-        }
-        return INVALID_OPERATION;
-    }
+    status_t setPreviewWindow(const sp<ANativeWindow>& buf);
 
-    status_t setPreviewScalingMode(int scalingMode)
-    {
-        int rc = OK;
-        mPreviewScalingMode = scalingMode;
-        if (mPreviewWindow != nullptr) {
-            rc = native_window_set_scaling_mode(mPreviewWindow.get(),
-                    scalingMode);
-        }
-        return rc;
-    }
+    status_t setPreviewScalingMode(int scalingMode);
 
-    status_t setPreviewTransform(int transform) {
-        int rc = OK;
-        mPreviewTransform = transform;
-        if (mPreviewWindow != nullptr) {
-            rc = native_window_set_buffers_transform(mPreviewWindow.get(),
-                    mPreviewTransform);
-        }
-        return rc;
-    }
+    status_t setPreviewTransform(int transform);
 
     /** Set the notification and data callbacks */
     void setCallbacks(notify_callback notify_cb,
                       data_callback data_cb,
                       data_callback_timestamp data_cb_timestamp,
-                      void* user)
-    {
-        mNotifyCb = notify_cb;
-        mDataCb = data_cb;
-        mDataCbTimestamp = data_cb_timestamp;
-        mCbUser = user;
-
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-
-        if (mDevice->ops->set_callbacks) {
-            mDevice->ops->set_callbacks(mDevice,
-                                   __notify_cb,
-                                   __data_cb,
-                                   __data_cb_timestamp,
-                                   __get_memory,
-                                   this);
-        }
-    }
+                      void* user);
 
     /**
      * The following three functions all take a msgtype,
@@ -209,12 +123,7 @@
     /**
      * Enable a message, or set of messages.
      */
-    void enableMsgType(int32_t msgType)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->enable_msg_type)
-            mDevice->ops->enable_msg_type(mDevice, msgType);
-    }
+    void enableMsgType(int32_t msgType);
 
     /**
      * Disable a message, or a set of messages.
@@ -226,57 +135,29 @@
      * modify/access any video recording frame after calling
      * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
      */
-    void disableMsgType(int32_t msgType)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->disable_msg_type)
-            mDevice->ops->disable_msg_type(mDevice, msgType);
-    }
+    void disableMsgType(int32_t msgType);
 
     /**
      * Query whether a message, or a set of messages, is enabled.
      * Note that this is operates as an AND, if any of the messages
      * queried are off, this will return false.
      */
-    int msgTypeEnabled(int32_t msgType)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->msg_type_enabled)
-            return mDevice->ops->msg_type_enabled(mDevice, msgType);
-        return false;
-    }
+    int msgTypeEnabled(int32_t msgType);
 
     /**
      * Start preview mode.
      */
-    status_t startPreview()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->start_preview)
-            return mDevice->ops->start_preview(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t startPreview();
 
     /**
      * Stop a previously started preview.
      */
-    void stopPreview()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->stop_preview)
-            mDevice->ops->stop_preview(mDevice);
-    }
+    void stopPreview();
 
     /**
      * Returns true if preview is enabled.
      */
-    int previewEnabled()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->preview_enabled)
-            return mDevice->ops->preview_enabled(mDevice);
-        return false;
-    }
+    int previewEnabled();
 
     /**
      * Request the camera hal to store meta data or real YUV data in
@@ -310,13 +191,7 @@
      * @return OK on success.
      */
 
-    status_t storeMetaDataInBuffers(int enable)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->store_meta_data_in_buffers)
-            return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
-        return enable ? INVALID_OPERATION: OK;
-    }
+    status_t storeMetaDataInBuffers(int enable);
 
     /**
      * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
@@ -327,34 +202,17 @@
      * to manage the life-cycle of the video recording frames, and the client must
      * not modify/access any video recording frames.
      */
-    status_t startRecording()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->start_recording)
-            return mDevice->ops->start_recording(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t startRecording();
 
     /**
      * Stop a previously started recording.
      */
-    void stopRecording()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->stop_recording)
-            mDevice->ops->stop_recording(mDevice);
-    }
+    void stopRecording();
 
     /**
      * Returns true if recording is enabled.
      */
-    int recordingEnabled()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->recording_enabled)
-            return mDevice->ops->recording_enabled(mDevice);
-        return false;
-    }
+    int recordingEnabled();
 
     /**
      * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
@@ -366,30 +224,14 @@
      * responsibility of managing the life-cycle of the video recording
      * frames.
      */
-    void releaseRecordingFrame(const sp<IMemory>& mem)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->release_recording_frame) {
-            ssize_t offset;
-            size_t size;
-            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-            void *data = ((uint8_t *)heap->base()) + offset;
-            return mDevice->ops->release_recording_frame(mDevice, data);
-        }
-    }
+    void releaseRecordingFrame(const sp<IMemory>& mem);
 
     /**
      * Start auto focus, the notification callback routine is called
      * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
      * will be called again if another auto focus is needed.
      */
-    status_t autoFocus()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->auto_focus)
-            return mDevice->ops->auto_focus(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t autoFocus();
 
     /**
      * Cancels auto-focus function. If the auto-focus is still in progress,
@@ -397,151 +239,73 @@
      * or not, this function will return the focus position to the default.
      * If the camera does not support auto-focus, this is a no-op.
      */
-    status_t cancelAutoFocus()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->cancel_auto_focus)
-            return mDevice->ops->cancel_auto_focus(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t cancelAutoFocus();
 
     /**
      * Take a picture.
      */
-    status_t takePicture()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->take_picture)
-            return mDevice->ops->take_picture(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t takePicture();
 
     /**
      * Cancel a picture that was started with takePicture.  Calling this
      * method when no picture is being taken is a no-op.
      */
-    status_t cancelPicture()
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->cancel_picture)
-            return mDevice->ops->cancel_picture(mDevice);
-        return INVALID_OPERATION;
-    }
+    status_t cancelPicture();
 
     /**
      * Set the camera parameters. This returns BAD_VALUE if any parameter is
      * invalid or not supported. */
-    status_t setParameters(const CameraParameters &params)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->set_parameters)
-            return mDevice->ops->set_parameters(mDevice,
-                                               params.flatten().string());
-        return INVALID_OPERATION;
-    }
+    status_t setParameters(const CameraParameters &params);
 
     /** Return the camera parameters. */
-    CameraParameters getParameters() const
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        CameraParameters parms;
-        if (mDevice->ops->get_parameters) {
-            char *temp = mDevice->ops->get_parameters(mDevice);
-            String8 str_parms(temp);
-            if (mDevice->ops->put_parameters)
-                mDevice->ops->put_parameters(mDevice, temp);
-            else
-                free(temp);
-            parms.unflatten(str_parms);
-        }
-        return parms;
-    }
+    CameraParameters getParameters() const;
 
     /**
      * Send command to camera driver.
      */
-    status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->send_command)
-            return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
-        return INVALID_OPERATION;
-    }
+    status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
 
     /**
      * Release the hardware resources owned by this object.  Note that this is
      * *not* done in the destructor.
      */
-    void release() {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->release)
-            mDevice->ops->release(mDevice);
-    }
+    void release();
 
     /**
      * Dump state of the camera hardware
      */
-    status_t dump(int fd, const Vector<String16>& /*args*/) const
-    {
-        ALOGV("%s(%s)", __FUNCTION__, mName.string());
-        if (mDevice->ops->dump)
-            return mDevice->ops->dump(mDevice, fd);
-        return OK; // It's fine if the HAL doesn't implement dump()
-    }
+    status_t dump(int fd, const Vector<String16>& /*args*/) const;
 
 private:
     camera_device_t *mDevice;
+    sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;
     String8 mName;
 
-    static void __notify_cb(int32_t msg_type, int32_t ext1,
-                            int32_t ext2, void *user)
-    {
-        ALOGV("%s", __FUNCTION__);
-        CameraHardwareInterface *__this =
-                static_cast<CameraHardwareInterface *>(user);
-        __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
-    }
+    static void sNotifyCb(int32_t msg_type, int32_t ext1,
+                            int32_t ext2, void *user);
 
-    static void __data_cb(int32_t msg_type,
+    static void sDataCb(int32_t msg_type,
                           const camera_memory_t *data, unsigned int index,
                           camera_frame_metadata_t *metadata,
-                          void *user)
-    {
-        ALOGV("%s", __FUNCTION__);
-        CameraHardwareInterface *__this =
-                static_cast<CameraHardwareInterface *>(user);
-        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
-        if (index >= mem->mNumBufs) {
-            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
-                 index, mem->mNumBufs);
-            return;
-        }
-        __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
-    }
+                          void *user);
 
-    static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
+    static void sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
                              const camera_memory_t *data, unsigned index,
-                             void *user)
-    {
-        ALOGV("%s", __FUNCTION__);
-        CameraHardwareInterface *__this =
-                static_cast<CameraHardwareInterface *>(user);
-        // Start refcounting the heap object from here on.  When the clients
-        // drop all references, it will be destroyed (as well as the enclosed
-        // MemoryHeapBase.
-        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
-        if (index >= mem->mNumBufs) {
-            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
-                 index, mem->mNumBufs);
-            return;
-        }
-        __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser);
-    }
+                             void *user);
+
+    // TODO: b/35625849
+    // Meta data buffer layout for passing a native_handle to codec
+    // matching frameworks/native/include/media/hardware/MetadataBufferType.h and
+    //          frameworks/native/include/media/hardware/HardwareAPI.h
+    struct VideoNativeHandleMetadata {
+        static const uint32_t kMetadataBufferTypeNativeHandleSource = 3;
+        uint32_t eType; // must be kMetadataBufferTypeNativeHandleSource
+        native_handle_t* pHandle;
+    };
 
     // This is a utility class that combines a MemoryHeapBase and a MemoryBase
     // in one.  Since we tend to use them in a one-to-one relationship, this is
     // handy.
-
     class CameraHeapMemory : public RefBase {
     public:
         CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) :
@@ -572,7 +336,7 @@
                                              i * mBufSize,
                                              mBufSize);
 
-            handle.release = __put_memory;
+            handle.release = sPutMemory;
         }
 
         virtual ~CameraHeapMemory()
@@ -588,199 +352,94 @@
         camera_memory_t handle;
     };
 
-    static camera_memory_t* __get_memory(int fd, size_t buf_size, uint_t num_bufs,
-                                         void *user __attribute__((unused)))
-    {
-        CameraHeapMemory *mem;
-        if (fd < 0)
-            mem = new CameraHeapMemory(buf_size, num_bufs);
-        else
-            mem = new CameraHeapMemory(fd, buf_size, num_bufs);
-        mem->incStrong(mem);
-        return &mem->handle;
-    }
+    static camera_memory_t* sGetMemory(int fd, size_t buf_size, uint_t num_bufs,
+                                         void *user __attribute__((unused)));
 
-    static void __put_memory(camera_memory_t *data)
-    {
-        if (!data)
-            return;
+    static void sPutMemory(camera_memory_t *data);
 
-        CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
-        mem->decStrong(mem);
-    }
+    static ANativeWindow *sToAnw(void *user);
 
-    static ANativeWindow *__to_anw(void *user)
-    {
-        CameraHardwareInterface *__this =
-                reinterpret_cast<CameraHardwareInterface *>(user);
-        return __this->mPreviewWindow.get();
-    }
-#define anw(n) __to_anw(((struct camera_preview_window *)(n))->user)
-#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
-        ((struct camera_preview_window *)(n))->user)
+    static int sDequeueBuffer(struct preview_stream_ops* w,
+                                buffer_handle_t** buffer, int *stride);
 
-    static int __dequeue_buffer(struct preview_stream_ops* w,
-                                buffer_handle_t** buffer, int *stride)
-    {
-        int rc;
-        ANativeWindow *a = anw(w);
-        ANativeWindowBuffer* anb;
-        rc = native_window_dequeue_buffer_and_wait(a, &anb);
-        if (!rc) {
-            *buffer = &anb->handle;
-            *stride = anb->stride;
-        }
-        return rc;
-    }
+    static int sLockBuffer(struct preview_stream_ops* w,
+                      buffer_handle_t* /*buffer*/);
 
-#ifndef container_of
-#define container_of(ptr, type, member) ({                      \
-        const __typeof__(((type *) 0)->member) *__mptr = (ptr);     \
-        (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
-#endif
+    static int sEnqueueBuffer(struct preview_stream_ops* w,
+                      buffer_handle_t* buffer);
 
-    static int __lock_buffer(struct preview_stream_ops* w,
-                      buffer_handle_t* /*buffer*/)
-    {
-        ANativeWindow *a = anw(w);
-        (void)a;
-        return 0;
-    }
+    static int sCancelBuffer(struct preview_stream_ops* w,
+                      buffer_handle_t* buffer);
 
-    static int __enqueue_buffer(struct preview_stream_ops* w,
-                      buffer_handle_t* buffer)
-    {
-        ANativeWindow *a = anw(w);
-        return a->queueBuffer(a,
-                  container_of(buffer, ANativeWindowBuffer, handle), -1);
-    }
+    static int sSetBufferCount(struct preview_stream_ops* w, int count);
 
-    static int __cancel_buffer(struct preview_stream_ops* w,
-                      buffer_handle_t* buffer)
-    {
-        ANativeWindow *a = anw(w);
-        return a->cancelBuffer(a,
-                  container_of(buffer, ANativeWindowBuffer, handle), -1);
-    }
+    static int sSetBuffersGeometry(struct preview_stream_ops* w,
+                      int width, int height, int format);
 
-    static int __set_buffer_count(struct preview_stream_ops* w, int count)
-    {
-        ANativeWindow *a = anw(w);
+    static int sSetCrop(struct preview_stream_ops *w,
+                      int left, int top, int right, int bottom);
 
-        if (a != nullptr) {
-            // Workaround for b/27039775
-            // Previously, setting the buffer count would reset the buffer
-            // queue's flag that allows for all buffers to be dequeued on the
-            // producer side, instead of just the producer's declared max count,
-            // if no filled buffers have yet been queued by the producer.  This
-            // reset no longer happens, but some HALs depend on this behavior,
-            // so it needs to be maintained for HAL backwards compatibility.
-            // Simulate the prior behavior by disconnecting/reconnecting to the
-            // window and setting the values again.  This has the drawback of
-            // actually causing memory reallocation, which may not have happened
-            // in the past.
-            CameraHardwareInterface *hw = hwi(w);
-            native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
-            native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
-            if (hw->mPreviewScalingMode != NOT_SET) {
-                native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
-            }
-            if (hw->mPreviewTransform != NOT_SET) {
-                native_window_set_buffers_transform(a, hw->mPreviewTransform);
-            }
-            if (hw->mPreviewWidth != NOT_SET) {
-                native_window_set_buffers_dimensions(a,
-                        hw->mPreviewWidth, hw->mPreviewHeight);
-                native_window_set_buffers_format(a, hw->mPreviewFormat);
-            }
-            if (hw->mPreviewUsage != 0) {
-                native_window_set_usage(a, hw->mPreviewUsage);
-            }
-            if (hw->mPreviewSwapInterval != NOT_SET) {
-                a->setSwapInterval(a, hw->mPreviewSwapInterval);
-            }
-            if (hw->mPreviewCrop.left != NOT_SET) {
-                native_window_set_crop(a, &(hw->mPreviewCrop));
-            }
-        }
+    static int sSetTimestamp(struct preview_stream_ops *w,
+                               int64_t timestamp);
 
-        return native_window_set_buffer_count(a, count);
-    }
+    static int sSetUsage(struct preview_stream_ops* w, int usage);
 
-    static int __set_buffers_geometry(struct preview_stream_ops* w,
-                      int width, int height, int format)
-    {
-        int rc;
-        ANativeWindow *a = anw(w);
-        CameraHardwareInterface *hw = hwi(w);
-        hw->mPreviewWidth = width;
-        hw->mPreviewHeight = height;
-        hw->mPreviewFormat = format;
-        rc = native_window_set_buffers_dimensions(a, width, height);
-        if (!rc) {
-            rc = native_window_set_buffers_format(a, format);
-        }
-        return rc;
-    }
+    static int sSetSwapInterval(struct preview_stream_ops *w, int interval);
 
-    static int __set_crop(struct preview_stream_ops *w,
-                      int left, int top, int right, int bottom)
-    {
-        ANativeWindow *a = anw(w);
-        CameraHardwareInterface *hw = hwi(w);
-        hw->mPreviewCrop.left = left;
-        hw->mPreviewCrop.top = top;
-        hw->mPreviewCrop.right = right;
-        hw->mPreviewCrop.bottom = bottom;
-        return native_window_set_crop(a, &(hw->mPreviewCrop));
-    }
-
-    static int __set_timestamp(struct preview_stream_ops *w,
-                               int64_t timestamp) {
-        ANativeWindow *a = anw(w);
-        return native_window_set_buffers_timestamp(a, timestamp);
-    }
-
-    static int __set_usage(struct preview_stream_ops* w, int usage)
-    {
-        ANativeWindow *a = anw(w);
-        CameraHardwareInterface *hw = hwi(w);
-        hw->mPreviewUsage = usage;
-        return native_window_set_usage(a, usage);
-    }
-
-    static int __set_swap_interval(struct preview_stream_ops *w, int interval)
-    {
-        ANativeWindow *a = anw(w);
-        CameraHardwareInterface *hw = hwi(w);
-        hw->mPreviewSwapInterval = interval;
-        return a->setSwapInterval(a, interval);
-    }
-
-    static int __get_min_undequeued_buffer_count(
+    static int sGetMinUndequeuedBufferCount(
                       const struct preview_stream_ops *w,
-                      int *count)
-    {
-        ANativeWindow *a = anw(w);
-        return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
-    }
+                      int *count);
 
-    void initHalPreviewWindow()
-    {
-        mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
-        mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
-        mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
-        mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
-        mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
-        mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
-        mHalPreviewWindow.nw.set_crop = __set_crop;
-        mHalPreviewWindow.nw.set_timestamp = __set_timestamp;
-        mHalPreviewWindow.nw.set_usage = __set_usage;
-        mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
+    void initHalPreviewWindow();
 
-        mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
-                __get_min_undequeued_buffer_count;
-    }
+    std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
+    void cleanupCirculatingBuffers();
+
+    /**
+     * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
+     */
+    hardware::Return<void> notifyCallback(
+            hardware::camera::device::V1_0::NotifyCallbackMsg msgType,
+            int32_t ext1, int32_t ext2) override;
+    hardware::Return<uint32_t> registerMemory(
+            const hardware::hidl_handle& descriptor,
+            uint32_t bufferSize, uint32_t bufferCount) override;
+    hardware::Return<void> unregisterMemory(uint32_t memId) override;
+    hardware::Return<void> dataCallback(
+            hardware::camera::device::V1_0::DataCallbackMsg msgType,
+            uint32_t data, uint32_t bufferIndex,
+            const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) override;
+    hardware::Return<void> dataCallbackTimestamp(
+            hardware::camera::device::V1_0::DataCallbackMsg msgType,
+            uint32_t data, uint32_t bufferIndex, int64_t timestamp) override;
+    hardware::Return<void> handleCallbackTimestamp(
+            hardware::camera::device::V1_0::DataCallbackMsg msgType,
+            const hardware::hidl_handle& frameData, uint32_t data,
+            uint32_t bufferIndex, int64_t timestamp) override;
+
+    /**
+     * Implementation of android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback
+     */
+    hardware::Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            enqueueBuffer(uint64_t bufferId) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            cancelBuffer(uint64_t bufferId) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setBufferCount(uint32_t count) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setBuffersGeometry(uint32_t w, uint32_t h,
+                    hardware::graphics::common::V1_0::PixelFormat format) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setUsage(hardware::graphics::allocator::V2_0::ProducerUsage usage) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setSwapInterval(int32_t interval) override;
+    hardware::Return<void> getMinUndequeuedBufferCount(
+        getMinUndequeuedBufferCount_cb _hidl_cb) override;
+    hardware::Return<hardware::camera::common::V1_0::Status>
+            setTimestamp(int64_t timestamp) override;
 
     sp<ANativeWindow>        mPreviewWindow;
 
@@ -806,6 +465,48 @@
     int mPreviewUsage;
     int mPreviewSwapInterval;
     android_native_rect_t mPreviewCrop;
+
+    struct BufferHasher {
+        size_t operator()(const buffer_handle_t& buf) const {
+            if (buf == nullptr)
+                return 0;
+
+            size_t result = 1;
+            result = 31 * result + buf->numFds;
+            result = 31 * result + buf->numInts;
+            int length = buf->numFds + buf->numInts;
+            for (int i = 0; i < length; i++) {
+                result = 31 * result + buf->data[i];
+            }
+            return result;
+        }
+    };
+
+    struct BufferComparator {
+        bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
+            if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) {
+                int length = buf1->numFds + buf1->numInts;
+                for (int i = 0; i < length; i++) {
+                    if (buf1->data[i] != buf2->data[i]) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+    };
+
+    std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
+    typedef std::unordered_map<const buffer_handle_t, uint64_t,
+            BufferHasher, BufferComparator> BufferIdMap;
+    // stream ID -> per stream buffer ID map
+    BufferIdMap mBufferIdMap;
+    std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
+    uint64_t mNextBufferId = 1;
+    static const uint64_t BUFFER_ID_NO_BUFFER = 0;
+
+    std::unordered_map<int, camera_memory_t*> mHidlMemPoolMap;
 };
 
 };  // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index f20556d..4d5abed 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -63,6 +63,7 @@
 
 Camera3Device::Camera3Device(const String8 &id):
         mId(id),
+        mOperatingMode(NO_MODE),
         mIsConstrainedHighSpeedConfiguration(false),
         mStatus(STATUS_UNINITIALIZED),
         mStatusWaiters(0),
@@ -514,19 +515,25 @@
     return StreamRotation::ROTATION_0;
 }
 
-StreamConfigurationMode Camera3Device::mapToStreamConfigurationMode(
-        camera3_stream_configuration_mode_t operationMode) {
-    switch(operationMode) {
-        case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
-            return StreamConfigurationMode::NORMAL_MODE;
-        case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
-            return StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
-        case CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START:
-            // Needs to be mapped by vendor extensions
-            break;
+status_t Camera3Device::mapToStreamConfigurationMode(
+        camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
+    if (mode == nullptr) return BAD_VALUE;
+    if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+        switch(operationMode) {
+            case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
+                *mode = StreamConfigurationMode::NORMAL_MODE;
+                break;
+            case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+                *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
+                break;
+            default:
+                ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
+                return BAD_VALUE;
+        }
+    } else {
+        *mode = static_cast<StreamConfigurationMode>(operationMode);
     }
-    ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
-    return StreamConfigurationMode::NORMAL_MODE;
+    return OK;
 }
 
 camera3_buffer_status_t Camera3Device::mapHidlBufferStatus(BufferStatus status) {
@@ -677,8 +684,12 @@
         lines.appendFormat("    Error cause: %s\n", mErrorCause.string());
     }
     lines.appendFormat("    Stream configuration:\n");
-    lines.appendFormat("    Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
-            "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
+    const char *mode =
+            mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
+            mOperatingMode == static_cast<int>(
+                StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
+            "CUSTOM";
+    lines.appendFormat("    Operation mode: %s (%d) \n", mode, mOperatingMode);
 
     if (mInputStream != NULL) {
         write(fd, lines.string(), lines.size());
@@ -1093,7 +1104,9 @@
     status_t res;
 
     if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
-        res = configureStreamsLocked();
+        // This point should only be reached via API1 (API2 must explicitly call configureStreams)
+        // so unilaterally select normal operating mode.
+        res = configureStreamsLocked(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
         // Stream configuration failed. Client might try other configuraitons.
         if (res != OK) {
             CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
@@ -1195,7 +1208,8 @@
     // Continue captures if active at start
     if (wasActive) {
         ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
-        res = configureStreamsLocked();
+        // Reuse current operating mode for new stream config
+        res = configureStreamsLocked(mOperatingMode);
         if (res != OK) {
             ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
                     __FUNCTION__, mNextStreamId, strerror(-res), res);
@@ -1357,7 +1371,8 @@
     // Continue captures if active at start
     if (wasActive) {
         ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
-        res = configureStreamsLocked();
+        // Reuse current operating mode for new stream config
+        res = configureStreamsLocked(mOperatingMode);
         if (res != OK) {
             CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
                     mNextStreamId, strerror(-res), res);
@@ -1501,19 +1516,14 @@
     return INVALID_OPERATION;
 }
 
-status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
+status_t Camera3Device::configureStreams(int operatingMode) {
     ATRACE_CALL();
     ALOGV("%s: E", __FUNCTION__);
 
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
-        mNeedConfig = true;
-        mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
-    }
-
-    return configureStreamsLocked();
+    return configureStreamsLocked(operatingMode);
 }
 
 status_t Camera3Device::getInputBufferProducer(
@@ -2161,7 +2171,7 @@
     mNeedConfig = true;
 }
 
-status_t Camera3Device::configureStreamsLocked() {
+status_t Camera3Device::configureStreamsLocked(int operatingMode) {
     ATRACE_CALL();
     status_t res;
 
@@ -2170,6 +2180,21 @@
         return INVALID_OPERATION;
     }
 
+    if (operatingMode < 0) {
+        CLOGE("Invalid operating mode: %d", operatingMode);
+        return BAD_VALUE;
+    }
+
+    bool isConstrainedHighSpeed =
+            static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
+            operatingMode;
+
+    if (mOperatingMode != operatingMode) {
+        mNeedConfig = true;
+        mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
+        mOperatingMode = operatingMode;
+    }
+
     if (!mNeedConfig) {
         ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
         return OK;
@@ -2188,9 +2213,7 @@
     ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
 
     camera3_stream_configuration config;
-    config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
-            CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
-            CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
+    config.operation_mode = mOperatingMode;
     config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
 
     Vector<camera3_stream_t*> streams;
@@ -3149,8 +3172,12 @@
             }
         }
 
-        requestedConfiguration.operationMode = mapToStreamConfigurationMode(
-                (camera3_stream_configuration_mode_t) config->operation_mode);
+        res = mapToStreamConfigurationMode(
+                (camera3_stream_configuration_mode_t) config->operation_mode,
+                /*out*/ &requestedConfiguration.operationMode);
+        if (res != OK) {
+            return res;
+        }
 
         // Invoke configureStreams
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index e19b62e..998cc0b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -135,7 +135,9 @@
     status_t deleteStream(int id) override;
     status_t deleteReprocessStream(int id) override;
 
-    status_t configureStreams(bool isConstraiedHighSpeed = false) override;
+    status_t configureStreams(int operatingMode =
+            static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
+            override;
     status_t getInputBufferProducer(
             sp<IGraphicBufferProducer> *producer) override;
 
@@ -212,6 +214,11 @@
     // Camera device ID
     const String8              mId;
 
+    // Current stream configuration mode;
+    int                        mOperatingMode;
+    // Constant to use for no set operating mode
+    static const int           NO_MODE = -1;
+
     // Flag indicating is the current active stream configuration is constrained high speed.
     bool                       mIsConstrainedHighSpeedConfiguration;
 
@@ -508,7 +515,7 @@
      * Take the currently-defined set of streams and configure the HAL to use
      * them. This is a long-running operation (may be several hundered ms).
      */
-    status_t           configureStreamsLocked();
+    status_t           configureStreamsLocked(int operatingMode);
 
     /**
      * Cancel stream configuration that did not finish successfully.
@@ -574,8 +581,9 @@
     static hardware::camera::device::V3_2::ConsumerUsageFlags mapToConsumerUsage(uint32_t usage);
     static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
             camera3_stream_rotation_t rotation);
-    static hardware::camera::device::V3_2::StreamConfigurationMode mapToStreamConfigurationMode(
-            camera3_stream_configuration_mode_t operationMode);
+    // Returns a negative error code if the passed-in operation mode is not valid.
+    static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
+            /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
     static camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status);
     static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
     static uint32_t mapConsumerToFrameworkUsage(
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index deb6735..bf6af86 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -32,6 +32,8 @@
 
 #include <utils/Trace.h>
 
+#include <cutils/atomic.h>
+
 #include "Camera3StreamSplitter.h"
 
 namespace android {
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index a8f2ca9..081caf0 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -59,3 +59,7 @@
 connect: 1
 fcntl64: 1
 rt_tgsigqueueinfo: 1
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 165694c..72a1edb 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -45,3 +45,7 @@
 connect: 1
 fcntl64: 1
 rt_tgsigqueueinfo: 1
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index 7e7b858..6f2d33f 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -36,3 +36,7 @@
 connect: 1
 rt_tgsigqueueinfo: 1
 writev: 1
+geteuid: 1
+getgid: 1
+getegid: 1
+getgroups: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index 189855c..4a06e5a 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -44,3 +44,7 @@
 rt_sigprocmask: 1
 fcntl64: 1
 rt_tgsigqueueinfo: 1
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
diff --git a/services/soundtrigger/SoundTriggerHalHidl.h b/services/soundtrigger/SoundTriggerHalHidl.h
index 916fcc4..0c68cf1 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.h
+++ b/services/soundtrigger/SoundTriggerHalHidl.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_HIDL_H
 #define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_HIDL_H
 
+#include <stdatomic.h>
 #include <utils/RefBase.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 78845b7..5b8d990 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -544,10 +544,11 @@
     ALOGV("remove client %p", moduleClient.get());
     mModuleClients.removeAt(index);
 
-    for (size_t i = 0; i < mModels.size(); i++) {
-        sp<Model> model = mModels.valueAt(i);
+    // Iterate in reverse order as models are removed from list inside the loop.
+    for (size_t i = mModels.size(); i > 0; i--) {
+        sp<Model> model = mModels.valueAt(i - 1);
         if (moduleClient == model->mModuleClient) {
-            mModels.removeItemsAt(i);
+            mModels.removeItemsAt(i - 1);
             ALOGV("detach() unloading model %d", model->mHandle);
             if (mHalInterface != 0) {
                 if (model->mState == Model::STATE_ACTIVE) {