SurfaceFlinger: Add parent-less relative layering.

This is a temporary functionality for the intermediate state where not
all child-surface like things in WM land are ported to use Child
Surfaces. In particular, we have ported SurfaceView to use child
surfaces and relative Z ordering. However the TV frameworks provide a
View framework component which overlays views over the SurfaceView but
below the main application window. Since we have not ported View
framework surfaces to use child layers, there is nothing the WM or
View Framework can do about this situation. Luckily the WM API's to
have requested this are @hide but we have the one media framework
component using it. In order to solve this issue we provide a method
to set Z ordering relative to another window without inheriting
its coordinate space as a child window would. This way the WM can
recognize these TYPE_APPLICATION_MEDIA_OVERLAY windows and Z-order
them at -1 with respect to the parents (and the SurfaceView can be at
-2).

Test: Included in transaction tests. Also manual test of bug repro steps with accomp frameworks/base CL
Bug: 36693738
Change-Id: I921852d3d34f67f79ec745b9703f9e679867e7a1
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c211c7b..b10d437 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1719,10 +1719,55 @@
     mCurrentState.sequence++;
     mCurrentState.z = z;
     mCurrentState.modified = true;
+
+    // Discard all relative layering.
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+        if (strongRelative != nullptr) {
+            strongRelative->removeZOrderRelative(this);
+        }
+        mCurrentState.zOrderRelativeOf = nullptr;
+    }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
+void Layer::removeZOrderRelative(const wp<Layer>& relative) {
+    mCurrentState.zOrderRelatives.remove(relative);
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
+}
+
+void Layer::addZOrderRelative(const wp<Layer>& relative) {
+    mCurrentState.zOrderRelatives.add(relative);
+    mCurrentState.modified = true;
+    mCurrentState.sequence++;
+    setTransactionFlags(eTransactionNeeded);
+}
+
+bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t z) {
+    sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
+    if (handle == nullptr) {
+        return false;
+    }
+    sp<Layer> relative = handle->owner.promote();
+    if (relative == nullptr) {
+        return false;
+    }
+
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
+    mCurrentState.z = z;
+
+    mCurrentState.zOrderRelativeOf = relative;
+    relative->addZOrderRelative(this);
+
+    setTransactionFlags(eTransactionNeeded);
+
+    return true;
+}
+
 bool Layer::setSize(uint32_t w, uint32_t h) {
     if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
         return false;
@@ -2506,40 +2551,70 @@
     return mDrawingState.z;
 }
 
+LayerVector Layer::makeTraversalList() {
+    if (mDrawingState.zOrderRelatives.size() == 0) {
+        return mDrawingChildren;
+    }
+    LayerVector traverse;
+
+    for (const wp<Layer>& weakRelative : mDrawingState.zOrderRelatives) {
+        sp<Layer> strongRelative = weakRelative.promote();
+        if (strongRelative != nullptr) {
+            traverse.add(strongRelative);
+        } else {
+            // We need to erase from current state instead of drawing
+            // state so we don't overwrite when copying
+            // the current state to the drawing state.
+            mCurrentState.zOrderRelatives.remove(weakRelative);
+        }
+    }
+
+    for (const sp<Layer>& child : mDrawingChildren) {
+        traverse.add(child);
+    }
+
+    return traverse;
+}
+
 /**
- * Negatively signed children are before 'this' in Z-order.
+ * Negatively signed relatives are before 'this' in Z-order.
  */
 void Layer::traverseInZOrder(const std::function<void(Layer*)>& exec) {
+    LayerVector list = makeTraversalList();
+
     size_t i = 0;
-    for (; i < mDrawingChildren.size(); i++) {
-        const auto& child = mDrawingChildren[i];
-        if (child->getZ() >= 0)
+    for (; i < list.size(); i++) {
+        const auto& relative = list[i];
+        if (relative->getZ() >= 0) {
             break;
-        child->traverseInZOrder(exec);
+        }
+        relative->traverseInZOrder(exec);
     }
     exec(this);
-    for (; i < mDrawingChildren.size(); i++) {
-        const auto& child = mDrawingChildren[i];
-        child->traverseInZOrder(exec);
+    for (; i < list.size(); i++) {
+        const auto& relative = list[i];
+        relative->traverseInZOrder(exec);
     }
 }
 
 /**
- * Positively signed children are before 'this' in reverse Z-order.
+ * Positively signed relatives are before 'this' in reverse Z-order.
  */
 void Layer::traverseInReverseZOrder(const std::function<void(Layer*)>& exec) {
+    LayerVector list = makeTraversalList();
+
     int32_t i = 0;
-    for (i = mDrawingChildren.size()-1; i>=0; i--) {
-        const auto& child = mDrawingChildren[i];
-        if (child->getZ() < 0) {
+    for (i = list.size()-1; i>=0; i--) {
+        const auto& relative = list[i];
+        if (relative->getZ() < 0) {
             break;
         }
-        child->traverseInReverseZOrder(exec);
+        relative->traverseInReverseZOrder(exec);
     }
     exec(this);
     for (; i>=0; i--) {
-        const auto& child = mDrawingChildren[i];
-        child->traverseInReverseZOrder(exec);
+        const auto& relative = list[i];
+        relative->traverseInReverseZOrder(exec);
     }
 }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e21be8b..a5224ec 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -151,6 +151,12 @@
 
         uint32_t appId;
         uint32_t type;
+
+        // If non-null, a Surface this Surface's Z-order is interpreted relative to.
+        wp<Layer> zOrderRelativeOf;
+
+        // A list of surfaces whose Z-order is interpreted relative to ours.
+        SortedVector<wp<Layer>> zOrderRelatives;
     };
 
     // -----------------------------------------------------------------------
@@ -173,6 +179,8 @@
     bool setFinalCrop(const Rect& crop, bool immediate);
 
     bool setLayer(int32_t z);
+    bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
+
     bool setSize(uint32_t w, uint32_t h);
 #ifdef USE_HWC2
     bool setAlpha(float alpha);
@@ -549,6 +557,10 @@
 
     void setParent(const sp<Layer>& layer);
 
+    LayerVector makeTraversalList();
+    void addZOrderRelative(const wp<Layer>& relative);
+    void removeZOrderRelative(const wp<Layer>& relative);
+
     // -----------------------------------------------------------------------
 
     class SyncPoint
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index 7ba6ad3..90e6395 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -42,13 +42,21 @@
 
 void LayerVector::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
     for (size_t i = 0; i < size(); i++) {
-        (*this)[i]->traverseInZOrder(consume);
+        const auto& layer = (*this)[i];
+        if (layer->getDrawingState().zOrderRelativeOf != nullptr) {
+            continue;
+        }
+        layer->traverseInZOrder(consume);
     }
 }
 
 void LayerVector::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
     for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
-        (*this)[i]->traverseInReverseZOrder(consume);
+        const auto& layer = (*this)[i];
+        if (layer->getDrawingState().zOrderRelativeOf != nullptr) {
+            continue;
+        }
+        layer->traverseInReverseZOrder(consume);
      }
 }
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 26baaae..dcb24e4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2820,6 +2820,11 @@
                 }
             }
         }
+        if (what & layer_state_t::eRelativeLayerChanged) {
+            if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) {
+                flags |= eTransactionNeeded|eTraversalNeeded;
+            }
+        }
         if (what & layer_state_t::eSizeChanged) {
             if (layer->setSize(s.w, s.h)) {
                 flags |= eTraversalNeeded;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index a46ba48..441fc7e 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -662,6 +662,49 @@
     }
 }
 
+TEST_F(LayerUpdateTest, LayerSetRelativeLayerWorks) {
+    sp<ScreenCapture> sc;
+    {
+        SCOPED_TRACE("before adding relative surface");
+        ScreenCapture::captureScreen(&sc);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
+    }
+
+    auto relativeSurfaceControl = mComposerClient->createSurface(
+            String8("Test Surface"), 64, 64, PIXEL_FORMAT_RGBA_8888, 0);
+    fillSurfaceRGBA8(relativeSurfaceControl, 255, 177, 177);
+    waitForPostedBuffers();
+
+    // Now we stack the surface above the foreground surface and make sure it is visible.
+    SurfaceComposerClient::openGlobalTransaction();
+    relativeSurfaceControl->setPosition(64, 64);
+    relativeSurfaceControl->show();
+    relativeSurfaceControl->setRelativeLayer(mFGSurfaceControl->getHandle(), 1);
+    SurfaceComposerClient::closeGlobalTransaction(true);
+
+
+    {
+        SCOPED_TRACE("after adding relative surface");
+        ScreenCapture::captureScreen(&sc);
+        // our relative surface should be visible now.
+        sc->checkPixel(75, 75, 255, 177, 177);
+    }
+
+    // A call to setLayer will override a call to setRelativeLayer
+    SurfaceComposerClient::openGlobalTransaction();
+    relativeSurfaceControl->setLayer(0);
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    {
+        SCOPED_TRACE("after set layer");
+        ScreenCapture::captureScreen(&sc);
+        // now the FG surface should be visible again.
+        sc->expectFGColor(75, 75);
+    }
+}
+
 class ChildLayerTest : public LayerUpdateTest {
 protected:
     void SetUp() override {