Merge "[sf] Move texture deletion to main thread via pool" into qt-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 5836f11..7ac0eb7 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -62,7 +62,7 @@
 
 using std::string;
 
-#define MAX_SYS_FILES 10
+#define MAX_SYS_FILES 11
 
 const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
 const char* k_userInitiatedTraceProperty = "debug.atrace.user_initiated";
@@ -133,7 +133,11 @@
         { OPT,      "events/sched/sched_blocked_reason/enable" },
         { OPT,      "events/sched/sched_cpu_hotplug/enable" },
         { OPT,      "events/sched/sched_pi_setprio/enable" },
+        { OPT,      "events/sched/sched_process_exit/enable" },
         { OPT,      "events/cgroup/enable" },
+        { OPT,      "events/oom/oom_score_adj_update/enable" },
+        { OPT,      "events/task/task_rename/enable" },
+        { OPT,      "events/task/task_newtask/enable" },
     } },
     { "irq",        "IRQ Events",   0, {
         { REQ,      "events/irq/enable" },
@@ -231,10 +235,6 @@
         { OPT,      "events/kmem/rss_stat/enable" },
         { OPT,      "events/kmem/ion_heap_grow/enable" },
         { OPT,      "events/kmem/ion_heap_shrink/enable" },
-        { OPT,      "events/oom/oom_score_adj_update/enable" },
-        { OPT,      "events/sched/sched_process_exit/enable" },
-        { OPT,      "events/task/task_rename/enable" },
-        { OPT,      "events/task/task_newtask/enable" },
     } },
 };
 
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 7c58a85..032d072 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -33,6 +33,8 @@
     chmod 0666 /sys/kernel/tracing/events/sched/sched_cpu_hotplug/enable
     chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_pi_setprio/enable
     chmod 0666 /sys/kernel/tracing/events/sched/sched_pi_setprio/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_process_exit/enable
+    chmod 0666 /sys/kernel/tracing/events/sched/sched_process_exit/enable
     chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_waking/enable
     chmod 0666 /sys/kernel/tracing/events/sched/sched_waking/enable
     chmod 0666 /sys/kernel/debug/tracing/events/cgroup/enable
diff --git a/headers/media_plugin/media/drm/DrmAPI.h b/headers/media_plugin/media/drm/DrmAPI.h
index 59bd292..17b9993 100644
--- a/headers/media_plugin/media/drm/DrmAPI.h
+++ b/headers/media_plugin/media/drm/DrmAPI.h
@@ -115,7 +115,8 @@
             kKeyStatusType_Expired,
             kKeyStatusType_OutputNotAllowed,
             kKeyStatusType_StatusPending,
-            kKeyStatusType_InternalError
+            kKeyStatusType_InternalError,
+            kKeyStatusType_UsableInFuture
         };
 
         // Used by sendKeysChange to report the usability status of each
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index d0642c6..2f5ccb8 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -38,6 +38,7 @@
         RELEASE_PLAYER                        = IBinder::FIRST_CALL_TRANSACTION + 3,
         TRACK_RECORDER                        = IBinder::FIRST_CALL_TRANSACTION + 4,
         RECORDER_EVENT                        = IBinder::FIRST_CALL_TRANSACTION + 5,
+        RELEASE_RECORDER                      = IBinder::FIRST_CALL_TRANSACTION + 6,
     };
 
     DECLARE_META_INTERFACE(AudioManager)
@@ -52,6 +53,7 @@
     /*oneway*/ virtual status_t releasePlayer(audio_unique_id_t piid) = 0;
     virtual audio_unique_id_t trackRecorder(const sp<IBinder>& recorder) = 0;
     /*oneway*/ virtual status_t recorderEvent(audio_unique_id_t riid, recorder_state_t event) = 0;
+    /*oneway*/ virtual status_t releaseRecorder(audio_unique_id_t riid) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/graphicsenv/GpuStatsInfo.cpp b/libs/graphicsenv/GpuStatsInfo.cpp
index cbf6e50..047d683 100644
--- a/libs/graphicsenv/GpuStatsInfo.cpp
+++ b/libs/graphicsenv/GpuStatsInfo.cpp
@@ -35,6 +35,10 @@
     if ((status = parcel->writeInt32(vkLoadingCount)) != OK) return status;
     if ((status = parcel->writeInt32(vkLoadingFailureCount)) != OK) return status;
     if ((status = parcel->writeInt32(vulkanVersion)) != OK) return status;
+    if ((status = parcel->writeInt32(cpuVulkanVersion)) != OK) return status;
+    if ((status = parcel->writeInt32(glesVersion)) != OK) return status;
+    if ((status = parcel->writeInt32(angleLoadingCount)) != OK) return status;
+    if ((status = parcel->writeInt32(angleLoadingFailureCount)) != OK) return status;
     return OK;
 }
 
@@ -49,6 +53,10 @@
     if ((status = parcel->readInt32(&vkLoadingCount)) != OK) return status;
     if ((status = parcel->readInt32(&vkLoadingFailureCount)) != OK) return status;
     if ((status = parcel->readInt32(&vulkanVersion)) != OK) return status;
+    if ((status = parcel->readInt32(&cpuVulkanVersion)) != OK) return status;
+    if ((status = parcel->readInt32(&glesVersion)) != OK) return status;
+    if ((status = parcel->readInt32(&angleLoadingCount)) != OK) return status;
+    if ((status = parcel->readInt32(&angleLoadingFailureCount)) != OK) return status;
     return OK;
 }
 
@@ -60,9 +68,13 @@
     StringAppendF(&result, "driverBuildTime = %" PRId64 "\n", driverBuildTime);
     StringAppendF(&result, "glLoadingCount = %d\n", glLoadingCount);
     StringAppendF(&result, "glLoadingFailureCount = %d\n", glLoadingFailureCount);
+    StringAppendF(&result, "angleLoadingCount = %d\n", angleLoadingCount);
+    StringAppendF(&result, "angleLoadingFailureCount = %d\n", angleLoadingFailureCount);
     StringAppendF(&result, "vkLoadingCount = %d\n", vkLoadingCount);
     StringAppendF(&result, "vkLoadingFailureCount = %d\n", vkLoadingFailureCount);
     StringAppendF(&result, "vulkanVersion = %d\n", vulkanVersion);
+    StringAppendF(&result, "cpuVulkanVersion = %d\n", cpuVulkanVersion);
+    StringAppendF(&result, "glesVersion = %d\n", glesVersion);
     return result;
 }
 
@@ -72,6 +84,7 @@
     if ((status = parcel->writeUint64(driverVersionCode)) != OK) return status;
     if ((status = parcel->writeInt64Vector(glDriverLoadingTime)) != OK) return status;
     if ((status = parcel->writeInt64Vector(vkDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->writeInt64Vector(angleDriverLoadingTime)) != OK) return status;
     return OK;
 }
 
@@ -81,6 +94,7 @@
     if ((status = parcel->readUint64(&driverVersionCode)) != OK) return status;
     if ((status = parcel->readInt64Vector(&glDriverLoadingTime)) != OK) return status;
     if ((status = parcel->readInt64Vector(&vkDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->readInt64Vector(&angleDriverLoadingTime)) != OK) return status;
     return OK;
 }
 
@@ -93,6 +107,11 @@
         StringAppendF(&result, " %d", loadingTime);
     }
     result.append("\n");
+    result.append("angleDriverLoadingTime:");
+    for (int32_t loadingTime : angleDriverLoadingTime) {
+        StringAppendF(&result, " %d", loadingTime);
+    }
+    result.append("\n");
     result.append("vkDriverLoadingTime:");
     for (int32_t loadingTime : vkDriverLoadingTime) {
         StringAppendF(&result, " %d", loadingTime);
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 8728f03..2bfd908 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -228,9 +228,8 @@
     bool isIntendedDriverLoaded = false;
     if (api == GraphicsEnv::Api::API_GL) {
         driver = mGpuStats.glDriverToLoad;
-        isIntendedDriverLoaded = isLoaded &&
-                ((mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) ||
-                 (mGpuStats.glDriverToLoad == mGpuStats.glDriverFallback));
+        isIntendedDriverLoaded =
+                isLoaded && (mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE);
     } else {
         driver = mGpuStats.vkDriverToLoad;
         isIntendedDriverLoaded =
@@ -240,16 +239,6 @@
     sendGpuStatsLocked(driver, isIntendedDriverLoaded, driverLoadingTime);
 }
 
-void GraphicsEnv::clearDriverLoadingInfo(GraphicsEnv::Api api) {
-    ATRACE_CALL();
-
-    std::lock_guard<std::mutex> lock(mStatsLock);
-    if (api == GraphicsEnv::Api::API_GL) {
-        mGpuStats.glDriverToLoad = GraphicsEnv::Driver::NONE;
-        mGpuStats.glDriverFallback = GraphicsEnv::Driver::NONE;
-    }
-}
-
 static sp<IGpuService> getGpuService() {
     const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
     if (!binder) {
diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
index e96c932..bdcf0d6 100644
--- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
+++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
@@ -45,6 +45,10 @@
     int32_t vkLoadingCount = 0;
     int32_t vkLoadingFailureCount = 0;
     int32_t vulkanVersion = 0;
+    int32_t cpuVulkanVersion = 0;
+    int32_t glesVersion = 0;
+    int32_t angleLoadingCount = 0;
+    int32_t angleLoadingFailureCount = 0;
 };
 
 /*
@@ -64,6 +68,7 @@
     uint64_t driverVersionCode = 0;
     std::vector<int64_t> glDriverLoadingTime = {};
     std::vector<int64_t> vkDriverLoadingTime = {};
+    std::vector<int64_t> angleDriverLoadingTime = {};
 };
 
 } // namespace android
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index b10cab7..6d4cbc1 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -89,7 +89,6 @@
                      const std::string& appPackageName, const int32_t vulkanVersion);
     void setDriverToLoad(Driver driver);
     void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
-    void clearDriverLoadingInfo(Api api);
     void sendGpuStatsLocked(Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
 
     bool shouldUseAngle(std::string appName);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a8b1a4c..4372e16 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -142,6 +142,28 @@
         return result;
     }
 
+    virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+                                   sp<GraphicBuffer>* outBuffer) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeUint64(displayOrLayerStack);
+        status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_BY_ID, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("captureScreen failed to transact: %d", result);
+            return result;
+        }
+        result = reply.readInt32();
+        if (result != NO_ERROR) {
+            ALOGE("captureScreen failed to readInt32: %d", result);
+            return result;
+        }
+
+        *outDataspace = static_cast<ui::Dataspace>(reply.readInt32());
+        *outBuffer = new GraphicBuffer();
+        reply.read(**outBuffer);
+        return result;
+    }
+
     virtual status_t captureLayers(
             const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
             const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
@@ -1042,6 +1064,19 @@
             }
             return NO_ERROR;
         }
+        case CAPTURE_SCREEN_BY_ID: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            uint64_t displayOrLayerStack = data.readUint64();
+            ui::Dataspace outDataspace = ui::Dataspace::V0_SRGB;
+            sp<GraphicBuffer> outBuffer;
+            status_t res = captureScreen(displayOrLayerStack, &outDataspace, &outBuffer);
+            reply->writeInt32(res);
+            if (res == NO_ERROR) {
+                reply->writeInt32(static_cast<int32_t>(outDataspace));
+                reply->write(*outBuffer);
+            }
+            return NO_ERROR;
+        }
         case CAPTURE_LAYERS: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> layerHandleBinder = data.readStrongBinder();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 437cdd7..5d4367d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1572,6 +1572,13 @@
                    useIdentityTransform, rotation, false, outBuffer, ignored);
 }
 
+status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+                                   sp<GraphicBuffer>* outBuffer) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == nullptr) return NO_INIT;
+    return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer);
+}
+
 status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
                                          const ui::Dataspace reqDataSpace,
                                          const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index e64ba9b..cee1b81 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -1061,7 +1061,7 @@
 
 status_t H2BGraphicBufferProducer::attachBuffer(
         int* outSlot, const sp<GraphicBuffer>& buffer) {
-    AnwBuffer tBuffer;
+    AnwBuffer tBuffer{};
     wrapAs(&tBuffer, *buffer);
     status_t fnStatus;
     status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
@@ -1076,7 +1076,7 @@
         int slot,
         const QueueBufferInput& input,
         QueueBufferOutput* output) {
-    HGraphicBufferProducer::QueueBufferInput tInput;
+    HGraphicBufferProducer::QueueBufferInput tInput{};
     native_handle_t* nh;
     if (!wrapAs(&tInput, &nh, input)) {
         ALOGE("H2BGraphicBufferProducer::queueBuffer - "
diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
index e039593..e891ec5 100644
--- a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
@@ -15,7 +15,7 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "H2BGraphicBufferProducer@2.0"
+#define LOG_TAG "B2HGraphicBufferProducer@2.0"
 
 #include <android-base/logging.h>
 
@@ -30,13 +30,38 @@
 #include <vndk/hardware_buffer.h>
 
 namespace android {
-
 namespace hardware {
 namespace graphics {
 namespace bufferqueue {
 namespace V2_0 {
 namespace utils {
 
+namespace /* unnamed */ {
+
+using BQueueBufferInput = ::android::
+        IGraphicBufferProducer::QueueBufferInput;
+using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer::QueueBufferInput;
+using BQueueBufferOutput = ::android::
+        IGraphicBufferProducer::QueueBufferOutput;
+using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer::QueueBufferOutput;
+
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
+
+bool b2h(BQueueBufferOutput const& from, HQueueBufferOutput* to) {
+    to->width = from.width;
+    to->height = from.height;
+    to->transformHint = static_cast<int32_t>(from.transformHint);
+    to->numPendingBuffers = from.numPendingBuffers;
+    to->nextFrameNumber = from.nextFrameNumber;
+    to->bufferReplaced = from.bufferReplaced;
+    return true;
+}
+
+} // unnamed namespace
+
 // B2HGraphicBufferProducer
 // ========================
 
@@ -161,11 +186,7 @@
         int32_t slot,
         QueueBufferInput const& hInput,
         queueBuffer_cb _hidl_cb) {
-    using HOutput = QueueBufferOutput;
-    using BInput = BGraphicBufferProducer::QueueBufferInput;
-    using BOutput = BGraphicBufferProducer::QueueBufferOutput;
-
-    BInput bInput{
+    BQueueBufferInput bInput{
             hInput.timestamp,
             hInput.isAutoTimestamp,
             static_cast<android_dataspace>(hInput.dataSpace),
@@ -178,35 +199,32 @@
 
     // Convert crop.
     if (!h2b(hInput.crop, &bInput.crop)) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
         return {};
     }
 
     // Convert surfaceDamage.
     if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
         return {};
     }
 
     // Convert fence.
     if (!h2b(hInput.fence, &bInput.fence)) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
         return {};
     }
 
-    BOutput bOutput{};
+    BQueueBufferOutput bOutput{};
     HStatus hStatus{};
-    bool converted = b2h(
-            mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
-            &hStatus);
+    QueueBufferOutput hOutput{};
+    bool converted =
+            b2h(
+                mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
+                &hStatus) &&
+            b2h(bOutput, &hOutput);
 
-    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
-             HOutput{bOutput.width,
-                     bOutput.height,
-                     static_cast<int32_t>(bOutput.transformHint),
-                     bOutput.numPendingBuffers,
-                     bOutput.nextFrameNumber,
-                     bOutput.bufferReplaced});
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
     return {};
 }
 
@@ -236,33 +254,23 @@
         HConnectionType hConnectionType,
         bool producerControlledByApp,
         connect_cb _hidl_cb) {
-    using BOutput = BGraphicBufferProducer::QueueBufferOutput;
-    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
     sp<BProducerListener> bListener = new H2BProducerListener(hListener);
-    if (!bListener) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+    int bConnectionType{};
+    if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
         return {};
     }
-    int bConnectionType;
-    if (!h2b(hConnectionType, &bConnectionType)) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
-        return {};
-    }
-    BOutput bOutput{};
+    BQueueBufferOutput bOutput{};
     HStatus hStatus{};
-    bool converted = b2h(
-            mBase->connect(bListener,
-                           bConnectionType,
-                           producerControlledByApp,
-                           &bOutput),
-            &hStatus);
-    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
-             HOutput{bOutput.width,
-                     bOutput.height,
-                     static_cast<int32_t>(bOutput.transformHint),
-                     bOutput.numPendingBuffers,
-                     bOutput.nextFrameNumber,
-                     bOutput.bufferReplaced});
+    QueueBufferOutput hOutput{};
+    bool converted =
+            b2h(mBase->connect(bListener,
+                               bConnectionType,
+                               producerControlledByApp,
+                               &bOutput),
+                &hStatus) &&
+            b2h(bOutput, &hOutput);
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
     return {};
 }
 
diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
index 1023ef1..2f5b73c 100644
--- a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
@@ -29,13 +29,54 @@
 #include <vndk/hardware_buffer.h>
 
 namespace android {
-
 namespace hardware {
 namespace graphics {
 namespace bufferqueue {
 namespace V2_0 {
 namespace utils {
 
+namespace /* unnamed */ {
+
+using BQueueBufferInput = ::android::
+        IGraphicBufferProducer::QueueBufferInput;
+using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer::QueueBufferInput;
+using BQueueBufferOutput = ::android::
+        IGraphicBufferProducer::QueueBufferOutput;
+using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer::QueueBufferOutput;
+
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
+
+bool b2h(BQueueBufferInput const& from, HQueueBufferInput* to,
+         HFenceWrapper* hFenceWrapper) {
+    to->timestamp = from.timestamp;
+    to->isAutoTimestamp = static_cast<bool>(from.isAutoTimestamp);
+    to->dataSpace = static_cast<int32_t>(from.dataSpace);
+    to->transform = static_cast<int32_t>(from.transform);
+    to->stickyTransform = static_cast<int32_t>(from.stickyTransform);
+    if (!b2h(from.crop, &to->crop) ||
+            !b2h(from.surfaceDamage, &to->surfaceDamage) ||
+            !b2h(from.fence, hFenceWrapper)) {
+        return false;
+    }
+    to->fence = hFenceWrapper->getHandle();
+    return true;
+}
+
+bool h2b(HQueueBufferOutput const& from, BQueueBufferOutput* to) {
+    to->width = from.width;
+    to->height = from.height;
+    to->transformHint = static_cast<uint32_t>(from.transformHint);
+    to->numPendingBuffers = from.numPendingBuffers;
+    to->nextFrameNumber = from.nextFrameNumber;
+    to->bufferReplaced = from.bufferReplaced;
+    return true;
+}
+
+} // unnamed namespace
+
 // H2BGraphicBufferProducer
 // ========================
 
@@ -209,47 +250,13 @@
         int slot,
         QueueBufferInput const& input,
         QueueBufferOutput* output) {
-    HRect hCrop{};
-    (void)b2h(input.crop, &hCrop);
-
-    using HInput = HGraphicBufferProducer::QueueBufferInput;
-    HInput hInput{
-            input.timestamp,
-            static_cast<bool>(input.isAutoTimestamp),
-            static_cast<int32_t>(input.dataSpace),
-            {}, // crop
-            static_cast<int32_t>(input.transform),
-            static_cast<int32_t>(input.stickyTransform),
-            {}, // fence
-            {}  // surfaceDamage
-            };
-
-    // Convert crop.
-    if (!b2h(input.crop, &hInput.crop)) {
-        LOG(ERROR) << "queueBuffer: corrupted input crop rectangle.";
-        return UNKNOWN_ERROR;
-    }
-
-    // Convert surfaceDamage.
-    size_t numRects;
-    Rect const* rectArray = input.surfaceDamage.getArray(&numRects);
-    hInput.surfaceDamage.resize(numRects);
-    for (size_t i = 0; i < numRects; ++i) {
-        if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) {
-            LOG(ERROR) << "queueBuffer: corrupted input surface damage.";
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    // Convert fence.
+    HQueueBufferInput hInput{};
     HFenceWrapper hFenceWrapper;
-    if (!b2h(input.fence, &hFenceWrapper)) {
-        LOG(ERROR) << "queueBuffer: corrupted input fence.";
+    if (!b2h(input, &hInput, &hFenceWrapper)) {
+        LOG(ERROR) << "queueBuffer: corrupted input.";
         return UNKNOWN_ERROR;
     }
-    hInput.fence = hFenceWrapper.getHandle();
 
-    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
     bool converted{};
     status_t bStatus{};
     Return<void> transResult = mBase->queueBuffer(
@@ -257,15 +264,8 @@
             hInput,
             [&converted, &bStatus, output](
                     HStatus hStatus,
-                    HOutput const& hOutput) {
-                converted = h2b(hStatus, &bStatus);
-                output->width = hOutput.width;
-                output->height = hOutput.height;
-                output->transformHint =
-                        static_cast<uint32_t>(hOutput.transformHint);
-                output->numPendingBuffers = hOutput.numPendingBuffers;
-                output->nextFrameNumber = hOutput.nextFrameNumber;
-                output->bufferReplaced = hOutput.bufferReplaced;
+                    HQueueBufferOutput const& hOutput) {
+                converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
             });
 
     if (!transResult.isOk()) {
@@ -332,7 +332,6 @@
         }
     }
 
-    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
     bool converted{};
     status_t bStatus{};
     Return<void> transResult = mBase->connect(
@@ -341,15 +340,8 @@
             producerControlledByApp,
             [&converted, &bStatus, output](
                     HStatus hStatus,
-                    HOutput hOutput) {
-                converted = h2b(hStatus, &bStatus);
-                output->width = hOutput.width;
-                output->height = hOutput.height;
-                output->transformHint =
-                        static_cast<uint32_t>(hOutput.transformHint);
-                output->numPendingBuffers = hOutput.numPendingBuffers;
-                output->nextFrameNumber = hOutput.nextFrameNumber;
-                output->bufferReplaced = hOutput.bufferReplaced;
+                    HQueueBufferOutput const& hOutput) {
+                converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
             });
     if (!transResult.isOk()) {
         LOG(ERROR) << "connect: transaction failed.";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e8c7a39..fd67754 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -247,6 +247,9 @@
                              useIdentityTransform, rotation);
     }
 
+    virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+                                   sp<GraphicBuffer>* outBuffer) = 0;
+
     template <class AA>
     struct SpHash {
         size_t operator()(const sp<AA>& k) const { return std::hash<AA*>()(k.get()); }
@@ -473,6 +476,7 @@
         GET_ALLOWED_DISPLAY_CONFIGS,
         GET_DISPLAY_BRIGHTNESS_SUPPORT,
         SET_DISPLAY_BRIGHTNESS,
+        CAPTURE_SCREEN_BY_ID,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 9d34468..a038838 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -515,6 +515,8 @@
                             const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                             uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                             uint32_t rotation, sp<GraphicBuffer>* outBuffer);
+    static status_t capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+                            sp<GraphicBuffer>* outBuffer);
     static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                   float frameScale, sp<GraphicBuffer>* outBuffer);
diff --git a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
index 0e57f20..029dcc0 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
@@ -68,7 +68,7 @@
     Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
         sp<GraphicBuffer> buf;
         status_t status = mBase->requestBuffer(slot, &buf);
-        AnwBuffer anwBuffer;
+        AnwBuffer anwBuffer{};
         if (buf != nullptr) {
             ::android::conversion::wrapAs(&anwBuffer, *buf);
         }
@@ -89,15 +89,15 @@
             uint32_t width, uint32_t height,
             ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
             bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
-        int slot;
+        int slot{};
         sp<Fence> fence;
         ::android::FrameEventHistoryDelta outTimestamps;
         status_t status = mBase->dequeueBuffer(
             &slot, &fence, width, height,
             static_cast<::android::PixelFormat>(format), usage, nullptr,
             getFrameTimestamps ? &outTimestamps : nullptr);
-        hidl_handle tFence;
-        HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps;
+        hidl_handle tFence{};
+        HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{};
 
         native_handle_t* nh = nullptr;
         if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
@@ -144,8 +144,8 @@
         sp<GraphicBuffer> outBuffer;
         sp<Fence> outFence;
         status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
-        AnwBuffer tBuffer;
-        hidl_handle tFence;
+        AnwBuffer tBuffer{};
+        hidl_handle tFence{};
 
         if (outBuffer == nullptr) {
             LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
@@ -185,7 +185,7 @@
     Return<void> queueBuffer(
             int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
             HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
-        HGraphicBufferProducer::QueueBufferOutput tOutput;
+        HGraphicBufferProducer::QueueBufferOutput tOutput{};
         BGraphicBufferProducer::QueueBufferInput lInput(
                 0, false, HAL_DATASPACE_UNKNOWN,
                 ::android::Rect(0, 0, 1, 1),
@@ -246,7 +246,7 @@
                 producerControlledByApp,
                 &lOutput);
 
-        HGraphicBufferProducer::QueueBufferOutput tOutput;
+        HGraphicBufferProducer::QueueBufferOutput tOutput{};
         std::vector<std::vector<native_handle_t*> > nhAA;
         if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
             LOG(ERROR) << "TWGraphicBufferProducer::connect - "
@@ -320,11 +320,11 @@
         status_t status = mBase->getLastQueuedBuffer(
                 &lOutBuffer, &lOutFence, lOutTransformMatrix);
 
-        AnwBuffer tOutBuffer;
+        AnwBuffer tOutBuffer{};
         if (lOutBuffer != nullptr) {
             ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
         }
-        hidl_handle tOutFence;
+        hidl_handle tOutFence{};
         native_handle_t* nh = nullptr;
         if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
             LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
@@ -346,7 +346,7 @@
         ::android::FrameEventHistoryDelta lDelta;
         mBase->getFrameTimestamps(&lDelta);
 
-        HGraphicBufferProducer::FrameEventHistoryDelta tDelta;
+        HGraphicBufferProducer::FrameEventHistoryDelta tDelta{};
         std::vector<std::vector<native_handle_t*> > nhAA;
         if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
             LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
@@ -365,7 +365,7 @@
     }
 
     Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
-        uint64_t outId;
+        uint64_t outId{};
         status_t status = mBase->getUniqueId(&outId);
         _hidl_cb(static_cast<int32_t>(status), outId);
         return Void();
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 014b1fa..db97fae 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -623,6 +623,10 @@
                            bool /*captureSecureLayers*/) override {
         return NO_ERROR;
     }
+    status_t captureScreen(uint64_t /*displayOrLayerStack*/, ui::Dataspace* /*outDataspace*/,
+                           sp<GraphicBuffer>* /*outBuffer*/) override {
+        return NO_ERROR;
+    }
     virtual status_t captureLayers(
             const sp<IBinder>& /*parentHandle*/, sp<GraphicBuffer>* /*outBuffer*/,
             const ui::Dataspace /*reqDataspace*/, const ui::PixelFormat /*reqPixelFormat*/,
diff --git a/services/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp
index f5d4826..6235f06 100644
--- a/services/audiomanager/IAudioManager.cpp
+++ b/services/audiomanager/IAudioManager.cpp
@@ -122,6 +122,13 @@
         data.writeInt32((int32_t) event);
         return remote()->transact(RECORDER_EVENT, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    virtual status_t releaseRecorder(audio_unique_id_t riid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
+        data.writeInt32((int32_t) riid);
+        return remote()->transact(RELEASE_RECORDER, data, &reply, IBinder::FLAG_ONEWAY);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioManager, "android.media.IAudioService");
diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp
index 1cb78db..8b01c28 100644
--- a/services/gpuservice/gpustats/GpuStats.cpp
+++ b/services/gpuservice/gpustats/GpuStats.cpp
@@ -19,14 +19,15 @@
 
 #include "GpuStats.h"
 
-#include <unordered_set>
-
+#include <cutils/properties.h>
 #include <log/log.h>
 #include <utils/Trace.h>
 
+#include <unordered_set>
+
 namespace android {
 
-static bool addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
+static void addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
                             GpuStatsGlobalInfo* const outGlobalInfo) {
     switch (driver) {
         case GraphicsEnv::Driver::GL:
@@ -39,13 +40,13 @@
             outGlobalInfo->vkLoadingCount++;
             if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
             break;
+        case GraphicsEnv::Driver::ANGLE:
+            outGlobalInfo->angleLoadingCount++;
+            if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
+            break;
         default:
-            // Currently we don't support GraphicsEnv::Driver::ANGLE because the
-            // basic driver package info only belongs to system or updated driver.
-            return false;
+            break;
     }
-
-    return true;
 }
 
 static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime,
@@ -53,13 +54,20 @@
     switch (driver) {
         case GraphicsEnv::Driver::GL:
         case GraphicsEnv::Driver::GL_UPDATED:
-            if (outAppInfo->glDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
-            outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+            if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
             break;
         case GraphicsEnv::Driver::VULKAN:
         case GraphicsEnv::Driver::VULKAN_UPDATED:
-            if (outAppInfo->vkDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
-            outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+            if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
+            break;
+        case GraphicsEnv::Driver::ANGLE:
+            if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
             break;
         default:
             break;
@@ -89,17 +97,15 @@
 
     if (!mGlobalStats.count(driverVersionCode)) {
         GpuStatsGlobalInfo globalInfo;
-        if (!addLoadingCount(driver, isDriverLoaded, &globalInfo)) {
-            return;
-        }
+        addLoadingCount(driver, isDriverLoaded, &globalInfo);
         globalInfo.driverPackageName = driverPackageName;
         globalInfo.driverVersionName = driverVersionName;
         globalInfo.driverVersionCode = driverVersionCode;
         globalInfo.driverBuildTime = driverBuildTime;
         globalInfo.vulkanVersion = vulkanVersion;
         mGlobalStats.insert({driverVersionCode, globalInfo});
-    } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
-        return;
+    } else {
+        addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
     }
 
     if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
@@ -120,6 +126,16 @@
     addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
 }
 
+void GpuStats::interceptSystemDriverStatsLocked() {
+    // Append cpuVulkanVersion and glesVersion to system driver stats
+    if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
+        return;
+    }
+
+    mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
+    mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
+}
+
 void GpuStats::dump(const Vector<String16>& args, std::string* result) {
     ATRACE_CALL();
 
@@ -176,6 +192,8 @@
 }
 
 void GpuStats::dumpGlobalLocked(std::string* result) {
+    interceptSystemDriverStatsLocked();
+
     for (const auto& ele : mGlobalStats) {
         result->append(ele.second.toString());
         result->append("\n");
@@ -196,6 +214,8 @@
     outStats->clear();
     outStats->reserve(mGlobalStats.size());
 
+    interceptSystemDriverStatsLocked();
+
     for (const auto& ele : mGlobalStats) {
         outStats->emplace_back(ele.second);
     }
diff --git a/services/gpuservice/gpustats/GpuStats.h b/services/gpuservice/gpustats/GpuStats.h
index bb74fbb..49699ee 100644
--- a/services/gpuservice/gpustats/GpuStats.h
+++ b/services/gpuservice/gpustats/GpuStats.h
@@ -52,6 +52,8 @@
     void dumpGlobalLocked(std::string* result);
     // Dump app stats
     void dumpAppLocked(std::string* result);
+    // Append cpuVulkanVersion and glesVersion to system driver stats
+    void interceptSystemDriverStatsLocked();
 
     // Below limits the memory usage of GpuStats to be less than 10KB. This is
     // the preferred number for statsd while maintaining nice data quality.
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index b874411..31a2dab 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -3611,8 +3611,9 @@
 }
 
 void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
-    dump += StringPrintf(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
-    dump += StringPrintf(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
+    dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
+    dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
+    dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
     dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
 
     if (!mFocusedApplicationHandlesByDisplay.empty()) {
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 659329e..be75c64 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -467,11 +467,6 @@
                               asBaseType(INTERNAL_WAKE), &eventFlagState);
         availableEvents = mEventQueue->availableToRead();
 
-        if ((eventFlagState & asBaseType(EventQueueFlagBits::READ_AND_PROCESS)) &&
-                availableEvents == 0) {
-            ALOGW("Event FMQ wake without any events");
-        }
-
         if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) {
             ALOGD("Event FMQ internal wake, returning from poll with no events");
             return DEAD_OBJECT;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8ef03fb..23c6e89 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5099,6 +5099,14 @@
             ALOGE("Attempting to access SurfaceFlinger with unused code: %u", code);
             return PERMISSION_DENIED;
         }
+        case CAPTURE_SCREEN_BY_ID: {
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int uid = ipc->getCallingUid();
+            if ((uid == AID_GRAPHICS) || (uid == AID_SYSTEM) || (uid == AID_SHELL)) {
+                return OK;
+            }
+            return PERMISSION_DENIED;
+        }
     }
 
     // These codes are used for the IBinder protocol to either interrogate the recipient
@@ -5513,6 +5521,66 @@
                                useIdentityTransform, outCapturedSecureLayers);
 }
 
+static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) {
+    switch (colorMode) {
+        case ColorMode::DISPLAY_P3:
+        case ColorMode::BT2100_PQ:
+        case ColorMode::BT2100_HLG:
+        case ColorMode::DISPLAY_BT2020:
+            return Dataspace::DISPLAY_P3;
+        default:
+            return Dataspace::V0_SRGB;
+    }
+}
+
+const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
+    const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack});
+    if (displayToken) {
+        return getDisplayDeviceLocked(displayToken);
+    }
+    // Couldn't find display by displayId. Try to get display by layerStack since virtual displays
+    // may not have a displayId.
+    for (const auto& [token, display] : mDisplays) {
+        if (display->getLayerStack() == displayOrLayerStack) {
+            return display;
+        }
+    }
+    return nullptr;
+}
+
+status_t SurfaceFlinger::captureScreen(uint64_t displayOrLayerStack, Dataspace* outDataspace,
+                                       sp<GraphicBuffer>* outBuffer) {
+    sp<DisplayDevice> display;
+    uint32_t width;
+    uint32_t height;
+    ui::Transform::orientation_flags captureOrientation;
+    {
+        Mutex::Autolock _l(mStateLock);
+        display = getDisplayByIdOrLayerStack(displayOrLayerStack);
+        if (!display) {
+            return BAD_VALUE;
+        }
+
+        width = uint32_t(display->getViewport().width());
+        height = uint32_t(display->getViewport().height());
+
+        captureOrientation = fromSurfaceComposerRotation(
+                static_cast<ISurfaceComposer::Rotation>(display->getOrientation()));
+        *outDataspace =
+                pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
+    }
+
+    DisplayRenderArea renderArea(display, Rect(), width, height, *outDataspace, captureOrientation,
+                                 false /* captureSecureLayers */);
+
+    auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display,
+                                    std::placeholders::_1);
+    bool ignored = false;
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, ui::PixelFormat::RGBA_8888,
+                               false /* useIdentityTransform */,
+                               ignored /* outCapturedSecureLayers */);
+}
+
 status_t SurfaceFlinger::captureLayers(
         const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
         const Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5871774..d9de07b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -405,6 +405,8 @@
             const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
             uint32_t reqWidth, uint32_t reqHeight,
             bool useIdentityTransform, ISurfaceComposer::Rotation rotation, bool captureSecureLayers) override;
+    status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
+                           sp<GraphicBuffer>* outBuffer) override;
     status_t captureLayers(
             const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
             const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
@@ -636,6 +638,7 @@
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                  const sp<GraphicBuffer>& buffer, bool useIdentityTransform,
                                  bool& outCapturedSecureLayers);
+    const sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
                                      ANativeWindowBuffer* buffer, bool useIdentityTransform,
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 4e040a3..2bcb568 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -41,7 +41,7 @@
 
     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
     virtual bool isEnabled() = 0;
-    virtual std::string miniDump();
+    virtual std::string miniDump() = 0;
 
     virtual void incrementTotalFrames() = 0;
     virtual void incrementMissedFrames() = 0;