Merge "Implement ISensorsCallback"
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 7870c7b..37237df 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -108,7 +108,7 @@
         OP_MANAGE_IPSEC_TUNNELS = 75,
         OP_START_FOREGROUND = 76,
         OP_BLUETOOTH_SCAN = 77,
-        OP_USE_FACE = 78,
+        OP_USE_BIOMETRIC = 78,
     };
 
     AppOpsManager();
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index 549e4b3..e0ae469 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -71,8 +71,6 @@
 }
 
 binder_status_t PruneStatusT(status_t status) {
-    if (status > 0) return status;
-
     switch (status) {
         case ::android::OK:
             return STATUS_OK;
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
index 1025a88..cec2ae5 100644
--- a/services/sensorservice/RecentEventLogger.cpp
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -26,6 +26,7 @@
 
 namespace {
     constexpr size_t LOG_SIZE = 10;
+    constexpr size_t LOG_SIZE_MED = 30;  // debugging for slower sensors
     constexpr size_t LOG_SIZE_LARGE = 50;  // larger samples for debugging
 }// unnamed namespace
 
@@ -98,10 +99,16 @@
 
 
 size_t RecentEventLogger::logSizeBySensorType(int sensorType) {
-    return (sensorType == SENSOR_TYPE_STEP_COUNTER ||
-            sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
-            sensorType == SENSOR_TYPE_ACCELEROMETER ||
-            sensorType == SENSOR_TYPE_LIGHT) ? LOG_SIZE_LARGE : LOG_SIZE;
+    if (sensorType == SENSOR_TYPE_STEP_COUNTER ||
+        sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+        sensorType == SENSOR_TYPE_ACCELEROMETER ||
+        sensorType == SENSOR_TYPE_LIGHT) {
+        return LOG_SIZE_LARGE;
+    }
+    if (sensorType == SENSOR_TYPE_PROXIMITY) {
+        return LOG_SIZE_MED;
+    }
+    return LOG_SIZE;
 }
 
 RecentEventLogger::SensorEventLog::SensorEventLog(const sensors_event_t& e) : mEvent(e) {
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 744bdba..4f12d3e 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -4,6 +4,7 @@
         "-DLOG_TAG=\"SurfaceFlinger\"",
         "-Wall",
         "-Werror",
+        "-Wformat",
         "-Wthread-safety",
         "-Wunused",
         "-Wunreachable-code",
@@ -18,6 +19,10 @@
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
     ],
+    include_dirs: [
+        "frameworks/native/vulkan/vkjson",
+        "frameworks/native/vulkan/include",
+    ],
     shared_libs: [
         "android.frameworks.vr.composer@1.0",
         "android.hardware.configstore-utils",
@@ -84,6 +89,18 @@
     ],
 }
 
+cc_defaults {
+    name: "libsurfaceflinger_production_defaults",
+    defaults: ["libsurfaceflinger_defaults"],
+    cflags: [
+        "-fvisibility=hidden",
+        "-fwhole-program-vtables", // requires ThinLTO
+    ],
+    lto: {
+        thin: true,
+    },
+}
+
 cc_library_headers {
     name: "libsurfaceflinger_headers",
     export_include_dirs: ["."],
@@ -137,33 +154,23 @@
 }
 
 cc_library_shared {
+    // Please use libsurfaceflinger_defaults to configure how the sources are
+    // built, so the same settings can be used elsewhere.
     name: "libsurfaceflinger",
-    defaults: ["libsurfaceflinger_defaults"],
-    cflags: [
-        "-fvisibility=hidden",
-        "-Werror=format",
-    ],
+    defaults: ["libsurfaceflinger_production_defaults"],
     srcs: [
         ":libsurfaceflinger_sources",
+
+        // Note: SurfaceFlingerFactory is not in the default sources so that it
+        // can be easily replaced.
+        "SurfaceFlingerFactory.cpp",
     ],
     logtags: ["EventLog/EventLogTags.logtags"],
-    include_dirs: [
-        "frameworks/native/vulkan/vkjson",
-        "frameworks/native/vulkan/include",
-    ],
-    cppflags: [
-        "-fwhole-program-vtables", // requires ThinLTO
-    ],
-    lto: {
-        thin: true,
-    },
 }
 
-cc_binary {
-    name: "surfaceflinger",
+cc_defaults {
+    name: "libsurfaceflinger_binary",
     defaults: ["surfaceflinger_defaults"],
-    init_rc: ["surfaceflinger.rc"],
-    srcs: ["main_surfaceflinger.cpp"],
     whole_static_libs: [
         "libsigchain",
     ],
@@ -180,7 +187,6 @@
         "libhidltransport",
         "liblayers_proto",
         "liblog",
-        "libsurfaceflinger",
         "libtimestats_proto",
         "libutils",
     ],
@@ -189,19 +195,19 @@
         "libtrace_proto",
     ],
     ldflags: ["-Wl,--export-dynamic"],
+}
 
-    // TODO(b/71715793): These version-scripts are required due to the use of
-    // whole_static_libs to pull in libsigchain. To work, the files had to be
-    // locally duplicated from their original location
-    // $ANDROID_ROOT/art/sigchainlib/
-    multilib: {
-        lib32: {
-            version_script: "version-script32.txt",
-        },
-        lib64: {
-            version_script: "version-script64.txt",
-        },
-    },
+filegroup {
+    name: "surfaceflinger_binary_sources",
+    srcs: ["main_surfaceflinger.cpp"],
+}
+
+cc_binary {
+    name: "surfaceflinger",
+    defaults: ["libsurfaceflinger_binary"],
+    init_rc: ["surfaceflinger.rc"],
+    srcs: [":surfaceflinger_binary_sources"],
+    shared_libs: ["libsurfaceflinger"],
 }
 
 cc_library_shared {
diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
index 3e9d443..97028a8 100644
--- a/services/surfaceflinger/Barrier.h
+++ b/services/surfaceflinger/Barrier.h
@@ -18,46 +18,40 @@
 #define ANDROID_BARRIER_H
 
 #include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
+#include <condition_variable>
+#include <mutex>
 
 namespace android {
 
 class Barrier
 {
 public:
-    inline Barrier() : state(CLOSED) { }
-    inline ~Barrier() { }
-
     // Release any threads waiting at the Barrier.
     // Provides release semantics: preceding loads and stores will be visible
     // to other threads before they wake up.
     void open() {
-        Mutex::Autolock _l(lock);
-        state = OPENED;
-        cv.broadcast();
+        std::lock_guard<std::mutex> lock(mMutex);
+        mIsOpen = true;
+        mCondition.notify_all();
     }
 
     // Reset the Barrier, so wait() will block until open() has been called.
     void close() {
-        Mutex::Autolock _l(lock);
-        state = CLOSED;
+        std::lock_guard<std::mutex> lock(mMutex);
+        mIsOpen = false;
     }
 
     // Wait until the Barrier is OPEN.
     // Provides acquire semantics: no subsequent loads or stores will occur
     // until wait() returns.
     void wait() const {
-        Mutex::Autolock _l(lock);
-        while (state == CLOSED) {
-            cv.wait(lock);
-        }
+        std::unique_lock<std::mutex> lock(mMutex);
+        mCondition.wait(lock, [this]() NO_THREAD_SAFETY_ANALYSIS { return mIsOpen; });
     }
 private:
-    enum { OPENED, CLOSED };
-    mutable     Mutex       lock;
-    mutable     Condition   cv;
-    volatile    int         state;
+    mutable std::mutex mMutex;
+    mutable std::condition_variable mCondition;
+    int mIsOpen GUARDED_BY(mMutex){false};
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 4839bfb..521cdbf 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -207,8 +207,9 @@
 }
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
-    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was true
+    bool sidebandStreamChanged = true;
+    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
+        // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
         getBE().compositionInfo.hwc.sidebandStream = mConsumer->getSidebandStream();
         if (getBE().compositionInfo.hwc.sidebandStream != nullptr) {
@@ -259,7 +260,7 @@
             Mutex::Autolock lock(mQueueItemLock);
             mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
+            mQueuedFrames--;
         }
         return BAD_VALUE;
     } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
@@ -270,7 +271,7 @@
         if (queuedBuffer) {
             Mutex::Autolock lock(mQueueItemLock);
             mQueueItems.clear();
-            android_atomic_and(0, &mQueuedFrames);
+            mQueuedFrames = 0;
             mTimeStats.clearLayerRecord(getName().c_str());
         }
 
@@ -294,7 +295,7 @@
         while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
             mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
+            mQueuedFrames--;
         }
 
         const std::string layerName(getName().c_str());
@@ -306,7 +307,7 @@
 
     // Decrement the queued-frames count.  Signal another event if we
     // have more frames pending.
-    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) {
+    if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
         mFlinger->signalLayerUpdate();
     }
 
@@ -367,7 +368,7 @@
         }
 
         mQueueItems.push_back(item);
-        android_atomic_inc(&mQueuedFrames);
+        mQueuedFrames++;
 
         // Wake up any pending callbacks
         mLastFrameNumberReceived = item.mFrameNumber;
@@ -404,8 +405,9 @@
 }
 
 void BufferQueueLayer::onSidebandStreamChanged() {
-    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was false
+    bool sidebandStreamChanged = false;
+    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, true)) {
+        // mSidebandStreamChanged was changed to true
         mFlinger->signalLayerUpdate();
     }
 }
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 579ed81..400f412 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -137,8 +137,8 @@
     int mActiveBufferSlot;
 
     // thread-safe
-    volatile int32_t mQueuedFrames;
-    volatile int32_t mSidebandStreamChanged; // used like an atomic boolean
+    std::atomic<int32_t> mQueuedFrames{0};
+    std::atomic<bool> mSidebandStreamChanged{false};
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 03b63bd..19c84d0 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -62,12 +62,11 @@
 
 namespace android {
 
-int32_t Layer::sSequence = 1;
+std::atomic<int32_t> Layer::sSequence{1};
 
 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
              uint32_t h, uint32_t flags)
       : contentDirty(false),
-        sequence(uint32_t(android_atomic_inc(&sSequence))),
         mFlinger(flinger),
         mPremultipliedAlpha(true),
         mName(name),
@@ -1019,11 +1018,11 @@
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    return android_atomic_or(flags, &mTransactionFlags);
+    return mTransactionFlags.fetch_or(flags);
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3845b22..74f0a63 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -73,7 +73,7 @@
 // ---------------------------------------------------------------------------
 
 class Layer : public virtual RefBase {
-    static int32_t sSequence;
+    static std::atomic<int32_t> sSequence;
 
 public:
     friend class LayerBE;
@@ -89,7 +89,7 @@
     // Layer serial number.  This gives layers an explicit ordering, so we
     // have a stable sort order when their layer stack and Z-order are
     // the same.
-    int32_t sequence;
+    int32_t sequence{sSequence++};
 
     enum { // flags for doTransaction()
         eDontUpdateGeometryState = 0x00000001,
@@ -271,6 +271,7 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
+    uint32_t getTransactionFlags() const { return mTransactionFlags; }
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
 
@@ -696,7 +697,7 @@
     // these are protected by an external lock
     State mCurrentState;
     State mDrawingState;
-    volatile int32_t mTransactionFlags;
+    std::atomic<uint32_t> mTransactionFlags{0};
 
     // Accessed from main thread and binder threads
     Mutex mPendingStateMutex;
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index 04ab121..9c2d312 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -57,7 +57,7 @@
 }
 
 void LayerStats::traverseLayerTreeStatsLocked(
-        const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+        const std::vector<LayerProtoParser::Layer*>& layerTree,
         const LayerProtoParser::LayerGlobal& layerGlobal,
         std::vector<std::string>* const outLayerShapeVec) {
     for (const auto& layer : layerTree) {
@@ -82,7 +82,7 @@
         base::StringAppendF(&key, ",%s",
                             destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
                                             layerGlobal.resolution[1], false));
-        base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str());
+        base::StringAppendF(&key, ",%s", scaleRatioWH(layer).c_str());
         base::StringAppendF(&key, ",%s", alpha(static_cast<float>(layer->color.a)));
 
         outLayerShapeVec->push_back(key);
@@ -98,7 +98,7 @@
     std::vector<std::string> layerShapeVec;
 
     std::lock_guard<std::mutex> lock(mMutex);
-    traverseLayerTreeStatsLocked(layerTree, layerGlobal, &layerShapeVec);
+    traverseLayerTreeStatsLocked(layerTree.topLevelLayers, layerGlobal, &layerShapeVec);
 
     std::string layerShapeKey =
             base::StringPrintf("%d,%s,%s,%s", static_cast<int32_t>(layerShapeVec.size()),
diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h
index 7a190fd..944073b 100644
--- a/services/surfaceflinger/LayerStats.h
+++ b/services/surfaceflinger/LayerStats.h
@@ -38,7 +38,7 @@
 private:
     // Traverse layer tree to get all visible layers' stats
     void traverseLayerTreeStatsLocked(
-            const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+            const std::vector<LayerProtoParser::Layer*>& layerTree,
             const LayerProtoParser::LayerGlobal& layerGlobal,
             std::vector<std::string>* const outLayerShapeVec);
     // Convert layer's top-left position into 8x8 percentage of the display
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fa9cc79..157cbea 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -259,12 +259,10 @@
 
 SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag)
       : BnSurfaceComposer(),
-        mTransactionFlags(0),
         mTransactionPending(false),
         mAnimTransactionPending(false),
         mLayersRemoved(false),
         mLayersAdded(false),
-        mRepaintEverything(0),
         mBootTime(systemTime()),
         mDisplayTokens(),
         mVisibleRegionsDirty(false),
@@ -1468,7 +1466,7 @@
 
     resyncToHardwareVsync(false);
 
-    android_atomic_or(1, &mRepaintEverything);
+    mRepaintEverything = true;
     setTransactionFlags(eDisplayTransactionNeeded);
 }
 
@@ -1527,7 +1525,7 @@
 
     mRefreshPending = false;
 
-    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+    const bool repaintEverything = mRepaintEverything.exchange(false);
     preComposition();
     rebuildLayerStacks();
     calculateWorkingSet();
@@ -3355,11 +3353,11 @@
 }
 
 uint32_t SurfaceFlinger::peekTransactionFlags() {
-    return android_atomic_release_load(&mTransactionFlags);
+    return mTransactionFlags;
 }
 
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
@@ -3368,7 +3366,7 @@
 
 uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags,
         VSyncModulator::TransactionStart transactionStart) {
-    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
+    uint32_t old = mTransactionFlags.fetch_or(flags);
     mVsyncModulator.setTransactionStart(transactionStart);
     if ((old & flags)==0) { // wake the server up
         signalTransaction();
@@ -4620,10 +4618,12 @@
                         mGraphicBufferProducerList.size(), mMaxGraphicBufferProducerListSize);
     colorizer.reset(result);
 
-    LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
-    auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
-    result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
-    result.append("\n");
+    {
+        LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
+        auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
+        result.append(LayerProtoParser::layerTreeToString(layerTree).c_str());
+        result.append("\n");
+    }
 
     result.append("\nFrame-Composition information:\n");
     dumpFrameCompositionInfo(result);
@@ -4661,7 +4661,7 @@
     }
     result.appendFormat("  transaction-flags         : %08x\n"
                         "  gpu_to_cpu_unsupported    : %d\n",
-                        mTransactionFlags, !mGpuToCpuSupported);
+                        mTransactionFlags.load(), !mGpuToCpuSupported);
 
     if (display) {
         const auto activeConfig = getHwComposer().getActiveConfig(display->getId());
@@ -5178,7 +5178,7 @@
 }
 
 void SurfaceFlinger::repaintEverything() {
-    android_atomic_or(1, &mRepaintEverything);
+    mRepaintEverything = true;
     signalTransaction();
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 01d18d9..e2be544 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -793,7 +793,7 @@
     // access must be protected by mStateLock
     mutable Mutex mStateLock;
     State mCurrentState{LayerVector::StateSet::Current};
-    volatile int32_t mTransactionFlags;
+    std::atomic<int32_t> mTransactionFlags{0};
     Condition mTransactionCV;
     bool mTransactionPending;
     bool mAnimTransactionPending;
@@ -812,8 +812,7 @@
     bool mLayersRemoved;
     bool mLayersAdded;
 
-    // access must be protected by mInvalidateLock
-    volatile int32_t mRepaintEverything;
+    std::atomic<bool> mRepaintEverything{false};
 
     // helper methods
     void configureHwcCommonData(const CompositionInfo& compositionInfo) const;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.cpp b/services/surfaceflinger/SurfaceFlingerFactory.cpp
new file mode 100644
index 0000000..b37d6f0
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlingerFactory.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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 "SurfaceFlingerFactory.h"
+#include "SurfaceFlinger.h"
+
+namespace android::surfaceflinger {
+
+sp<SurfaceFlinger> createSurfaceFlinger() {
+    return new SurfaceFlinger();
+}
+
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
new file mode 100644
index 0000000..65eb797
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cutils/compiler.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class SurfaceFlinger;
+
+namespace surfaceflinger {
+
+ANDROID_API sp<SurfaceFlinger> createSurfaceFlinger();
+
+} // namespace surfaceflinger
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 0b4c6fc..57bda5a 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -96,8 +96,9 @@
         const sp<const Layer>& layer)
 {
     Transaction* transaction(increment->mutable_transaction());
-    transaction->set_synchronous(layer->mTransactionFlags & BnSurfaceComposer::eSynchronous);
-    transaction->set_animation(layer->mTransactionFlags & BnSurfaceComposer::eAnimation);
+    const uint32_t layerFlags = layer->getTransactionFlags();
+    transaction->set_synchronous(layerFlags & BnSurfaceComposer::eSynchronous);
+    transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
     addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 370b3b8..67dcd06 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -27,32 +27,36 @@
 namespace android {
 
 void SurfaceTracing::enable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (mEnabled) {
         return;
     }
-    ATRACE_CALL();
     mEnabled = true;
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
-    mTrace.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                            LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    mTrace = std::make_unique<LayersTraceFileProto>();
+    mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                             LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
 }
 
 status_t SurfaceTracing::disable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (!mEnabled) {
         return NO_ERROR;
     }
-    ATRACE_CALL();
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     mEnabled = false;
     status_t err(writeProtoFileLocked());
     ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
     ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
-    mTrace.Clear();
+    mTrace.reset();
     return err;
 }
 
 bool SurfaceTracing::isEnabled() const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     return mEnabled;
 }
 
@@ -61,29 +65,29 @@
     if (!mEnabled) {
         return;
     }
-    LayersTraceProto* entry = mTrace.add_entry();
+    LayersTraceProto* entry = mTrace->add_entry();
     entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry->set_where(where);
     entry->mutable_layers()->Swap(&layers);
 
     constexpr int maxBufferedEntryCount = 3600;
-    if (mTrace.entry_size() >= maxBufferedEntryCount) {
+    if (mTrace->entry_size() >= maxBufferedEntryCount) {
         // TODO: flush buffered entries without disabling tracing
         ALOGE("too many buffered frames; force disable tracing");
         mEnabled = false;
         writeProtoFileLocked();
-        mTrace.Clear();
+        mTrace.reset();
     }
 }
 
 status_t SurfaceTracing::writeProtoFileLocked() {
     ATRACE_CALL();
 
-    if (!mTrace.IsInitialized()) {
+    if (!mTrace->IsInitialized()) {
         return NOT_ENOUGH_DATA;
     }
     std::string output;
-    if (!mTrace.SerializeToString(&output)) {
+    if (!mTrace->SerializeToString(&output)) {
         return PERMISSION_DENIED;
     }
     if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
@@ -97,7 +101,7 @@
     std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
     result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
-    result.appendFormat("  number of entries: %d\n", mTrace.entry_size());
+    result.appendFormat("  number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 27e2c9e..fd8cb82 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -20,6 +20,7 @@
 #include <utils/Errors.h>
 #include <utils/String8.h>
 
+#include <memory>
 #include <mutex>
 
 using namespace android::surfaceflinger;
@@ -46,7 +47,7 @@
     bool mEnabled = false;
     std::string mOutputFileName = DEFAULT_FILENAME;
     mutable std::mutex mTraceMutex;
-    LayersTraceFileProto mTrace;
+    std::unique_ptr<LayersTraceFileProto> mTrace;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index bf12df6..1d7fb67 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -37,11 +37,6 @@
     return lhs->id < rhs->id;
 }
 
-bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs,
-                   const std::unique_ptr<LayerProtoParser::Layer>& rhs) {
-    return sortLayers(lhs.get(), rhs.get());
-}
-
 const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo(
         const LayersProto& layersProto) {
     LayerGlobal layerGlobal;
@@ -52,77 +47,80 @@
     return layerGlobal;
 }
 
-std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree(
-        const LayersProto& layersProto) {
-    std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto);
-    std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers;
+LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(const LayersProto& layersProto) {
+    LayerTree layerTree;
+    layerTree.allLayers = generateLayerList(layersProto);
 
-    for (std::pair<int32_t, Layer*> kv : layerMap) {
-        if (kv.second->parent == nullptr) {
-            // Make unique_ptr for top level layers since they are not children. This ensures there
-            // will only be one unique_ptr made for each layer.
-            layers.push_back(std::unique_ptr<Layer>(kv.second));
+    // find and sort the top-level layers
+    for (Layer& layer : layerTree.allLayers) {
+        if (layer.parent == nullptr) {
+            layerTree.topLevelLayers.push_back(&layer);
         }
     }
+    std::sort(layerTree.topLevelLayers.begin(), layerTree.topLevelLayers.end(), sortLayers);
 
-    std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs);
-    return layers;
+    return layerTree;
 }
 
-std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
+std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList(
         const LayersProto& layersProto) {
+    std::vector<Layer> layerList;
     std::unordered_map<int32_t, Layer*> layerMap;
 
+    // build the layer list and the layer map
+    layerList.reserve(layersProto.layers_size());
+    layerMap.reserve(layersProto.layers_size());
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        layerMap[layerProto.id()] = generateLayer(layerProto);
+        layerList.emplace_back(generateLayer(layersProto.layers(i)));
+        // this works because layerList never changes capacity
+        layerMap[layerList.back().id] = &layerList.back();
     }
 
+    // fix up children and relatives
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        updateChildrenAndRelative(layerProto, layerMap);
+        updateChildrenAndRelative(layersProto.layers(i), layerMap);
     }
 
-    return layerMap;
+    return layerList;
 }
 
-LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
-    Layer* layer = new Layer();
-    layer->id = layerProto.id();
-    layer->name = layerProto.name();
-    layer->type = layerProto.type();
-    layer->transparentRegion = generateRegion(layerProto.transparent_region());
-    layer->visibleRegion = generateRegion(layerProto.visible_region());
-    layer->damageRegion = generateRegion(layerProto.damage_region());
-    layer->layerStack = layerProto.layer_stack();
-    layer->z = layerProto.z();
-    layer->position = {layerProto.position().x(), layerProto.position().y()};
-    layer->requestedPosition = {layerProto.requested_position().x(),
+LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerProto) {
+    Layer layer;
+    layer.id = layerProto.id();
+    layer.name = layerProto.name();
+    layer.type = layerProto.type();
+    layer.transparentRegion = generateRegion(layerProto.transparent_region());
+    layer.visibleRegion = generateRegion(layerProto.visible_region());
+    layer.damageRegion = generateRegion(layerProto.damage_region());
+    layer.layerStack = layerProto.layer_stack();
+    layer.z = layerProto.z();
+    layer.position = {layerProto.position().x(), layerProto.position().y()};
+    layer.requestedPosition = {layerProto.requested_position().x(),
                                 layerProto.requested_position().y()};
-    layer->size = {layerProto.size().w(), layerProto.size().h()};
-    layer->crop = generateRect(layerProto.crop());
-    layer->isOpaque = layerProto.is_opaque();
-    layer->invalidate = layerProto.invalidate();
-    layer->dataspace = layerProto.dataspace();
-    layer->pixelFormat = layerProto.pixel_format();
-    layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
+    layer.size = {layerProto.size().w(), layerProto.size().h()};
+    layer.crop = generateRect(layerProto.crop());
+    layer.isOpaque = layerProto.is_opaque();
+    layer.invalidate = layerProto.invalidate();
+    layer.dataspace = layerProto.dataspace();
+    layer.pixelFormat = layerProto.pixel_format();
+    layer.color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
                     layerProto.color().a()};
-    layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
+    layer.requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
                              layerProto.requested_color().b(), layerProto.requested_color().a()};
-    layer->flags = layerProto.flags();
-    layer->transform = generateTransform(layerProto.transform());
-    layer->requestedTransform = generateTransform(layerProto.requested_transform());
-    layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
-    layer->bufferTransform = generateTransform(layerProto.buffer_transform());
-    layer->queuedFrames = layerProto.queued_frames();
-    layer->refreshPending = layerProto.refresh_pending();
-    layer->hwcFrame = generateRect(layerProto.hwc_frame());
-    layer->hwcCrop = generateFloatRect(layerProto.hwc_crop());
-    layer->hwcTransform = layerProto.hwc_transform();
-    layer->windowType = layerProto.window_type();
-    layer->appId = layerProto.app_id();
-    layer->hwcCompositionType = layerProto.hwc_composition_type();
-    layer->isProtected = layerProto.is_protected();
+    layer.flags = layerProto.flags();
+    layer.transform = generateTransform(layerProto.transform());
+    layer.requestedTransform = generateTransform(layerProto.requested_transform());
+    layer.activeBuffer = generateActiveBuffer(layerProto.active_buffer());
+    layer.bufferTransform = generateTransform(layerProto.buffer_transform());
+    layer.queuedFrames = layerProto.queued_frames();
+    layer.refreshPending = layerProto.refresh_pending();
+    layer.hwcFrame = generateRect(layerProto.hwc_frame());
+    layer.hwcCrop = generateFloatRect(layerProto.hwc_crop());
+    layer.hwcTransform = layerProto.hwc_transform();
+    layer.windowType = layerProto.window_type();
+    layer.appId = layerProto.app_id();
+    layer.hwcCompositionType = layerProto.hwc_composition_type();
+    layer.isProtected = layerProto.is_protected();
 
     return layer;
 }
@@ -186,9 +184,7 @@
 
     for (int i = 0; i < layerProto.children_size(); i++) {
         if (layerMap.count(layerProto.children(i)) > 0) {
-            // Only make unique_ptrs for children since they are guaranteed to be unique, only one
-            // parent per child. This ensures there will only be one unique_ptr made for each layer.
-            currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)]));
+            currLayer->children.push_back(layerMap[layerProto.children(i)]);
         }
     }
 
@@ -211,29 +207,28 @@
     }
 }
 
-std::string LayerProtoParser::layersToString(
-        std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) {
+std::string LayerProtoParser::layerTreeToString(const LayerTree& layerTree) {
     std::string result;
-    for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) {
+    for (const LayerProtoParser::Layer* layer : layerTree.topLevelLayers) {
         if (layer->zOrderRelativeOf != nullptr) {
             continue;
         }
-        result.append(layerToString(layer.get()).c_str());
+        result.append(layerToString(layer));
     }
 
     return result;
 }
 
-std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) {
+std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
     std::string result;
 
     std::vector<Layer*> traverse(layer->relatives);
-    for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) {
+    for (LayerProtoParser::Layer* child : layer->children) {
         if (child->zOrderRelativeOf != nullptr) {
             continue;
         }
 
-        traverse.push_back(child.get());
+        traverse.push_back(child);
     }
 
     std::sort(traverse.begin(), traverse.end(), sortLayers);
@@ -244,13 +239,13 @@
         if (relative->z >= 0) {
             break;
         }
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
-    result.append(layer->to_string().c_str());
+    result.append(layer->to_string());
     result.append("\n");
     for (; i < traverse.size(); i++) {
         auto& relative = traverse[i];
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
 
     return result;
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index b1610cf..6b3b497 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -80,7 +80,7 @@
     public:
         int32_t id;
         std::string name;
-        std::vector<std::unique_ptr<Layer>> children;
+        std::vector<Layer*> children;
         std::vector<Layer*> relatives;
         std::string type;
         LayerProtoParser::Region transparentRegion;
@@ -126,13 +126,22 @@
         int32_t globalTransform;
     };
 
+    class LayerTree {
+    public:
+        // all layers in LayersProto and in the original order
+        std::vector<Layer> allLayers;
+
+        // pointers to top-level layers in allLayers
+        std::vector<Layer*> topLevelLayers;
+    };
+
     static const LayerGlobal generateLayerGlobalInfo(const LayersProto& layersProto);
-    static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto);
-    static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers);
+    static LayerTree generateLayerTree(const LayersProto& layersProto);
+    static std::string layerTreeToString(const LayerTree& layerTree);
 
 private:
-    static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto);
-    static LayerProtoParser::Layer* generateLayer(const LayerProto& layerProto);
+    static std::vector<Layer> generateLayerList(const LayersProto& layersProto);
+    static LayerProtoParser::Layer generateLayer(const LayerProto& layerProto);
     static LayerProtoParser::Region generateRegion(const RegionProto& regionProto);
     static LayerProtoParser::Rect generateRect(const RectProto& rectProto);
     static LayerProtoParser::FloatRect generateFloatRect(const FloatRectProto& rectProto);
@@ -142,7 +151,7 @@
     static void updateChildrenAndRelative(const LayerProto& layerProto,
                                           std::unordered_map<int32_t, Layer*>& layerMap);
 
-    static std::string layerToString(LayerProtoParser::Layer* layer);
+    static std::string layerToString(const LayerProtoParser::Layer* layer);
 };
 
 } // namespace surfaceflinger
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index b1ff522..9c2edca 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -21,16 +21,16 @@
 #include <android/frameworks/displayservice/1.0/IDisplayService.h>
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <cutils/sched_policy.h>
-#include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <configstore/Utils.h>
+#include <cutils/sched_policy.h>
 #include <displayservice/DisplayService.h>
 #include <hidl/LegacySupport.h>
-#include <configstore/Utils.h>
 #include "GpuService.h"
 #include "SurfaceFlinger.h"
+#include "SurfaceFlingerFactory.h"
 
 using namespace android;
 
@@ -85,7 +85,7 @@
     ps->startThreadPool();
 
     // instantiate surfaceflinger
-    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
+    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
 
     setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
 
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 4577153..3e1be8e 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -101,10 +101,7 @@
     for (int i = 0; i < 100000; i++) {
         surfaceflinger::LayersProto layersProto = generateLayerProto();
         auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
-        // Allow some layerTrees to just fall out of scope (instead of std::move)
-        if (i % 2) {
-            surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree));
-        }
+        surfaceflinger::LayerProtoParser::layerTreeToString(layerTree);
     }
     system(cmd.c_str());
 }
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
index 499a8f6..04b9511 100644
--- a/services/vr/bufferhubd/Android.bp
+++ b/services/vr/bufferhubd/Android.bp
@@ -12,46 +12,65 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-sourceFiles = [
-    "buffer_channel.cpp",
-    "buffer_hub.cpp",
-    "buffer_node.cpp",
-    "bufferhubd.cpp",
-    "consumer_channel.cpp",
-    "producer_channel.cpp",
-    "consumer_queue_channel.cpp",
-    "producer_queue_channel.cpp",
-]
-
-headerLibraries = ["libdvr_headers"]
-
-staticLibraries = [
-    "libperformance",
-    "libbufferhub",
-]
-
 sharedLibraries = [
     "libbase",
     "libbinder",
     "libcutils",
-    "liblog",
-    "libsync",
-    "libutils",
     "libgui",
-    "libui",
+    "liblog",
     "libpdx_default_transport",
+    "libsync",
+    "libui",
+    "libutils",
 ]
 
+cc_library_static {
+    name: "libbufferhubd",
+    srcs: [
+        "binder/android/dvr/IBufferHub.aidl",
+        "buffer_channel.cpp",
+        "buffer_hub.cpp",
+        "buffer_hub_binder.cpp",
+        "buffer_node.cpp",
+        "consumer_channel.cpp",
+        "consumer_queue_channel.cpp",
+        "producer_channel.cpp",
+        "producer_queue_channel.cpp",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"libbufferhubd\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    export_include_dirs: ["include"],
+    header_libs: ["libdvr_headers"],
+    shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+    ],
+    aidl: {
+        local_include_dirs: ["binder"],
+        include_dirs: ["frameworks/native/aidl/binder"],
+        export_aidl_headers: true,
+    },
+}
+
 cc_binary {
-    srcs: sourceFiles,
+    srcs: ["bufferhubd.cpp"],
     cflags: [
         "-DLOG_TAG=\"bufferhubd\"",
         "-DTRACE=0",
         "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
     ],
-    header_libs: headerLibraries,
-    static_libs: staticLibraries,
+    header_libs: ["libdvr_headers"],
     shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+        "libbufferhubd",
+        "libperformance",
+    ],
     name: "bufferhubd",
     init_rc: ["bufferhubd.rc"],
 }
+
+subdirs = ["tests"]
\ No newline at end of file
diff --git a/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
new file mode 100644
index 0000000..6a86adc
--- /dev/null
+++ b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
@@ -0,0 +1,5 @@
+package android.dvr;
+
+/** {@hide} */
+interface IBufferHub {
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_channel.cpp b/services/vr/bufferhubd/buffer_channel.cpp
index 2150d62..6d22dee 100644
--- a/services/vr/bufferhubd/buffer_channel.cpp
+++ b/services/vr/bufferhubd/buffer_channel.cpp
@@ -1,5 +1,5 @@
-#include "buffer_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index c0ee31b..15391da 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -1,9 +1,5 @@
-#include "buffer_hub.h"
-
 #include <inttypes.h>
-#include <log/log.h>
 #include <poll.h>
-#include <utils/Trace.h>
 
 #include <iomanip>
 #include <memory>
@@ -11,12 +7,15 @@
 #include <string>
 #include <thread>
 
+#include <log/log.h>
 #include <pdx/default_transport/service_endpoint.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
-#include "producer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::Channel;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub_binder.cpp b/services/vr/bufferhubd/buffer_hub_binder.cpp
new file mode 100644
index 0000000..def15f1
--- /dev/null
+++ b/services/vr/bufferhubd/buffer_hub_binder.cpp
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+#include <log/log.h>
+#include <private/dvr/buffer_hub_binder.h>
+
+namespace android {
+namespace dvr {
+
+status_t BufferHubBinderService::start() {
+  ProcessState::self()->startThreadPool();
+  IPCThreadState::self()->disableBackgroundScheduling(true);
+  status_t result = BinderService<BufferHubBinderService>::publish();
+  if (result != OK) {
+    ALOGE("Publishing bufferhubd failed with error %d", result);
+    return result;
+  }
+
+  return result;
+}
+
+status_t BufferHubBinderService::dump(int fd, const Vector<String16> & /* args */) {
+  // TODO(b/115435506): not implemented yet
+  FILE *out = fdopen(dup(fd), "w");
+
+  fprintf(out, "BufferHubBinderService::dump(): Not Implemented.\n");
+
+  fclose(out);
+  return NO_ERROR;
+}
+
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.cpp b/services/vr/bufferhubd/buffer_node.cpp
index de22bba..5a04d0c 100644
--- a/services/vr/bufferhubd/buffer_node.cpp
+++ b/services/vr/bufferhubd/buffer_node.cpp
@@ -1,6 +1,5 @@
-#include "buffer_node.h"
-
 #include <private/dvr/buffer_hub_defs.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/bufferhubd.cpp b/services/vr/bufferhubd/bufferhubd.cpp
index b27f218..0ca7edc 100644
--- a/services/vr/bufferhubd/bufferhubd.cpp
+++ b/services/vr/bufferhubd/bufferhubd.cpp
@@ -1,13 +1,12 @@
 #include <sched.h>
+#include <sys/resource.h>
 #include <unistd.h>
 
-#include <log/log.h>
-#include <sys/resource.h>
-
 #include <dvr/performance_client_api.h>
+#include <log/log.h>
 #include <pdx/service_dispatcher.h>
-
-#include "buffer_hub.h"
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_hub_binder.h>
 
 int main(int, char**) {
   int ret = -1;
@@ -34,11 +33,14 @@
   else
     ALOGI("New nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
 
+  CHECK_ERROR(android::dvr::BufferHubBinderService::start() != android::OK,
+              error, "Failed to create bufferhub binder service\n");
+
   dispatcher = android::pdx::ServiceDispatcher::Create();
   CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher\n");
 
   service = android::dvr::BufferHubService::Create();
-  CHECK_ERROR(!service, error, "Failed to create buffer hub service\n");
+  CHECK_ERROR(!service, error, "Failed to create bufferhubd service\n");
   dispatcher->AddService(service);
 
   ret = dvrSetSchedulerClass(0, "graphics");
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index a6d2dbb..623c9d6 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -1,12 +1,10 @@
-#include "consumer_channel.h"
-
-#include <log/log.h>
-#include <utils/Trace.h>
-
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "producer_channel.h"
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::Channel;
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index 4d43001..74b549d 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -1,8 +1,6 @@
-#include "consumer_queue_channel.h"
-
 #include <pdx/channel_handle.h>
-
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::RemoteChannelHandle;
diff --git a/services/vr/bufferhubd/buffer_channel.h b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
similarity index 96%
rename from services/vr/bufferhubd/buffer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_channel.h
index ac99a73..bcc93a1 100644
--- a/services/vr/bufferhubd/buffer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
@@ -1,11 +1,10 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 
-#include "buffer_hub.h"
-#include "buffer_node.h"
-
 #include <pdx/channel_handle.h>
 #include <pdx/file_handle.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_hub.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_hub.h
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
new file mode 100644
index 0000000..c0281fd
--- /dev/null
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
@@ -0,0 +1,23 @@
+#ifndef ANDROID_DVR_BUFFER_HUB_BINDER_H
+#define ANDROID_DVR_BUFFER_HUB_BINDER_H
+
+#include <binder/BinderService.h>
+
+#include "android/dvr/BnBufferHub.h"
+
+namespace android {
+namespace dvr {
+
+class BufferHubBinderService : public BinderService<BufferHubBinderService>, public BnBufferHub {
+ public:
+  static status_t start();
+  static const char* getServiceName() { return "bufferhubd"; }
+  // Dump bufferhub related information to given fd (usually stdout)
+  // usage: adb shell dumpsys bufferhubd
+  virtual status_t dump(int fd, const Vector<String16> &args) override;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif // ANDROID_DVR_BUFFER_HUB_BINDER_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.h b/services/vr/bufferhubd/include/private/dvr/buffer_node.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_node.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_node.h
diff --git a/services/vr/bufferhubd/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
similarity index 97%
rename from services/vr/bufferhubd/consumer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_channel.h
index 55cf969..0d70409 100644
--- a/services/vr/bufferhubd/consumer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/consumer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
similarity index 93%
rename from services/vr/bufferhubd/consumer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
index 8437c4c..d98dbbc 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
@@ -1,14 +1,12 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
-#include <private/dvr/bufferhub_rpc.h>
-
 #include <queue>
 
-#include "consumer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_channel.h
index 10a4ce7..242198f 100644
--- a/services/vr/bufferhubd/producer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
@@ -1,8 +1,6 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <functional>
 #include <memory>
 #include <vector>
@@ -11,6 +9,7 @@
 #include <pdx/file_handle.h>
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 #include <private/dvr/ion_buffer.h>
 
 namespace android {
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
index e4fa243..c4003da 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/status.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 19d48f2..057d4f4 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -1,19 +1,18 @@
-#include "producer_channel.h"
-
-#include <log/log.h>
-#include <sync/sync.h>
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #include <sys/poll.h>
-#include <utils/Trace.h>
 
 #include <algorithm>
 #include <atomic>
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 88f5508..6b5027c 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -1,9 +1,8 @@
-#include "producer_queue_channel.h"
-
 #include <inttypes.h>
 
-#include "consumer_queue_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::Message;
diff --git a/services/vr/bufferhubd/tests/Android.bp b/services/vr/bufferhubd/tests/Android.bp
new file mode 100644
index 0000000..4d1d43f
--- /dev/null
+++ b/services/vr/bufferhubd/tests/Android.bp
@@ -0,0 +1,16 @@
+cc_test {
+    name: "buffer_hub_binder_service-test",
+    srcs: ["buffer_hub_binder_service-test.cpp"],
+    cflags: [
+        "-DLOG_TAG=\"buffer_hub_binder_service-test\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    static_libs: ["libbufferhubd"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
new file mode 100644
index 0000000..e3f2825
--- /dev/null
+++ b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
@@ -0,0 +1,22 @@
+#include <private/dvr/buffer_hub_binder.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class BufferHubBinderServiceTest : public ::testing::Test {
+  // Add setup and teardown if necessary
+};
+
+TEST_F(BufferHubBinderServiceTest, TestInitialize) {
+  // Test if start binder server returns OK
+  EXPECT_EQ(BufferHubBinderService::start(), OK);
+}
+
+}  // namespace
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 4c2d223..a607a5d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1165,27 +1165,28 @@
         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
         if (result < 0)
             return result;
+
         if (!pPhysicalDeviceGroupProperties) {
             *pPhysicalDeviceGroupCount = device_count;
             return result;
         }
 
-        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
         if (!device_count) {
             *pPhysicalDeviceGroupCount = 0;
             return result;
         }
+        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
+        if (!device_count)
+            return VK_INCOMPLETE;
 
         android::Vector<VkPhysicalDevice> devices;
         devices.resize(device_count);
-
+        *pPhysicalDeviceGroupCount = device_count;
         result = EnumeratePhysicalDevices(instance, &device_count,
                                           devices.editArray());
         if (result < 0)
             return result;
 
-        devices.resize(device_count);
-        *pPhysicalDeviceGroupCount = device_count;
         for (uint32_t i = 0; i < device_count; ++i) {
             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];