Merge "Added SKIP_SCREENSHOT flag for layers"
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6d1f399..8d2a7d9 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -861,9 +861,8 @@
         mStatus = BAD_INDEX;
         return *this;
     }
-    if ((mask & layer_state_t::eLayerOpaque) ||
-            (mask & layer_state_t::eLayerHidden) ||
-            (mask & layer_state_t::eLayerSecure)) {
+    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
+        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot)) {
         s->what |= layer_state_t::eFlagsChanged;
     }
     s->flags &= ~mask;
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 3afbabf..ec0a8d1 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -36,6 +36,7 @@
     enum { // (keep in sync with SurfaceControl.java)
         eHidden = 0x00000004,
         eDestroyBackbuffer = 0x00000020,
+        eSkipScreenshot = 0x00000040,
         eSecure = 0x00000080,
         eNonPremultiplied = 0x00000100,
         eOpaque = 0x00000400,
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index a763d1d..7a9bb12 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -76,9 +76,10 @@
  */
 struct layer_state_t {
     enum {
-        eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java
-        eLayerOpaque = 0x02, // SURFACE_OPAQUE
-        eLayerSecure = 0x80, // SECURE
+        eLayerHidden = 0x01,         // SURFACE_HIDDEN in SurfaceControl.java
+        eLayerOpaque = 0x02,         // SURFACE_OPAQUE
+        eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT
+        eLayerSecure = 0x80,         // SECURE
     };
 
     enum {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 09ec819..b19e453 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -89,6 +89,8 @@
     if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
     if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
     if (args.flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
+    if (args.flags & ISurfaceComposerClient::eSkipScreenshot)
+        layerFlags |= layer_state_t::eLayerSkipScreenshot;
 
     mCurrentState.active_legacy.w = args.w;
     mCurrentState.active_legacy.h = args.h;
@@ -2658,6 +2660,16 @@
     }
 }
 
+bool Layer::getPrimaryDisplayOnly() const {
+    const State& s(mDrawingState);
+    if (s.flags & layer_state_t::eLayerSkipScreenshot) {
+        return true;
+    }
+
+    sp<Layer> parent = mDrawingParent.promote();
+    return parent == nullptr ? false : parent->getPrimaryDisplayOnly();
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5dad4a9..88ece50 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -695,8 +695,7 @@
 
     InputWindowInfo::Type getWindowType() const { return mWindowType; }
 
-    void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; }
-    bool getPrimaryDisplayOnly() const { return mPrimaryDisplayOnly; }
+    bool getPrimaryDisplayOnly() const;
 
     void updateMirrorInfo();
 
@@ -963,8 +962,6 @@
     const std::string mName;
     const std::string mTransactionName{"TX - " + mName};
 
-    bool mPrimaryDisplayOnly = false;
-
     // These are only accessed by the main thread or the tracing thread.
     State mDrawingState;
     // Store a copy of the pending state so that the drawing thread can access the
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bca27e3..6a0f24a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3887,23 +3887,6 @@
 
     std::string uniqueName = getUniqueLayerName(name.string());
 
-    bool primaryDisplayOnly = false;
-
-    // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java
-    // TODO b/64227542
-    if (metadata.has(METADATA_WINDOW_TYPE)) {
-        int32_t windowType = metadata.getInt32(METADATA_WINDOW_TYPE, 0);
-        if (windowType == 441731) {
-            using U = std::underlying_type_t<InputWindowInfo::Type>;
-            // TODO(b/129481165): This static assert can be safely removed once conversion warnings
-            // are re-enabled.
-            static_assert(std::is_same_v<U, int32_t>);
-            metadata.setInt32(METADATA_WINDOW_TYPE,
-                              static_cast<U>(InputWindowInfo::Type::NAVIGATION_BAR_PANEL));
-            primaryDisplayOnly = true;
-        }
-    }
-
     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceBufferQueue:
             result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
@@ -3944,10 +3927,6 @@
         return result;
     }
 
-    if (primaryDisplayOnly) {
-        layer->setPrimaryDisplayOnly();
-    }
-
     bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
     result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                             addToCurrentState, outTransformHint);
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 962a0cf..3ab2ad1 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -572,6 +572,97 @@
     mCapture->expectBorder(Rect(128, 128, 160, 160), Color::BLACK);
 }
 
+TEST_F(ScreenCaptureTest, CaptureDisplayPrimaryDisplayOnly) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
+
+    const Color layerColor = Color::RED;
+    const Rect bounds = Rect(10, 10, 40, 40);
+
+    Transaction()
+            .show(layer)
+            .hide(mFGSurfaceControl)
+            .setLayerStack(layer, 0)
+            .setLayer(layer, INT32_MAX)
+            .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
+            .setCrop_legacy(layer, bounds)
+            .apply();
+
+    DisplayCaptureArgs captureArgs;
+    captureArgs.displayToken = mDisplay;
+
+    {
+        ScreenCapture::captureDisplay(&mCapture, captureArgs);
+        mCapture->expectColor(bounds, layerColor);
+        mCapture->expectBorder(bounds, {63, 63, 195, 255});
+    }
+
+    Transaction()
+            .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
+                      layer_state_t::eLayerSkipScreenshot)
+            .apply();
+
+    {
+        // Can't screenshot test layer since it now has flag
+        // eLayerSkipScreenshot
+        ScreenCapture::captureDisplay(&mCapture, captureArgs);
+        mCapture->expectColor(bounds, {63, 63, 195, 255});
+        mCapture->expectBorder(bounds, {63, 63, 195, 255});
+    }
+}
+
+TEST_F(ScreenCaptureTest, CaptureDisplayChildPrimaryDisplayOnly) {
+    sp<SurfaceControl> layer;
+    sp<SurfaceControl> childLayer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
+    ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("test layer", 0, 0,
+                                                     ISurfaceComposerClient::eFXSurfaceEffect,
+                                                     layer.get()));
+
+    const Color layerColor = Color::RED;
+    const Color childColor = Color::BLUE;
+    const Rect bounds = Rect(10, 10, 40, 40);
+    const Rect childBounds = Rect(20, 20, 30, 30);
+
+    Transaction()
+            .show(layer)
+            .show(childLayer)
+            .hide(mFGSurfaceControl)
+            .setLayerStack(layer, 0)
+            .setLayer(layer, INT32_MAX)
+            .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
+            .setColor(childLayer, {childColor.r / 255, childColor.g / 255, childColor.b / 255})
+            .setCrop_legacy(layer, bounds)
+            .setCrop_legacy(childLayer, childBounds)
+            .apply();
+
+    DisplayCaptureArgs captureArgs;
+    captureArgs.displayToken = mDisplay;
+
+    {
+        ScreenCapture::captureDisplay(&mCapture, captureArgs);
+        mCapture->expectColor(childBounds, childColor);
+        mCapture->expectBorder(childBounds, layerColor);
+        mCapture->expectBorder(bounds, {63, 63, 195, 255});
+    }
+
+    Transaction()
+            .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
+                      layer_state_t::eLayerSkipScreenshot)
+            .apply();
+
+    {
+        // Can't screenshot child layer since the parent has the flag
+        // eLayerSkipScreenshot
+        ScreenCapture::captureDisplay(&mCapture, captureArgs);
+        mCapture->expectColor(childBounds, {63, 63, 195, 255});
+        mCapture->expectBorder(childBounds, {63, 63, 195, 255});
+        mCapture->expectBorder(bounds, {63, 63, 195, 255});
+    }
+}
+
 TEST_F(ScreenCaptureTest, CaptureLayerWithUid) {
     uid_t fakeUid = 12345;