Merge "Support external display rendering in vr flinger" into pi-dev
diff --git a/cmds/dumpstate/DumpstateInternal.cpp b/cmds/dumpstate/DumpstateInternal.cpp
index 83e30a2..819d5b9 100644
--- a/cmds/dumpstate/DumpstateInternal.cpp
+++ b/cmds/dumpstate/DumpstateInternal.cpp
@@ -98,13 +98,25 @@
     capheader.version = _LINUX_CAPABILITY_VERSION_3;
     capheader.pid = 0;
 
-    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
-    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
-    capdata[0].inheritable = 0;
-    capdata[1].inheritable = 0;
+    if (capget(&capheader, &capdata[0]) != 0) {
+        MYLOGE("capget failed: %s\n", strerror(errno));
+        return false;
+    }
 
-    if (capset(&capheader, &capdata[0]) < 0) {
-        MYLOGE("capset failed: %s\n", strerror(errno));
+    const uint32_t cap_syslog_mask = CAP_TO_MASK(CAP_SYSLOG);
+    const uint32_t cap_syslog_index = CAP_TO_INDEX(CAP_SYSLOG);
+    bool has_cap_syslog = (capdata[cap_syslog_index].effective & cap_syslog_mask) != 0;
+
+    memset(&capdata, 0, sizeof(capdata));
+    if (has_cap_syslog) {
+        // Only attempt to keep CAP_SYSLOG if it was present to begin with.
+        capdata[cap_syslog_index].permitted |= cap_syslog_mask;
+        capdata[cap_syslog_index].effective |= cap_syslog_mask;
+    }
+
+    if (capset(&capheader, &capdata[0]) != 0) {
+        MYLOGE("capset({%#x, %#x}) failed: %s\n", capdata[0].effective,
+               capdata[1].effective, strerror(errno));
         return false;
     }
 
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 371533c..10f252f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -176,6 +176,11 @@
     std::unique_ptr<std::vector<DumpData>> dump_data(new std::vector<DumpData>());
     std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir);
 
+    if (dump_dir == nullptr) {
+        MYLOGW("Unable to open directory %s: %s\n", dir_path.c_str(), strerror(errno));
+        return dump_data.release();
+    }
+
     struct dirent* entry = nullptr;
     while ((entry = readdir(dump_dir.get()))) {
         if (entry->d_type != DT_REG) {
@@ -191,13 +196,13 @@
         android::base::unique_fd fd(
             TEMP_FAILURE_RETRY(open(abs_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
         if (fd == -1) {
-            MYLOGW("Unable to open dump file: %s %s\n", abs_path.c_str(), strerror(errno));
+            MYLOGW("Unable to open dump file %s: %s\n", abs_path.c_str(), strerror(errno));
             break;
         }
 
         struct stat st = {};
         if (fstat(fd, &st) == -1) {
-            MYLOGW("Unable to stat dump file: %s %s\n", abs_path.c_str(), strerror(errno));
+            MYLOGW("Unable to stat dump file %s: %s\n", abs_path.c_str(), strerror(errno));
             continue;
         }
 
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index b9e0139..39fddc5 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -280,7 +280,8 @@
             "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
             "the library and successfully fetched the passthrough implementation.");
     mImplementationsTable.setDescription(
-            "All available passthrough implementations (all -impl.so files)");
+            "All available passthrough implementations (all -impl.so files).\n"
+            "These may return subclasses through their respective HIDL_FETCH_I* functions.");
 }
 
 static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Version& version) {
@@ -394,11 +395,11 @@
                 interfaces[interfaceName].instances.insert(instanceName);
             }
             if (!manifest.add(vintf::ManifestHal{
-                    .format = vintf::HalFormat::HIDL,
-                    .name = fqName.package(),
-                    .versions = {version},
-                    .transportArch = {transport, arch},
-                    .interfaces = interfaces})) {
+                    vintf::HalFormat::HIDL,
+                    std::string{fqName.package()},
+                    {version},
+                    {transport, arch},
+                    std::move(interfaces)})) {
                 err() << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
             }
         }
diff --git a/headers/media_plugin/media/openmax/OMX_IndexExt.h b/headers/media_plugin/media/openmax/OMX_IndexExt.h
index 5a029d0..c2bf97e 100644
--- a/headers/media_plugin/media/openmax/OMX_IndexExt.h
+++ b/headers/media_plugin/media/openmax/OMX_IndexExt.h
@@ -85,6 +85,7 @@
     OMX_IndexParamMaxFrameDurationForBitrateControl,/**< reference: OMX_PARAM_U32TYPE */
     OMX_IndexParamVideoVp9,                         /**< reference: OMX_VIDEO_PARAM_VP9TYPE */
     OMX_IndexParamVideoAndroidVp9Encoder,           /**< reference: OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE */
+    OMX_IndexParamVideoAndroidImageGrid,            /**< reference: OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE */
     OMX_IndexExtVideoEndUnused,
 
     /* Image & Video common configurations */
diff --git a/headers/media_plugin/media/openmax/OMX_Video.h b/headers/media_plugin/media/openmax/OMX_Video.h
index dc5cdab..9fd2fd2 100644
--- a/headers/media_plugin/media/openmax/OMX_Video.h
+++ b/headers/media_plugin/media/openmax/OMX_Video.h
@@ -89,6 +89,7 @@
     OMX_VIDEO_CodingVP9,        /**< Google VP9 */
     OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */
     OMX_VIDEO_CodingDolbyVision,/**< Dolby Vision */
+    OMX_VIDEO_CodingImageHEIC,  /**< HEIF image encoded with HEVC */
     OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/headers/media_plugin/media/openmax/OMX_VideoExt.h b/headers/media_plugin/media/openmax/OMX_VideoExt.h
index c102564..4b90765 100644
--- a/headers/media_plugin/media/openmax/OMX_VideoExt.h
+++ b/headers/media_plugin/media/openmax/OMX_VideoExt.h
@@ -213,6 +213,7 @@
     OMX_VIDEO_HEVCProfileUnknown      = 0x0,
     OMX_VIDEO_HEVCProfileMain         = 0x1,
     OMX_VIDEO_HEVCProfileMain10       = 0x2,
+    OMX_VIDEO_HEVCProfileMainStill    = 0x4,
     // Main10 profile with HDR SEI support.
     OMX_VIDEO_HEVCProfileMain10HDR10  = 0x1000,
     OMX_VIDEO_HEVCProfileMax          = 0x7FFFFFFF
@@ -421,6 +422,48 @@
     OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
 } OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
 
+/**
+ * Android specific param for specifying image grid layout information for image encoding
+ * use cases, corresponding to index OMX_IndexParamVideoAndroidImageGrid.
+ *
+ * OMX_VIDEO_CodingImageHEIC encoders must handle this param type. When this param is set
+ * on the component with bEnabled set to true, nGrid* indicates the desired grid config
+ * by the client. The component can use this as a heuristic, but is free to choose any
+ * suitable grid configs, and the client shall always get the actual from the component
+ * after the param is set. Encoder will receive each input image in full, and shall encode
+ * it into tiles in row-major, top-row first, left-to-right order, and send each encoded
+ * tile in a separate output buffer. All output buffers for the same input buffer shall
+ * carry the same timestamp as the input buffer. If the input buffer is marked EOS,
+ * the EOS should only appear on the last output buffer for that input buffer.
+ *
+ * OMX_VIDEO_CodingHEVC encoders might also receive this param when it's used for image
+ * encoding, although in this case the param only serves as a hint. The encoder will
+ * receive the input image tiles in row-major, top-row first, left-to-right order.
+ * The grid config can be used for quality control, or optimizations.
+ *
+ * If this param is not set, the component shall assume that grid option is disabled.
+ *
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to (output port for encoders)
+ *  bEnabled                   : Whether grid is enabled. If true, nGrid* specifies the grid
+ *                               config; otherwise nGrid* shall be ignored.
+ *  nGridWidth                 : Width of each tile.
+ *  nGridHeight                : Height of each tile.
+ *  nGridRows                  : Number of rows in the grid.
+ *  nGridCols                  : Number of cols in the grid.
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnabled;
+    OMX_U32 nGridWidth;
+    OMX_U32 nGridHeight;
+    OMX_U32 nGridRows;
+    OMX_U32 nGridCols;
+} OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index a1a0928..2768ad8 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -122,6 +122,7 @@
     ],
 
     shared_libs: [
+        "android.hardware.graphics.common@1.1",
         "libsync",
         "libbinder",
         "libbufferhubqueue",  // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
@@ -154,6 +155,7 @@
         "libui",
         "android.hidl.token@1.0-utils",
         "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.common@1.1",
     ],
 
     export_header_lib_headers: [
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 5de84ec..0244bb5 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -132,12 +132,13 @@
 
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
                                    sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
-                                   float frameScale) {
+                                   float frameScale, bool childrenOnly) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(layerHandleBinder);
         data.write(sourceCrop);
         data.writeFloat(frameScale);
+        data.writeBool(childrenOnly);
         status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
 
         if (err != NO_ERROR) {
@@ -349,7 +350,7 @@
     }
 
     virtual status_t getDisplayColorModes(const sp<IBinder>& display,
-            Vector<android_color_mode_t>* outColorModes) {
+            Vector<ColorMode>* outColorModes) {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -372,34 +373,34 @@
             outColorModes->clear();
             outColorModes->resize(numModes);
             for (size_t i = 0; i < numModes; ++i) {
-                outColorModes->replaceAt(static_cast<android_color_mode_t>(reply.readInt32()), i);
+                outColorModes->replaceAt(static_cast<ColorMode>(reply.readInt32()), i);
             }
         }
         return result;
     }
 
-    virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) {
+    virtual ColorMode getActiveColorMode(const sp<IBinder>& display) {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
             ALOGE("getActiveColorMode failed to writeInterfaceToken: %d", result);
-            return static_cast<android_color_mode_t>(result);
+            return static_cast<ColorMode>(result);
         }
         result = data.writeStrongBinder(display);
         if (result != NO_ERROR) {
             ALOGE("getActiveColorMode failed to writeStrongBinder: %d", result);
-            return static_cast<android_color_mode_t>(result);
+            return static_cast<ColorMode>(result);
         }
         result = remote()->transact(BnSurfaceComposer::GET_ACTIVE_COLOR_MODE, data, &reply);
         if (result != NO_ERROR) {
             ALOGE("getActiveColorMode failed to transact: %d", result);
-            return static_cast<android_color_mode_t>(result);
+            return static_cast<ColorMode>(result);
         }
-        return static_cast<android_color_mode_t>(reply.readInt32());
+        return static_cast<ColorMode>(reply.readInt32());
     }
 
     virtual status_t setActiveColorMode(const sp<IBinder>& display,
-            android_color_mode_t colorMode) {
+            ColorMode colorMode) {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -411,7 +412,7 @@
             ALOGE("setActiveColorMode failed to writeStrongBinder: %d", result);
             return result;
         }
-        result = data.writeInt32(colorMode);
+        result = data.writeInt32(static_cast<int32_t>(colorMode));
         if (result != NO_ERROR) {
             ALOGE("setActiveColorMode failed to writeInt32: %d", result);
             return result;
@@ -629,8 +630,10 @@
             Rect sourceCrop(Rect::EMPTY_RECT);
             data.read(sourceCrop);
             float frameScale = data.readFloat();
+            bool childrenOnly = data.readBool();
 
-            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale);
+            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale,
+                                         childrenOnly);
             reply->writeInt32(res);
             if (res == NO_ERROR) {
                 reply->write(*outBuffer);
@@ -736,7 +739,7 @@
         }
         case GET_DISPLAY_COLOR_MODES: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            Vector<android_color_mode_t> colorModes;
+            Vector<ColorMode> colorModes;
             sp<IBinder> display = nullptr;
             status_t result = data.readStrongBinder(&display);
             if (result != NO_ERROR) {
@@ -748,7 +751,7 @@
             if (result == NO_ERROR) {
                 reply->writeUint32(static_cast<uint32_t>(colorModes.size()));
                 for (size_t i = 0; i < colorModes.size(); ++i) {
-                    reply->writeInt32(colorModes[i]);
+                    reply->writeInt32(static_cast<int32_t>(colorModes[i]));
                 }
             }
             return NO_ERROR;
@@ -761,7 +764,7 @@
                 ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
                 return result;
             }
-            android_color_mode_t colorMode = getActiveColorMode(display);
+            ColorMode colorMode = getActiveColorMode(display);
             result = reply->writeInt32(static_cast<int32_t>(colorMode));
             return result;
         }
@@ -780,7 +783,7 @@
                 return result;
             }
             result = setActiveColorMode(display,
-                    static_cast<android_color_mode_t>(colorModeInt));
+                    static_cast<ColorMode>(colorModeInt));
             result = reply->writeInt32(result);
             return result;
         }
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index e08d6b0..2e1c24b 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -326,7 +326,7 @@
 
     sp<IBinder> display(
         composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
-    Vector<android_color_mode_t> colorModes;
+    Vector<ColorMode> colorModes;
     status_t err =
         composerService()->getDisplayColorModes(display, &colorModes);
 
@@ -338,11 +338,11 @@
                 &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
 
     *supported = false;
-    for (android_color_mode_t colorMode : colorModes) {
+    for (ColorMode colorMode : colorModes) {
         switch (colorMode) {
-            case HAL_COLOR_MODE_DISPLAY_P3:
-            case HAL_COLOR_MODE_ADOBE_RGB:
-            case HAL_COLOR_MODE_DCI_P3:
+            case ColorMode::DISPLAY_P3:
+            case ColorMode::ADOBE_RGB:
+            case ColorMode::DCI_P3:
                 if (wideColorBoardConfig) {
                     *supported = true;
                 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 92a24ad..61ed976 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -698,16 +698,16 @@
 }
 
 status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display,
-        Vector<android_color_mode_t>* outColorModes) {
+        Vector<ColorMode>* outColorModes) {
     return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes);
 }
 
-android_color_mode_t SurfaceComposerClient::getActiveColorMode(const sp<IBinder>& display) {
+ColorMode SurfaceComposerClient::getActiveColorMode(const sp<IBinder>& display) {
     return ComposerService::getComposerService()->getActiveColorMode(display);
 }
 
 status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display,
-        android_color_mode_t colorMode) {
+        ColorMode colorMode) {
     return ComposerService::getComposerService()->setActiveColorMode(display, colorMode);
 }
 
@@ -751,7 +751,17 @@
                                          float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
-    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale);
+    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
+                                    false /* childrenOnly */);
+    return ret;
+}
+
+status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+                                              float frameScale, sp<GraphicBuffer>* outBuffer) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
+                                    true /* childrenOnly */);
     return ret;
 }
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e26e332..afe9358 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -30,6 +30,7 @@
 #include <ui/FrameStats.h>
 #include <ui/PixelFormat.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/GraphicsTypes.h>
 
 #include <vector>
 
@@ -160,10 +161,10 @@
     virtual status_t setActiveConfig(const sp<IBinder>& display, int id) = 0;
 
     virtual status_t getDisplayColorModes(const sp<IBinder>& display,
-            Vector<android_color_mode_t>* outColorModes) = 0;
-    virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) = 0;
+            Vector<ColorMode>* outColorModes) = 0;
+    virtual ColorMode getActiveColorMode(const sp<IBinder>& display) = 0;
     virtual status_t setActiveColorMode(const sp<IBinder>& display,
-            android_color_mode_t colorMode) = 0;
+            ColorMode colorMode) = 0;
 
     /* Capture the specified screen. requires READ_FRAME_BUFFER permission
      * This function will fail if there is a secure window on screen.
@@ -173,9 +174,12 @@
                                    int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
                                    Rotation rotation = eRotateNone) = 0;
 
+    /**
+     * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
+     */
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
                                    sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
-                                   float frameScale = 1.0) = 0;
+                                   float frameScale = 1.0, bool childrenOnly = false) = 0;
 
     /* Clears the frame statistics for animations.
      *
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 3fe6635..162fe6e 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -29,6 +29,7 @@
 #include <utils/threads.h>
 
 #include <ui/FrameStats.h>
+#include <ui/GraphicsTypes.h>
 #include <ui/PixelFormat.h>
 
 #include <gui/CpuConsumer.h>
@@ -88,13 +89,13 @@
 
     // Gets the list of supported color modes for the given display
     static status_t getDisplayColorModes(const sp<IBinder>& display,
-            Vector<android_color_mode_t>* outColorModes);
+            Vector<ColorMode>* outColorModes);
 
     // Gets the active color mode for the given display
-    static android_color_mode_t getActiveColorMode(const sp<IBinder>& display);
+    static ColorMode getActiveColorMode(const sp<IBinder>& display);
 
     // Sets the active color mode for the given display
-    static status_t setActiveColorMode(const sp<IBinder>& display, android_color_mode_t colorMode);
+    static status_t setActiveColorMode(const sp<IBinder>& display, ColorMode colorMode);
 
     /* Triggers screen on/off or low power mode and waits for it to complete */
     static void setDisplayPowerMode(const sp<IBinder>& display, int mode);
@@ -297,8 +298,10 @@
                             uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
                             bool useIdentityTransform, uint32_t rotation,
                             sp<GraphicBuffer>* outBuffer);
-    static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float fameScale,
+    static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
                                   sp<GraphicBuffer>* outBuffer);
+    static status_t captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+                                       float frameScale, sp<GraphicBuffer>* outBuffer);
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 8060b6e..66d5595 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -577,15 +577,15 @@
         return NO_ERROR;
     }
     status_t getDisplayColorModes(const sp<IBinder>& /*display*/,
-            Vector<android_color_mode_t>* /*outColorModes*/) override {
+            Vector<ColorMode>* /*outColorModes*/) override {
         return NO_ERROR;
     }
-    android_color_mode_t getActiveColorMode(const sp<IBinder>& /*display*/)
+    ColorMode getActiveColorMode(const sp<IBinder>& /*display*/)
             override {
-        return HAL_COLOR_MODE_NATIVE;
+        return ColorMode::NATIVE;
     }
     status_t setActiveColorMode(const sp<IBinder>& /*display*/,
-            android_color_mode_t /*colorMode*/) override { return NO_ERROR; }
+        ColorMode /*colorMode*/) override { return NO_ERROR; }
     status_t captureScreen(const sp<IBinder>& /*display*/,
             sp<GraphicBuffer>* /*outBuffer*/,
             Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
@@ -593,8 +593,8 @@
             bool /*useIdentityTransform*/,
             Rotation /*rotation*/) override { return NO_ERROR; }
     virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
-                                   sp<GraphicBuffer>* /*outBuffer*/,
-                                   const Rect& /*sourceCrop*/, float /*frameScale*/) override {
+                                   sp<GraphicBuffer>* /*outBuffer*/, const Rect& /*sourceCrop*/,
+                                   float /*frameScale*/, bool /*childrenOnly*/) override {
         return NO_ERROR;
     }
     status_t clearAnimationFrameStats() override { return NO_ERROR; }
diff --git a/libs/ui/DebugUtils.cpp b/libs/ui/DebugUtils.cpp
index 17ebf80..d7e191d 100644
--- a/libs/ui/DebugUtils.cpp
+++ b/libs/ui/DebugUtils.cpp
@@ -22,6 +22,7 @@
 #include <string>
 
 using android::base::StringPrintf;
+using android::ColorMode;
 
 std::string decodeStandard(android_dataspace dataspace) {
     const uint32_t dataspaceSelect = (dataspace & HAL_DATASPACE_STANDARD_MASK);
@@ -197,37 +198,37 @@
                                        decodeRange(dataspace).c_str());
 }
 
-std::string decodeColorMode(android_color_mode colorMode) {
+std::string decodeColorMode(ColorMode colorMode) {
     switch (colorMode) {
-        case HAL_COLOR_MODE_NATIVE:
-            return std::string("HAL_COLOR_MODE_NATIVE");
+        case ColorMode::NATIVE:
+            return std::string("ColorMode::NATIVE");
 
-        case HAL_COLOR_MODE_STANDARD_BT601_625:
-            return std::string("HAL_COLOR_MODE_BT601_625");
+        case ColorMode::STANDARD_BT601_625:
+            return std::string("ColorMode::BT601_625");
 
-        case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
-            return std::string("HAL_COLOR_MODE_BT601_625_UNADJUSTED");
+        case ColorMode::STANDARD_BT601_625_UNADJUSTED:
+            return std::string("ColorMode::BT601_625_UNADJUSTED");
 
-        case HAL_COLOR_MODE_STANDARD_BT601_525:
-            return std::string("HAL_COLOR_MODE_BT601_525");
+        case ColorMode::STANDARD_BT601_525:
+            return std::string("ColorMode::BT601_525");
 
-        case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
-            return std::string("HAL_COLOR_MODE_BT601_525_UNADJUSTED");
+        case ColorMode::STANDARD_BT601_525_UNADJUSTED:
+            return std::string("ColorMode::BT601_525_UNADJUSTED");
 
-        case HAL_COLOR_MODE_STANDARD_BT709:
-            return std::string("HAL_COLOR_MODE_BT709");
+        case ColorMode::STANDARD_BT709:
+            return std::string("ColorMode::BT709");
 
-        case HAL_COLOR_MODE_DCI_P3:
-            return std::string("HAL_COLOR_MODE_DCI_P3");
+        case ColorMode::DCI_P3:
+            return std::string("ColorMode::DCI_P3");
 
-        case HAL_COLOR_MODE_SRGB:
-            return std::string("HAL_COLOR_MODE_SRGB");
+        case ColorMode::SRGB:
+            return std::string("ColorMode::SRGB");
 
-        case HAL_COLOR_MODE_ADOBE_RGB:
-            return std::string("HAL_COLOR_MODE_ADOBE_RGB");
+        case ColorMode::ADOBE_RGB:
+            return std::string("ColorMode::ADOBE_RGB");
 
-        case HAL_COLOR_MODE_DISPLAY_P3:
-            return std::string("HAL_COLOR_MODE_DISPLAY_P3");
+        case ColorMode::DISPLAY_P3:
+            return std::string("ColorMode::DISPLAY_P3");
     }
 
     return android::base::StringPrintf("Unknown color mode %d", colorMode);
diff --git a/libs/ui/include/ui/DebugUtils.h b/libs/ui/include/ui/DebugUtils.h
index dad9446..3370107 100644
--- a/libs/ui/include/ui/DebugUtils.h
+++ b/libs/ui/include/ui/DebugUtils.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <system/graphics.h>
+#include <ui/GraphicsTypes.h>
 #include <ui/PixelFormat.h>
 
 #include <string>
@@ -29,6 +29,6 @@
 std::string decodeTransfer(android_dataspace dataspace);
 std::string decodeRange(android_dataspace dataspace);
 std::string dataspaceDetails(android_dataspace dataspace);
-std::string decodeColorMode(android_color_mode colormode);
+std::string decodeColorMode(android::ColorMode colormode);
 std::string decodePixelFormat(android::PixelFormat format);
 std::string to_string(const android::Rect& rect);
diff --git a/libs/ui/include/ui/GraphicsTypes.h b/libs/ui/include/ui/GraphicsTypes.h
new file mode 100644
index 0000000..fa9a812
--- /dev/null
+++ b/libs/ui/include/ui/GraphicsTypes.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/graphics/common/1.1/types.h>
+#include <system/graphics.h>
+
+namespace android {
+
+using android::hardware::graphics::common::V1_0::ColorMode;
+
+}  // namespace android
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index 0ee77f4..32d40e8 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -594,9 +594,10 @@
 
   if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
     auto status = AcceptConnection(message);
-    if (!status)
-      return status;
-    return ReenableEpollEvent(socket_fd_.Borrow());
+    auto reenable_status = ReenableEpollEvent(socket_fd_.Borrow());
+    if (!reenable_status)
+      return reenable_status;
+    return status;
   }
 
   BorrowedHandle channel_fd{event.data.fd};
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 0c0fedc..ba28eb5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -87,6 +87,7 @@
         "BufferLayerConsumer.cpp",
         "Client.cpp",
         "ColorLayer.cpp",
+        "ContainerLayer.cpp",
         "DisplayDevice.cpp",
         "DisplayHardware/ComposerHal.cpp",
         "DisplayHardware/FramebufferSurface.cpp",
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 4022b31..0cde398 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -13,16 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#pragma once
 
-#ifndef ANDROID_COLOR_LAYER_H
-#define ANDROID_COLOR_LAYER_H
-
-#include <stdint.h>
 #include <sys/types.h>
 
-#include "Layer.h"
+#include <cstdint>
 
-// ---------------------------------------------------------------------------
+#include "Layer.h"
 
 namespace android {
 
@@ -36,36 +33,8 @@
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
                         bool useIdentityTransform) const;
     bool isVisible() const override;
-    virtual bool isOpaque(const Layer::State&) const { return false; }
-    virtual bool isFixedSize() const { return true; }
 
-    void notifyAvailableFrames() override {}
-    PixelFormat getPixelFormat() const override { return PIXEL_FORMAT_NONE; }
-    uint32_t getEffectiveScalingMode() const override { return 0; }
-    void releasePendingBuffer(nsecs_t) override {}
-    Region latchBuffer(bool&, nsecs_t) override { return Region(); }
-    void useSurfaceDamage() override {}
-    void useEmptyDamage() override {}
-    bool isBufferLatched() const override { return false; }
-    bool onPreComposition(nsecs_t) override { return true; }
-    void abandon() override {}
     void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
-    void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {}
-    bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; }
-    bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/,
-                           const std::shared_ptr<FenceTime>& /*presentFence*/,
-                           const CompositorTiming& /*compositorTiming*/) override {
-        return false;
-    }
-    void setTransformHint(uint32_t /*orientation*/) const override {}
-    std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override {
-        return {};
-    }
-    bool getTransformToDisplayInverse() const override { return false; }
 };
 
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_COLOR_LAYER_H
+} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
new file mode 100644
index 0000000..f259d93
--- /dev/null
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "ContainerLayer"
+
+#include "ContainerLayer.h"
+
+namespace android {
+
+ContainerLayer::ContainerLayer(SurfaceFlinger* flinger, const sp<Client>& client,
+                               const String8& name, uint32_t w, uint32_t h, uint32_t flags)
+      : Layer(flinger, client, name, w, h, flags) {
+    mDrawingState = mCurrentState;
+}
+
+void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) const {}
+
+bool ContainerLayer::isVisible() const {
+    return !isHiddenByPolicy();
+}
+
+void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&) {}
+
+} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
new file mode 100644
index 0000000..543f60a
--- /dev/null
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <sys/types.h>
+
+#include <cstdint>
+
+#include "Layer.h"
+
+namespace android {
+
+class ContainerLayer : public Layer {
+public:
+    ContainerLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
+                   uint32_t w, uint32_t h, uint32_t flags);
+    virtual ~ContainerLayer() = default;
+
+    const char* getTypeId() const override { return "ContainerLayer"; }
+    void onDraw(const RenderArea& renderArea, const Region& clip,
+                bool useIdentityTransform) const override;
+    bool isVisible() const override;
+
+    void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index d40666e..92d5e21 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -99,7 +99,7 @@
     mNativeWindow = surface = new Surface(producer, false);
     ANativeWindow* const window = mNativeWindow.get();
 
-    mActiveColorMode = HAL_COLOR_MODE_NATIVE;
+    mActiveColorMode = ColorMode::NATIVE;
     mDisplayHasWideColor = supportWideColor;
     mDisplayHasHdr = supportHdr;
 
@@ -292,11 +292,11 @@
 }
 
 // ----------------------------------------------------------------------------
-void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
+void DisplayDevice::setActiveColorMode(ColorMode mode) {
     mActiveColorMode = mode;
 }
 
-android_color_mode_t DisplayDevice::getActiveColorMode() const {
+ColorMode DisplayDevice::getActiveColorMode() const {
     return mActiveColorMode;
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index d5ed15f..737971f 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -31,6 +31,7 @@
 
 #include <gui/ISurfaceComposer.h>
 #include <hardware/hwcomposer_defs.h>
+#include <ui/GraphicsTypes.h>
 #include "RenderArea.h"
 #include "RenderEngine/Surface.h"
 
@@ -155,8 +156,8 @@
     void setPowerMode(int mode);
     bool isDisplayOn() const;
 
-    android_color_mode_t getActiveColorMode() const;
-    void setActiveColorMode(android_color_mode_t mode);
+    ColorMode getActiveColorMode() const;
+    void setActiveColorMode(ColorMode mode);
     void setCompositionDataSpace(android_dataspace dataspace);
 
     /* ------------------------------------------------------------------------
@@ -230,7 +231,7 @@
     // Current active config
     int mActiveConfig;
     // current active color mode
-    android_color_mode_t mActiveColorMode;
+    ColorMode mActiveColorMode;
 
     // Need to know if display is wide-color capable or not.
     // Initialized by SurfaceFlinger when the DisplayDevice is created.
@@ -279,7 +280,7 @@
     bool needsFiltering() const override { return mDevice->needsFiltering(); }
     Rect getSourceCrop() const override { return mSourceCrop; }
     bool getWideColorSupport() const override { return mDevice->getWideColorSupport(); }
-    android_color_mode_t getActiveColorMode() const override {
+    ColorMode getActiveColorMode() const override {
         return mDevice->getActiveColorMode();
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index f14c2fe..b7bf964 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -362,9 +362,9 @@
     return Error::None;
 }
 
-Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
+Error Display::getColorModes(std::vector<android::ColorMode>* outModes) const
 {
-    std::vector<Hwc2::ColorMode> modes;
+    std::vector<android::ColorMode> modes;
     auto intError = mComposer.getColorModes(mId, &modes);
     uint32_t numModes = modes.size();
     auto error = static_cast<Error>(intError);
@@ -374,7 +374,7 @@
 
     outModes->resize(numModes);
     for (size_t i = 0; i < numModes; i++) {
-        (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
+        (*outModes)[i] = modes[i];
     }
     return Error::None;
 }
@@ -537,10 +537,9 @@
     return static_cast<Error>(intError);
 }
 
-Error Display::setColorMode(android_color_mode_t mode)
+Error Display::setColorMode(android::ColorMode mode)
 {
-    auto intError = mComposer.setColorMode(
-            mId, static_cast<Hwc2::ColorMode>(mode));
+    auto intError = mComposer.setColorMode(mId, mode);
     return static_cast<Error>(intError);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index e74f00d..0fc37ec 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -25,6 +25,7 @@
 
 #include <gui/HdrMetadata.h>
 #include <math/mat4.h>
+#include <ui/GraphicsTypes.h>
 #include <ui/HdrCapabilities.h>
 
 #include <utils/Log.h>
@@ -209,7 +210,7 @@
     [[clang::warn_unused_result]] Error getChangedCompositionTypes(
             std::unordered_map<Layer*, Composition>* outTypes);
     [[clang::warn_unused_result]] Error getColorModes(
-            std::vector<android_color_mode_t>* outModes) const;
+            std::vector<android::ColorMode>* outModes) const;
 
     // Doesn't call into the HWC2 device, so no errors are possible
     std::vector<std::shared_ptr<const Config>> getConfigs() const;
@@ -233,7 +234,7 @@
             uint32_t slot, const android::sp<android::GraphicBuffer>& target,
             const android::sp<android::Fence>& acquireFence,
             android_dataspace_t dataspace);
-    [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
+    [[clang::warn_unused_result]] Error setColorMode(android::ColorMode mode);
     [[clang::warn_unused_result]] Error setColorTransform(
             const android::mat4& matrix, android_color_transform_t hint);
     [[clang::warn_unused_result]] Error setOutputBuffer(
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2cafd8e..6d5917d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -311,8 +311,8 @@
     return config;
 }
 
-std::vector<android_color_mode_t> HWComposer::getColorModes(int32_t displayId) const {
-    std::vector<android_color_mode_t> modes;
+std::vector<ColorMode> HWComposer::getColorModes(int32_t displayId) const {
+    std::vector<ColorMode> modes;
 
     if (!isValidDisplay(displayId)) {
         ALOGE("getColorModes: Attempted to access invalid display %d",
@@ -324,13 +324,13 @@
     if (error != HWC2::Error::None) {
         ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
-        return std::vector<android_color_mode_t>();
+        return std::vector<ColorMode>();
     }
 
     return modes;
 }
 
-status_t HWComposer::setActiveColorMode(int32_t displayId, android_color_mode_t mode) {
+status_t HWComposer::setActiveColorMode(int32_t displayId, ColorMode mode) {
     if (!isValidDisplay(displayId)) {
         ALOGE("setActiveColorMode: Display %d is not valid", displayId);
         return BAD_INDEX;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index b75dc6a..c442b2f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 
 #include <ui/Fence.h>
+#include <ui/GraphicsTypes.h>
 
 #include <utils/BitSet.h>
 #include <utils/Condition.h>
@@ -158,9 +159,9 @@
     std::shared_ptr<const HWC2::Display::Config>
             getActiveConfig(int32_t displayId) const;
 
-    std::vector<android_color_mode_t> getColorModes(int32_t displayId) const;
+    std::vector<ColorMode> getColorModes(int32_t displayId) const;
 
-    status_t setActiveColorMode(int32_t displayId, android_color_mode_t mode);
+    status_t setActiveColorMode(int32_t displayId, ColorMode mode);
 
     bool isUsingVrComposer() const;
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 78dd40b..44e60ed 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1594,6 +1594,12 @@
     return true;
 }
 
+void Layer::reparentChildrenForDrawing(const sp<Layer>& newParent) {
+    for (const sp<Layer>& child : mDrawingChildren) {
+        child->mDrawingParent = newParent;
+    }
+}
+
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
     if (newParentHandle == nullptr) {
         return false;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3671a2b..996d686 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_LAYER_H
 #define ANDROID_LAYER_H
 
-#include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/RefBase.h>
@@ -35,6 +34,7 @@
 #include <gui/BufferQueue.h>
 
 #include <list>
+#include <cstdint>
 
 #include "Client.h"
 #include "FrameTracker.h"
@@ -287,14 +287,15 @@
     bool setOverrideScalingMode(int32_t overrideScalingMode);
     void setInfo(uint32_t type, uint32_t appId);
     bool reparentChildren(const sp<IBinder>& layer);
+    void reparentChildrenForDrawing(const sp<Layer>& layer);
     bool reparent(const sp<IBinder>& newParentHandle);
     bool detachChildren();
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
     // one empty rect.
-    virtual void useSurfaceDamage() = 0;
-    virtual void useEmptyDamage() = 0;
+    virtual void useSurfaceDamage() {}
+    virtual void useEmptyDamage() {}
 
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
@@ -320,7 +321,7 @@
      * pixel format includes an alpha channel) and the "opaque" flag set
      * on the layer.  It does not examine the current plane alpha value.
      */
-    virtual bool isOpaque(const Layer::State& s) const = 0;
+    virtual bool isOpaque(const Layer::State&) const { return false; }
 
     /*
      * isSecure - true if this surface is secure, that is if it prevents
@@ -344,7 +345,8 @@
     /*
      * isFixedSize - true if content has a fixed size
      */
-    virtual bool isFixedSize() const = 0;
+    virtual bool isFixedSize() const { return true; }
+
 
     bool isPendingRemoval() const { return mPendingRemoval; }
 
@@ -359,7 +361,7 @@
                         bool useIdentityTransform) const = 0;
 
 public:
-    virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0;
+    virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
 
     void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z);
     void forceClientComposition(int32_t hwcId);
@@ -379,27 +381,30 @@
      */
     virtual void onLayerDisplayed(const sp<Fence>& releaseFence);
 
-    virtual void abandon() = 0;
+    virtual void abandon() {}
 
-    virtual bool shouldPresentNow(const DispSync& dispSync) const = 0;
-    virtual void setTransformHint(uint32_t orientation) const = 0;
+    virtual bool shouldPresentNow(const DispSync& /*dispSync*/) const { return false; }
+    virtual void setTransformHint(uint32_t /*orientation*/) const { }
 
     /*
      * called before composition.
      * returns true if the layer has pending updates.
      */
-    virtual bool onPreComposition(nsecs_t refreshStartTime) = 0;
+    virtual bool onPreComposition(nsecs_t /*refreshStartTime*/) { return true; }
 
     /*
      * called after composition.
      * returns true if the layer latched a new buffer this frame.
      */
-    virtual bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
-                                   const std::shared_ptr<FenceTime>& presentFence,
-                                   const CompositorTiming& compositorTiming) = 0;
+    virtual bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/,
+                                   const std::shared_ptr<FenceTime>& /*presentFence*/,
+                                   const CompositorTiming& /*compositorTiming*/) {
+        return false;
+    }
 
     // If a buffer was replaced this frame, release the former buffer
-    virtual void releasePendingBuffer(nsecs_t dequeueReadyTime) = 0;
+    virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { }
+
 
     /*
      * draw - performs some global clipping optimizations
@@ -445,8 +450,11 @@
      * operation, so this should be set only if needed). Typically this is used
      * to figure out if the content or size of a surface has changed.
      */
-    virtual Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) = 0;
-    virtual bool isBufferLatched() const = 0;
+    virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) {
+        return {};
+    }
+
+    virtual bool isBufferLatched() const { return false; }
 
     bool isPotentialCursor() const { return mPotentialCursor; }
     /*
@@ -519,13 +527,15 @@
     void logFrameStats();
     void getFrameStats(FrameStats* outStats) const;
 
-    virtual std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) = 0;
+    virtual std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) {
+        return {};
+    }
 
     void onDisconnect();
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
                                   FrameEventHistoryDelta* outDelta);
 
-    virtual bool getTransformToDisplayInverse() const = 0;
+    virtual bool getTransformToDisplayInverse() const { return false; }
 
     Transform getTransform() const;
 
@@ -649,7 +659,7 @@
     // Returns mCurrentScaling mode (originating from the
     // Client) or mOverrideScalingMode mode (originating from
     // the Surface Controller) if set.
-    virtual uint32_t getEffectiveScalingMode() const = 0;
+    virtual uint32_t getEffectiveScalingMode() const { return 0; }
 
 public:
     /*
@@ -670,8 +680,8 @@
 
     sp<IBinder> getHandle();
     const String8& getName() const;
-    virtual void notifyAvailableFrames() = 0;
-    virtual PixelFormat getPixelFormat() const = 0;
+    virtual void notifyAvailableFrames() {}
+    virtual PixelFormat getPixelFormat() const { return PIXEL_FORMAT_NONE; }
     bool getPremultipledAlpha() const;
 
 protected:
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index fa4df83..b9c4909 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -1,7 +1,11 @@
 #pragma once
 
+#include <ui/GraphicsTypes.h>
+
 #include "Transform.h"
 
+#include <functional>
+
 namespace android {
 
 class RenderArea {
@@ -22,11 +26,13 @@
     virtual bool needsFiltering() const = 0;
     virtual Rect getSourceCrop() const = 0;
 
+    virtual void render(std::function<void()> drawLayers) { drawLayers(); }
+
     int getReqHeight() const { return mReqHeight; };
     int getReqWidth() const { return mReqWidth; };
     Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
     virtual bool getWideColorSupport() const = 0;
-    virtual android_color_mode_t getActiveColorMode() const = 0;
+    virtual ColorMode getActiveColorMode() const = 0;
 
     status_t updateDimensions();
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cb410a1..5dd5d7c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -61,20 +61,21 @@
 #include <private/android_filesystem_config.h>
 #include <private/gui/SyncFeatures.h>
 
+#include "BufferLayer.h"
 #include "Client.h"
-#include "clz.h"
+#include "ColorLayer.h"
 #include "Colorizer.h"
+#include "ContainerLayer.h"
 #include "DdmConnection.h"
-#include "DisplayDevice.h"
 #include "DispSync.h"
+#include "DisplayDevice.h"
 #include "EventControlThread.h"
 #include "EventThread.h"
 #include "Layer.h"
-#include "BufferLayer.h"
 #include "LayerVector.h"
-#include "ColorLayer.h"
 #include "MonitoredProducer.h"
 #include "SurfaceFlinger.h"
+#include "clz.h"
 
 #include "DisplayHardware/ComposerHal.h"
 #include "DisplayHardware/FramebufferSurface.h"
@@ -912,7 +913,7 @@
     return NO_ERROR;
 }
 status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
-        Vector<android_color_mode_t>* outColorModes) {
+        Vector<ColorMode>* outColorModes) {
     if ((outColorModes == nullptr) || (display.get() == nullptr)) {
         return BAD_VALUE;
     }
@@ -933,7 +934,7 @@
         return type;
     }
 
-    std::vector<android_color_mode_t> modes;
+    std::vector<ColorMode> modes;
     {
         ConditionalLock _l(mStateLock,
                 std::this_thread::get_id() != mMainThreadId);
@@ -945,18 +946,18 @@
     return NO_ERROR;
 }
 
-android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
+ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
     sp<const DisplayDevice> device(getDisplayDevice(display));
     if (device != nullptr) {
         return device->getActiveColorMode();
     }
-    return static_cast<android_color_mode_t>(BAD_VALUE);
+    return static_cast<ColorMode>(BAD_VALUE);
 }
 
 void SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
-        android_color_mode_t mode) {
+        ColorMode mode) {
     int32_t type = hw->getDisplayType();
-    android_color_mode_t currentMode = hw->getActiveColorMode();
+    ColorMode currentMode = hw->getActiveColorMode();
 
     if (mode == currentMode) {
         return;
@@ -976,20 +977,20 @@
 
 
 status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
-        android_color_mode_t colorMode) {
+        ColorMode colorMode) {
     class MessageSetActiveColorMode: public MessageBase {
         SurfaceFlinger& mFlinger;
         sp<IBinder> mDisplay;
-        android_color_mode_t mMode;
+        ColorMode mMode;
     public:
         MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
-                               android_color_mode_t mode) :
+                               ColorMode mode) :
             mFlinger(flinger), mDisplay(disp) { mMode = mode; }
         virtual bool handler() {
-            Vector<android_color_mode_t> modes;
+            Vector<ColorMode> modes;
             mFlinger.getDisplayColorModes(mDisplay, &modes);
             bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
-            if (mMode < 0 || !exists) {
+            if (mMode < ColorMode::NATIVE || !exists) {
                 ALOGE("Attempt to set invalid active color mode %s (%d) for display %p",
                       decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
                 return true;
@@ -1782,9 +1783,9 @@
 
 // pickColorMode translates a given dataspace into the best available color mode.
 // Currently only support sRGB and Display-P3.
-android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const {
+ColorMode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const {
     if (mForceNativeColorMode) {
-        return HAL_COLOR_MODE_NATIVE;
+        return ColorMode::NATIVE;
     }
 
     switch (dataSpace) {
@@ -1793,18 +1794,18 @@
         case HAL_DATASPACE_UNKNOWN:
         case HAL_DATASPACE_SRGB:
         case HAL_DATASPACE_V0_SRGB:
-            return HAL_COLOR_MODE_SRGB;
+            return ColorMode::SRGB;
             break;
 
         case HAL_DATASPACE_DISPLAY_P3:
-            return HAL_COLOR_MODE_DISPLAY_P3;
+            return ColorMode::DISPLAY_P3;
             break;
 
         default:
             // TODO (courtneygo): Do we want to assert an error here?
             ALOGE("No color mode mapping for %s (%#x)", dataspaceDetails(dataSpace).c_str(),
                   dataSpace);
-            return HAL_COLOR_MODE_SRGB;
+            return ColorMode::SRGB;
             break;
     }
 }
@@ -1926,7 +1927,7 @@
         }
 
         if (hasWideColorDisplay) {
-            android_color_mode newColorMode;
+            ColorMode newColorMode;
             android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
 
             for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
@@ -2268,13 +2269,13 @@
                 if (dispSurface != nullptr) {
                     bool hasWideColorSupport = false;
                     if (hasWideColorDisplay) {
-                        std::vector<android_color_mode_t> modes =
+                        std::vector<ColorMode> modes =
                                 getHwComposer().getColorModes(state.type);
-                        for (android_color_mode_t colorMode : modes) {
+                        for (ColorMode colorMode : modes) {
                             switch (colorMode) {
-                                case HAL_COLOR_MODE_DISPLAY_P3:
-                                case HAL_COLOR_MODE_ADOBE_RGB:
-                                case HAL_COLOR_MODE_DCI_P3:
+                                case ColorMode::DISPLAY_P3:
+                                case ColorMode::ADOBE_RGB:
+                                case ColorMode::DCI_P3:
                                     hasWideColorSupport = true;
                                     break;
                                 default:
@@ -2297,9 +2298,9 @@
                                               dispSurface, producer, hasWideColorSupport,
                                               hasHdrSupport);
 
-                    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
+                    ColorMode defaultColorMode = ColorMode::NATIVE;
                     if (hasWideColorSupport) {
-                        defaultColorMode = HAL_COLOR_MODE_SRGB;
+                        defaultColorMode = ColorMode::SRGB;
                     }
                     setActiveColorModeInternal(hw, defaultColorMode);
                     hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
@@ -2740,7 +2741,7 @@
 
         android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN;
         if (displayDevice->getWideColorSupport() &&
-                displayDevice->getActiveColorMode() == HAL_COLOR_MODE_DISPLAY_P3) {
+              displayDevice->getActiveColorMode() == ColorMode::DISPLAY_P3) {
             outputDataspace = HAL_DATASPACE_DISPLAY_P3;
         }
         getBE().mRenderEngine->setOutputDataSpace(outputDataspace);
@@ -3878,12 +3879,12 @@
         }
 
         result.appendFormat("Display %d color modes:\n", hwcId);
-        std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(hwcId);
+        std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
         for (auto&& mode : modes) {
             result.appendFormat("    %s (%d)\n", decodeColorMode(mode).c_str(), mode);
         }
 
-        android_color_mode_t currentMode = displayDevice->getActiveColorMode();
+        ColorMode currentMode = displayDevice->getActiveColorMode();
         result.appendFormat("    Current color mode: %s (%d)\n",
                             decodeColorMode(currentMode).c_str(), currentMode);
     }
@@ -4418,19 +4419,18 @@
 
 status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
                                        sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
-                                       float frameScale) {
+                                       float frameScale, bool childrenOnly) {
     ATRACE_CALL();
 
     class LayerRenderArea : public RenderArea {
     public:
-        LayerRenderArea(const sp<Layer>& layer, const Rect crop, int32_t reqWidth,
-                        int32_t reqHeight)
-              : RenderArea(reqHeight, reqWidth), mLayer(layer), mCrop(crop) {}
-        const Transform& getTransform() const override {
-            // Make the top level transform the inverse the transform and it's parent so it sets
-            // the whole capture back to 0,0
-            return *new Transform(mLayer->getTransform().inverse());
-        }
+        LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
+                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
+              : RenderArea(reqHeight, reqWidth),
+                mLayer(layer),
+                mCrop(crop),
+                mFlinger(flinger),
+                mChildrenOnly(childrenOnly) {}
         Rect getBounds() const override {
             const Layer::State& layerState(mLayer->getDrawingState());
             return Rect(layerState.active.w, layerState.active.h);
@@ -4439,6 +4439,34 @@
         int getWidth() const override { return mLayer->getDrawingState().active.w; }
         bool isSecure() const override { return false; }
         bool needsFiltering() const override { return false; }
+        const Transform& getTransform() const { return mTransform; }
+
+        class ReparentForDrawing {
+        public:
+            const sp<Layer>& oldParent;
+            const sp<Layer>& newParent;
+
+            ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent)
+                  : oldParent(oldParent), newParent(newParent) {
+                oldParent->reparentChildrenForDrawing(newParent);
+            }
+            ~ReparentForDrawing() { newParent->reparentChildrenForDrawing(oldParent); }
+        };
+
+        void render(std::function<void()> drawLayers) override {
+            if (!mChildrenOnly) {
+                mTransform = mLayer->getTransform().inverse();
+                drawLayers();
+            } else {
+                Rect bounds = getBounds();
+                screenshotParentLayer =
+                        new ContainerLayer(mFlinger, nullptr, String8("Screenshot Parent"),
+                                           bounds.getWidth(), bounds.getHeight(), 0);
+
+                ReparentForDrawing reparent(mLayer, screenshotParentLayer);
+                drawLayers();
+            }
+        }
 
         Rect getSourceCrop() const override {
             if (mCrop.isEmpty()) {
@@ -4448,11 +4476,19 @@
             }
         }
         bool getWideColorSupport() const override { return false; }
-        android_color_mode_t getActiveColorMode() const override { return HAL_COLOR_MODE_NATIVE; }
+        ColorMode getActiveColorMode() const override { return ColorMode::NATIVE; }
 
     private:
         const sp<Layer> mLayer;
         const Rect mCrop;
+
+        // In the "childrenOnly" case we reparent the children to a screenshot
+        // layer which has no properties set and which does not draw.
+        sp<ContainerLayer> screenshotParentLayer;
+        Transform mTransform;
+
+        SurfaceFlinger* mFlinger;
+        const bool mChildrenOnly;
     };
 
     auto layerHandle = reinterpret_cast<Layer::Handle*>(layerHandleBinder.get());
@@ -4463,6 +4499,13 @@
         return NAME_NOT_FOUND;
     }
 
+    const int uid = IPCThreadState::self()->getCallingUid();
+    const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
+    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
+        ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
+        return PERMISSION_DENIED;
+    }
+
     Rect crop(sourceCrop);
     if (sourceCrop.width() <= 0) {
         crop.left = 0;
@@ -4477,12 +4520,14 @@
     int32_t reqWidth = crop.width() * frameScale;
     int32_t reqHeight = crop.height() * frameScale;
 
-    LayerRenderArea renderArea(parent, crop, reqWidth, reqHeight);
+    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
 
-    auto traverseLayers = [parent](const LayerVector::Visitor& visitor) {
+    auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
         parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
             if (!layer->isVisible()) {
                 return;
+            } else if (childrenOnly && layer == parent.get()) {
+                return;
             }
             visitor(layer);
         });
@@ -4529,8 +4574,10 @@
         int fd = -1;
         {
             Mutex::Autolock _l(mStateLock);
-            result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
-                                             useIdentityTransform, forSystem, &fd);
+            renderArea.render([&]() {
+                result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
+                                                 useIdentityTransform, forSystem, &fd);
+            });
         }
 
         {
@@ -4603,7 +4650,7 @@
 
     android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN;
     if (renderArea.getWideColorSupport() &&
-            renderArea.getActiveColorMode() == HAL_COLOR_MODE_DISPLAY_P3) {
+          renderArea.getActiveColorMode() == ColorMode::DISPLAY_P3) {
         outputDataspace = HAL_DATASPACE_DISPLAY_P3;
     }
     getBE().mRenderEngine->setOutputDataSpace(outputDataspace);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 392acaa..104adef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -387,16 +387,16 @@
                                    int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
                                    ISurfaceComposer::Rotation rotation);
     virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
-                                   const Rect& sourceCrop, float frameScale);
+                                   const Rect& sourceCrop, float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& display,
             DisplayStatInfo* stats);
     virtual status_t getDisplayConfigs(const sp<IBinder>& display,
             Vector<DisplayInfo>* configs);
     virtual int getActiveConfig(const sp<IBinder>& display);
     virtual status_t getDisplayColorModes(const sp<IBinder>& display,
-            Vector<android_color_mode_t>* configs);
-    virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display);
-    virtual status_t setActiveColorMode(const sp<IBinder>& display, android_color_mode_t colorMode);
+            Vector<ColorMode>* configs);
+    virtual ColorMode getActiveColorMode(const sp<IBinder>& display);
+    virtual status_t setActiveColorMode(const sp<IBinder>& display, ColorMode colorMode);
     virtual void setPowerMode(const sp<IBinder>& display, int mode);
     virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
     virtual status_t clearAnimationFrameStats();
@@ -446,7 +446,7 @@
                               bool stateLockHeld);
 
     // Called on the main thread in response to setActiveColorMode()
-    void setActiveColorModeInternal(const sp<DisplayDevice>& hw, android_color_mode_t colorMode);
+    void setActiveColorModeInternal(const sp<DisplayDevice>& hw, ColorMode colorMode);
 
     // Returns whether the transaction actually modified any state
     bool handleMessageTransaction();
@@ -619,7 +619,7 @@
 
     // Given a dataSpace, returns the appropriate color_mode to use
     // to display that dataSpace.
-    android_color_mode pickColorMode(android_dataspace dataSpace) const;
+    ColorMode pickColorMode(android_dataspace dataSpace) const;
     android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b,
             bool hasHdr) const;
 
diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp
index 485090c..ac147fe 100644
--- a/services/surfaceflinger/layerproto/Android.bp
+++ b/services/surfaceflinger/layerproto/Android.bp
@@ -10,6 +10,7 @@
     ],
 
     shared_libs: [
+        "android.hardware.graphics.common@1.1",
         "libui",
         "libprotobuf-cpp-lite",
         "libbase",
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 92c26af..fd21991 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -192,6 +192,16 @@
         *sc = std::make_unique<ScreenCapture>(outBuffer);
     }
 
+    static void captureChildLayers(std::unique_ptr<ScreenCapture>* sc, sp<IBinder>& parentHandle,
+                                   Rect crop = Rect::EMPTY_RECT, float frameScale = 1.0) {
+        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+        SurfaceComposerClient::Transaction().apply(true);
+
+        sp<GraphicBuffer> outBuffer;
+        ASSERT_EQ(NO_ERROR, sf->captureLayers(parentHandle, &outBuffer, crop, frameScale, true));
+        *sc = std::make_unique<ScreenCapture>(outBuffer);
+    }
+
     void expectColor(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
         ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mOutBuffer->getPixelFormat());
         expectBufferColor(mOutBuffer, mPixels, rect, color, tolerance);
@@ -2306,6 +2316,74 @@
     mCapture->expectChildColor(0, 0);
 }
 
+TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
+    auto fgHandle = mFGSurfaceControl->getHandle();
+
+    sp<SurfaceControl> child =
+            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+                                           0, mFGSurfaceControl.get());
+    fillSurfaceRGBA8(child, 200, 200, 200);
+
+    SurfaceComposerClient::Transaction().show(child).apply(true);
+
+    // Captures mFGSurfaceControl's child
+    ScreenCapture::captureChildLayers(&mCapture, fgHandle);
+    mCapture->checkPixel(10, 10, 0, 0, 0);
+    mCapture->expectChildColor(0, 0);
+}
+
+
+// In the following tests we verify successful skipping of a parent layer,
+// so we use the same verification logic and only change how we mutate
+// the parent layer to verify that various properties are ignored.
+class ScreenCaptureChildOnlyTest : public LayerUpdateTest {
+public:
+    void SetUp() override {
+        LayerUpdateTest::SetUp();
+
+        mChild =
+            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+                    0, mFGSurfaceControl.get());
+        fillSurfaceRGBA8(mChild, 200, 200, 200);
+
+        SurfaceComposerClient::Transaction().show(mChild).apply(true);
+    }
+
+    void verify() {
+        auto fgHandle = mFGSurfaceControl->getHandle();
+        ScreenCapture::captureChildLayers(&mCapture, fgHandle);
+        mCapture->checkPixel(10, 10, 0, 0, 0);
+        mCapture->expectChildColor(0, 0);
+    }
+
+    std::unique_ptr<ScreenCapture> mCapture;
+    sp<SurfaceControl> mChild;
+};
+
+TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
+
+    SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
+
+    // Even though the parent is hidden we should still capture the child.
+    verify();
+}
+
+TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
+
+    SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true);
+
+    // Even though the parent is cropped out we should still capture the child.
+    verify();
+}
+
+TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
+
+    SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2);
+
+    // We should not inherit the parent scaling.
+    verify();
+}
+
 TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
     auto fgHandle = mFGSurfaceControl->getHandle();
 
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp b/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
index 4878c14..86e2e1e 100644
--- a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
+++ b/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
@@ -22,6 +22,7 @@
 #include <android-base/unique_fd.h>
 #include <hardware/hardware.h>
 #include <sync/sync.h>
+#include <ui/GraphicsTypes.h>
 
 #define HWC2_INCLUDE_STRINGIFICATION
 #define HWC2_USE_CPP11
@@ -34,6 +35,8 @@
 #include "Hwc2TestClientTarget.h"
 #include "Hwc2TestVirtualDisplay.h"
 
+using android::ColorMode;
+
 void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
         hwc2_display_t display, int32_t connected);
 void hwc2TestVsyncCallback(hwc2_callback_data_t callbackData,
@@ -865,7 +868,7 @@
     }
 
     void getColorModes(hwc2_display_t display,
-            std::vector<android_color_mode_t>* outColorModes,
+            std::vector<ColorMode>* outColorModes,
             hwc2_error_t* outErr = nullptr)
     {
         auto pfn = reinterpret_cast<HWC2_PFN_GET_COLOR_MODES>(
@@ -892,7 +895,7 @@
         }
     }
 
-    void setColorMode(hwc2_display_t display, android_color_mode_t colorMode,
+    void setColorMode(hwc2_display_t display, ColorMode colorMode,
             hwc2_error_t* outErr = nullptr)
     {
         auto pfn = reinterpret_cast<HWC2_PFN_SET_COLOR_MODE>(
@@ -905,7 +908,7 @@
             *outErr = err;
         } else {
             ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set color mode "
-                    << colorMode;
+                    << static_cast<int>(colorMode);
         }
     }
 
@@ -4252,33 +4255,33 @@
     EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
 }
 
-static const std::array<android_color_mode, 9> androidColorModes = {{
-    HAL_COLOR_MODE_NATIVE,
-    HAL_COLOR_MODE_STANDARD_BT601_625,
-    HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED,
-    HAL_COLOR_MODE_STANDARD_BT601_525,
-    HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED,
-    HAL_COLOR_MODE_STANDARD_BT709,
-    HAL_COLOR_MODE_DCI_P3,
-    HAL_COLOR_MODE_SRGB,
-    HAL_COLOR_MODE_ADOBE_RGB,
+static const std::array<ColorMode, 9> androidColorModes = {{
+    ColorMode::NATIVE,
+    ColorMode::STANDARD_BT601_625,
+    ColorMode::STANDARD_BT601_625_UNADJUSTED,
+    ColorMode::STANDARD_BT601_525,
+    ColorMode::STANDARD_BT601_525_UNADJUSTED,
+    ColorMode::STANDARD_BT709,
+    ColorMode::DCI_P3,
+    ColorMode::SRGB,
+    ColorMode::ADOBE_RGB,
 }};
 
 /* TESTCASE: Tests that the HWC2 can get the color modes for a display. The
- * display must support HAL_COLOR_MODE_NATIVE */
+ * display must support ColorMode::NATIVE */
 TEST_F(Hwc2Test, GET_COLOR_MODES)
 {
     ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
             [] (Hwc2Test* test, hwc2_display_t display) {
 
-                std::vector<android_color_mode_t> colorModes;
+                std::vector<ColorMode> colorModes;
 
                 ASSERT_NO_FATAL_FAILURE(test->getColorModes(display,
                         &colorModes));
 
                 EXPECT_NE(std::count(colorModes.begin(), colorModes.end(),
-                        HAL_COLOR_MODE_NATIVE), 0) << "all displays"
-                        " must support HAL_COLOR_MODE_NATIVE";
+                        ColorMode::NATIVE), 0) << "all displays"
+                        " must support ColorMode::NATIVE";
             }
     ));
 }
@@ -4287,7 +4290,7 @@
 TEST_F(Hwc2Test, GET_COLOR_MODES_bad_display)
 {
     hwc2_display_t display;
-    std::vector<android_color_mode_t> colorModes;
+    std::vector<ColorMode> colorModes;
     hwc2_error_t err = HWC2_ERROR_NONE;
 
     ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
@@ -4302,7 +4305,7 @@
     ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
             [] (Hwc2Test* test, hwc2_display_t display) {
 
-                const android_color_mode_t colorMode = HAL_COLOR_MODE_NATIVE;
+                const ColorMode colorMode = ColorMode::NATIVE;
 
                 EXPECT_NO_FATAL_FAILURE(test->setColorMode(display, colorMode));
             }
@@ -4313,7 +4316,7 @@
 TEST_F(Hwc2Test, SET_COLOR_MODES_bad_display)
 {
     hwc2_display_t display;
-    const android_color_mode_t colorMode = HAL_COLOR_MODE_NATIVE;
+    const ColorMode colorMode = ColorMode::NATIVE;
     hwc2_error_t err = HWC2_ERROR_NONE;
 
     ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
@@ -4328,8 +4331,7 @@
     ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
             [] (Hwc2Test* test, hwc2_display_t display) {
 
-                const android_color_mode_t colorMode =
-                        static_cast<android_color_mode_t>(-1);
+                const ColorMode colorMode = static_cast<ColorMode>(-1);
                 hwc2_error_t err = HWC2_ERROR_NONE;
 
                 ASSERT_NO_FATAL_FAILURE(test->setColorMode(display, colorMode,
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
index 180e232..313c022 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.cpp
+++ b/services/vr/hardware_composer/impl/vr_hwc.cpp
@@ -15,6 +15,7 @@
  */
 #include "impl/vr_hwc.h"
 
+#include "android-base/stringprintf.h"
 #include <cutils/properties.h>
 #include <private/dvr/display_client.h>
 #include <ui/Fence.h>
@@ -26,6 +27,7 @@
 using namespace android::hardware::graphics::common::V1_0;
 using namespace android::hardware::graphics::composer::V2_1;
 
+using android::base::StringPrintf;
 using android::hardware::hidl_handle;
 using android::hardware::hidl_string;
 using android::hardware::hidl_vec;
@@ -225,6 +227,20 @@
     memcpy(color_transform_, matrix, sizeof(color_transform_));
 }
 
+void HwcDisplay::dumpDebugInfo(std::string* result) const {
+  if (!result) {
+    return;
+  }
+  *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\
+      , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_);
+  *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\
+      layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height,
+      buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format);
+  for (const auto& layer : layers_) {
+    layer.dumpDebugInfo(result);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // VrHwcClient
 
@@ -831,7 +847,19 @@
 }
 
 Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
-  hidl_cb(hidl_string());
+  std::string result;
+
+  {
+    std::lock_guard<std::mutex> guard(mutex_);
+    result = "\nVrHwc states:\n";
+    for (const auto& pair : displays_) {
+      result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first);
+      pair.second->dumpDebugInfo(&result);
+    }
+    result += "\n";
+  }
+
+  hidl_cb(hidl_string(result));
   return Void();
 }
 
@@ -881,5 +909,22 @@
   return iter == displays_.end() ? nullptr : iter->second.get();
 }
 
+void HwcLayer::dumpDebugInfo(std::string* result) const {
+  if (!result) {
+    return;
+  }
+  *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\
+      cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\
+      display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n",
+      composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y,
+      info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform,
+      info.display_frame.left, info.display_frame.top, info.display_frame.right,
+      info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right,
+      info.crop.bottom, info.blend_mode);
+  *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\
+      , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride,
+      buffer_metadata.layerCount, buffer_metadata.format);
+}
+
 }  // namespace dvr
 }  // namespace android
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
index 1c308f2..d5d5f55 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.h
+++ b/services/vr/hardware_composer/impl/vr_hwc.h
@@ -116,6 +116,8 @@
     info.id = new_id;
   }
 
+  void dumpDebugInfo(std::string* result) const;
+
   Composition composition_type;
   ComposerView::ComposerLayer info;
   IVrComposerClient::BufferMetadata buffer_metadata;
@@ -163,6 +165,8 @@
   int32_t color_transform_hint() const { return color_transform_hint_; }
   void SetColorTransform(const float* matrix, int32_t hint);
 
+  void dumpDebugInfo(std::string* result) const;
+
  private:
   // The client target buffer and the associated fence.
   sp<GraphicBuffer> buffer_;