Merge "Rename snapshotProfile to createProfileSnapshot for better consistency"
diff --git a/cmds/cmd/Android.mk b/cmds/cmd/Android.mk
index d565e57..4868555 100644
--- a/cmds/cmd/Android.mk
+++ b/cmds/cmd/Android.mk
@@ -10,6 +10,8 @@
     libselinux \
 	libbinder
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_C_INCLUDES += \
     $(JNI_H_INCLUDE)
 
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 6511b44..48d5d4a 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -104,7 +104,7 @@
         if (is_selinux_enabled() && seLinuxContext.size() > 0) {
             String8 seLinuxContext8(seLinuxContext);
             security_context_t tmp = NULL;
-            int ret = getfilecon(fullPath.string(), &tmp);
+            getfilecon(fullPath.string(), &tmp);
             Unique_SecurityContext context(tmp);
             if (checkWrite) {
                 int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(),
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 4b67d8f..2e3e3ca 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -691,7 +691,9 @@
     printf("Kernel: ");
     DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
     printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
-    ds.RunCommand("UPTIME", {"uptime"}, CommandOptions::DEFAULT);
+    printf("Uptime: ");
+    RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
+                   CommandOptions::WithTimeout(1).Always().Build());
     printf("Bugreport format version: %s\n", version_.c_str());
     printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
            PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
@@ -1093,7 +1095,6 @@
     DurationReporter duration_reporter("DUMPSTATE");
 
     dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
-    /* TODO: Remove duplicate uptime call when tools use it from header */
     RunCommand("UPTIME", {"uptime"});
     DumpBlockStatFiles();
     dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index 3264666..5b66b92 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -52,6 +52,6 @@
      * Unknown or unknowable versions are returned as 0.
      */
 
-    int getVersionCodeForPackage(in String packageName);
+    long getVersionCodeForPackage(in String packageName);
 
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0dbe786..939a209 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -543,9 +543,14 @@
 {
 }
 
+SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
+    : mStatus(NO_ERROR), mClient(client)
+{
+}
+
 void SurfaceComposerClient::onFirstRef() {
     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-    if (sf != 0) {
+    if (sf != 0 && mStatus == NO_INIT) {
         auto rootProducer = mParent.promote();
         sp<ISurfaceComposerClient> conn;
         conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index f6a2b8f..f5fb8ac 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -166,5 +166,28 @@
     return mClient;
 }
 
+void SurfaceControl::writeToParcel(Parcel* parcel)
+{
+    parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
+    parcel->writeStrongBinder(mHandle);
+    parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
+}
+
+sp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel)
+{
+    sp<IBinder> client = parcel->readStrongBinder();
+    sp<IBinder> handle = parcel->readStrongBinder();
+    if (client == nullptr || handle == nullptr)
+    {
+        ALOGE("Invalid parcel");
+        return nullptr;
+    }
+    sp<IBinder> gbp;
+    parcel->readNullableStrongBinder(&gbp);
+    return new SurfaceControl(new SurfaceComposerClient(
+                    interface_cast<ISurfaceComposerClient>(client)),
+            handle.get(), interface_cast<IGraphicBufferProducer>(gbp));
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 3f13946..55b96ac 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -52,6 +52,7 @@
     friend class Composer;
 public:
                 SurfaceComposerClient();
+                SurfaceComposerClient(const sp<ISurfaceComposerClient>& client);
                 SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent);
     virtual     ~SurfaceComposerClient();
 
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 384815d..1416d87 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -44,6 +44,9 @@
 class SurfaceControl : public RefBase
 {
 public:
+    static sp<SurfaceControl> readFromParcel(Parcel* parcel);
+    void writeToParcel(Parcel* parcel);
+
     static bool isValid(const sp<SurfaceControl>& surface) {
         return (surface != 0) && surface->isValid();
     }
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index abeb719..5eba913 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -68,6 +68,8 @@
         "-DLOG_TAG=\"buffer_transport_benchmark\"",
         "-DTRACE=0",
         "-O2",
+        "-Wall",
+        "-Werror",
     ],
     name: "buffer_transport_benchmark",
     tags: ["optional"],
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
index 658b496..d4d25b0 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
@@ -34,7 +34,6 @@
 static const String16 kBinderService = String16("bufferTransport");
 static const uint32_t kBufferWidth = 100;
 static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferLayerCount = 1;
 static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
 static const uint64_t kBufferUsage =
     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
@@ -75,10 +74,9 @@
  private:
   struct FrameListener : public ConsumerBase::FrameAvailableListener {
    public:
-    FrameListener(BufferTransportService* service,
+    FrameListener(BufferTransportService* /*service*/,
                   sp<BufferItemConsumer> buffer_item_consumer)
-        : service_(service),
-          buffer_item_consumer_(buffer_item_consumer) {}
+        : buffer_item_consumer_(buffer_item_consumer) {}
 
     void onFrameAvailable(const BufferItem& /*item*/) override {
       BufferItem buffer;
@@ -106,7 +104,6 @@
     }
 
    private:
-    BufferTransportService* service_ = nullptr;
     sp<BufferItemConsumer> buffer_item_consumer_;
   };
 
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
index c21deb0..5c837e7 100644
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -5,7 +5,6 @@
 #include <dvr/dvr_surface.h>
 #include <system/graphics.h>
 
-#include <base/logging.h>
 #include <gtest/gtest.h>
 
 namespace android {
@@ -22,7 +21,7 @@
 
   DvrBuffer* buffer2 = nullptr;
   int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2);
-  ASSERT_EQ(0, ret1);
+  ASSERT_EQ(0, ret2);
   ASSERT_NE(nullptr, buffer2);
 
   AHardwareBuffer* hardware_buffer1 = nullptr;
@@ -159,7 +158,7 @@
     ASSERT_EQ(0, e3);
     ASSERT_NE(nullptr, buffer);
     // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
 
     uint64_t* data = static_cast<uint64_t*>(buffer);
     constexpr size_t num_values = size / sizeof(uint64_t);
@@ -192,7 +191,7 @@
     ASSERT_EQ(0, e3);
     ASSERT_NE(nullptr, buffer);
     // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
 
     uint64_t* data = static_cast<uint64_t*>(buffer);
     constexpr size_t num_values = size / sizeof(uint64_t);
@@ -233,7 +232,7 @@
   ASSERT_EQ(0, e3);
   ASSERT_NE(nullptr, buffer);
   // Verify that the buffer pointer is at least 16 byte aligned.
-  ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
 
   uint64_t* data = static_cast<uint64_t*>(buffer);
   constexpr size_t num_values = size / sizeof(uint64_t);
@@ -241,7 +240,7 @@
   for (size_t i = 0; i < num_values; ++i) {
     zero |= data[i];
   }
-  ASSERT_EQ(0, zero);
+  ASSERT_EQ(0U, zero);
 
   int32_t fence = -1;
   int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 0d947b1..e8f4150 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -109,14 +109,14 @@
 }
 
 bool BufferLayer::isProtected() const {
-    const sp<GraphicBuffer>& buffer(getBE().mBuffer);
+    const sp<GraphicBuffer>& buffer(getBE().compositionInfo.mBuffer);
     return (buffer != 0) &&
             (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
 }
 
 bool BufferLayer::isVisible() const {
     return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
-            (getBE().mBuffer != NULL || getBE().mSidebandStream != NULL);
+            (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL);
 }
 
 bool BufferLayer::isFixedSize() const {
@@ -172,7 +172,7 @@
                          bool useIdentityTransform) const {
     ATRACE_CALL();
 
-    if (CC_UNLIKELY(getBE().mBuffer == 0)) {
+    if (CC_UNLIKELY(getBE().compositionInfo.mBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
         // SurfaceView because the WindowManager can't know when the client
@@ -250,8 +250,8 @@
         }
 
         // Set things up for texturing.
-        mTexture.setDimensions(getBE().mBuffer->getWidth(),
-                               getBE().mBuffer->getHeight());
+        mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(),
+                               getBE().compositionInfo.mBuffer->getHeight());
         mTexture.setFiltering(useFiltering);
         mTexture.setMatrix(textureMatrix);
 
@@ -387,8 +387,8 @@
         // mSidebandStreamChanged was true
         mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
         // replicated in LayerBE until FE/BE is ready to be synchronized
-        getBE().mSidebandStream = mSidebandStream;
-        if (getBE().mSidebandStream != NULL) {
+        getBE().compositionInfo.hwc.sidebandStream = mSidebandStream;
+        if (getBE().compositionInfo.hwc.sidebandStream != NULL) {
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
@@ -422,7 +422,7 @@
     // Capture the old state of the layer for comparisons later
     const State& s(getDrawingState());
     const bool oldOpacity = isOpaque(s);
-    sp<GraphicBuffer> oldBuffer = getBE().mBuffer;
+    sp<GraphicBuffer> oldBuffer = getBE().compositionInfo.mBuffer;
 
     if (!allTransactionsSignaled()) {
         mFlinger->signalLayerUpdate();
@@ -499,11 +499,11 @@
     }
 
     // update the active buffer
-    getBE().mBuffer =
-            mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().mBufferSlot);
+    getBE().compositionInfo.mBuffer =
+            mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
     // replicated in LayerBE until FE/BE is ready to be synchronized
-    mActiveBuffer = getBE().mBuffer;
-    if (getBE().mBuffer == NULL) {
+    mActiveBuffer = getBE().compositionInfo.mBuffer;
+    if (getBE().compositionInfo.mBuffer == NULL) {
         // this can only happen if the very first buffer was rejected.
         return outDirtyRegion;
     }
@@ -540,15 +540,15 @@
     }
 
     if (oldBuffer != NULL) {
-        uint32_t bufWidth = getBE().mBuffer->getWidth();
-        uint32_t bufHeight = getBE().mBuffer->getHeight();
+        uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
+        uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
         if (bufWidth != uint32_t(oldBuffer->width) ||
             bufHeight != uint32_t(oldBuffer->height)) {
             recomputeVisibleRegions = true;
         }
     }
 
-    mCurrentOpacity = getOpacityForFormat(getBE().mBuffer->format);
+    mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format);
     if (oldOpacity != isOpaque(s)) {
         recomputeVisibleRegions = true;
     }
@@ -611,13 +611,13 @@
     }
 
     // Sideband layers
-    if (getBE().mSidebandStream.get()) {
+    if (getBE().compositionInfo.hwc.sidebandStream.get()) {
         setCompositionType(hwcId, HWC2::Composition::Sideband);
         ALOGV("[%s] Requesting Sideband composition", mName.string());
-        error = hwcLayer->setSidebandStream(getBE().mSidebandStream->handle());
+        error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
         if (error != HWC2::Error::None) {
             ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
-                  getBE().mSidebandStream->handle(), to_string(error).c_str(),
+                  getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
                   static_cast<int32_t>(error));
         }
         return;
@@ -641,14 +641,14 @@
 
     uint32_t hwcSlot = 0;
     sp<GraphicBuffer> hwcBuffer;
-    hwcInfo.bufferCache.getHwcBuffer(getBE().mBufferSlot,
-                                     getBE().mBuffer, &hwcSlot, &hwcBuffer);
+    hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
+                                     getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
 
     auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
     error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
-              getBE().mBuffer->handle, to_string(error).c_str(),
+              getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
               static_cast<int32_t>(error));
     }
 }
@@ -656,7 +656,7 @@
 bool BufferLayer::isOpaque(const Layer::State& s) const {
     // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
     // layer's opaque flag.
-    if ((getBE().mSidebandStream == nullptr) && (getBE().mBuffer == nullptr)) {
+    if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) {
         return false;
     }
 
diff --git a/services/surfaceflinger/Effects/Daltonizer.cpp b/services/surfaceflinger/Effects/Daltonizer.cpp
index c953c68..01c9c0f 100644
--- a/services/surfaceflinger/Effects/Daltonizer.cpp
+++ b/services/surfaceflinger/Effects/Daltonizer.cpp
@@ -133,8 +133,6 @@
                         0.7, 0.7, 1.0, 0,
                           0,   0,   0, 1);
 
-    const mat4 identity;
-
     // And the magic happens here...
     // We construct the matrix that will perform the whole correction.
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2a4abcb..fa4d289 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -39,7 +39,6 @@
 #include <ui/PixelFormat.h>
 
 #include <gui/BufferItem.h>
-#include <gui/BufferQueue.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
 
@@ -63,9 +62,7 @@
 namespace android {
 
 LayerBE::LayerBE()
-      : mBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
-        mBuffer(nullptr),
-        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
+      : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
 }
 
 
@@ -257,9 +254,9 @@
     if (!mCurrentCrop.isEmpty()) {
         // if the buffer crop is defined, we use that
         crop = mCurrentCrop;
-    } else if (getBE().mBuffer != NULL) {
+    } else if (getBE().compositionInfo.mBuffer != NULL) {
         // otherwise we use the whole buffer
-        crop = getBE().mBuffer->getBounds();
+        crop = getBE().compositionInfo.mBuffer->getBounds();
     } else {
         // if we don't have a buffer yet, we use an empty/invalid crop
         crop.makeInvalid();
@@ -1002,9 +999,9 @@
     // to the old buffer. However in the state where we don't have an old buffer
     // there is no such concern but we may still be being used as a parent layer.
     const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) &&
-            (getBE().mBuffer != nullptr);
+            (getBE().compositionInfo.mBuffer != nullptr);
     if (!isFixedSize()) {
-        if (resizePending && getBE().mSidebandStream == NULL) {
+        if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) {
             flags |= eDontUpdateGeometryState;
         }
     }
@@ -1401,7 +1398,7 @@
     info.mMatrix[1][0] = ds.active.transform[1][0];
     info.mMatrix[1][1] = ds.active.transform[1][1];
     {
-        sp<const GraphicBuffer> buffer = getBE().mBuffer;
+        sp<const GraphicBuffer> buffer = getBE().compositionInfo.mBuffer;
         if (buffer != 0) {
             info.mActiveBufferWidth = buffer->getWidth();
             info.mActiveBufferHeight = buffer->getHeight();
@@ -1616,14 +1613,25 @@
     return mDrawingState.z;
 }
 
+bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    return state.zOrderRelativeOf != nullptr;
+}
+
 __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
-        LayerVector::StateSet stateSet) {
+        LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers) {
     LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
     const State& state = useDrawing ? mDrawingState : mCurrentState;
 
+    if (state.zOrderRelatives.size() == 0) {
+        *outSkipRelativeZUsers = true;
+        return children;
+    }
+
     LayerVector traverse;
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
         sp<Layer> strongRelative = weakRelative.promote();
@@ -1647,19 +1655,35 @@
  * Negatively signed relatives are before 'this' in Z-order.
  */
 void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {
-    LayerVector list = makeTraversalList(stateSet);
+    // In the case we have other layers who are using a relative Z to us, makeTraversalList will
+    // produce a new list for traversing, including our relatives, and not including our children
+    // who are relatives of another surface. In the case that there are no relative Z,
+    // makeTraversalList returns our children directly to avoid significant overhead.
+    // However in this case we need to take the responsibility for filtering children which
+    // are relatives of another surface here.
+    bool skipRelativeZUsers = false;
+    const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
 
     size_t i = 0;
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
+        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+            continue;
+        }
+
         if (relative->getZ() >= 0) {
             break;
         }
         relative->traverseInZOrder(stateSet, visitor);
     }
+
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
+
+        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+            continue;
+        }
         relative->traverseInZOrder(stateSet, visitor);
     }
 }
@@ -1669,11 +1693,18 @@
  */
 void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                     const LayerVector::Visitor& visitor) {
-    LayerVector list = makeTraversalList(stateSet);
+    // See traverseInZOrder for documentation.
+    bool skipRelativeZUsers = false;
+    LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
 
     int32_t i = 0;
     for (i = int32_t(list.size()) - 1; i >= 0; i--) {
         const auto& relative = list[i];
+
+        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+            continue;
+        }
+
         if (relative->getZ() < 0) {
             break;
         }
@@ -1682,6 +1713,11 @@
     visitor(this);
     for (; i >= 0; i--) {
         const auto& relative = list[i];
+
+        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+            continue;
+        }
+
         relative->traverseInReverseZOrder(stateSet, visitor);
     }
 }
@@ -1720,15 +1756,15 @@
         // for in the transform. We need to mirror this scaling in child surfaces
         // or we will break the contract where WM can treat child surfaces as
         // pixels in the parent surface.
-        if (p->isFixedSize() && p->getBE().mBuffer != nullptr) {
+        if (p->isFixedSize() && p->getBE().compositionInfo.mBuffer != nullptr) {
             int bufferWidth;
             int bufferHeight;
             if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
-                bufferWidth = p->getBE().mBuffer->getWidth();
-                bufferHeight = p->getBE().mBuffer->getHeight();
+                bufferWidth = p->getBE().compositionInfo.mBuffer->getWidth();
+                bufferHeight = p->getBE().compositionInfo.mBuffer->getHeight();
             } else {
-                bufferHeight = p->getBE().mBuffer->getWidth();
-                bufferWidth = p->getBE().mBuffer->getHeight();
+                bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth();
+                bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight();
             }
             float sx = p->getDrawingState().active.w / static_cast<float>(bufferWidth);
             float sy = p->getDrawingState().active.h / static_cast<float>(bufferHeight);
@@ -1828,7 +1864,7 @@
         layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
     }
 
-    auto buffer = getBE().mBuffer;
+    auto buffer = getBE().compositionInfo.mBuffer;
     if (buffer != nullptr) {
         LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer());
     }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8ac5094..cf7fc50 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -31,6 +31,7 @@
 
 #include <gui/ISurfaceComposerClient.h>
 #include <gui/LayerState.h>
+#include <gui/BufferQueue.h>
 
 #include <list>
 
@@ -66,15 +67,37 @@
 
 // ---------------------------------------------------------------------------
 
+struct CompositionInfo {
+    HWC2::Composition compositionType;
+    sp<GraphicBuffer> mBuffer = nullptr;
+    int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
+    struct {
+        HWComposer* hwc;
+        sp<Fence> fence;
+        HWC2::BlendMode blendMode;
+        Rect displayFrame;
+        float alpha;
+        FloatRect sourceCrop;
+        HWC2::Transform transform;
+        int z;
+        int type;
+        int appId;
+        Region visibleRegion;
+        Region surfaceDamage;
+        sp<NativeHandle> sidebandStream;
+        android_dataspace dataspace;
+        hwc_color_t color;
+    } hwc;
+    struct {
+        RenderEngine* renderEngine;
+        Mesh* mesh;
+    } renderEngine;
+};
+
 class LayerBE {
 public:
     LayerBE();
 
-    // main thread
-    int mBufferSlot;
-    sp<GraphicBuffer> mBuffer;
-    sp<NativeHandle> mSidebandStream;
-
     // The mesh used to draw the layer in GLES composition mode
     Mesh mMesh;
 
@@ -102,6 +125,8 @@
     // case we need to keep track. In non-mirror mode, a layer will have only one
     // HWCInfo. This map key is a display layerStack.
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+    CompositionInfo compositionInfo;
 };
 
 class Layer : public virtual RefBase {
@@ -571,7 +596,7 @@
 
     void setParent(const sp<Layer>& layer);
 
-    LayerVector makeTraversalList(LayerVector::StateSet stateSet);
+    LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
     void addZOrderRelative(const wp<Layer>& relative);
     void removeZOrderRelative(const wp<Layer>& relative);
 
@@ -645,6 +670,7 @@
 
 protected:
     // -----------------------------------------------------------------------
+    bool usingRelativeZ(LayerVector::StateSet stateSet);
 
     bool mPremultipliedAlpha;
     String8 mName;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 142892e..54695b5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -153,6 +153,15 @@
     return std::string(value) == "true";
 }
 
+SurfaceFlingerBE::SurfaceFlingerBE()
+      : mHwcServiceName(getHwcServiceName()),
+        mRenderEngine(nullptr),
+        mFrameBuckets(),
+        mTotalTime(0),
+        mLastSwapTime(0),
+        mComposerSequenceId(0) {
+}
+
 SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(),
         mTransactionFlags(0),
@@ -161,8 +170,6 @@
         mLayersRemoved(false),
         mLayersAdded(false),
         mRepaintEverything(0),
-        mHwcServiceName(getHwcServiceName()),
-        mRenderEngine(nullptr),
         mBootTime(systemTime()),
         mBuiltinDisplays(),
         mVisibleRegionsDirty(false),
@@ -184,13 +191,9 @@
         mHWVsyncAvailable(false),
         mHasColorMatrix(false),
         mHasPoweredOff(false),
-        mFrameBuckets(),
-        mTotalTime(0),
-        mLastSwapTime(0),
         mNumLayers(0),
         mVrFlingerRequestsDisplay(false),
-        mMainThreadId(std::this_thread::get_id()),
-        mComposerSequenceId(0)
+        mMainThreadId(std::this_thread::get_id())
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -225,7 +228,7 @@
     hasWideColorDisplay =
             getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
 
-    mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset);
+    mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
 
     // debugging stuff...
     char value[PROPERTY_VALUE_MAX];
@@ -588,11 +591,11 @@
     Mutex::Autolock _l(mStateLock);
 
     // start the EventThread
-    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
-            vsyncPhaseOffsetNs, true, "app");
+    sp<VSyncSource> vsyncSrc =
+            new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
     mEventThread = new EventThread(vsyncSrc, *this, false);
-    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
-            sfVsyncPhaseOffsetNs, true, "sf");
+    sp<VSyncSource> sfVsyncSrc =
+            new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
     mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
     mEventQueue.setEventThread(mSFEventThread);
 
@@ -607,14 +610,14 @@
     }
 
     // Get a RenderEngine for the given display / config (can't fail)
-    mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
+    getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
             hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
-    LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr, "couldn't create RenderEngine");
+    LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
             "Starting with vr flinger active is not currently supported.");
-    mHwc.reset(new HWComposer(mHwcServiceName));
-    mHwc->registerCallback(this, mComposerSequenceId);
+    getBE().mHwc.reset(new HWComposer(getBE().mHwcServiceName));
+    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
 
     if (useVrFlinger) {
         auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
@@ -631,8 +634,8 @@
             });
             postMessageAsync(message);
         };
-        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
-                mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
+        mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),
+                getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
                 vrFlingerRequestDisplayCallback);
         if (!mVrFlinger) {
             ALOGE("Failed to start vrflinger");
@@ -648,7 +651,7 @@
     // set initial conditions (e.g. unblank default device)
     initializeDisplays();
 
-    mRenderEngine->primeCache();
+    getBE().mRenderEngine->primeCache();
 
     // Inform native graphics APIs whether the present timestamp is supported:
     if (getHwComposer().hasCapability(
@@ -690,11 +693,11 @@
 }
 
 size_t SurfaceFlinger::getMaxTextureSize() const {
-    return mRenderEngine->getMaxTextureSize();
+    return getBE().mRenderEngine->getMaxTextureSize();
 }
 
 size_t SurfaceFlinger::getMaxViewportDims() const {
-    return mRenderEngine->getMaxViewportDims();
+    return getBE().mRenderEngine->getMaxViewportDims();
 }
 
 // ----------------------------------------------------------------------------
@@ -1042,7 +1045,7 @@
     }
 
     std::unique_ptr<HdrCapabilities> capabilities =
-            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
+            getBE().mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
     if (capabilities) {
         std::swap(*outCapabilities, *capabilities);
     } else {
@@ -1190,7 +1193,7 @@
         return;
     }
 
-    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+    const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
     const nsecs_t period = activeConfig->getVsyncPeriod();
 
     mPrimaryDispSync.reset();
@@ -1233,12 +1236,12 @@
         hwc2_display_t displayId, int64_t timestamp) {
     Mutex::Autolock lock(mStateLock);
     // Ignore any vsyncs from a previous hardware composer.
-    if (sequenceId != mComposerSequenceId) {
+    if (sequenceId != getBE().mComposerSequenceId) {
         return;
     }
 
     int32_t type;
-    if (!mHwc->onVsync(displayId, timestamp, &type)) {
+    if (!getBE().mHwc->onVsync(displayId, timestamp, &type)) {
         return;
     }
 
@@ -1259,8 +1262,8 @@
 }
 
 void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
-    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-    *compositorTiming = mCompositorTiming;
+    std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+    *compositorTiming = getBE().mCompositorTiming;
 }
 
 void SurfaceFlinger::createDefaultDisplayDevice() {
@@ -1274,7 +1277,7 @@
     sp<IGraphicBufferConsumer> consumer;
     BufferQueue::createBufferQueue(&producer, &consumer);
 
-    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
+    sp<FramebufferSurface> fbs = new FramebufferSurface(*getBE().mHwc, type, consumer);
 
     bool hasWideColorModes = false;
     std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
@@ -1326,20 +1329,20 @@
             std::this_thread::get_id() != mMainThreadId);
 
     if (primaryDisplay) {
-        mHwc->onHotplug(display, connection);
+        getBE().mHwc->onHotplug(display, connection);
         if (!mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY].get()) {
             createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
         }
         createDefaultDisplayDevice();
     } else {
-        if (sequenceId != mComposerSequenceId) {
+        if (sequenceId != getBE().mComposerSequenceId) {
             return;
         }
-        if (mHwc->isUsingVrComposer()) {
+        if (getBE().mHwc->isUsingVrComposer()) {
             ALOGE("External displays are not supported by the vr hardware composer.");
             return;
         }
-        mHwc->onHotplug(display, connection);
+        getBE().mHwc->onHotplug(display, connection);
         auto type = DisplayDevice::DISPLAY_EXTERNAL;
         if (connection == HWC2::Connection::Connected) {
             createBuiltinDisplayLocked(type);
@@ -1356,7 +1359,7 @@
 void SurfaceFlinger::onRefreshReceived(int sequenceId,
                                        hwc2_display_t /*display*/) {
     Mutex::Autolock lock(mStateLock);
-    if (sequenceId != mComposerSequenceId) {
+    if (sequenceId != getBE().mComposerSequenceId) {
         return;
     }
     repaintEverythingLocked();
@@ -1385,11 +1388,11 @@
     if (!mVrFlinger)
         return;
     bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
-    if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
+    if (vrFlingerRequestsDisplay == getBE().mHwc->isUsingVrComposer()) {
         return;
     }
 
-    if (vrFlingerRequestsDisplay && !mHwc->getComposer()->isRemote()) {
+    if (vrFlingerRequestsDisplay && !getBE().mHwc->getComposer()->isRemote()) {
         ALOGE("Vr flinger is only supported for remote hardware composer"
               " service connections. Ignoring request to transition to vr"
               " flinger.");
@@ -1407,13 +1410,12 @@
     }
 
     resetDisplayState();
-    mHwc.reset();  // Delete the current instance before creating the new one
-    mHwc.reset(new HWComposer(
-            vrFlingerRequestsDisplay ? "vr" : mHwcServiceName));
-    mHwc->registerCallback(this, ++mComposerSequenceId);
+    getBE().mHwc.reset(); // Delete the current instance before creating the new one
+    getBE().mHwc.reset(new HWComposer(vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName));
+    getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId);
 
-    LOG_ALWAYS_FATAL_IF(!mHwc->getComposer()->isRemote(),
-            "Switched to non-remote hardware composer");
+    LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(),
+                        "Switched to non-remote hardware composer");
 
     if (vrFlingerRequestsDisplay) {
         mVrFlinger->GrantDisplayOwnership();
@@ -1430,7 +1432,7 @@
     setPowerModeInternal(hw, currentDisplayPowerMode, /*stateLockHeld*/ true);
 
     // Reset the timing values to account for the period of the swapped in HWC
-    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+    const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
     const nsecs_t period = activeConfig->getVsyncPeriod();
     mAnimFrameTracker.setDisplayRefreshPeriod(period);
 
@@ -1508,13 +1510,13 @@
     doComposition();
     postComposition(refreshStartTime);
 
-    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
+    mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
 
     mHadClientComposition = false;
     for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
         const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
         mHadClientComposition = mHadClientComposition ||
-                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
+                getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
     }
 
     mLayersWithQueuedFrames.clear();
@@ -1558,9 +1560,11 @@
             continue;
         }
 
-        status_t result = displayDevice->prepareFrame(*mHwc);
-        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
-                " %d (%s)", displayId, result, strerror(-result));
+        status_t result = displayDevice->prepareFrame(*getBE().mHwc);
+        ALOGE_IF(result != NO_ERROR,
+                 "prepareFrame for display %zd failed:"
+                 " %d (%s)",
+                 displayId, result, strerror(-result));
     }
 }
 
@@ -1594,10 +1598,10 @@
         std::shared_ptr<FenceTime>& presentFenceTime) {
     // Update queue of past composite+present times and determine the
     // most recently known composite to present latency.
-    mCompositePresentTimes.push({compositeTime, presentFenceTime});
+    getBE().mCompositePresentTimes.push({compositeTime, presentFenceTime});
     nsecs_t compositeToPresentLatency = -1;
-    while (!mCompositePresentTimes.empty()) {
-        CompositePresentTime& cpt = mCompositePresentTimes.front();
+    while (!getBE().mCompositePresentTimes.empty()) {
+        SurfaceFlingerBE::CompositePresentTime& cpt = getBE().mCompositePresentTimes.front();
         // Cached values should have been updated before calling this method,
         // which helps avoid duplicate syscalls.
         nsecs_t displayTime = cpt.display->getCachedSignalTime();
@@ -1605,12 +1609,12 @@
             break;
         }
         compositeToPresentLatency = displayTime - cpt.composite;
-        mCompositePresentTimes.pop();
+        getBE().mCompositePresentTimes.pop();
     }
 
     // Don't let mCompositePresentTimes grow unbounded, just in case.
-    while (mCompositePresentTimes.size() > 16) {
-        mCompositePresentTimes.pop();
+    while (getBE().mCompositePresentTimes.size() > 16) {
+        getBE().mCompositePresentTimes.pop();
     }
 
     setCompositorTimingSnapped(
@@ -1642,10 +1646,10 @@
     nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
             idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
 
-    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-    mCompositorTiming.deadline = vsyncPhase - idealLatency;
-    mCompositorTiming.interval = vsyncInterval;
-    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
+    std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+    getBE().mCompositorTiming.deadline = vsyncPhase - idealLatency;
+    getBE().mCompositorTiming.interval = vsyncInterval;
+    getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
 void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
@@ -1662,20 +1666,20 @@
     // |mStateLock| not needed as we are on the main thread
     const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
-    mGlCompositionDoneTimeline.updateSignalTimes();
+    getBE().mGlCompositionDoneTimeline.updateSignalTimes();
     std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
-    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
+    if (getBE().mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
         glCompositionDoneFenceTime =
                 std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
-        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
+        getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
     } else {
         glCompositionDoneFenceTime = FenceTime::NO_FENCE;
     }
 
-    mDisplayTimeline.updateSignalTimes();
-    sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
+    getBE().mDisplayTimeline.updateSignalTimes();
+    sp<Fence> presentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
     auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
-    mDisplayTimeline.push(presentFenceTime);
+    getBE().mDisplayTimeline.push(presentFenceTime);
 
     nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
     nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
@@ -1687,8 +1691,8 @@
         vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
     CompositorTiming compositorTiming;
     {
-        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-        compositorTiming = mCompositorTiming;
+        std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+        compositorTiming = getBE().mCompositorTiming;
     }
 
     mDrawingState.traverseInZOrder([&](Layer* layer) {
@@ -1724,7 +1728,7 @@
             // The HWC doesn't support present fences, so use the refresh
             // timestamp instead.
             nsecs_t presentTime =
-                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
+                    getBE().mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
             mAnimFrameTracker.setActualPresentTime(presentTime);
         }
         mAnimFrameTracker.advanceFrame();
@@ -1738,16 +1742,16 @@
     if (mHasPoweredOff) {
         mHasPoweredOff = false;
     } else {
-        nsecs_t elapsedTime = currentTime - mLastSwapTime;
+        nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime;
         size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
-        if (numPeriods < NUM_BUCKETS - 1) {
-            mFrameBuckets[numPeriods] += elapsedTime;
+        if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) {
+            getBE().mFrameBuckets[numPeriods] += elapsedTime;
         } else {
-            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
+            getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] += elapsedTime;
         }
-        mTotalTime += elapsedTime;
+        getBE().mTotalTime += elapsedTime;
     }
-    mLastSwapTime = currentTime;
+    getBE().mLastSwapTime = currentTime;
 }
 
 void SurfaceFlinger::rebuildLayerStacks() {
@@ -1923,7 +1927,7 @@
                 for (size_t i = 0; i < currentLayers.size(); i++) {
                     const auto& layer = currentLayers[i];
                     if (!layer->hasHwcLayer(hwcId)) {
-                        if (!layer->createHwcLayer(mHwc.get(), hwcId)) {
+                        if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
                             layer->forceClientComposition(hwcId);
                             continue;
                         }
@@ -1950,7 +1954,7 @@
             continue;
         }
         if (colorMatrix != mPreviousColorMatrix) {
-            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
+            status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
             ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
                     "display %zd: %d", displayId, result);
         }
@@ -1988,7 +1992,7 @@
             continue;
         }
 
-        status_t result = displayDevice->prepareFrame(*mHwc);
+        status_t result = displayDevice->prepareFrame(*getBE().mHwc);
         ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
                 " %d (%s)", displayId, result, strerror(-result));
     }
@@ -2030,7 +2034,7 @@
         }
         const auto hwcId = displayDevice->getHwcDisplayId();
         if (hwcId >= 0) {
-            mHwc->presentAndGetReleaseFences(hwcId);
+            getBE().mHwc->presentAndGetReleaseFences(hwcId);
         }
         displayDevice->onSwapBuffersCompleted();
         displayDevice->makeCurrent();
@@ -2039,7 +2043,7 @@
             // by HWC only when the release fence from this frame (if any) is
             // signaled.  Always get the release fence from HWC first.
             auto hwcLayer = layer->getHwcLayer(hwcId);
-            sp<Fence> releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+            sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
 
             // If the layer was client composited in the previous frame, we
             // need to merge with the previous client target acquire fence.
@@ -2058,14 +2062,14 @@
         // displayDevice->getVisibleLayersSortedByZ.  The best we can do is to
         // supply them with the present fence.
         if (!displayDevice->getLayersNeedingFences().isEmpty()) {
-            sp<Fence> presentFence = mHwc->getPresentFence(hwcId);
+            sp<Fence> presentFence = getBE().mHwc->getPresentFence(hwcId);
             for (auto& layer : displayDevice->getLayersNeedingFences()) {
                 layer->onLayerDisplayed(presentFence);
             }
         }
 
         if (hwcId >= 0) {
-            mHwc->clearReleaseFences(hwcId);
+            getBE().mHwc->clearReleaseFences(hwcId);
         }
     }
 
@@ -2229,7 +2233,7 @@
                         if (state.surface != NULL) {
 
                             // Allow VR composer to use virtual displays.
-                            if (mUseHwcVirtualDisplays || mHwc->isUsingVrComposer()) {
+                            if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) {
                                 int width = 0;
                                 int status = state.surface->query(
                                         NATIVE_WINDOW_WIDTH, &width);
@@ -2248,14 +2252,14 @@
                                 auto format = static_cast<android_pixel_format_t>(
                                         intFormat);
 
-                                mHwc->allocateVirtualDisplay(width, height, &format,
+                                getBE().mHwc->allocateVirtualDisplay(width, height, &format,
                                         &hwcId);
                             }
 
                             // TODO: Plumb requested format back up to consumer
 
                             sp<VirtualDisplaySurface> vds =
-                                    new VirtualDisplaySurface(*mHwc,
+                                    new VirtualDisplaySurface(*getBE().mHwc,
                                             hwcId, state.surface, bqProducer,
                                             bqConsumer, state.displayName);
 
@@ -2269,7 +2273,7 @@
                                 state.surface.get());
 
                         hwcId = state.type;
-                        dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
+                        dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer);
                         producer = bqProducer;
                     }
 
@@ -2657,20 +2661,20 @@
     const auto hwcId = displayDevice->getHwcDisplayId();
 
     mat4 oldColorMatrix;
-    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
-            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
+    const bool applyColorMatrix = !getBE().mHwc->hasDeviceComposition(hwcId) &&
+            !getBE().mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
     if (applyColorMatrix) {
         mat4 colorMatrix = mColorMatrix * mDaltonizer();
         oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
     }
 
-    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
+    bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId);
     if (hasClientComposition) {
         ALOGV("hasClientComposition");
 
-        mRenderEngine->setWideColor(
+        getBE().mRenderEngine->setWideColor(
                 displayDevice->getWideColorSupport() && !mForceNativeColorMode);
-        mRenderEngine->setColorMode(mForceNativeColorMode ?
+        getBE().mRenderEngine->setColorMode(mForceNativeColorMode ?
                 HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode());
         if (!displayDevice->makeCurrent()) {
             ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
@@ -2685,14 +2689,14 @@
         }
 
         // Never touch the framebuffer if we don't have any framebuffer layers
-        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
+        const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
         if (hasDeviceComposition) {
             // when using overlays, we assume a fully transparent framebuffer
             // NOTE: we could reduce how much we need to clear, for instance
             // remove where there are opaque FB layers. however, on some
             // GPUs doing a "clean slate" clear might be more efficient.
             // We'll revisit later if needed.
-            mRenderEngine->clearWithColor(0, 0, 0, 0);
+            getBE().mRenderEngine->clearWithColor(0, 0, 0, 0);
         } else {
             // we start with the whole screen area and remove the scissor part
             // we're left with the letterbox region
@@ -2722,7 +2726,7 @@
 
                 // enable scissor for this frame
                 const uint32_t height = displayDevice->getHeight();
-                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
+                getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
                         scissor.getWidth(), scissor.getHeight());
             }
         }
@@ -2787,7 +2791,7 @@
     }
 
     // disable scissor at the end of the frame
-    mRenderEngine->disableScissor();
+    getBE().mRenderEngine->disableScissor();
     return true;
 }
 
@@ -3359,7 +3363,7 @@
     setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL,
                          /*stateLockHeld*/ false);
 
-    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+    const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
     const nsecs_t period = activeConfig->getVsyncPeriod();
     mAnimFrameTracker.setDisplayRefreshPeriod(period);
 
@@ -3612,7 +3616,7 @@
         index++;
     }
 
-    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+    const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
     const nsecs_t period = activeConfig->getVsyncPeriod();
     result.appendFormat("%" PRId64 "\n", period);
 
@@ -3675,24 +3679,24 @@
 void SurfaceFlinger::dumpStaticScreenStats(String8& result) const
 {
     result.appendFormat("Static screen stats:\n");
-    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
-        float bucketTimeSec = mFrameBuckets[b] / 1e9;
+    for (size_t b = 0; b < SurfaceFlingerBE::NUM_BUCKETS - 1; ++b) {
+        float bucketTimeSec = getBE().mFrameBuckets[b] / 1e9;
         float percent = 100.0f *
-                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
+                static_cast<float>(getBE().mFrameBuckets[b]) / getBE().mTotalTime;
         result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
                 b + 1, bucketTimeSec, percent);
     }
-    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
+    float bucketTimeSec = getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] / 1e9;
     float percent = 100.0f *
-            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
+            static_cast<float>(getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1]) / getBE().mTotalTime;
     result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
-            NUM_BUCKETS - 1, bucketTimeSec, percent);
+            SurfaceFlingerBE::NUM_BUCKETS - 1, bucketTimeSec, percent);
 }
 
 void SurfaceFlinger::recordBufferingStats(const char* layerName,
         std::vector<OccupancyTracker::Segment>&& history) {
-    Mutex::Autolock lock(mBufferingStatsMutex);
-    auto& stats = mBufferingStats[layerName];
+    Mutex::Autolock lock(getBE().mBufferingStatsMutex);
+    auto& stats = getBE().mBufferingStats[layerName];
     for (const auto& segment : history) {
         if (!segment.usedThirdBuffer) {
             stats.twoBufferTime += segment.totalTime;
@@ -3721,12 +3725,12 @@
     result.append("Buffering stats:\n");
     result.append("  [Layer name] <Active time> <Two buffer> "
             "<Double buffered> <Triple buffered>\n");
-    Mutex::Autolock lock(mBufferingStatsMutex);
+    Mutex::Autolock lock(getBE().mBufferingStatsMutex);
     typedef std::tuple<std::string, float, float, float> BufferTuple;
     std::map<float, BufferTuple, std::greater<float>> sorted;
-    for (const auto& statsPair : mBufferingStats) {
+    for (const auto& statsPair : getBE().mBufferingStats) {
         const char* name = statsPair.first.c_str();
-        const BufferingStats& stats = statsPair.second;
+        const SurfaceFlingerBE::BufferingStats& stats = statsPair.second;
         if (stats.numSegments == 0) {
             continue;
         }
@@ -3829,7 +3833,7 @@
     result.append(SyncFeatures::getInstance().toString());
     result.append("\n");
 
-    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+    const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
 
     colorizer.bold(result);
     result.append("DispSync configuration: ");
@@ -3881,7 +3885,7 @@
     HWComposer& hwc(getHwComposer());
     sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
-    mRenderEngine->dump(result);
+    getBE().mRenderEngine->dump(result);
 
     hw->undefinedRegion.dump(result, "undefinedRegion");
     result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 974de94..2477bdc 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -92,6 +92,7 @@
 class EventControlThread;
 class VSyncSource;
 class InjectVSyncSource;
+class SurfaceFlingerBE;
 
 typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction;
 
@@ -108,12 +109,97 @@
     eTransactionMask          = 0x07
 };
 
+class SurfaceFlingerBE
+{
+public:
+    SurfaceFlingerBE();
+
+    // The current hardware composer interface.
+    //
+    // The following thread safety rules apply when accessing mHwc, either
+    // directly or via getHwComposer():
+    //
+    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
+    //    only when switching into and out of vr. Recreating mHwc must only be
+    //    done on the main thread.
+    //
+    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
+    //    mStateLock.
+    //
+    // 3. When accessing mHwc on a thread other than the main thread, we always
+    //    need to acquire mStateLock. This is because the main thread could be
+    //    in the process of destroying the current mHwc instance.
+    //
+    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
+    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
+    // destroy it, so it's always safe to access mHwc from any thread without
+    // acquiring mStateLock.
+    std::unique_ptr<HWComposer> mHwc;
+
+    const std::string mHwcServiceName; // "default" for real use, something else for testing.
+
+    // constant members (no synchronization needed for access)
+    std::unique_ptr<RenderEngine> mRenderEngine;
+    EGLContext mEGLContext;
+    EGLDisplay mEGLDisplay;
+    
+    FenceTimeline mGlCompositionDoneTimeline;
+    FenceTimeline mDisplayTimeline;
+
+    // protected by mCompositorTimingLock;
+    mutable std::mutex mCompositorTimingLock;
+    CompositorTiming mCompositorTiming;
+    
+    // Only accessed from the main thread.
+    struct CompositePresentTime {
+        nsecs_t composite { -1 };
+        std::shared_ptr<FenceTime> display { FenceTime::NO_FENCE };
+    };
+    std::queue<CompositePresentTime> mCompositePresentTimes;
+
+    static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
+    nsecs_t mFrameBuckets[NUM_BUCKETS];
+    nsecs_t mTotalTime;
+    std::atomic<nsecs_t> mLastSwapTime;
+
+    // Double- vs. triple-buffering stats
+    struct BufferingStats {
+        BufferingStats()
+          : numSegments(0),
+            totalTime(0),
+            twoBufferTime(0),
+            doubleBufferedTime(0),
+            tripleBufferedTime(0) {}
+
+        size_t numSegments;
+        nsecs_t totalTime;
+
+        // "Two buffer" means that a third buffer was never used, whereas
+        // "double-buffered" means that on average the segment only used two
+        // buffers (though it may have used a third for some part of the
+        // segment)
+        nsecs_t twoBufferTime;
+        nsecs_t doubleBufferedTime;
+        nsecs_t tripleBufferedTime;
+    };
+    mutable Mutex mBufferingStatsMutex;
+    std::unordered_map<std::string, BufferingStats> mBufferingStats;
+
+    // The composer sequence id is a monotonically increasing integer that we
+    // use to differentiate callbacks from different hardware composer
+    // instances. Each hardware composer instance gets a different sequence id.
+    int32_t mComposerSequenceId;
+};
+
+
 class SurfaceFlinger : public BnSurfaceComposer,
                        public PriorityDumper,
                        private IBinder::DeathRecipient,
                        private HWC2::ComposerCallback
 {
 public:
+    SurfaceFlingerBE& getBE() { return mBE; }
+    const SurfaceFlingerBE& getBE() const { return mBE; }
 
     // This is the phase offset in nanoseconds of the software vsync event
     // relative to the vsync event reported by HWComposer.  The software vsync
@@ -219,7 +305,7 @@
     const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
 
     RenderEngine& getRenderEngine() const {
-        return *mRenderEngine;
+        return *getBE().mRenderEngine;
     }
 
     bool authenticateSurfaceTextureLocked(
@@ -509,7 +595,7 @@
      * H/W composer
      */
 
-    HWComposer& getHwComposer() const { return *mHwc; }
+    HWComposer& getHwComposer() const { return *getBE().mHwc; }
 
     /* ------------------------------------------------------------------------
      * Compositing
@@ -632,32 +718,7 @@
     // access must be protected by mInvalidateLock
     volatile int32_t mRepaintEverything;
 
-    // The current hardware composer interface.
-    //
-    // The following thread safety rules apply when accessing mHwc, either
-    // directly or via getHwComposer():
-    //
-    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
-    //    only when switching into and out of vr. Recreating mHwc must only be
-    //    done on the main thread.
-    //
-    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
-    //    mStateLock.
-    //
-    // 3. When accessing mHwc on a thread other than the main thread, we always
-    //    need to acquire mStateLock. This is because the main thread could be
-    //    in the process of destroying the current mHwc instance.
-    //
-    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
-    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
-    // destroy it, so it's always safe to access mHwc from any thread without
-    // acquiring mStateLock.
-    std::unique_ptr<HWComposer> mHwc;
-
-    const std::string mHwcServiceName; // "default" for real use, something else for testing.
-
     // constant members (no synchronization needed for access)
-    std::unique_ptr<RenderEngine> mRenderEngine;
     nsecs_t mBootTime;
     bool mGpuToCpuSupported;
     sp<EventThread> mEventThread;
@@ -676,8 +737,6 @@
     std::vector<sp<Layer>> mLayersWithQueuedFrames;
     sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
     bool mHadClientComposition = false;
-    FenceTimeline mGlCompositionDoneTimeline;
-    FenceTimeline mDisplayTimeline;
 
     // this may only be written from the main thread with mStateLock held
     // it may be read from other threads with mStateLock held
@@ -716,17 +775,6 @@
     bool mPrimaryHWVsyncEnabled;
     bool mHWVsyncAvailable;
 
-    // protected by mCompositorTimingLock;
-    mutable std::mutex mCompositorTimingLock;
-    CompositorTiming mCompositorTiming;
-
-    // Only accessed from the main thread.
-    struct CompositePresentTime {
-        nsecs_t composite { -1 };
-        std::shared_ptr<FenceTime> display { FenceTime::NO_FENCE };
-    };
-    std::queue<CompositePresentTime> mCompositePresentTimes;
-
     std::atomic<bool> mRefreshPending{false};
 
     /* ------------------------------------------------------------------------
@@ -743,35 +791,9 @@
 
     // Static screen stats
     bool mHasPoweredOff;
-    static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
-    nsecs_t mFrameBuckets[NUM_BUCKETS];
-    nsecs_t mTotalTime;
-    std::atomic<nsecs_t> mLastSwapTime;
 
     size_t mNumLayers;
 
-    // Double- vs. triple-buffering stats
-    struct BufferingStats {
-        BufferingStats()
-          : numSegments(0),
-            totalTime(0),
-            twoBufferTime(0),
-            doubleBufferedTime(0),
-            tripleBufferedTime(0) {}
-
-        size_t numSegments;
-        nsecs_t totalTime;
-
-        // "Two buffer" means that a third buffer was never used, whereas
-        // "double-buffered" means that on average the segment only used two
-        // buffers (though it may have used a third for some part of the
-        // segment)
-        nsecs_t twoBufferTime;
-        nsecs_t doubleBufferedTime;
-        nsecs_t tripleBufferedTime;
-    };
-    mutable Mutex mBufferingStatsMutex;
-    std::unordered_map<std::string, BufferingStats> mBufferingStats;
 
     // Verify that transaction is being called by an approved process:
     // either AID_GRAPHICS or AID_SYSTEM.
@@ -781,13 +803,11 @@
     std::atomic<bool> mVrFlingerRequestsDisplay;
     static bool useVrFlinger;
     std::thread::id mMainThreadId;
-    // The composer sequence id is a monotonically increasing integer that we
-    // use to differentiate callbacks from different hardware composer
-    // instances. Each hardware composer instance gets a different sequence id.
-    int32_t mComposerSequenceId;
 
     float mSaturation = 1.0f;
     bool mForceNativeColorMode = false;
+
+    SurfaceFlingerBE mBE;
 };
 }; // namespace android
 
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
index d97ffa3..d949d48 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
@@ -581,7 +581,7 @@
 }
 
 void FakeComposerClient::onSurfaceFlingerStart() {
-    mSurfaceComposer == nullptr;
+    mSurfaceComposer = nullptr;
     do {
         mSurfaceComposer = new android::SurfaceComposerClient;
         android::status_t initResult = mSurfaceComposer->initCheck();
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 7f4c58a..8a97ea4 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -165,7 +165,7 @@
     sp<ComposerClient> client = new ComposerClient(*mMockComposer);
     mMockComposer->setClient(client.get());
     mFakeService = new FakeComposerService(client);
-    mFakeService->registerAsService("mock");
+    (void)mFakeService->registerAsService("mock");
 
     android::hardware::ProcessState::self()->startThreadPool();
     android::ProcessState::self()->startThreadPool();
@@ -323,7 +323,7 @@
     sp<ComposerClient> client = new ComposerClient(*sFakeComposer);
     sFakeComposer->setClient(client.get());
     sp<IComposer> fakeService = new FakeComposerService(client);
-    fakeService->registerAsService("mock");
+    (void)fakeService->registerAsService("mock");
 
     android::hardware::ProcessState::self()->startThreadPool();
     android::ProcessState::self()->startThreadPool();