Merge "Add a system property test before scanning touch video devices."
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 849eb44..909bdd7 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -98,9 +98,11 @@
     return binder::Status::ok();
 }
 
-binder::Status DumpstateService::startBugreport(int, int bugreport_mode, int32_t* returned_id) {
-    // TODO(111441001): return a request id here.
-    *returned_id = -1;
+binder::Status DumpstateService::startBugreport(const android::base::unique_fd& /* bugreportFd */,
+                                                const android::base::unique_fd& /* screenshotFd */,
+                                                int bugreport_mode,
+                                                const sp<IDumpstateListener>& /* listener */) {
+    // TODO(b/111441001): Pass in fds & other arguments to DumpOptions.
     MYLOGI("startBugreport() with mode: %d\n", bugreport_mode);
 
     if (bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_FULL &&
diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h
index 58095b3..1736ae8 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -20,6 +20,7 @@
 #include <mutex>
 #include <vector>
 
+#include <android-base/unique_fd.h>
 #include <binder/BinderService.h>
 
 #include "android/os/BnDumpstate.h"
@@ -41,7 +42,9 @@
                                bool getSectionDetails,
                                sp<IDumpstateToken>* returned_token) override;
 
-    binder::Status startBugreport(int fd, int bugreport_mode, int32_t* returned_id) override;
+    binder::Status startBugreport(const android::base::unique_fd& bugreportFd,
+                                  const android::base::unique_fd& screenshotFd, int bugreport_mode,
+                                  const sp<IDumpstateListener>& listener) override;
 
   private:
     Dumpstate& ds_;
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index 617eab3..ba3e290 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -63,6 +63,12 @@
 
     /*
      * Starts a bugreport in the background.
+     *
+     * @param bugreportFd the file to which the zipped bugreport should be written
+     * @param screenshotFd the file to which screenshot should be written; optional
+     * @param bugreportMode the mode that specifies other run time options; must be one of above
+     * @param listener callback for updates; optional
      */
-    int startBugreport(int fd, int bugreportMode);
+     void startBugreport(FileDescriptor bugreportFd, FileDescriptor screenshotFd, int bugreportMode,
+                         IDumpstateListener listener);
 }
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 516e3d8..8a05c43 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1572,6 +1572,15 @@
     RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
                SEC_TO_MSEC(10));
 
+    if (ds.IsZipping()) {
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
+                   CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+        DumpHals();
+    } else {
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
+                   CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
+    }
+
     printf("========================================================\n");
     printf("== dumpstate: done (id %d)\n", ds.id_);
     printf("========================================================\n");
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index 384f21f..34886a9 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -286,10 +286,6 @@
             std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event)
                     .detach();
         } break;
-        case increment.kSurfaceDeletion: {
-            std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), event)
-                    .detach();
-        } break;
         case increment.kBufferUpdate: {
             std::lock_guard<std::mutex> lock1(mLayerLock);
             std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock);
@@ -628,47 +624,10 @@
     return NO_ERROR;
 }
 
-status_t Replayer::deleteSurfaceControl(
-        const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) {
-    ALOGV("Deleting %d Surface Control", delete_.id());
-    event->readyToExecute();
-
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-
-    mLayersPendingRemoval.push_back(delete_.id());
-
-    const auto& iterator = mBufferQueueSchedulers.find(delete_.id());
-    if (iterator != mBufferQueueSchedulers.end()) {
-        (*iterator).second->stopScheduling();
-    }
-
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (mLayers[delete_.id()] != nullptr) {
-        mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle());
-    }
-
-    return NO_ERROR;
-}
-
-void Replayer::doDeleteSurfaceControls() {
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (!mLayersPendingRemoval.empty()) {
-        for (int id : mLayersPendingRemoval) {
-            mLayers.erase(id);
-            mColors.erase(id);
-            mBufferQueueSchedulers.erase(id);
-        }
-        mLayersPendingRemoval.clear();
-    }
-}
-
 status_t Replayer::injectVSyncEvent(
         const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) {
     ALOGV("Injecting VSync Event");
 
-    doDeleteSurfaceControls();
-
     event->readyToExecute();
 
     SurfaceComposerClient::injectVSync(vSyncEvent.when());
diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h
index 120dd9b..ad807ee 100644
--- a/cmds/surfacereplayer/replayer/Replayer.h
+++ b/cmds/surfacereplayer/replayer/Replayer.h
@@ -70,8 +70,6 @@
     status_t doTransaction(const Transaction& transaction, const std::shared_ptr<Event>& event);
     status_t createSurfaceControl(const SurfaceCreation& create,
             const std::shared_ptr<Event>& event);
-    status_t deleteSurfaceControl(const SurfaceDeletion& delete_,
-            const std::shared_ptr<Event>& event);
     status_t injectVSyncEvent(const VSyncEvent& vsyncEvent, const std::shared_ptr<Event>& event);
     void createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event);
     void deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event);
@@ -120,7 +118,6 @@
     void setDisplayProjection(SurfaceComposerClient::Transaction& t,
             display_id id, const ProjectionChange& pc);
 
-    void doDeleteSurfaceControls();
     void waitUntilTimestamp(int64_t timestamp);
     void waitUntilDeferredTransactionLayerExists(
             const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock);
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index 5ec02b1..f6381f7 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -124,7 +124,9 @@
 
 
 #define CHECK_INTERFACE(interface, data, reply)                         \
-    if (!(data).checkInterface(this)) { return PERMISSION_DENIED; }     \
+    do {                                                                \
+      if (!(data).checkInterface(this)) { return PERMISSION_DENIED; }   \
+    } while (false)                                                     \
 
 
 // ----------------------------------------------------------------------
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 660e3c3..9dc7431 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -284,7 +284,16 @@
     } else {
         // The "Developer Options" value wasn't set to force the use of ANGLE.  Need to temporarily
         // load ANGLE and call the updatable opt-in/out logic:
-        void* featureSo = loadLibrary("feature_support");
+
+        // Check if ANGLE is enabled. Workaround for several bugs:
+        // b/119305693 b/119322355 b/119305887
+        // Something is not working correctly in the feature library
+        char prop[PROPERTY_VALUE_MAX];
+        property_get("debug.angle.enable", prop, "0");
+        void* featureSo = nullptr;
+        if (atoi(prop)) {
+            featureSo = loadLibrary("feature_support");
+        }
         if (featureSo) {
             ALOGV("loaded ANGLE's opt-in/out logic from namespace");
             mUseAngle = checkAngleRules(featureSo);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index a6890ee..928ef95 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -31,7 +31,7 @@
 
 enum class Tag : uint32_t {
     CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
-    DESTROY_SURFACE,
+    CREATE_WITH_SURFACE_PARENT,
     CLEAR_LAYER_FRAME_STATS,
     GET_LAYER_FRAME_STATS,
     LAST = GET_LAYER_FRAME_STATS,
@@ -57,9 +57,16 @@
                                                                             handle, gbp);
     }
 
-    status_t destroySurface(const sp<IBinder>& handle) override {
-        return callRemote<decltype(&ISurfaceComposerClient::destroySurface)>(Tag::DESTROY_SURFACE,
-                                                                             handle);
+    status_t createWithSurfaceParent(const String8& name, uint32_t width, uint32_t height,
+                                     PixelFormat format, uint32_t flags,
+                                     const sp<IGraphicBufferProducer>& parent, int32_t windowType,
+                                     int32_t ownerUid, sp<IBinder>* handle,
+                                     sp<IGraphicBufferProducer>* gbp) override {
+        return callRemote<decltype(
+                &ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT,
+                                                                   name, width, height, format,
+                                                                   flags, parent, windowType,
+                                                                   ownerUid, handle, gbp);
     }
 
     status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
@@ -92,8 +99,8 @@
     switch (tag) {
         case Tag::CREATE_SURFACE:
             return callLocal(data, reply, &ISurfaceComposerClient::createSurface);
-        case Tag::DESTROY_SURFACE:
-            return callLocal(data, reply, &ISurfaceComposerClient::destroySurface);
+        case Tag::CREATE_WITH_SURFACE_PARENT:
+            return callLocal(data, reply, &ISurfaceComposerClient::createWithSurfaceParent);
         case Tag::CLEAR_LAYER_FRAME_STATS:
             return callLocal(data, reply, &ISurfaceComposerClient::clearLayerFrameStats);
         case Tag::GET_LAYER_FRAME_STATS:
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 824e43f..8b9e4d7 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -205,6 +205,22 @@
     return *this;
 }
 
+void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle,
+        const sp<ISurfaceComposerClient>& client) {
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    Vector<ComposerState> composerStates;
+    Vector<DisplayState> displayStates;
+
+    ComposerState s;
+    s.client = client;
+    s.state.surface = handle;
+    s.state.what |= layer_state_t::eReparent;
+    s.state.parentHandleForChild = nullptr;
+
+    composerStates.add(s);
+    sf->setTransactionState(composerStates, displayStates, 0, nullptr, {});
+}
+
 status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
     if (mStatus != NO_ERROR) {
         return mStatus;
@@ -819,17 +835,6 @@
 
 #endif
 
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
-        const sp<SurfaceControl>& sc) {
-    layer_state_t* s = getLayerState(sc);
-    if (!s) {
-        mStatus = BAD_INDEX;
-        return *this;
-    }
-    s->what |= layer_state_t::eDestroySurface;
-    return *this;
-}
-
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform(
     const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) {
     layer_state_t* s = getLayerState(sc);
@@ -972,6 +977,29 @@
     return s;
 }
 
+sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w,
+                                                                  uint32_t h, PixelFormat format,
+                                                                  uint32_t flags, Surface* parent,
+                                                                  int32_t windowType,
+                                                                  int32_t ownerUid) {
+    sp<SurfaceControl> sur;
+    status_t err = mStatus;
+
+    if (mStatus == NO_ERROR) {
+        sp<IBinder> handle;
+        sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer();
+        sp<IGraphicBufferProducer> gbp;
+
+        err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp, windowType,
+                                               ownerUid, &handle, &gbp);
+        ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
+        if (err == NO_ERROR) {
+            return new SurfaceControl(this, handle, gbp, true /* owned */);
+        }
+    }
+    return nullptr;
+}
+
 status_t SurfaceComposerClient::createSurfaceChecked(
         const String8& name,
         uint32_t w,
@@ -1004,13 +1032,6 @@
     return err;
 }
 
-status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) {
-    if (mStatus != NO_ERROR)
-        return mStatus;
-    status_t err = mClient->destroySurface(sid);
-    return err;
-}
-
 status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const {
     if (mStatus != NO_ERROR) {
         return mStatus;
@@ -1134,6 +1155,7 @@
     return ComposerService::getComposerService()->getDisplayedContentSample(display, maxFrames,
                                                                             timestamp, outStats);
 }
+
 // ----------------------------------------------------------------------------
 
 status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index b6ef286..8e500a4 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -63,7 +63,13 @@
 
 SurfaceControl::~SurfaceControl()
 {
-    destroy();
+    if (mClient != nullptr && mHandle != nullptr && mOwned) {
+        SurfaceComposerClient::doDropReferenceTransaction(mHandle, mClient->getClient());
+    }
+    mClient.clear();
+    mHandle.clear();
+    mGraphicBufferProducer.clear();
+    IPCThreadState::self()->flushCommands();
 }
 
 void SurfaceControl::destroy()
@@ -71,7 +77,7 @@
     // Avoid destroying the server-side surface if we are not the owner of it, meaning that we
     // retrieved it from another process.
     if (isValid() && mOwned) {
-        mClient->destroySurface(mHandle);
+        SurfaceComposerClient::Transaction().reparent(this, nullptr).apply();
     }
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 82b01b8..f443df8 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -58,7 +58,12 @@
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
-    virtual status_t destroySurface(const sp<IBinder>& handle) = 0;
+    virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
+                                             PixelFormat format, uint32_t flags,
+                                             const sp<IGraphicBufferProducer>& parent,
+                                             int32_t windowType, int32_t ownerUid,
+                                             sp<IBinder>* handle,
+                                             sp<IGraphicBufferProducer>* gbp) = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4a8e01b..f16f781 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -145,6 +145,13 @@
                                              ui::Dataspace* wideColorGamutDataspace,
                                              ui::PixelFormat* wideColorGamutPixelFormat);
 
+    /**
+     * Called from SurfaceControl d'tor to 'destroy' the surface (or rather, reparent it
+     * to null), but without needing an sp<SurfaceControl> to avoid infinite ressurection.
+     */
+    static void doDropReferenceTransaction(const sp<IBinder>& handle,
+            const sp<ISurfaceComposerClient>& client);
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
@@ -161,15 +168,27 @@
     );
 
     status_t createSurfaceChecked(
-            const String8& name,// name of the surface
-            uint32_t w,         // width in pixel
-            uint32_t h,         // height in pixel
-            PixelFormat format, // pixel-format desired
+            const String8& name, // name of the surface
+            uint32_t w,          // width in pixel
+            uint32_t h,          // height in pixel
+            PixelFormat format,  // pixel-format desired
             sp<SurfaceControl>* outSurface,
-            uint32_t flags = 0, // usage flags
+            uint32_t flags = 0,               // usage flags
             SurfaceControl* parent = nullptr, // parent
             int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
-            int32_t ownerUid = -1 // UID of the task
+            int32_t ownerUid = -1    // UID of the task
+    );
+
+    //! Create a surface
+    sp<SurfaceControl> createWithSurfaceParent(
+            const String8& name,       // name of the surface
+            uint32_t w,                // width in pixel
+            uint32_t h,                // height in pixel
+            PixelFormat format,        // pixel-format desired
+            uint32_t flags = 0,        // usage flags
+            Surface* parent = nullptr, // parent
+            int32_t windowType = -1,   // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
+            int32_t ownerUid = -1      // UID of the task
     );
 
     //! Create a virtual display
@@ -338,8 +357,6 @@
         Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 #endif
 
-        Transaction& destroySurface(const sp<SurfaceControl>& sc);
-
         // Set a color transform matrix on the given layer on the built-in display.
         Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
                                        const vec3& translation);
@@ -368,8 +385,6 @@
         void setEarlyWakeup();
     };
 
-    status_t    destroySurface(const sp<IBinder>& id);
-
     status_t clearLayerFrameStats(const sp<IBinder>& token) const;
     status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
     static status_t clearAnimationFrameStats();
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 03545a6..2796c75 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -208,6 +208,17 @@
      */
     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT       = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
     /**
+     * The buffer will be used as a composer HAL overlay layer.
+     *
+     * This flag is currently only needed when using ASurfaceTransaction_setBuffer
+     * to set a buffer. In all other cases, the framework adds this flag
+     * internally to buffers that could be presented in a composer overlay.
+     * ASurfaceTransaction_setBuffer is special because it uses buffers allocated
+     * directly through AHardwareBuffer_allocate instead of buffers allocated
+     * by the framework.
+     */
+    AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY       = 1ULL << 11,
+    /**
      * The buffer is protected from direct CPU access or being read by
      * non-secure hardware, such as video encoders.
      *
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 94a6650..2915bb8 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -30,6 +30,7 @@
 #include <GLES2/gl2ext.h>
 #include <android-base/stringprintf.h>
 #include <cutils/compiler.h>
+#include <cutils/properties.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/Texture.h>
 #include <renderengine/private/Description.h>
@@ -416,6 +417,13 @@
         mBt2020ToSrgb = mXyzToSrgb * mBt2020ToXyz;
         mBt2020ToDisplayP3 = mXyzToDisplayP3 * mBt2020ToXyz;
     }
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.egl.traceGpuCompletion", value, "0");
+    if (atoi(value)) {
+        mTraceGpuCompletion = true;
+        mFlushTracer = std::make_unique<FlushTracer>(this);
+    }
 }
 
 GLESRenderEngine::~GLESRenderEngine() {
@@ -461,6 +469,12 @@
         ALOGW("failed to dup EGL native fence sync: %#x", eglGetError());
     }
 
+    // Only trace if we have a valid fence, as current usage falls back to
+    // calling finish() if the fence fd is invalid.
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer) && fenceFd.get() >= 0) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
     return fenceFd;
 }
 
@@ -476,8 +490,15 @@
         return false;
     }
 
-    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
-                                         2000000000 /*2 sec*/);
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer)) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
+    return waitSync(sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR);
+}
+
+bool GLESRenderEngine::waitSync(EGLSyncKHR sync, EGLint flags) {
+    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, flags, 2000000000 /*2 sec*/);
     EGLint error = eglGetError();
     eglDestroySyncKHR(mEGLDisplay, sync);
     if (result != EGL_CONDITION_SATISFIED_KHR) {
@@ -1224,6 +1245,61 @@
     return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
 }
 
+// FlushTracer implementation
+GLESRenderEngine::FlushTracer::FlushTracer(GLESRenderEngine* engine) : mEngine(engine) {
+    mThread = std::thread(&GLESRenderEngine::FlushTracer::loop, this);
+}
+
+GLESRenderEngine::FlushTracer::~FlushTracer() {
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mRunning = false;
+    }
+    mCondition.notify_all();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
+void GLESRenderEngine::FlushTracer::queueSync(EGLSyncKHR sync) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    char name[64];
+    const uint64_t frameNum = mFramesQueued++;
+    snprintf(name, sizeof(name), "Queueing sync for frame: %lu",
+             static_cast<unsigned long>(frameNum));
+    ATRACE_NAME(name);
+    mQueue.push({sync, frameNum});
+    ATRACE_INT("GPU Frames Outstanding", mQueue.size());
+    mCondition.notify_one();
+}
+
+void GLESRenderEngine::FlushTracer::loop() {
+    while (mRunning) {
+        QueueEntry entry;
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+
+            mCondition.wait(mMutex,
+                            [&]() REQUIRES(mMutex) { return !mQueue.empty() && !mRunning; });
+
+            if (!mRunning) {
+                // if mRunning is false, then FlushTracer is being destroyed, so
+                // bail out now.
+                break;
+            }
+            entry = mQueue.front();
+            mQueue.pop();
+        }
+        {
+            char name[64];
+            snprintf(name, sizeof(name), "waiting for frame %lu",
+                     static_cast<unsigned long>(entry.mFrameNum));
+            ATRACE_NAME(name);
+            mEngine->waitSync(entry.mSync, 0);
+        }
+    }
+}
+
 } // namespace gl
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 511a784..b596242 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -17,8 +17,13 @@
 #ifndef SF_GLESRENDERENGINE_H_
 #define SF_GLESRENDERENGINE_H_
 
+#include <android-base/thread_annotations.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -119,6 +124,7 @@
                                        Protection protection);
     static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
                                                    int hwcFormat, Protection protection);
+    bool waitSync(EGLSyncKHR sync, EGLint flags);
 
     // A data space is considered HDR data space if it has BT2020 color space
     // with PQ or HLG transfer function.
@@ -159,6 +165,8 @@
     mat4 mBt2020ToDisplayP3;
 
     bool mInProtectedContext = false;
+    // If set to true, then enables tracing flush() and finish() to systrace.
+    bool mTraceGpuCompletion = false;
     int32_t mFboHeight = 0;
 
     // Current dataspace of layer being rendered
@@ -170,6 +178,30 @@
     // Whether device supports color management, currently color management
     // supports sRGB, DisplayP3 color spaces.
     const bool mUseColorManagement = false;
+
+    class FlushTracer {
+    public:
+        FlushTracer(GLESRenderEngine* engine);
+        ~FlushTracer();
+        void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex);
+
+        struct QueueEntry {
+            EGLSyncKHR mSync = nullptr;
+            uint64_t mFrameNum = 0;
+        };
+
+    private:
+        void loop();
+        GLESRenderEngine* const mEngine;
+        std::thread mThread;
+        std::condition_variable_any mCondition;
+        std::mutex mMutex;
+        std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);
+        uint64_t mFramesQueued GUARDED_BY(mMutex) = 0;
+        bool mRunning = true;
+    };
+    friend class FlushTracer;
+    std::unique_ptr<FlushTracer> mFlushTracer;
 };
 
 } // namespace gl
diff --git a/libs/sensorprivacy/SensorPrivacyManager.cpp b/libs/sensorprivacy/SensorPrivacyManager.cpp
index 1da79a0..f973cba 100644
--- a/libs/sensorprivacy/SensorPrivacyManager.cpp
+++ b/libs/sensorprivacy/SensorPrivacyManager.cpp
@@ -85,4 +85,22 @@
     return false;
 }
 
+status_t SensorPrivacyManager::linkToDeath(const sp<IBinder::DeathRecipient>& recipient)
+{
+    sp<hardware::ISensorPrivacyManager> service = getService();
+    if (service != nullptr) {
+        return IInterface::asBinder(service)->linkToDeath(recipient);
+    }
+    return INVALID_OPERATION;
+}
+
+status_t SensorPrivacyManager::unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient)
+{
+    sp<hardware::ISensorPrivacyManager> service = getService();
+    if (service != nullptr) {
+        return IInterface::asBinder(service)->unlinkToDeath(recipient);
+    }
+    return INVALID_OPERATION;
+}
+
 }; // namespace android
diff --git a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
index 8826595..2546a68 100644
--- a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
+++ b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
@@ -34,6 +34,9 @@
     void removeSensorPrivacyListener(const sp<hardware::ISensorPrivacyListener>& listener);
     bool isSensorPrivacyEnabled();
 
+    status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient);
+    status_t unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient);
+
 private:
     Mutex mLock;
     sp<hardware::ISensorPrivacyManager> mService;
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index d1f0564..74b4b3d 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -131,8 +131,8 @@
   bool hung_up() const { return hung_up_; }
 
  protected:
-  BufferHubQueue(pdx::LocalChannelHandle channel);
-  BufferHubQueue(const std::string& endpoint_path);
+  explicit BufferHubQueue(pdx::LocalChannelHandle channel);
+  explicit BufferHubQueue(const std::string& endpoint_path);
 
   // Imports the queue parameters by querying BufferHub for the parameters for
   // this channel.
@@ -458,7 +458,7 @@
  private:
   friend BufferHubQueue;
 
-  ConsumerQueue(pdx::LocalChannelHandle handle);
+  explicit ConsumerQueue(pdx::LocalChannelHandle handle);
 
   // Add a consumer buffer to populate the queue. Once added, a consumer buffer
   // is NOT available to use until the producer side |Post| it. |WaitForBuffers|
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
index ad3f56b..36ab5f6 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
@@ -35,7 +35,7 @@
   }
 
   // Constructs an parcelable contains the channel parcelable.
-  BufferHubQueueParcelable(
+  explicit BufferHubQueueParcelable(
       std::unique_ptr<pdx::ChannelParcelable> channel_parcelable)
       : channel_parcelable_(std::move(channel_parcelable)) {}
 
diff --git a/libs/vr/libdisplay/include/private/dvr/display_protocol.h b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
index eff50ba..3786d1d 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_protocol.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
@@ -60,11 +60,13 @@
   using Base = Flags<Integer>;
   using Type = Integer;
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Flags(const Integer& value) : value_{value} {}
   Flags(const Flags&) = default;
   Flags& operator=(const Flags&) = default;
 
   Integer value() const { return value_; }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator Integer() const { return value_; }
 
   bool IsSet(Integer bits) const { return (value_ & bits) == bits; }
diff --git a/libs/vr/libpdx/private/pdx/channel_handle.h b/libs/vr/libpdx/private/pdx/channel_handle.h
index daa08f4..bd04305 100644
--- a/libs/vr/libpdx/private/pdx/channel_handle.h
+++ b/libs/vr/libpdx/private/pdx/channel_handle.h
@@ -26,7 +26,7 @@
 class ChannelHandleBase {
  public:
   ChannelHandleBase() = default;
-  ChannelHandleBase(const int32_t& value) : value_{value} {}
+  explicit ChannelHandleBase(const int32_t& value) : value_{value} {}
 
   ChannelHandleBase(const ChannelHandleBase&) = delete;
   ChannelHandleBase& operator=(const ChannelHandleBase&) = delete;
diff --git a/libs/vr/libpdx/private/pdx/client.h b/libs/vr/libpdx/private/pdx/client.h
index c35dabd..7e2d55c 100644
--- a/libs/vr/libpdx/private/pdx/client.h
+++ b/libs/vr/libpdx/private/pdx/client.h
@@ -206,7 +206,7 @@
 class Transaction final : public OutputResourceMapper,
                           public InputResourceMapper {
  public:
-  Transaction(Client& client);
+  explicit Transaction(Client& client);
   ~Transaction();
 
   template <typename T>
diff --git a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
index 0421220..43184dd 100644
--- a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
+++ b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
@@ -110,10 +110,10 @@
   using const_iterator = typename BufferType::const_iterator;
 
   BufferWrapper() {}
-  BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
+  explicit BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
   BufferWrapper(const BufferType& buffer, const Allocator& allocator)
       : buffer_(buffer, allocator) {}
-  BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
+  explicit BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
   BufferWrapper(BufferType&& buffer, const Allocator& allocator)
       : buffer_(std::move(buffer), allocator) {}
   BufferWrapper(const BufferWrapper&) = default;
diff --git a/libs/vr/libpdx/private/pdx/rpc/payload.h b/libs/vr/libpdx/private/pdx/rpc/payload.h
index a48a64c..d2df14f 100644
--- a/libs/vr/libpdx/private/pdx/rpc/payload.h
+++ b/libs/vr/libpdx/private/pdx/rpc/payload.h
@@ -83,7 +83,7 @@
                        public MessageWriter,
                        public MessageReader {
  public:
-  ServicePayload(Message& message) : message_(message) {}
+  explicit ServicePayload(Message& message) : message_(message) {}
 
   // MessageWriter
   void* GetNextWriteBufferSection(size_t size) override {
@@ -120,7 +120,8 @@
       MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
   using BufferType = typename ContainerType::BufferType;
 
-  ClientPayload(Transaction& transaction) : transaction_{transaction} {}
+  explicit ClientPayload(Transaction& transaction)
+      : transaction_{transaction} {}
 
   // MessageWriter
   void* GetNextWriteBufferSection(size_t size) override {
diff --git a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
index 1cb85de..88868fe 100644
--- a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
+++ b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
@@ -13,7 +13,7 @@
  public:
   using BaseType = T;
 
-  PointerWrapper(T* pointer) : pointer_(pointer) {}
+  explicit PointerWrapper(T* pointer) : pointer_(pointer) {}
   PointerWrapper(const PointerWrapper&) = default;
   PointerWrapper(PointerWrapper&&) noexcept = default;
   PointerWrapper& operator=(const PointerWrapper&) = default;
diff --git a/libs/vr/libpdx/private/pdx/rpc/serialization.h b/libs/vr/libpdx/private/pdx/rpc/serialization.h
index f12aef1..914ea66 100644
--- a/libs/vr/libpdx/private/pdx/rpc/serialization.h
+++ b/libs/vr/libpdx/private/pdx/rpc/serialization.h
@@ -134,7 +134,7 @@
 
   // ErrorType constructor for generic error codes. Explicitly not explicit,
   // implicit conversion from ErrorCode to ErrorType is desirable behavior.
-  // NOLINTNEXTLINE(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
   ErrorType(ErrorCode error_code) : error_code_(error_code) {}
 
   // ErrorType constructor for encoding type errors.
@@ -148,6 +148,7 @@
   // Evaluates to true if the ErrorType represents an error.
   explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator ErrorCode() const { return error_code_; }
   ErrorCode error_code() const { return error_code_; }
 
@@ -159,6 +160,7 @@
     return unexpected_encoding_.encoding_type;
   }
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator std::string() const {
     std::ostringstream stream;
 
diff --git a/libs/vr/libpdx/private/pdx/service.h b/libs/vr/libpdx/private/pdx/service.h
index d38b174..f5a2d5e 100644
--- a/libs/vr/libpdx/private/pdx/service.h
+++ b/libs/vr/libpdx/private/pdx/service.h
@@ -95,7 +95,7 @@
 class Message : public OutputResourceMapper, public InputResourceMapper {
  public:
   Message();
-  Message(const MessageInfo& info);
+  explicit Message(const MessageInfo& info);
   ~Message();
 
   /*
diff --git a/libs/vr/libpdx/private/pdx/status.h b/libs/vr/libpdx/private/pdx/status.h
index 7e51a52..498dd6d 100644
--- a/libs/vr/libpdx/private/pdx/status.h
+++ b/libs/vr/libpdx/private/pdx/status.h
@@ -11,6 +11,7 @@
 // This is a helper class for constructing Status<T> with an error code.
 struct ErrorStatus {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   ErrorStatus(int error) : error_{error} {}
   int error() const { return error_; }
 
@@ -31,12 +32,14 @@
   // Value copy/move constructors. These are intentionally not marked as
   // explicit to allow direct value returns from functions without having
   // to explicitly wrap them into Status<T>().
-  Status(const T& value) : value_{value} {}        // NOLINT(runtime/explicit)
-  Status(T&& value) : value_{std::move(value)} {}  // NOLINT(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const T& value) : value_{value} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(T&& value) : value_{std::move(value)} {}
 
   // Constructor for storing an error code inside the Status object.
-  Status(const ErrorStatus& error_status)  // NOLINT(runtime/explicit)
-      : error_{error_status.error()} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
 
   // Copy/move constructors. Move constructor leaves |other| object in empty
   // state.
@@ -135,8 +138,8 @@
 class Status<void> {
  public:
   Status() = default;
-  Status(const ErrorStatus& error_status)  // NOLINT(runtime/explicit)
-      : error_{error_status.error()} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
   void SetValue() { error_ = 0; }
   void SetError(int error) { error_ = error; }
 
diff --git a/libs/vr/libpdx/serialization_tests.cpp b/libs/vr/libpdx/serialization_tests.cpp
index 5ad1047..ee800f6 100644
--- a/libs/vr/libpdx/serialization_tests.cpp
+++ b/libs/vr/libpdx/serialization_tests.cpp
@@ -70,7 +70,7 @@
   FileHandleType fd;
 
   TestTemplateType() {}
-  TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
+  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
 
   bool operator==(const TestTemplateType& other) const {
     return fd.Get() == other.fd.Get();
diff --git a/libs/vr/libpdx/variant_tests.cpp b/libs/vr/libpdx/variant_tests.cpp
index e3520f5..a977fd3 100644
--- a/libs/vr/libpdx/variant_tests.cpp
+++ b/libs/vr/libpdx/variant_tests.cpp
@@ -14,18 +14,22 @@
 namespace {
 
 struct BaseType {
+  // NOLINTNEXTLINE(google-explicit-constructor)
   BaseType(int value) : value(value) {}
   int value;
 };
 
 struct DerivedType : BaseType {
+  // NOLINTNEXTLINE(google-explicit-constructor)
   DerivedType(int value) : BaseType{value} {};
 };
 
 template <typename T>
 class TestType {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   TestType(const T& value) : value_(value) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   TestType(T&& value) : value_(std::move(value)) {}
   TestType(const TestType&) = default;
   TestType(TestType&&) = default;
@@ -43,7 +47,9 @@
 template <typename T>
 class InstrumentType {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(const T& value) : value_(value) { constructor_count_++; }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(T&& value) : value_(std::move(value)) { constructor_count_++; }
   InstrumentType(const InstrumentType& other) : value_(other.value_) {
     constructor_count_++;
@@ -51,9 +57,11 @@
   InstrumentType(InstrumentType&& other) : value_(std::move(other.value_)) {
     constructor_count_++;
   }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(const TestType<T>& other) : value_(other.get()) {
     constructor_count_++;
   }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(TestType<T>&& other) : value_(other.take()) {
     constructor_count_++;
   }
@@ -1101,6 +1109,7 @@
 TEST(Variant, IsConstructible) {
   using ArrayType = const float[3];
   struct ImplicitBool {
+    // NOLINTNEXTLINE(google-explicit-constructor)
     operator bool() const { return true; }
   };
   struct ExplicitBool {
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
index f72dabc..5c9e74c 100644
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
@@ -82,7 +82,7 @@
 class SchedStats {
  public:
   SchedStats() : SchedStats(gettid()) {}
-  SchedStats(pid_t task_id) : task_id_(task_id) {}
+  explicit SchedStats(pid_t task_id) : task_id_(task_id) {}
   SchedStats(const SchedStats&) = default;
   SchedStats& operator=(const SchedStats&) = default;
 
@@ -379,7 +379,7 @@
  private:
   friend BASE;
 
-  BenchmarkService(std::unique_ptr<Endpoint> endpoint)
+  explicit BenchmarkService(std::unique_ptr<Endpoint> endpoint)
       : BASE("BenchmarkService", std::move(endpoint)),
         send_buffer(kMaxMessageSize),
         receive_buffer(kMaxMessageSize) {}
@@ -492,7 +492,7 @@
  private:
   friend BASE;
 
-  BenchmarkClient(const std::string& service_path)
+  explicit BenchmarkClient(const std::string& service_path)
       : BASE(ClientChannelFactory::Create(service_path),
              ProgramOptions.timeout) {}
 
diff --git a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
index 81bb17b..3ebab86 100644
--- a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
+++ b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
@@ -41,7 +41,8 @@
  private:
   friend BASE;
 
-  ServiceUtility(const std::string& endpoint_path, int* error = nullptr)
+  explicit ServiceUtility(const std::string& endpoint_path,
+                          int* error = nullptr)
       : BASE(ClientChannelFactory::Create(endpoint_path), 0) {
     if (error)
       *error = Client::error();
diff --git a/libs/vr/libpdx_uds/client_channel_tests.cpp b/libs/vr/libpdx_uds/client_channel_tests.cpp
index 1560030..c9c5d15 100644
--- a/libs/vr/libpdx_uds/client_channel_tests.cpp
+++ b/libs/vr/libpdx_uds/client_channel_tests.cpp
@@ -45,7 +45,7 @@
 
 class TestService : public ServiceBase<TestService> {
  public:
-  TestService(std::unique_ptr<Endpoint> endpoint)
+  explicit TestService(std::unique_ptr<Endpoint> endpoint)
       : ServiceBase{"TestService", std::move(endpoint)} {}
 
   Status<void> HandleMessage(Message& message) override {
@@ -78,7 +78,7 @@
 
 class TestServiceRunner {
  public:
-  TestServiceRunner(LocalHandle channel_socket) {
+  explicit TestServiceRunner(LocalHandle channel_socket) {
     auto endpoint = Endpoint::CreateFromSocketFd(LocalHandle{});
     endpoint->RegisterNewChannelForTests(std::move(channel_socket));
     service_ = TestService::Create(std::move(endpoint));
diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
index 63b5b10..704a569 100644
--- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h
+++ b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
@@ -57,7 +57,7 @@
 
 class SendPayload : public MessageWriter, public OutputResourceMapper {
  public:
-  SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
+  explicit SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
   Status<void> Send(const BorrowedHandle& socket_fd);
   Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred,
                     const iovec* data_vec = nullptr, size_t vec_count = 0);
@@ -85,7 +85,8 @@
 
 class ReceivePayload : public MessageReader, public InputResourceMapper {
  public:
-  ReceivePayload(RecvInterface* receiver = nullptr) : receiver_{receiver} {}
+  explicit ReceivePayload(RecvInterface* receiver = nullptr)
+      : receiver_{receiver} {}
   Status<void> Receive(const BorrowedHandle& socket_fd);
   Status<void> Receive(const BorrowedHandle& socket_fd, ucred* cred);
 
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
index 01ebf65..50fc484 100644
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
@@ -117,7 +117,7 @@
   // This class must be instantiated using Create() static methods above.
   Endpoint(const std::string& endpoint_path, bool blocking,
            bool use_init_socket_fd = true);
-  Endpoint(LocalHandle socket_fd);
+  explicit Endpoint(LocalHandle socket_fd);
 
   void Init(LocalHandle socket_fd);
 
diff --git a/libs/vr/libpdx_uds/remote_method_tests.cpp b/libs/vr/libpdx_uds/remote_method_tests.cpp
index 3f25776..4f0670e 100644
--- a/libs/vr/libpdx_uds/remote_method_tests.cpp
+++ b/libs/vr/libpdx_uds/remote_method_tests.cpp
@@ -94,7 +94,7 @@
   FileHandleType fd;
 
   TestTemplateType() {}
-  TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
+  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
 
  private:
   PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
@@ -328,7 +328,7 @@
  private:
   friend BASE;
 
-  TestClient(LocalChannelHandle channel_handle)
+  explicit TestClient(LocalChannelHandle channel_handle)
       : BASE{android::pdx::uds::ClientChannel::Create(
             std::move(channel_handle))} {}
   TestClient()
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 6d259bd..e1240d6 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -104,7 +104,7 @@
 class TraceArgs {
  public:
   template <typename... Args>
-  TraceArgs(const char* format, Args&&... args) {
+  explicit TraceArgs(const char* format, Args&&... args) {
     std::array<char, 1024> buffer;
     snprintf(buffer.data(), buffer.size(), format, std::forward<Args>(args)...);
     atrace_begin(ATRACE_TAG, buffer.data());
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index 6c25b3e..db0d6a7 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -195,7 +195,7 @@
     AcquiredBuffer acquired_buffer;
     pdx::LocalHandle release_fence;
 
-    SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
+    explicit SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
         : surface(surface) {}
 
     // Attempts to acquire a new buffer from the surface and return a tuple with
diff --git a/libs/vr/libvrflinger/hwc_types.h b/libs/vr/libvrflinger/hwc_types.h
index cbf636c..8b5c3b3 100644
--- a/libs/vr/libvrflinger/hwc_types.h
+++ b/libs/vr/libvrflinger/hwc_types.h
@@ -116,19 +116,24 @@
   Wrapper(const Wrapper&) = default;
 
   // Implicit conversion from ValueType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(ValueType value) : value(value) {}
 
   // Implicit conversion from BaseType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(BaseType value) : value(static_cast<ValueType>(value)) {}
 
   // Implicit conversion from an enum type of the same underlying type.
   template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(const T& value) : value(static_cast<ValueType>(value)) {}
 
   // Implicit conversion to BaseType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator BaseType() const { return static_cast<BaseType>(value); }
 
   // Implicit conversion to ValueType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator ValueType() const { return value; }
 
   template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
@@ -275,8 +280,10 @@
 struct Color final {
   Color(const Color&) = default;
   Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Color(hwc_color_t color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator hwc_color_t() const { return {r, g, b, a}; }
 
   uint8_t r __attribute__((aligned(1)));
diff --git a/libs/vr/libvrflinger/include/dvr/vr_flinger.h b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
index c740dde..ae52076 100644
--- a/libs/vr/libvrflinger/include/dvr/vr_flinger.h
+++ b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
@@ -49,7 +49,8 @@
   // Needs to be a separate class for binder's ref counting
   class PersistentVrStateCallback : public BnPersistentVrStateCallbacks {
    public:
-    PersistentVrStateCallback(RequestDisplayCallback request_display_callback)
+    explicit PersistentVrStateCallback(
+        RequestDisplayCallback request_display_callback)
         : request_display_callback_(request_display_callback) {}
     void onPersistentVrStateChanged(bool enabled) override;
    private:
diff --git a/libs/vr/libvrsensor/include/private/dvr/latency_model.h b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
index 40b4638..bf0e687 100644
--- a/libs/vr/libvrsensor/include/private/dvr/latency_model.h
+++ b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
@@ -10,7 +10,7 @@
 // window_size measurements and return their average after that.
 class LatencyModel {
  public:
-  LatencyModel(size_t window_size);
+  explicit LatencyModel(size_t window_size);
   ~LatencyModel() = default;
 
   void AddLatency(int64_t latency_ns);
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
index 72d210c..a4b81fe 100644
--- a/services/bufferhub/Android.bp
+++ b/services/bufferhub/Android.bp
@@ -34,6 +34,7 @@
     ],
     shared_libs: [
         "android.frameworks.bufferhub@1.0",
+        "libcrypto",
         "libcutils",
         "libhidlbase",
         "libhidltransport",
@@ -60,6 +61,7 @@
     shared_libs: [
         "android.frameworks.bufferhub@1.0",
         "libbufferhubservice",
+        "libcrypto",
         "libcutils",
         "libhidltransport",
         "libhwbinder",
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 54796a2..43235f2 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -14,13 +14,16 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <iomanip>
+#include <random>
 #include <sstream>
 
 #include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubService.h>
 #include <cutils/native_handle.h>
 #include <log/log.h>
+#include <openssl/hmac.h>
 #include <system/graphics-base.h>
 
 using ::android::BufferHubDefs::MetadataHeader;
@@ -32,6 +35,13 @@
 namespace V1_0 {
 namespace implementation {
 
+BufferHubService::BufferHubService() {
+    std::mt19937_64 randomEngine;
+    randomEngine.seed(time(nullptr));
+
+    mKey = randomEngine();
+}
+
 Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
                                               const uint32_t userMetadataSize,
                                               allocateBuffer_cb _hidl_cb) {
@@ -66,27 +76,49 @@
 
 Return<void> BufferHubService::importBuffer(const hidl_handle& tokenHandle,
                                             importBuffer_cb _hidl_cb) {
-    if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts != 1) {
+    if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts <= 1) {
         // nullptr handle or wrong format
         _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
                  /*bufferTraits=*/{});
         return Void();
     }
 
-    uint32_t token = tokenHandle->data[0];
+    int tokenId = tokenHandle->data[0];
 
     wp<BufferClient> originClientWp;
     {
-        std::lock_guard<std::mutex> lock(mTokenMapMutex);
-        auto iter = mTokenMap.find(token);
+        std::lock_guard<std::mutex> lock(mTokenMutex);
+        auto iter = mTokenMap.find(tokenId);
         if (iter == mTokenMap.end()) {
-            // Invalid token
+            // Token Id not exist
+            ALOGD("%s: token #%d not found.", __FUNCTION__, tokenId);
             _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
                      /*bufferTraits=*/{});
             return Void();
         }
 
-        originClientWp = iter->second;
+        const std::vector<uint8_t>& tokenHMAC = iter->second.first;
+
+        int numIntsForHMAC = (int)ceil(tokenHMAC.size() * sizeof(uint8_t) / (double)sizeof(int));
+        if (tokenHandle->numInts - 1 != numIntsForHMAC) {
+            // HMAC size not match
+            ALOGD("%s: token #%d HMAC size not match. Expected: %d Actual: %d", __FUNCTION__,
+                  tokenId, numIntsForHMAC, tokenHandle->numInts - 1);
+            _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
+                     /*bufferTraits=*/{});
+            return Void();
+        }
+
+        size_t hmacSize = tokenHMAC.size() * sizeof(uint8_t);
+        if (memcmp(tokenHMAC.data(), &tokenHandle->data[1], hmacSize) != 0) {
+            // HMAC not match
+            ALOGD("%s: token #%d HMAC not match.", __FUNCTION__, tokenId);
+            _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
+                     /*bufferTraits=*/{});
+            return Void();
+        }
+
+        originClientWp = iter->second.second;
         mTokenMap.erase(iter);
     }
 
@@ -225,9 +257,9 @@
     // Map from bufferId to tokenCount
     std::map<int, uint32_t> tokenCount;
     {
-        std::lock_guard<std::mutex> lock(mTokenMapMutex);
+        std::lock_guard<std::mutex> lock(mTokenMutex);
         for (auto iter = mTokenMap.begin(); iter != mTokenMap.end(); ++iter) {
-            sp<BufferClient> client = iter->second.promote();
+            sp<BufferClient> client = iter->second.second.promote();
             if (client != nullptr) {
                 const std::shared_ptr<BufferNode> node = client->getBufferNode();
                 auto mapIter = tokenCount.find(node->id());
@@ -262,21 +294,35 @@
 }
 
 hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
-    uint32_t token;
-    std::lock_guard<std::mutex> lock(mTokenMapMutex);
+    // Find next available token id
+    std::lock_guard<std::mutex> lock(mTokenMutex);
     do {
-        token = mTokenEngine();
-    } while (mTokenMap.find(token) != mTokenMap.end());
+        ++mLastTokenId;
+    } while (mTokenMap.find(mLastTokenId) != mTokenMap.end());
 
-    // native_handle_t use int[], so here need one slots to fit in uint32_t
-    native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
-    handle->data[0] = token;
+    std::array<uint8_t, EVP_MAX_MD_SIZE> hmac;
+    uint32_t hmacSize = 0U;
+
+    HMAC(/*evp_md=*/EVP_sha256(), /*key=*/&mKey, /*key_len=*/kKeyLen,
+         /*data=*/(uint8_t*)&mLastTokenId, /*data_len=*/mTokenIdSize,
+         /*out=*/hmac.data(), /*out_len=*/&hmacSize);
+
+    int numIntsForHMAC = (int)ceil(hmacSize / (double)sizeof(int));
+    native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1 + numIntsForHMAC);
+    handle->data[0] = mLastTokenId;
+    // Set all the the bits of last int to 0 since it might not be fully overwritten
+    handle->data[numIntsForHMAC] = 0;
+    memcpy(&handle->data[1], hmac.data(), hmacSize);
 
     // returnToken owns the native_handle_t* thus doing lifecycle management
     hidl_handle returnToken;
     returnToken.setTo(handle, /*shoudOwn=*/true);
 
-    mTokenMap.emplace(token, client);
+    std::vector<uint8_t> hmacVec;
+    hmacVec.resize(hmacSize);
+    memcpy(hmacVec.data(), hmac.data(), hmacSize);
+    mTokenMap.emplace(mLastTokenId, std::pair(hmacVec, client));
+
     return returnToken;
 }
 
@@ -291,10 +337,10 @@
 }
 
 void BufferHubService::removeTokenByClient(const BufferClient* client) {
-    std::lock_guard<std::mutex> lock(mTokenMapMutex);
+    std::lock_guard<std::mutex> lock(mTokenMutex);
     auto iter = mTokenMap.begin();
     while (iter != mTokenMap.end()) {
-        if (iter->second == client) {
+        if (iter->second.second == client) {
             auto oldIter = iter;
             ++iter;
             mTokenMap.erase(oldIter);
diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h
index 255f329..0195bcf 100644
--- a/services/bufferhub/include/bufferhub/BufferHubService.h
+++ b/services/bufferhub/include/bufferhub/BufferHubService.h
@@ -17,8 +17,10 @@
 #ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H
 #define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H
 
+#include <map>
 #include <mutex>
-#include <random>
+#include <set>
+#include <vector>
 
 #include <android/frameworks/bufferhub/1.0/IBufferHub.h>
 #include <bufferhub/BufferClient.h>
@@ -39,6 +41,8 @@
 
 class BufferHubService : public IBufferHub {
 public:
+    BufferHubService();
+
     Return<void> allocateBuffer(const HardwareBufferDescription& description,
                                 const uint32_t userMetadataSize,
                                 allocateBuffer_cb _hidl_cb) override;
@@ -60,11 +64,19 @@
     std::mutex mClientSetMutex;
     std::set<wp<BufferClient>> mClientSet GUARDED_BY(mClientSetMutex);
 
-    // TODO(b/118180214): use a more secure implementation
-    std::mt19937 mTokenEngine;
-    // The mapping from token to the client creates it.
-    std::mutex mTokenMapMutex;
-    std::map<uint32_t, const wp<BufferClient>> mTokenMap GUARDED_BY(mTokenMapMutex);
+    // Token generation related
+    // A random number used as private key for HMAC
+    uint64_t mKey;
+    static constexpr size_t kKeyLen = sizeof(uint64_t);
+
+    std::mutex mTokenMutex;
+    // The first TokenId will be 1. TokenId could be negative.
+    int mLastTokenId GUARDED_BY(mTokenMutex) = 0;
+    static constexpr size_t mTokenIdSize = sizeof(int);
+    // A map from token id to the token-buffer_client pair. Using token id as the key to reduce
+    // looking up time
+    std::map<int, std::pair<std::vector<uint8_t>, const wp<BufferClient>>> mTokenMap
+            GUARDED_BY(mTokenMutex);
 };
 
 } // namespace implementation
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 970632e..ecd5cb9 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -37,7 +37,7 @@
 #include <unordered_map>
 
 #include "InputListener.h"
-#include "InputReporter.h"
+#include "InputReporterInterface.h"
 
 
 namespace android {
@@ -1190,7 +1190,7 @@
     void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
     void traceWaitQueueLengthLocked(const sp<Connection>& connection);
 
-    sp<InputReporter> mReporter;
+    sp<InputReporterInterface> mReporter;
 };
 
 /* Enqueues and dispatches input events, endlessly. */
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 3d5f1d9..33bf163 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2641,6 +2641,11 @@
                 mOrientation = internalViewport->orientation;
             }
         }
+
+        // Update the PointerController if viewports changed.
+        if (mParameters.hasAssociatedDisplay) {
+            getPolicy()->obtainPointerController(getDeviceId());
+        }
         bumpGeneration();
     }
 }
@@ -2786,7 +2791,7 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
-        displayId = ADISPLAY_ID_DEFAULT;
+        displayId = mPointerController->getDisplayId();
     } else {
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
@@ -3612,10 +3617,10 @@
         mOrientedRanges.clear();
     }
 
-    // Create pointer controller if needed.
+    // Create or update pointer controller if needed.
     if (mDeviceMode == DEVICE_MODE_POINTER ||
             (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
-        if (mPointerController == nullptr) {
+        if (mPointerController == nullptr || viewportChanged) {
             mPointerController = getPolicy()->obtainPointerController(getDeviceId());
         }
     } else {
@@ -5404,8 +5409,9 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
 
+        const int32_t displayId = mPointerController->getDisplayId();
         NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
-                mSource, mViewport.displayId, policyFlags,
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
                 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                 /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
@@ -6312,6 +6318,7 @@
 void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
         bool down, bool hovering) {
     int32_t metaState = getContext()->getGlobalMetaState();
+    int32_t displayId = mViewport.displayId;
 
     if (mPointerController != nullptr) {
         if (down || hovering) {
@@ -6322,6 +6329,7 @@
         } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
             mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
         }
+        displayId = mPointerController->getDisplayId();
     }
 
     if (mPointerSimple.down && !down) {
@@ -6329,7 +6337,7 @@
 
         // Send up.
         NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
-                mSource, mViewport.displayId, policyFlags,
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
                 /* deviceTimestamp */ 0,
                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -6342,8 +6350,8 @@
         mPointerSimple.hovering = false;
 
         // Send hover exit.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                mSource, mViewport.displayId, policyFlags,
+        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
                 /* deviceTimestamp */ 0,
                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -6358,8 +6366,8 @@
             mPointerSimple.downTime = when;
 
             // Send down.
-            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                    mSource, mViewport.displayId, policyFlags,
+            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                    mSource, displayId, policyFlags,
                     AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
                     /* deviceTimestamp */ 0,
                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6369,8 +6377,8 @@
         }
 
         // Send move.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                mSource, mViewport.displayId, policyFlags,
+        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
                 /* deviceTimestamp */ 0,
                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6384,8 +6392,8 @@
             mPointerSimple.hovering = true;
 
             // Send hover enter.
-            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                    mSource, mViewport.displayId, policyFlags,
+            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                    mSource, displayId, policyFlags,
                     AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
                     mCurrentRawState.buttonState, 0,
                     /* deviceTimestamp */ 0,
@@ -6396,8 +6404,8 @@
         }
 
         // Send hover move.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                mSource, mViewport.displayId, policyFlags,
+        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
                 mCurrentRawState.buttonState, 0,
                 /* deviceTimestamp */ 0,
@@ -6419,8 +6427,8 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
 
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), 
-                mSource, mViewport.displayId, policyFlags,
+        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+                mSource, displayId, policyFlags,
                 AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
                 /* deviceTimestamp */ 0,
                 1, &mPointerSimple.currentProperties, &pointerCoords,
@@ -6482,11 +6490,13 @@
             ALOG_ASSERT(false);
         }
     }
+    const int32_t displayId = mPointerController != nullptr ?
+            mPointerController->getDisplayId() : mViewport.displayId;
 
     const int32_t deviceId = getDeviceId();
     std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
     NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId,
-            source, mViewport.displayId, policyFlags,
+            source, displayId, policyFlags,
             action, actionButton, flags, metaState, buttonState, edgeFlags,
             deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
             xPrecision, yPrecision, downTime, std::move(frames));
diff --git a/services/inputflinger/InputReporter.cpp b/services/inputflinger/InputReporter.cpp
index cf4220f..8d3153c 100644
--- a/services/inputflinger/InputReporter.cpp
+++ b/services/inputflinger/InputReporter.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,18 @@
  * limitations under the License.
  */
 
-#include "InputReporter.h"
+#include "InputReporterInterface.h"
 
 namespace android {
 
 // --- InputReporter ---
 
+class InputReporter : public InputReporterInterface {
+public:
+    void reportUnhandledKey(uint32_t sequenceNum) override;
+    void reportDroppedKey(uint32_t sequenceNum) override;
+};
+
 void InputReporter::reportUnhandledKey(uint32_t sequenceNum) {
   // do nothing
 }
@@ -28,7 +34,7 @@
   // do nothing
 }
 
-sp<InputReporter> createInputReporter() {
+sp<InputReporterInterface> createInputReporter() {
   return new InputReporter();
 }
 
diff --git a/services/inputflinger/include/InputReporter.h b/services/inputflinger/include/InputReporterInterface.h
similarity index 74%
rename from services/inputflinger/include/InputReporter.h
rename to services/inputflinger/include/InputReporterInterface.h
index c86dcda..906d7f2 100644
--- a/services/inputflinger/include/InputReporter.h
+++ b/services/inputflinger/include/InputReporterInterface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _UI_INPUT_REPORTER_H
-#define _UI_INPUT_REPORTER_H
+#ifndef _UI_INPUT_REPORTER_INTERFACE_H
+#define _UI_INPUT_REPORTER_INTERFACE_H
 
 #include <utils/RefBase.h>
 
@@ -25,9 +25,9 @@
  * The interface used by the InputDispatcher to report information about input events after
  * it is sent to the application, such as if a key is unhandled or dropped.
  */
-class InputReporter: public virtual RefBase {
+class InputReporterInterface : public virtual RefBase {
 protected:
-    virtual ~InputReporter() { }
+    virtual ~InputReporterInterface() { }
 
 public:
     // Report a key that was not handled by the system or apps.
@@ -35,19 +35,19 @@
     //   - The event was not handled and there is no fallback key; or
     //   - The event was not handled and it has a fallback key,
     //       but the fallback key was not handled.
-    virtual void reportUnhandledKey(uint32_t sequenceNum);
+    virtual void reportUnhandledKey(uint32_t sequenceNum) = 0;
 
     // Report a key that was dropped by InputDispatcher.
     // A key can be dropped for several reasons. See the enum
     // InputDispatcher::DropReason for details.
-    virtual void reportDroppedKey(uint32_t sequenceNum);
+    virtual void reportDroppedKey(uint32_t sequenceNum) = 0;
 };
 
 /*
  * Factory method for InputReporter.
  */
-sp<InputReporter> createInputReporter();
+sp<InputReporterInterface> createInputReporter();
 
 } // namespace android
 
-#endif // _UI_INPUT_REPORTER_H
+#endif // _UI_INPUT_REPORTER_INTERFACE_H
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index e94dd94..bc0f1f9 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -98,6 +98,9 @@
 
     /* Removes all spots. */
     virtual void clearSpots() = 0;
+
+    /* Gets the id of the display where the pointer should be shown. */
+    virtual int32_t getDisplayId() const = 0;
 };
 
 } // namespace android
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index d39d8dc..de87e7f 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -57,6 +57,7 @@
     float mMinX, mMinY, mMaxX, mMaxY;
     float mX, mY;
     int32_t mButtonState;
+    int32_t mDisplayId;
 
 protected:
     virtual ~FakePointerController() { }
@@ -64,7 +65,7 @@
 public:
     FakePointerController() :
         mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
-        mButtonState(0) {
+        mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
     }
 
     void setBounds(float minX, float minY, float maxX, float maxY) {
@@ -75,6 +76,10 @@
         mMaxY = maxY;
     }
 
+    void setDisplayId(int32_t displayId) {
+        mDisplayId = displayId;
+    }
+
     virtual void setPosition(float x, float y) {
         mX = x;
         mY = y;
@@ -93,6 +98,10 @@
         *outY = mY;
     }
 
+    virtual int32_t getDisplayId() const {
+        return mDisplayId;
+    }
+
 private:
     virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
         *outMinX = mMinX;
@@ -3169,6 +3178,30 @@
     ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
 }
 
+TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addMapperAndConfigure(mapper);
+
+    // Setup PointerController for second display.
+    constexpr int32_t SECOND_DISPLAY_ID = 1;
+    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+    mFakePointerController->setPosition(100, 200);
+    mFakePointerController->setButtonState(0);
+    mFakePointerController->setDisplayId(SECOND_DISPLAY_ID);
+
+    NotifyMotionArgs args;
+    process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
+    process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
+    process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+    ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId);
+}
+
 
 // --- TouchInputMapperTest ---
 
@@ -6318,4 +6351,30 @@
     ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
 }
 
+TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
+    // Setup PointerController for second display.
+    sp<FakePointerController> fakePointerController = new FakePointerController();
+    fakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+    fakePointerController->setPosition(100, 200);
+    fakePointerController->setButtonState(0);
+    fakePointerController->setDisplayId(SECONDARY_DISPLAY_ID);
+    mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
+
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    // Check source is mouse that would obtain the PointerController.
+    ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
+
+    NotifyMotionArgs motionArgs;
+    processPosition(mapper, 100, 100);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
+}
+
 } // namespace android
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 9b2cd50..189ae36 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -35,6 +35,7 @@
 using namespace android::hardware::sensors::V1_0::implementation;
 using android::hardware::sensors::V2_0::ISensorsCallback;
 using android::hardware::sensors::V2_0::EventQueueFlagBits;
+using android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
 using android::hardware::hidl_vec;
 using android::hardware::Return;
 using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
@@ -94,6 +95,8 @@
 SensorDevice::SensorDevice()
         : mHidlTransportErrors(20),
           mRestartWaiter(new HidlServiceRegistrationWaiter()),
+          mEventQueueFlag(nullptr),
+          mWakeLockQueueFlag(nullptr),
           mReconnecting(false) {
     if (!connectHidlService()) {
         return;
@@ -137,6 +140,11 @@
         hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
         mEventQueueFlag = nullptr;
     }
+
+    if (mWakeLockQueueFlag != nullptr) {
+        hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag);
+        mWakeLockQueueFlag = nullptr;
+    }
 }
 
 bool SensorDevice::connectHidlService() {
@@ -198,10 +206,16 @@
                 SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
                 true /* configureEventFlagWord */);
 
+        hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
         hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
 
+        hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag);
+        hardware::EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(),
+                                             &mWakeLockQueueFlag);
+
         CHECK(mSensors != nullptr && mEventQueue != nullptr &&
-                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);
+                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr &&
+                mWakeLockQueueFlag != nullptr);
 
         status_t status = StatusFromResult(checkReturn(mSensors->initialize(
                 *mEventQueue->getDesc(),
@@ -512,9 +526,12 @@
 }
 
 void SensorDevice::writeWakeLockHandled(uint32_t count) {
-    if (mSensors != nullptr && mSensors->supportsMessageQueues() &&
-            !mWakeLockQueue->write(&count)) {
-        ALOGW("Failed to write wake lock handled");
+    if (mSensors != nullptr && mSensors->supportsMessageQueues()) {
+        if (mWakeLockQueue->write(&count)) {
+            mWakeLockQueueFlag->wake(asBaseType(WakeLockQueueFlagBits::DATA_WRITTEN));
+        } else {
+            ALOGW("Failed to write wake lock handled");
+        }
     }
 }
 
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index e1024ac..2a69654 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -238,6 +238,7 @@
     std::unique_ptr<WakeLockQueue> mWakeLockQueue;
 
     hardware::EventFlag* mEventQueueFlag;
+    hardware::EventFlag* mWakeLockQueueFlag;
 
     std::array<Event, SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
 
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index ee4ec50..0e447d8 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -39,26 +39,6 @@
 {
 }
 
-Client::~Client()
-{
-    // We need to post a message to remove our remaining layers rather than
-    // do so directly by acquiring the SurfaceFlinger lock. If we were to
-    // attempt to directly call the lock it becomes effectively impossible
-    // to use sp<Client> while holding the SF lock as descoping it could
-    // then trigger a dead-lock.
-
-    const size_t count = mLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        sp<Layer> l = mLayers.valueAt(i).promote();
-        if (l == nullptr) {
-            continue;
-        }
-        mFlinger->postMessageAsync(new LambdaMessage([flinger = mFlinger, l]() {
-            flinger->removeLayer(l);
-        }));
-    }
-}
-
 status_t Client::initCheck() const {
     return NO_ERROR;
 }
@@ -115,8 +95,24 @@
                                  ownerUid, handle, gbp, &parent);
 }
 
-status_t Client::destroySurface(const sp<IBinder>& handle) {
-    return mFlinger->onLayerRemoved(this, handle);
+status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
+                                         PixelFormat format, uint32_t flags,
+                                         const sp<IGraphicBufferProducer>& parent,
+                                         int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
+                                         sp<IGraphicBufferProducer>* gbp) {
+    if (mFlinger->authenticateSurfaceTexture(parent) == false) {
+        return BAD_VALUE;
+    }
+
+    const auto& layer = (static_cast<MonitoredProducer*>(parent.get()))->getLayer();
+    if (layer == nullptr) {
+        return BAD_VALUE;
+    }
+
+    sp<IBinder> parentHandle = layer->getHandle();
+
+    return createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, handle,
+                         gbp);
 }
 
 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 4a74739..0f5ee4c 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -39,13 +39,12 @@
 {
 public:
     explicit Client(const sp<SurfaceFlinger>& flinger);
-    ~Client();
+    ~Client() = default;
 
     status_t initCheck() const;
 
     // protected by SurfaceFlinger::mStateLock
     void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
-
     void detachLayer(const Layer* layer);
 
     sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
@@ -59,7 +58,11 @@
             sp<IBinder>* handle,
             sp<IGraphicBufferProducer>* gbp);
 
-    virtual status_t destroySurface(const sp<IBinder>& handle);
+    virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
+                                             PixelFormat format, uint32_t flags,
+                                             const sp<IGraphicBufferProducer>& parent,
+                                             int32_t windowType, int32_t ownerUid,
+                                             sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp);
 
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b1827c1..3f2d10a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -179,6 +179,8 @@
     for (const auto& child : mCurrentChildren) {
         child->onRemovedFromCurrentState();
     }
+
+    mFlinger->markLayerPendingRemovalLocked(this);
 }
 
 void Layer::addToCurrentState() {
@@ -1571,6 +1573,7 @@
 
 ssize_t Layer::removeChild(const sp<Layer>& layer) {
     layer->setParent(nullptr);
+
     return mCurrentChildren.remove(layer);
 }
 
@@ -1605,14 +1608,14 @@
 }
 
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
-    if (newParentHandle == nullptr) {
-        return false;
-    }
+    bool callSetTransactionFlags = false;
 
-    auto handle = static_cast<Handle*>(newParentHandle.get());
-    sp<Layer> newParent = handle->owner.promote();
-    if (newParent == nullptr) {
-        ALOGE("Unable to promote Layer handle");
+    // While layers are detached, we allow most operations
+    // and simply halt performing the actual transaction. However
+    // for reparent != null we would enter the mRemovedFromCurrentState
+    // state, regardless of whether doTransaction was called, and
+    // so we need to prevent the update here.
+    if (mLayerDetached && newParentHandle == nullptr) {
         return false;
     }
 
@@ -1620,17 +1623,31 @@
     if (parent != nullptr) {
         parent->removeChild(this);
     }
-    newParent->addChild(this);
 
-    if (!newParent->isRemovedFromCurrentState()) {
-        addToCurrentState();
+    if (newParentHandle != nullptr) {
+        auto handle = static_cast<Handle*>(newParentHandle.get());
+        sp<Layer> newParent = handle->owner.promote();
+        if (newParent == nullptr) {
+            ALOGE("Unable to promote Layer handle");
+            return false;
+        }
+
+        newParent->addChild(this);
+        if (!newParent->isRemovedFromCurrentState()) {
+            addToCurrentState();
+        } else {
+            onRemovedFromCurrentState();
+        }
+
+        if (mLayerDetached) {
+            mLayerDetached = false;
+            callSetTransactionFlags = true;
+        }
+    } else {
+        onRemovedFromCurrentState();
     }
 
-    if (mLayerDetached) {
-        mLayerDetached = false;
-        setTransactionFlags(eTransactionNeeded);
-    }
-    if (attachChildren()) {
+    if (callSetTransactionFlags || attachChildren()) {
         setTransactionFlags(eTransactionNeeded);
     }
     return true;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 069dcc0..dc82b32 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2827,10 +2827,8 @@
             // showing at its last configured state until we eventually
             // abandon the buffer queue.
             if (l->isRemovedFromCurrentState()) {
-                l->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* child) {
-                    child->destroyHwcLayersForAllDisplays();
-                    latchAndReleaseBuffer(child);
-                });
+                l->destroyHwcLayersForAllDisplays();
+                latchAndReleaseBuffer(l);
             }
         }
         mLayersPendingRemoval.clear();
@@ -3304,30 +3302,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
-    Mutex::Autolock _l(mStateLock);
-    return removeLayerLocked(mStateLock, layer);
-}
-
-status_t SurfaceFlinger::removeLayerLocked(const Mutex& lock, const sp<Layer>& layer) {
-    if (layer->isLayerDetached()) {
-        return NO_ERROR;
-    }
-
-    const auto& p = layer->getParent();
-    ssize_t index;
-    if (p != nullptr) {
-        index = p->removeChild(layer);
-    } else {
-        index = mCurrentState.layersSortedByZ.remove(layer);
-    }
-
-    layer->onRemovedFromCurrentState();
-
-    markLayerPendingRemovalLocked(lock, layer);
-    return NO_ERROR;
-}
-
 uint32_t SurfaceFlinger::peekTransactionFlags() {
     return mTransactionFlags;
 }
@@ -3462,14 +3436,6 @@
     }
     transactionFlags |= clientStateFlags;
 
-    // Iterate through all layers again to determine if any need to be destroyed. Marking layers
-    // as destroyed should only occur after setting all other states. This is to allow for a
-    // child re-parent to happen before marking its original parent as destroyed (which would
-    // then mark the child as destroyed).
-    for (const ComposerState& state : states) {
-        setDestroyStateLocked(state);
-    }
-
     transactionFlags |= addInputWindowCommands(inputWindowCommands);
 
     // If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -3795,20 +3761,6 @@
     return flags;
 }
 
-void SurfaceFlinger::setDestroyStateLocked(const ComposerState& composerState) {
-    const layer_state_t& state = composerState.state;
-    sp<Client> client(static_cast<Client*>(composerState.client.get()));
-
-    sp<Layer> layer(client->getLayerUser(state.surface));
-    if (layer == nullptr) {
-        return;
-    }
-
-    if (state.what & layer_state_t::eDestroySurface) {
-        removeLayerLocked(mStateLock, layer);
-    }
-}
-
 uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
     uint32_t flags = 0;
     if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
@@ -3988,21 +3940,7 @@
 }
 
 
-status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
-{
-    // called by a client when it wants to remove a Layer
-    status_t err = NO_ERROR;
-    sp<Layer> l(client->getLayerUser(handle));
-    if (l != nullptr) {
-        mInterceptor->saveSurfaceDeletion(l);
-        err = removeLayer(l);
-        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                "error removing layer=%p (%s)", l.get(), strerror(-err));
-    }
-    return err;
-}
-
-void SurfaceFlinger::markLayerPendingRemovalLocked(const Mutex&, const sp<Layer>& layer) {
+void SurfaceFlinger::markLayerPendingRemovalLocked(const sp<Layer>& layer) {
     mLayersPendingRemoval.add(layer);
     mLayersRemoved = true;
     setTransactionFlags(eTransactionNeeded);
@@ -4011,7 +3949,14 @@
 void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer)
 {
     Mutex::Autolock lock(mStateLock);
-    markLayerPendingRemovalLocked(mStateLock, layer);
+    // If a layer has a parent, we allow it to out-live it's handle
+    // with the idea that the parent holds a reference and will eventually
+    // be cleaned up. However no one cleans up the top-level so we do so
+    // here.
+    if (layer->getParent() == nullptr) {
+        mCurrentState.layersSortedByZ.remove(layer);
+    }
+    markLayerPendingRemovalLocked(layer);
     layer.clear();
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 04f454c..ac730ab 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -550,7 +550,6 @@
     bool composerStateContainsUnsignaledFences(const Vector<ComposerState>& states);
     uint32_t setClientStateLocked(const ComposerState& composerState);
     uint32_t setDisplayStateLocked(const DisplayState& s);
-    void setDestroyStateLocked(const ComposerState& composerState);
     uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
 
     /* ------------------------------------------------------------------------
@@ -580,20 +579,11 @@
 
     String8 getUniqueLayerName(const String8& name);
 
-    // called in response to the window-manager calling
-    // ISurfaceComposerClient::destroySurface()
-    status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle);
-
-    void markLayerPendingRemovalLocked(const Mutex& /* mStateLock */, const sp<Layer>& layer);
-
     // called when all clients have released all their references to
     // this layer meaning it is entirely safe to destroy all
     // resources associated to this layer.
     void onHandleDestroyed(sp<Layer>& layer);
-
-    // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const sp<Layer>& layer);
-    status_t removeLayerLocked(const Mutex&, const sp<Layer>& layer);
+    void markLayerPendingRemovalLocked(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 3e1be8e..89c26f4 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -34,7 +34,7 @@
             auto surf = client->createSurface(String8("t"), 100, 100,
                     PIXEL_FORMAT_RGBA_8888, 0);
             ASSERT_TRUE(surf != nullptr);
-            client->destroySurface(surf->getHandle());
+            surf->clear();
         }
     };
 
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index e506757..8ec3e15 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -806,18 +806,6 @@
             Increment::IncrementCase::kSurfaceCreation);
 }
 
-TEST_F(SurfaceInterceptorTest, InterceptSurfaceDeletionWorks) {
-    enableInterceptor();
-    sp<SurfaceControl> layerToDelete = mComposerClient->createSurface(String8(LAYER_NAME),
-            SIZE_UPDATE, SIZE_UPDATE, PIXEL_FORMAT_RGBA_8888, 0);
-    mComposerClient->destroySurface(layerToDelete->getHandle());
-    disableInterceptor();
-
-    Trace capturedTrace;
-    ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
-    ASSERT_TRUE(singleIncrementFound(capturedTrace, Increment::IncrementCase::kSurfaceDeletion));
-}
-
 TEST_F(SurfaceInterceptorTest, InterceptDisplayCreationWorks) {
     captureTest(&SurfaceInterceptorTest::displayCreation,
             Increment::IncrementCase::kDisplayCreation);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index d118ad6..991ea36 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1023,7 +1023,7 @@
             .setRelativeLayer(layerG, layerR->getHandle(), 1)
             .apply();
 
-    mClient->destroySurface(layerG->getHandle());
+    layerG->clear();
     // layerG should have been removed
     screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
 }
@@ -4030,9 +4030,9 @@
     asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
     {
         mCapture = screenshot();
-        // Nothing should have changed.
+        // The surface should now be offscreen.
         mCapture->expectFGColor(64, 64);
-        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(74, 74);
         mCapture->expectFGColor(84, 84);
     }
 }
@@ -4610,7 +4610,7 @@
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
 
     auto redLayerHandle = redLayer->getHandle();
-    mClient->destroySurface(redLayerHandle);
+    redLayer->clear();
     SurfaceComposerClient::Transaction().apply(true);
 
     sp<GraphicBuffer> outBuffer;
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
index b478bb5..a82df7f 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
@@ -10,7 +10,7 @@
 class ParcelableComposerFrame : public Parcelable {
  public:
   ParcelableComposerFrame();
-  ParcelableComposerFrame(const ComposerView::Frame& frame);
+  explicit ParcelableComposerFrame(const ComposerView::Frame& frame);
   ~ParcelableComposerFrame() override;
 
   ComposerView::Frame frame() const { return frame_; }
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
index 4cf48f1..6d2ac09 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
@@ -12,7 +12,7 @@
 class ParcelableComposerLayer : public Parcelable {
  public:
   ParcelableComposerLayer();
-  ParcelableComposerLayer(const ComposerView::ComposerLayer& layer);
+  explicit ParcelableComposerLayer(const ComposerView::ComposerLayer& layer);
   ~ParcelableComposerLayer() override;
 
   ComposerView::ComposerLayer layer() const { return layer_; }
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
index daf9e6d..c4216f6 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
@@ -13,7 +13,7 @@
 class ParcelableUniqueFd : public Parcelable {
  public:
   ParcelableUniqueFd();
-  ParcelableUniqueFd(const base::unique_fd& fence);
+  explicit ParcelableUniqueFd(const base::unique_fd& fence);
   ~ParcelableUniqueFd() override;
 
   void set_fence(const base::unique_fd& fence) {
diff --git a/services/vr/hardware_composer/impl/vr_composer_client.h b/services/vr/hardware_composer/impl/vr_composer_client.h
index de22640..0b7ce5e 100644
--- a/services/vr/hardware_composer/impl/vr_composer_client.h
+++ b/services/vr/hardware_composer/impl/vr_composer_client.h
@@ -35,13 +35,13 @@
 
 class VrComposerClient : public ComposerClient {
  public:
-  VrComposerClient(android::dvr::VrHwc& hal);
+  explicit VrComposerClient(android::dvr::VrHwc& hal);
   virtual ~VrComposerClient();
 
  private:
   class VrCommandEngine : public ComposerCommandEngine {
    public:
-    VrCommandEngine(VrComposerClient& client);
+    explicit VrCommandEngine(VrComposerClient& client);
     ~VrCommandEngine() override;
 
     bool executeCommand(IComposerClient::Command command,
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
index f9872b2..e8c0212 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.h
+++ b/services/vr/hardware_composer/impl/vr_hwc.h
@@ -113,9 +113,7 @@
   using Composition =
       hardware::graphics::composer::V2_1::IComposerClient::Composition;
 
-  HwcLayer(Layer new_id) {
-    info.id = new_id;
-  }
+  explicit HwcLayer(Layer new_id) { info.id = new_id; }
 
   void dumpDebugInfo(std::string* result) const;
 
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
index 2c46209..2c88aec 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.h
@@ -13,7 +13,7 @@
 //
 class VirtualTouchpadService : public BnVirtualTouchpadService {
  public:
-  VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
+  explicit VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
       : touchpad_(std::move(touchpad)), client_pid_(0) {}
   ~VirtualTouchpadService() override;