Merge "blast: fix leak on BufferStateLayer death" into qt-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 7ac0eb7..a4b00f8 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -890,6 +890,7 @@
     setTagsProperty(0);
     clearAppProperties();
     pokeBinderServices();
+    pokeHalServices();
 
     if (g_tracePdx) {
         ServiceUtility::PokeServices();
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 032d072..f1426b6 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -47,6 +47,8 @@
     chmod 0666 /sys/kernel/tracing/events/power/clock_set_rate/enable
     chmod 0666 /sys/kernel/debug/tracing/events/power/cpu_frequency_limits/enable
     chmod 0666 /sys/kernel/tracing/events/power/cpu_frequency_limits/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/power/gpu_frequency/enable
+    chmod 0666 /sys/kernel/tracing/events/power/gpu_frequency/enable
     chmod 0666 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
     chmod 0666 /sys/kernel/tracing/events/cpufreq_interactive/enable
     chmod 0666 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 5427ff8..afa3d33 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2086,8 +2086,8 @@
 
 const char* Parcel::readCString() const
 {
-    const size_t avail = mDataSize-mDataPos;
-    if (avail > 0) {
+    if (mDataPos < mDataSize) {
+        const size_t avail = mDataSize-mDataPos;
         const char* str = reinterpret_cast<const char*>(mData+mDataPos);
         // is the string's trailing NUL within the parcel's valid bounds?
         const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
@@ -2835,10 +2835,16 @@
                 }
                 release_object(proc, *flat, this, &mOpenAshmemSize);
             }
-            binder_size_t* objects =
-                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
-            if (objects) {
-                mObjects = objects;
+
+            if (objectsSize == 0) {
+                free(mObjects);
+                mObjects = nullptr;
+            } else {
+                binder_size_t* objects =
+                    (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
+                if (objects) {
+                    mObjects = objects;
+                }
             }
             mObjectsSize = objectsSize;
             mNextObjectHint = 0;
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index 8b33a56..0ad99ce 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -102,13 +102,23 @@
     // Skip over fat response headers.  Not used (or propagated) in native code.
     if (mException == EX_HAS_REPLY_HEADER) {
         // Note that the header size includes the 4 byte size field.
-        const int32_t header_start = parcel.dataPosition();
+        const size_t header_start = parcel.dataPosition();
+        // Get available size before reading more
+        const size_t header_avail = parcel.dataAvail();
+
         int32_t header_size;
         status = parcel.readInt32(&header_size);
         if (status != OK) {
             setFromStatusT(status);
             return status;
         }
+
+        if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
+            android_errorWriteLog(0x534e4554, "132650049");
+            setFromStatusT(UNKNOWN_ERROR);
+            return UNKNOWN_ERROR;
+        }
+
         parcel.setDataPosition(header_start + header_size);
         // And fat response headers are currently only used when there are no
         // exceptions, so act like there was no error.
@@ -135,19 +145,36 @@
         setFromStatusT(status);
         return status;
     }
+    if (remote_stack_trace_header_size < 0 ||
+        static_cast<size_t>(remote_stack_trace_header_size) > parcel.dataAvail()) {
+
+        android_errorWriteLog(0x534e4554, "132650049");
+        setFromStatusT(UNKNOWN_ERROR);
+        return UNKNOWN_ERROR;
+    }
     parcel.setDataPosition(parcel.dataPosition() + remote_stack_trace_header_size);
 
     if (mException == EX_SERVICE_SPECIFIC) {
         status = parcel.readInt32(&mErrorCode);
     } else if (mException == EX_PARCELABLE) {
         // Skip over the blob of Parcelable data
-        const int32_t header_start = parcel.dataPosition();
+        const size_t header_start = parcel.dataPosition();
+        // Get available size before reading more
+        const size_t header_avail = parcel.dataAvail();
+
         int32_t header_size;
         status = parcel.readInt32(&header_size);
         if (status != OK) {
             setFromStatusT(status);
             return status;
         }
+
+        if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
+            android_errorWriteLog(0x534e4554, "132650049");
+            setFromStatusT(UNKNOWN_ERROR);
+            return UNKNOWN_ERROR;
+        }
+
         parcel.setDataPosition(header_start + header_size);
     }
     if (status != OK) {
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 407f77d..24b6c2d 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -37,6 +37,7 @@
 
 #include <memory>
 #include <string>
+#include <thread>
 
 // TODO(b/37049319) Get this from a header once one exists
 extern "C" {
@@ -163,17 +164,20 @@
 void GraphicsEnv::hintActivityLaunch() {
     ATRACE_CALL();
 
-    // If there's already graphics driver preloaded in the process, just send
-    // the stats info to GpuStats directly through async binder.
-    std::lock_guard<std::mutex> lock(mStatsLock);
-    if (mGpuStats.glDriverToSend) {
-        mGpuStats.glDriverToSend = false;
-        sendGpuStatsLocked(GraphicsEnv::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
-    }
-    if (mGpuStats.vkDriverToSend) {
-        mGpuStats.vkDriverToSend = false;
-        sendGpuStatsLocked(GraphicsEnv::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
-    }
+    std::thread trySendGpuStatsThread([this]() {
+        // If there's already graphics driver preloaded in the process, just send
+        // the stats info to GpuStats directly through async binder.
+        std::lock_guard<std::mutex> lock(mStatsLock);
+        if (mGpuStats.glDriverToSend) {
+            mGpuStats.glDriverToSend = false;
+            sendGpuStatsLocked(GraphicsEnv::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
+        }
+        if (mGpuStats.vkDriverToSend) {
+            mGpuStats.vkDriverToSend = false;
+            sendGpuStatsLocked(GraphicsEnv::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
+        }
+    });
+    trySendGpuStatsThread.detach();
 }
 
 void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
@@ -534,60 +538,73 @@
     mDebugLayersGLES = layers;
 }
 
+// Return true if all the required libraries from vndk and sphal namespace are
+// linked to the Game Driver namespace correctly.
+bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* vndkNamespace) {
+    const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
+    if (llndkLibraries.empty()) {
+        return false;
+    }
+    if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) {
+        ALOGE("Failed to link default namespace[%s]", dlerror());
+        return false;
+    }
+
+    const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP);
+    if (vndkspLibraries.empty()) {
+        return false;
+    }
+    if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) {
+        ALOGE("Failed to link vndk namespace[%s]", dlerror());
+        return false;
+    }
+
+    if (mSphalLibraries.empty()) {
+        return true;
+    }
+
+    // Make additional libraries in sphal to be accessible
+    auto sphalNamespace = android_get_exported_namespace("sphal");
+    if (!sphalNamespace) {
+        ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace",
+              mSphalLibraries.c_str());
+        return false;
+    }
+
+    if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) {
+        ALOGE("Failed to link sphal namespace[%s]", dlerror());
+        return false;
+    }
+
+    return true;
+}
+
 android_namespace_t* GraphicsEnv::getDriverNamespace() {
-    static std::once_flag once;
-    std::call_once(once, [this]() {
-        if (mDriverPath.empty()) return;
+    std::lock_guard<std::mutex> lock(mNamespaceMutex);
 
-        auto vndkNamespace = android_get_exported_namespace("vndk");
-        if (!vndkNamespace) return;
+    if (mDriverNamespace) {
+        return mDriverNamespace;
+    }
 
-        mDriverNamespace = android_create_namespace("gfx driver",
-                                                    mDriverPath.c_str(), // ld_library_path
-                                                    mDriverPath.c_str(), // default_library_path
-                                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
-                                                    nullptr, // permitted_when_isolated_path
-                                                    nullptr);
+    if (mDriverPath.empty()) {
+        return nullptr;
+    }
 
-        const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
-        if (llndkLibraries.empty()) {
-            mDriverNamespace = nullptr;
-            return;
-        }
-        if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) {
-            ALOGE("Failed to link default namespace[%s]", dlerror());
-            mDriverNamespace = nullptr;
-            return;
-        }
+    auto vndkNamespace = android_get_exported_namespace("vndk");
+    if (!vndkNamespace) {
+        return nullptr;
+    }
 
-        const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP);
-        if (vndkspLibraries.empty()) {
-            mDriverNamespace = nullptr;
-            return;
-        }
-        if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) {
-            ALOGE("Failed to link vndk namespace[%s]", dlerror());
-            mDriverNamespace = nullptr;
-            return;
-        }
+    mDriverNamespace = android_create_namespace("gfx driver",
+                                                mDriverPath.c_str(), // ld_library_path
+                                                mDriverPath.c_str(), // default_library_path
+                                                ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                                nullptr, // permitted_when_isolated_path
+                                                nullptr);
 
-        if (mSphalLibraries.empty()) return;
-
-        // Make additional libraries in sphal to be accessible
-        auto sphalNamespace = android_get_exported_namespace("sphal");
-        if (!sphalNamespace) {
-            ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace",
-                  mSphalLibraries.c_str());
-            mDriverNamespace = nullptr;
-            return;
-        }
-
-        if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) {
-            ALOGE("Failed to link sphal namespace[%s]", dlerror());
-            mDriverNamespace = nullptr;
-            return;
-        }
-    });
+    if (!linkDriverNamespaceLocked(vndkNamespace)) {
+        mDriverNamespace = nullptr;
+    }
 
     return mDriverNamespace;
 }
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 7d62750..f5d19db 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -129,6 +129,7 @@
     void* loadLibrary(std::string name);
     bool checkAngleRules(void* so);
     void updateUseAngle();
+    bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
 
     GraphicsEnv() = default;
     std::string mDriverPath;
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 5840d51..96d5eb9 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -94,7 +94,7 @@
 
 SensorManager::SensorManager(const String16& opPackageName)
     : mSensorList(nullptr), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
-    // okay we're not locked here, but it's not needed during construction
+    Mutex::Autolock _l(mLock);
     assertStateLocked();
 }
 
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index c0bace8..abc7a72 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -208,6 +208,10 @@
     defaults: ["gles_libs_defaults"],
     srcs: ["GLES2/gl2.cpp"],
     cflags: ["-DLOG_TAG=\"libGLESv2\""],
+
+    // Bug: http://b/133874658  Disable native_coverage as we investigate a
+    // crash in surfaceflinger on coverage-enabled cuttlefish builds.
+    native_coverage: false,
 }
 
 //##############################################################################
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index d5c46c6..038a432 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -84,6 +84,11 @@
     return android_load_sphal_library(path, mode);
 }
 
+static int do_android_unload_sphal_library(void* dso) {
+    ATRACE_CALL();
+    return android_unload_sphal_library(dso);
+}
+
 Loader::driver_t::driver_t(void* gles)
 {
     dso[0] = gles;
@@ -180,11 +185,81 @@
     "ro.board.platform",
 };
 
+static bool should_unload_system_driver(egl_connection_t* cnx) {
+    // Return false if the system driver has been unloaded once.
+    if (cnx->systemDriverUnloaded) {
+        return false;
+    }
+
+    // Return true if Angle namespace is set.
+    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
+    if (ns) {
+        return true;
+    }
+
+#ifndef __ANDROID_VNDK__
+    // Return true if updated driver namespace is set.
+    ns = android::GraphicsEnv::getInstance().getDriverNamespace();
+    if (ns) {
+        return true;
+    }
+#endif
+
+    return false;
+}
+
+static void uninit_api(char const* const* api, __eglMustCastToProperFunctionPointerType* curr) {
+    while (*api) {
+        *curr++ = nullptr;
+        api++;
+    }
+}
+
+void Loader::unload_system_driver(egl_connection_t* cnx) {
+    ATRACE_CALL();
+
+    uninit_api(gl_names,
+               (__eglMustCastToProperFunctionPointerType*)&cnx
+                       ->hooks[egl_connection_t::GLESv2_INDEX]
+                       ->gl);
+    uninit_api(gl_names,
+               (__eglMustCastToProperFunctionPointerType*)&cnx
+                       ->hooks[egl_connection_t::GLESv1_INDEX]
+                       ->gl);
+    uninit_api(egl_names, (__eglMustCastToProperFunctionPointerType*)&cnx->egl);
+
+    if (cnx->dso) {
+        ALOGD("Unload system gl driver.");
+        driver_t* hnd = (driver_t*)cnx->dso;
+        if (hnd->dso[2]) {
+            do_android_unload_sphal_library(hnd->dso[2]);
+        }
+        if (hnd->dso[1]) {
+            do_android_unload_sphal_library(hnd->dso[1]);
+        }
+        if (hnd->dso[0]) {
+            do_android_unload_sphal_library(hnd->dso[0]);
+        }
+        cnx->dso = nullptr;
+    }
+
+    cnx->systemDriverUnloaded = true;
+}
+
 void* Loader::open(egl_connection_t* cnx)
 {
     ATRACE_CALL();
     const nsecs_t openTime = systemTime();
 
+    if (should_unload_system_driver(cnx)) {
+        unload_system_driver(cnx);
+    }
+
+    // If a driver has been loaded, return the driver directly.
+    if (cnx->dso) {
+        return cnx->dso;
+    }
+
     setEmulatorGlesValue();
 
     // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries.
@@ -244,9 +319,15 @@
                         "couldn't find an OpenGL ES implementation, make sure you set %s or %s",
                         HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]);
 
-    cnx->libEgl   = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
-    cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");
-    cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
+    if (!cnx->libEgl) {
+        cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
+    }
+    if (!cnx->libGles1) {
+        cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
+    }
+    if (!cnx->libGles2) {
+        cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");
+    }
 
     if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
         android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL,
@@ -584,6 +665,7 @@
         return nullptr;
     }
 
+    ALOGD("Load updated gl driver.");
     android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED);
     driver_t* hnd = nullptr;
     void* dso = load_updated_driver("GLES", ns);
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 0292d02..6f31ab4 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -58,6 +58,7 @@
     driver_t* attempt_to_load_angle(egl_connection_t* cnx);
     driver_t* attempt_to_load_updated_driver(egl_connection_t* cnx);
     driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact);
+    void unload_system_driver(egl_connection_t* cnx);
     void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask);
 
     static __attribute__((noinline))
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 8870d5f..25b1009 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -187,13 +187,9 @@
 
     // dynamically load our EGL implementation
     egl_connection_t* cnx = &gEGLImpl;
-    if (cnx->dso == nullptr) {
-        cnx->hooks[egl_connection_t::GLESv1_INDEX] =
-                &gHooks[egl_connection_t::GLESv1_INDEX];
-        cnx->hooks[egl_connection_t::GLESv2_INDEX] =
-                &gHooks[egl_connection_t::GLESv2_INDEX];
-        cnx->dso = loader.open(cnx);
-    }
+    cnx->hooks[egl_connection_t::GLESv1_INDEX] = &gHooks[egl_connection_t::GLESv1_INDEX];
+    cnx->hooks[egl_connection_t::GLESv2_INDEX] = &gHooks[egl_connection_t::GLESv2_INDEX];
+    cnx->dso = loader.open(cnx);
 
     // Check to see if any layers are enabled and route functions through them
     if (cnx->dso) {
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 8841a3b..67d69b4 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -217,7 +217,7 @@
     Loader& loader(Loader::getInstance());
 
     egl_connection_t* const cnx = &gEGLImpl;
-    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
+    if (cnx->dso) {
         EGLDisplay dpy = EGL_NO_DISPLAY;
 
         if (cnx->useAngle) {
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 9e112cc..7bb9b59 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -44,7 +44,11 @@
         GLESv2_INDEX = 1
     };
 
-    inline egl_connection_t() : dso(nullptr) {
+    inline egl_connection_t() : dso(nullptr),
+                                libEgl(nullptr),
+                                libGles1(nullptr),
+                                libGles2(nullptr),
+                                systemDriverUnloaded(false) {
 
         char const* const* entries = platform_names;
         EGLFuncPointer* curr = reinterpret_cast<EGLFuncPointer*>(&platform);
@@ -76,6 +80,7 @@
     void*               libGles1;
     void*               libGles2;
 
+    bool                systemDriverUnloaded;
     bool                shouldUseAngle; // Should we attempt to load ANGLE
     bool                angleDecided;   // Have we tried to load ANGLE
     bool                useAngle;       // Was ANGLE successfully loaded
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
index a4b81fe..cd03bc2 100644
--- a/services/bufferhub/Android.bp
+++ b/services/bufferhub/Android.bp
@@ -63,6 +63,7 @@
         "libbufferhubservice",
         "libcrypto",
         "libcutils",
+        "libhidlbase",
         "libhidltransport",
         "libhwbinder",
         "liblog",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 31a2dab..c2ff4c9 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2172,9 +2172,8 @@
         return;
     }
 
-    int32_t displayId = inputWindowHandle->getInfo()->displayId;
     sp<InputWindowHandle> focusedWindowHandle =
-            getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
+            getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
 
     bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
 
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index a2b6ab6..f51fbb4 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -19,9 +19,7 @@
 #define LOG_TAG "BufferLayer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <cmath>
-#include <cstdlib>
-#include <mutex>
+#include "BufferLayer.h"
 
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/Display.h>
@@ -45,11 +43,14 @@
 #include <utils/StopWatch.h>
 #include <utils/Trace.h>
 
-#include "BufferLayer.h"
+#include <cmath>
+#include <cstdlib>
+#include <mutex>
+#include <sstream>
+
 #include "Colorizer.h"
 #include "DisplayDevice.h"
 #include "LayerRejecter.h"
-
 #include "TimeStats/TimeStats.h"
 
 namespace android {
@@ -525,6 +526,9 @@
             }
 
             if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
+                std::stringstream ss;
+                ss << "Dropping sync point " << (*point)->getFrameNumber();
+                ATRACE_NAME(ss.str().c_str());
                 point = mLocalSyncPoints.erase(point);
             } else {
                 ++point;
@@ -545,6 +549,12 @@
         if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled &&
             presentTimeIsCurrent) {
             point->setFrameAvailable();
+            sp<Layer> requestedSyncLayer = point->getRequestedSyncLayer();
+            if (requestedSyncLayer) {
+                // Need to update the transaction flag to ensure the layer's pending transaction
+                // gets applied.
+                requestedSyncLayer->setTransactionFlags(eTransactionNeeded);
+            }
         }
     }
 }
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 482c723..6bfd302 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -87,11 +87,18 @@
                                          LayerMetadata metadata, sp<IBinder>* handle,
                                          sp<IGraphicBufferProducer>* gbp) {
     if (mFlinger->authenticateSurfaceTexture(parent) == false) {
+        ALOGE("failed to authenticate surface texture");
+        // The extra parent layer check below before returning is to help with debugging
+        // b/134888387. Once the bug is fixed the check can be deleted.
+        if ((static_cast<MonitoredProducer*>(parent.get()))->getLayer() == nullptr) {
+            ALOGE("failed to find parent layer");
+        }
         return BAD_VALUE;
     }
 
     const auto& layer = (static_cast<MonitoredProducer*>(parent.get()))->getLayer();
     if (layer == nullptr) {
+        ALOGE("failed to find parent layer");
         return BAD_VALUE;
     }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 379b004..1318bc0 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -19,12 +19,7 @@
 #define LOG_TAG "Layer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <math.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <algorithm>
-#include <mutex>
+#include "Layer.h"
 
 #include <android-base/stringprintf.h>
 #include <compositionengine/Display.h>
@@ -39,7 +34,11 @@
 #include <gui/BufferItem.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
+#include <math.h>
 #include <renderengine/RenderEngine.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
 #include <ui/DebugUtils.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
@@ -49,12 +48,15 @@
 #include <utils/StopWatch.h>
 #include <utils/Trace.h>
 
+#include <algorithm>
+#include <mutex>
+#include <sstream>
+
 #include "BufferLayer.h"
 #include "ColorLayer.h"
 #include "Colorizer.h"
 #include "DisplayDevice.h"
 #include "DisplayHardware/HWComposer.h"
-#include "Layer.h"
 #include "LayerProtoHelper.h"
 #include "LayerRejecter.h"
 #include "MonitoredProducer.h"
@@ -144,28 +146,47 @@
  */
 void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}
 
-void Layer::onRemovedFromCurrentState() {
-    mRemovedFromCurrentState = true;
+void Layer::removeRemoteSyncPoints() {
+    for (auto& point : mRemoteSyncPoints) {
+        point->setTransactionApplied();
+    }
+    mRemoteSyncPoints.clear();
 
-    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
-        if (strongRelative != nullptr) {
-            strongRelative->removeZOrderRelative(this);
-            mFlinger->setTransactionFlags(eTraversalNeeded);
+    {
+        Mutex::Autolock pendingStateLock(mPendingStateMutex);
+        for (State pendingState : mPendingStates) {
+            pendingState.barrierLayer_legacy = nullptr;
         }
+    }
+}
+
+void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) {
+    if (mCurrentState.zOrderRelativeOf == nullptr) {
+        return;
+    }
+
+    sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+    if (strongRelative == nullptr) {
+        setZOrderRelativeOf(nullptr);
+        return;
+    }
+
+    if (!std::binary_search(layersInTree.begin(), layersInTree.end(), strongRelative.get())) {
+        strongRelative->removeZOrderRelative(this);
+        mFlinger->setTransactionFlags(eTraversalNeeded);
         setZOrderRelativeOf(nullptr);
     }
+}
+
+void Layer::removeFromCurrentState() {
+    mRemovedFromCurrentState = true;
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
     // will no longer invoke doTransaction for us, and so we will
     // never finish applying transactions. We signal the sync point
     // now so that another layer will not become indefinitely
     // blocked.
-    for (auto& point: mRemoteSyncPoints) {
-        point->setTransactionApplied();
-    }
-    mRemoteSyncPoints.clear();
+    removeRemoteSyncPoints();
 
     {
     Mutex::Autolock syncLock(mLocalSyncPointMutex);
@@ -175,13 +196,18 @@
     mLocalSyncPoints.clear();
     }
 
-    for (const auto& child : mCurrentChildren) {
-        child->onRemovedFromCurrentState();
-    }
-
     mFlinger->markLayerPendingRemovalLocked(this);
 }
 
+void Layer::onRemovedFromCurrentState() {
+    auto layersInTree = getLayersInTree(LayerVector::StateSet::Current);
+    std::sort(layersInTree.begin(), layersInTree.end());
+    for (const auto& layer : layersInTree) {
+        layer->removeFromCurrentState();
+        layer->removeRelativeZ(layersInTree);
+    }
+}
+
 void Layer::addToCurrentState() {
     mRemovedFromCurrentState = false;
 
@@ -653,6 +679,7 @@
     if (!mCurrentState.modified) {
         return;
     }
+    ATRACE_CALL();
 
     // If this transaction is waiting on the receipt of a frame, generate a sync
     // point and send it to the remote layer.
@@ -667,8 +694,11 @@
             // to be applied as per normal (no synchronization).
             mCurrentState.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy, this);
             if (barrierLayer->addSyncPoint(syncPoint)) {
+                std::stringstream ss;
+                ss << "Adding sync point " << mCurrentState.frameNumber_legacy;
+                ATRACE_NAME(ss.str().c_str());
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
@@ -686,6 +716,7 @@
 }
 
 void Layer::popPendingState(State* stateToCommit) {
+    ATRACE_CALL();
     *stateToCommit = mPendingStates[0];
 
     mPendingStates.removeAt(0);
@@ -717,6 +748,7 @@
             }
 
             if (mRemoteSyncPoints.front()->frameIsAvailable()) {
+                ATRACE_NAME("frameIsAvailable");
                 // Apply the state update
                 popPendingState(stateToCommit);
                 stateUpdateAvailable = true;
@@ -725,6 +757,7 @@
                 mRemoteSyncPoints.front()->setTransactionApplied();
                 mRemoteSyncPoints.pop_front();
             } else {
+                ATRACE_NAME("!frameIsAvailable");
                 break;
             }
         } else {
@@ -1171,6 +1204,7 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
+    ATRACE_CALL();
     mCurrentState.barrierLayer_legacy = barrierLayer;
     mCurrentState.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
@@ -1197,6 +1231,14 @@
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
     }
+    if (usingRelativeZ(LayerVector::StateSet::Drawing)) {
+        auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
+        if (zOrderRelativeOf != nullptr) {
+            if (zOrderRelativeOf->isHiddenByPolicy()) {
+                return true;
+            }
+        }
+    }
     return s.flags & layer_state_t::eLayerHidden;
 }
 
@@ -1510,6 +1552,7 @@
         if (client != nullptr && parentClient != client) {
             child->mLayerDetached = true;
             child->detachChildren();
+            child->removeRemoteSyncPoints();
         }
     }
 
@@ -1577,7 +1620,7 @@
     return mDrawingState.z;
 }
 
-bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) const {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const State& state = useDrawing ? mDrawingState : mCurrentState;
     return state.zOrderRelativeOf != nullptr;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3712b2a..8a80e15 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -571,6 +571,17 @@
     virtual bool isBufferLatched() const { return false; }
 
     /*
+     * Remove relative z for the layer if its relative parent is not part of the
+     * provided layer tree.
+     */
+    void removeRelativeZ(const std::vector<Layer*>& layersInTree);
+
+    /*
+     * Remove from current state and mark for removal.
+     */
+    void removeFromCurrentState();
+
+    /*
      * called with the state lock from a binder thread when the layer is
      * removed from the current list to the pending removal list
      */
@@ -733,8 +744,11 @@
 
     class SyncPoint {
     public:
-        explicit SyncPoint(uint64_t frameNumber)
-              : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {}
+        explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer)
+              : mFrameNumber(frameNumber),
+                mFrameIsAvailable(false),
+                mTransactionIsApplied(false),
+                mRequestedSyncLayer(requestedSyncLayer) {}
 
         uint64_t getFrameNumber() const { return mFrameNumber; }
 
@@ -746,10 +760,13 @@
 
         void setTransactionApplied() { mTransactionIsApplied = true; }
 
+        sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); }
+
     private:
         const uint64_t mFrameNumber;
         std::atomic<bool> mFrameIsAvailable;
         std::atomic<bool> mTransactionIsApplied;
+        wp<Layer> mRequestedSyncLayer;
     };
 
     // SyncPoints which will be signaled when the correct frame is at the head
@@ -807,7 +824,7 @@
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet);
+    bool usingRelativeZ(LayerVector::StateSet stateSet) const;
 
     bool mPremultipliedAlpha{true};
     String8 mName;
@@ -928,6 +945,8 @@
     void setZOrderRelativeOf(const wp<Layer>& relativeOf);
 
     bool mGetHandleCalled = false;
+
+    void removeRemoteSyncPoints();
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 7fa33f5..66906e9 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -280,6 +280,10 @@
         area.top = height - area.top;
         area.bottom = height - area.bottom;
         std::swap(area.top, area.bottom);
+
+        area.left = width - area.left;
+        area.right = width - area.right;
+        std::swap(area.left, area.right);
     }
 
     std::array<int32_t, 256> brightnessBuckets = {};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dd75868..2d31910 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -302,8 +302,8 @@
 
     mDefaultCompositionDataspace =
             static_cast<ui::Dataspace>(default_composition_dataspace(Dataspace::V0_SRGB));
-    mWideColorGamutCompositionDataspace =
-            static_cast<ui::Dataspace>(wcg_composition_dataspace(Dataspace::V0_SRGB));
+    mWideColorGamutCompositionDataspace = static_cast<ui::Dataspace>(wcg_composition_dataspace(
+            hasWideColorDisplay ? Dataspace::DISPLAY_P3 : Dataspace::V0_SRGB));
     defaultCompositionDataspace = mDefaultCompositionDataspace;
     wideColorGamutCompositionDataspace = mWideColorGamutCompositionDataspace;
     defaultCompositionPixelFormat = static_cast<ui::PixelFormat>(
@@ -2133,7 +2133,14 @@
     }
 
     mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
-    mTransactionCompletedThread.sendCallbacks();
+
+    // Lock the mStateLock in case SurfaceFlinger is in the middle of applying a transaction.
+    // If we do not lock here, a callback could be sent without all of its SurfaceControls and
+    // metrics.
+    {
+        Mutex::Autolock _l(mStateLock);
+        mTransactionCompletedThread.sendCallbacks();
+    }
 
     if (mLumaSampling && mRegionSamplingThread) {
         mRegionSamplingThread->notifyNewContent();
@@ -5606,6 +5613,11 @@
 
         captureOrientation = fromSurfaceComposerRotation(
                 static_cast<ISurfaceComposer::Rotation>(display->getOrientation()));
+        if (captureOrientation == ui::Transform::orientation_flags::ROT_90) {
+            captureOrientation = ui::Transform::orientation_flags::ROT_270;
+        } else if (captureOrientation == ui::Transform::orientation_flags::ROT_270) {
+            captureOrientation = ui::Transform::orientation_flags::ROT_90;
+        }
         *outDataspace =
                 pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
     }
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index 4f352ff..2b33ba1 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -177,15 +177,11 @@
 
 bool use_color_management(bool defaultValue) {
     auto tmpuseColorManagement = SurfaceFlingerProperties::use_color_management();
-    auto tmpHasHDRDisplay = SurfaceFlingerProperties::has_HDR_display();
-    auto tmpHasWideColorDisplay = SurfaceFlingerProperties::has_wide_color_display();
+    auto tmpHasHDRDisplayVal = has_HDR_display(defaultValue);
+    auto tmpHasWideColorDisplayVal = has_wide_color_display(defaultValue);
 
     auto tmpuseColorManagementVal = tmpuseColorManagement.has_value() ? *tmpuseColorManagement :
         defaultValue;
-    auto tmpHasHDRDisplayVal = tmpHasHDRDisplay.has_value() ? *tmpHasHDRDisplay :
-        defaultValue;
-    auto tmpHasWideColorDisplayVal = tmpHasWideColorDisplay.has_value() ? *tmpHasWideColorDisplay :
-        defaultValue;
 
     return tmpuseColorManagementVal || tmpHasHDRDisplayVal || tmpHasWideColorDisplayVal;
 }
diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
index 5ebae1e..6b4634a 100644
--- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter
+++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
@@ -1,5 +1,5 @@
 {
         "presubmit": {
-            "filter": "CredentialsTest.*:SurfaceFlingerStress.*:SurfaceInterceptorTest.*:LayerTransactionTest.*:LayerTypeTransactionTest.*:LayerUpdateTest.*:GeometryLatchingTest.*:CropLatchingTest.*:ChildLayerTest.*:ScreenCaptureTest.*:ScreenCaptureChildOnlyTest.*:DereferenceSurfaceControlTest.*:BoundlessLayerTest.*:MultiDisplayLayerBoundsTest.*:InvalidHandleTest.*:VirtualDisplayTest.*"
+            "filter": "CredentialsTest.*:SurfaceFlingerStress.*:SurfaceInterceptorTest.*:LayerTransactionTest.*:LayerTypeTransactionTest.*:LayerUpdateTest.*:GeometryLatchingTest.*:CropLatchingTest.*:ChildLayerTest.*:ScreenCaptureTest.*:ScreenCaptureChildOnlyTest.*:DereferenceSurfaceControlTest.*:BoundlessLayerTest.*:MultiDisplayLayerBoundsTest.*:InvalidHandleTest.*:VirtualDisplayTest.*:RelativeZTest.*"
         }
 }
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index ec1ac4b..d5f6534 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -385,6 +385,18 @@
         return createLayer(mClient, name, width, height, flags, parent);
     }
 
+    sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
+                                        SurfaceControl* parent = nullptr) {
+        auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
+                                        PIXEL_FORMAT_RGBA_8888,
+                                        ISurfaceComposerClient::eFXSurfaceColor, parent);
+        asTransaction([&](Transaction& t) {
+            t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
+            t.setAlpha(colorLayer, color.a / 255.0f);
+        });
+        return colorLayer;
+    }
+
     ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
         // wait for previous transactions (such as setSize) to complete
         Transaction().apply(true);
@@ -1103,6 +1115,56 @@
     }
 }
 
+TEST_P(LayerTypeTransactionTest, HideRelativeParentHidesLayer) {
+    sp<SurfaceControl> parent =
+            LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */,
+                                              ISurfaceComposerClient::eFXSurfaceColor);
+    sp<SurfaceControl> relativeParent =
+            LayerTransactionTest::createLayer("RelativeParent", 0 /* buffer width */,
+                    0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceColor);
+
+    sp<SurfaceControl> childLayer;
+    ASSERT_NO_FATAL_FAILURE(
+            childLayer = LayerTransactionTest::createLayer("childLayer", 0 /* buffer width */,
+                                                           0 /* buffer height */,
+                                                           ISurfaceComposerClient::eFXSurfaceColor,
+                                                           parent.get()));
+    Transaction()
+            .setColor(childLayer, half3{1.0f, 0.0f, 0.0f})
+            .setColor(parent, half3{0.0f, 0.0f, 0.0f})
+            .setColor(relativeParent, half3{0.0f, 1.0f, 0.0f})
+            .show(childLayer)
+            .show(parent)
+            .show(relativeParent)
+            .setLayer(parent, mLayerZBase - 1)
+            .setLayer(relativeParent, mLayerZBase)
+            .apply();
+
+    Transaction()
+            .setRelativeLayer(childLayer, relativeParent->getHandle(), 1)
+            .apply();
+
+    {
+        SCOPED_TRACE("setLayer above");
+        // Set layer should get applied and place the child above.
+        std::unique_ptr<ScreenCapture> screenshot;
+        ScreenCapture::captureScreen(&screenshot);
+        screenshot->expectColor(Rect(0, 0, 20, 30), Color::RED);
+    }
+
+    Transaction()
+        .hide(relativeParent)
+        .apply();
+
+    {
+        SCOPED_TRACE("hide relative parent");
+        // The relative should no longer be visible.
+        std::unique_ptr<ScreenCapture> screenshot;
+        ScreenCapture::captureScreen(&screenshot);
+        screenshot->expectColor(Rect(0, 0, 20, 30), Color::BLACK);
+    }
+}
+
 void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) {
     sp<SurfaceControl> layerR;
     sp<SurfaceControl> layerG;
@@ -4725,6 +4787,48 @@
         mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
     }
 }
+TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) {
+    sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
+    sp<SurfaceControl> childNewClient =
+            newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
+                                             PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
+
+    ASSERT_TRUE(childNewClient != nullptr);
+    ASSERT_TRUE(childNewClient->isValid());
+
+    fillSurfaceRGBA8(childNewClient, 200, 200, 200);
+
+    Transaction()
+            .hide(mChild)
+            .show(childNewClient)
+            .setPosition(childNewClient, 10, 10)
+            .setPosition(mFGSurfaceControl, 64, 64)
+            .apply();
+
+    {
+        mCapture = screenshot();
+        Rect rect = Rect(74, 74, 84, 84);
+        mCapture->expectBorder(rect, Color{195, 63, 63, 255});
+        mCapture->expectColor(rect, Color{200, 200, 200, 255});
+    }
+
+    Transaction()
+            .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(),
+                                          mFGSurfaceControl->getSurface()->getNextFrameNumber())
+            .apply();
+    Transaction().detachChildren(mFGSurfaceControl).apply();
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32));
+
+    // BufferLayer can still dequeue buffers even though there's a detached layer with a
+    // deferred transaction.
+    {
+        SCOPED_TRACE("new buffer");
+        mCapture = screenshot();
+        Rect rect = Rect(74, 74, 84, 84);
+        mCapture->expectBorder(rect, Color::RED);
+        mCapture->expectColor(rect, Color{200, 200, 200, 255});
+    }
+}
 
 TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
     asTransaction([&](Transaction& t) {
@@ -5833,4 +5937,126 @@
                 allowedConfigs.end());
 }
 
+class RelativeZTest : public LayerTransactionTest {
+protected:
+    virtual void SetUp() {
+        LayerTransactionTest::SetUp();
+        ASSERT_EQ(NO_ERROR, mClient->initCheck());
+
+        const auto display = SurfaceComposerClient::getInternalDisplayToken();
+        ASSERT_FALSE(display == nullptr);
+
+        // Back layer
+        mBackgroundLayer = createColorLayer("Background layer", Color::RED);
+
+        // Front layer
+        mForegroundLayer = createColorLayer("Foreground layer", Color::GREEN);
+
+        asTransaction([&](Transaction& t) {
+            t.setDisplayLayerStack(display, 0);
+            t.setLayer(mBackgroundLayer, INT32_MAX - 2).show(mBackgroundLayer);
+            t.setLayer(mForegroundLayer, INT32_MAX - 1).show(mForegroundLayer);
+        });
+    }
+
+    virtual void TearDown() {
+        LayerTransactionTest::TearDown();
+        mBackgroundLayer = 0;
+        mForegroundLayer = 0;
+    }
+
+    sp<SurfaceControl> mBackgroundLayer;
+    sp<SurfaceControl> mForegroundLayer;
+};
+
+// When a layer is reparented offscreen, remove relative z order if the relative parent
+// is still onscreen so that the layer is not drawn.
+TEST_F(RelativeZTest, LayerRemoved) {
+    std::unique_ptr<ScreenCapture> sc;
+
+    // Background layer (RED)
+    //   Child layer (WHITE) (relative to foregroud layer)
+    // Foregroud layer (GREEN)
+    sp<SurfaceControl> childLayer =
+            createColorLayer("Child layer", Color::BLUE, mBackgroundLayer.get());
+
+    Transaction{}
+            .setRelativeLayer(childLayer, mForegroundLayer->getHandle(), 1)
+            .show(childLayer)
+            .apply();
+
+    {
+        // The childLayer should be in front of the FG control.
+        ScreenCapture::captureScreen(&sc);
+        sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
+    }
+
+    // Background layer (RED)
+    // Foregroud layer (GREEN)
+    Transaction{}.reparent(childLayer, nullptr).apply();
+
+    // Background layer (RED)
+    //   Child layer (WHITE)
+    // Foregroud layer (GREEN)
+    Transaction{}.reparent(childLayer, mBackgroundLayer->getHandle()).apply();
+
+    {
+        // The relative z info for child layer should be reset, leaving FG control on top.
+        ScreenCapture::captureScreen(&sc);
+        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
+    }
+}
+
+// When a layer is reparented offscreen, preseve relative z order if the relative parent
+// is also offscreen. Regression test b/132613412
+TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
+    std::unique_ptr<ScreenCapture> sc;
+
+    // Background layer (RED)
+    // Foregroud layer (GREEN)
+    //   child level 1 (WHITE)
+    //     child level 2a (BLUE)
+    //       child level 3 (GREEN) (relative to child level 2b)
+    //     child level 2b (BLACK)
+    sp<SurfaceControl> childLevel1 =
+            createColorLayer("child level 1", Color::WHITE, mForegroundLayer.get());
+    sp<SurfaceControl> childLevel2a =
+            createColorLayer("child level 2a", Color::BLUE, childLevel1.get());
+    sp<SurfaceControl> childLevel2b =
+            createColorLayer("child level 2b", Color::BLACK, childLevel1.get());
+    sp<SurfaceControl> childLevel3 =
+            createColorLayer("child level 3", Color::GREEN, childLevel2a.get());
+
+    Transaction{}
+            .setRelativeLayer(childLevel3, childLevel2b->getHandle(), 1)
+            .show(childLevel2a)
+            .show(childLevel2b)
+            .show(childLevel3)
+            .apply();
+
+    {
+        // The childLevel3 should be in front of childLevel2b.
+        ScreenCapture::captureScreen(&sc);
+        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
+    }
+
+    // Background layer (RED)
+    // Foregroud layer (GREEN)
+    Transaction{}.reparent(childLevel1, nullptr).apply();
+
+    // Background layer (RED)
+    // Foregroud layer (GREEN)
+    //   child level 1 (WHITE)
+    //     child level 2 back (BLUE)
+    //       child level 3 (GREEN) (relative to child level 2b)
+    //     child level 2 front (BLACK)
+    Transaction{}.reparent(childLevel1, mForegroundLayer->getHandle()).apply();
+
+    {
+        // Nothing should change at this point since relative z info was preserved.
+        ScreenCapture::captureScreen(&sc);
+        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
+    }
+}
+
 } // namespace android
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index d9df204..4c34b93 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -137,7 +137,7 @@
     "libbinder",
     "liblog",
     "libhardware",
-    "libhwbinder",
+    "libhidlbase",
     "libui",
     "libutils",
     "libvr_hwc-hal",