Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ffc7b84 authored by chaviw's avatar chaviw
Browse files

Pass IScreenCaptureListener to screen capture functions

The call is still synchronous but the SF screen capture requests take in
the IScreenCaptureListener object so the results can be sent back
asynchronously.

Test: SurfaceFlinger_test
Test: libgui_test
Bug: 162367424
Change-Id: If20fc69c1bb9eca71f76c151d2aee160a666c506
parent 026919a2
Loading
Loading
Loading
Loading
+22 −49
Original line number Diff line number Diff line
@@ -109,52 +109,33 @@ public:
    }

    virtual status_t captureDisplay(const DisplayCaptureArgs& args,
                                    ScreenCaptureResults& captureResults) {
                                    const sp<IScreenCaptureListener>& captureListener) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

        SAFE_PARCEL(args.write, data);
        status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("captureDisplay failed to transact: %d", result);
            return result;
        }
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        SAFE_PARCEL(captureResults.read, reply);
        return NO_ERROR;
        return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
    }

    virtual status_t captureDisplay(uint64_t displayOrLayerStack,
                                    ScreenCaptureResults& captureResults) {
                                    const sp<IScreenCaptureListener>& captureListener) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        SAFE_PARCEL(data.writeUint64, displayOrLayerStack)
        status_t result =
                remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("captureDisplay failed to transact: %d", result);
            return result;
        }
        SAFE_PARCEL(data.writeUint64, displayOrLayerStack);
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        SAFE_PARCEL(captureResults.read, reply);
        return NO_ERROR;
        return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
    }

    virtual status_t captureLayers(const LayerCaptureArgs& args,
                                   ScreenCaptureResults& captureResults) {
                                   const sp<IScreenCaptureListener>& captureListener) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

        SAFE_PARCEL(args.write, data);
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("captureLayers failed to transact: %d", result);
            return result;
        }

        SAFE_PARCEL(captureResults.read, reply);
        return NO_ERROR;
        return remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
    }

    virtual bool authenticateSurfaceTexture(
@@ -1251,37 +1232,29 @@ status_t BnSurfaceComposer::onTransact(
        case CAPTURE_DISPLAY: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            DisplayCaptureArgs args;
            ScreenCaptureResults captureResults;

            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(args.read, data);
            status_t res = captureDisplay(args, captureResults);
            if (res == NO_ERROR) {
                SAFE_PARCEL(captureResults.write, *reply);
            }
            return res;
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureDisplay(args, captureListener);
        }
        case CAPTURE_DISPLAY_BY_ID: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            uint64_t displayOrLayerStack = 0;
            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(data.readUint64, &displayOrLayerStack);
            ScreenCaptureResults captureResults;
            status_t res = captureDisplay(displayOrLayerStack, captureResults);
            if (res == NO_ERROR) {
                SAFE_PARCEL(captureResults.write, *reply);
            }
            return res;
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureDisplay(displayOrLayerStack, captureListener);
        }
        case CAPTURE_LAYERS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            LayerCaptureArgs args;
            ScreenCaptureResults captureResults;

            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(args.read, data);
            status_t res = captureLayers(args, captureResults);
            if (res == NO_ERROR) {
                SAFE_PARCEL(captureResults.write, *reply);
            }
            return res;
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureLayers(args, captureListener);
        }
        case AUTHENTICATE_SURFACE: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+34 −3
Original line number Diff line number Diff line
@@ -1921,26 +1921,57 @@ status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColo
}

// ----------------------------------------------------------------------------
status_t SyncScreenCaptureListener::onScreenCaptureComplete(
        const ScreenCaptureResults& captureResults) {
    resultsPromise.set_value(captureResults);
    return NO_ERROR;
}

ScreenCaptureResults SyncScreenCaptureListener::waitForResults() {
    std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
    return resultsFuture.get();
}

status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
                                          ScreenCaptureResults& captureResults) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    return s->captureDisplay(captureArgs, captureResults);

    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    status_t status = s->captureDisplay(captureArgs, captureListener);
    if (status != NO_ERROR) {
        return status;
    }
    captureResults = captureListener->waitForResults();
    return captureResults.result;
}

status_t ScreenshotClient::captureDisplay(uint64_t displayOrLayerStack,
                                          ScreenCaptureResults& captureResults) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    return s->captureDisplay(displayOrLayerStack, captureResults);

    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    status_t status = s->captureDisplay(displayOrLayerStack, captureListener);
    if (status != NO_ERROR) {
        return status;
    }
    captureResults = captureListener->waitForResults();
    return captureResults.result;
}

status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
                                         ScreenCaptureResults& captureResults) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    return s->captureLayers(captureArgs, captureResults);

    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    status_t status = s->captureLayers(captureArgs, captureListener);
    if (status != NO_ERROR) {
        return status;
    }
    captureResults = captureListener->waitForResults();
    return captureResults.result;
}

} // namespace android
+4 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <binder/IBinder.h>
#include <binder/IInterface.h>

#include <gui/IScreenCaptureListener.h>
#include <gui/ITransactionCompletedListener.h>

#include <math/vec4.h>
@@ -255,10 +256,10 @@ public:
     * match the size of the output buffer.
     */
    virtual status_t captureDisplay(const DisplayCaptureArgs& args,
                                    ScreenCaptureResults& captureResults) = 0;
                                    const sp<IScreenCaptureListener>& captureListener) = 0;

    virtual status_t captureDisplay(uint64_t displayOrLayerStack,
                                    ScreenCaptureResults& captureResults) = 0;
                                    const sp<IScreenCaptureListener>& captureListener) = 0;

    template <class AA>
    struct SpHash {
@@ -271,7 +272,7 @@ public:
     * is a secure window on screen
     */
    virtual status_t captureLayers(const LayerCaptureArgs& args,
                                   ScreenCaptureResults& captureResults) = 0;
                                   const sp<IScreenCaptureListener>& captureListener) = 0;

    /* Clears the frame statistics for animations.
     *
+10 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <stdint.h>
#include <sys/types.h>
#include <future>
#include <set>
#include <unordered_map>
#include <unordered_set>
@@ -593,10 +594,17 @@ private:

// ---------------------------------------------------------------------------

class SyncScreenCaptureListener : public BnScreenCaptureListener {
public:
    status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override;
    ScreenCaptureResults waitForResults();

private:
    std::promise<ScreenCaptureResults> resultsPromise;
};

class ScreenshotClient {
public:
    // if cropping isn't required, callers may pass in a default Rect, e.g.:
    //   capture(display, producer, Rect(), reqWidth, ...);
    static status_t captureDisplay(const DisplayCaptureArgs& captureArgs,
                                   ScreenCaptureResults& captureResults);
    static status_t captureDisplay(uint64_t displayOrLayerStack,
+18 −4
Original line number Diff line number Diff line
@@ -203,6 +203,20 @@ protected:
        ASSERT_EQ(false, ::testing::Test::HasFailure());
    }

    static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
                                   ScreenCaptureResults& captureResults) {
        const auto sf = ComposerService::getComposerService();
        SurfaceComposerClient::Transaction().apply(true);

        const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
        status_t status = sf->captureDisplay(captureArgs, captureListener);
        if (status != NO_ERROR) {
            return status;
        }
        captureResults = captureListener->waitForResults();
        return captureResults.result;
    }

    sp<SurfaceComposerClient> mClient;
    sp<ISurfaceComposer> mComposer;

@@ -306,7 +320,7 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
    adapter.waitForCallbacks();

    // capture screen and verify that it is red
    ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults));
    ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
    ASSERT_NO_FATAL_FAILURE(
            checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
}
@@ -383,7 +397,7 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) {

    adapter.waitForCallbacks();
    // capture screen and verify that it is red
    ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults));
    ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));

    ASSERT_NO_FATAL_FAILURE(
            checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
@@ -440,7 +454,7 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {

    adapter.waitForCallbacks();
    // capture screen and verify that it is red
    ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults));
    ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));

    ASSERT_NO_FATAL_FAILURE(
            checkScreenCapture(r, g, b,
@@ -481,7 +495,7 @@ public:
        ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);

        adapter.waitForCallbacks();
        ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults));
        ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));

        switch (tr) {
            case ui::Transform::ROT_0:
Loading