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
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 2c50acc..0ac493d 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -109,52 +109,33 @@
}
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 @@
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);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 62a3c45..65a1a01 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1921,26 +1921,57 @@
}
// ----------------------------------------------------------------------------
+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
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e955ea8..e057b68 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -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 @@
* 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 @@
* 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.
*
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 1a9710a..05151ba 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -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 @@
// ---------------------------------------------------------------------------
+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,
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index d88c477..4a186b1 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -203,6 +203,20 @@
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 @@
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 @@
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 @@
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 @@
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:
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 9fd8c42..aedba2a 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -197,6 +197,20 @@
ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU));
}
+ 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<Surface> mSurface;
sp<SurfaceComposerClient> mComposerClient;
sp<SurfaceControl> mSurfaceControl;
@@ -250,7 +264,7 @@
captureArgs.height = 64;
ScreenCaptureResults captureResults;
- ASSERT_EQ(NO_ERROR, sf->captureDisplay(captureArgs, captureResults));
+ ASSERT_EQ(NO_ERROR, captureDisplay(captureArgs, captureResults));
ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
NATIVE_WINDOW_API_CPU));
@@ -280,7 +294,7 @@
&buf));
ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
}
- ASSERT_EQ(NO_ERROR, sf->captureDisplay(captureArgs, captureResults));
+ ASSERT_EQ(NO_ERROR, captureDisplay(captureArgs, captureResults));
}
TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -743,7 +757,7 @@
status_t setActiveColorMode(const sp<IBinder>& /*display*/,
ColorMode /*colorMode*/) override { return NO_ERROR; }
status_t captureDisplay(const DisplayCaptureArgs& /* captureArgs */,
- ScreenCaptureResults& /* captureResults */) override {
+ const sp<IScreenCaptureListener>& /* captureListener */) override {
return NO_ERROR;
}
status_t getAutoLowLatencyModeSupport(const sp<IBinder>& /*display*/,
@@ -757,11 +771,12 @@
}
void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {}
status_t captureDisplay(uint64_t /*displayOrLayerStack*/,
- ScreenCaptureResults& /* captureResults */) override {
+ const sp<IScreenCaptureListener>& /* captureListener */) override {
return NO_ERROR;
}
- virtual status_t captureLayers(const LayerCaptureArgs& /* captureArgs */,
- ScreenCaptureResults& /* captureResults */) override {
+ virtual status_t captureLayers(
+ const LayerCaptureArgs& /* captureArgs */,
+ const sp<IScreenCaptureListener>& /* captureListener */) override {
return NO_ERROR;
}
status_t clearAnimationFrameStats() override { return NO_ERROR; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ccbb569..7572be3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5493,7 +5493,7 @@
}
status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
status_t validate = validateScreenshotPermissions(args);
@@ -5531,8 +5531,12 @@
auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
traverseLayersInLayerStack(layerStack, args.uid, visitor);
};
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
- args.pixelFormat, captureResults);
+ ScreenCaptureResults captureResults;
+ status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+ args.pixelFormat, captureResults);
+ captureResults.result = status;
+ captureListener->onScreenCaptureComplete(captureResults);
+ return status;
}
status_t SurfaceFlinger::setSchedFifo(bool enabled) {
@@ -5575,7 +5579,7 @@
}
status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
ui::LayerStack layerStack;
wp<DisplayDevice> displayWeak;
ui::Size size;
@@ -5596,8 +5600,7 @@
}
RenderAreaFuture renderAreaFuture = promise::defer([=] {
- return DisplayRenderArea::create(displayWeak, Rect(), size,
- captureResults.capturedDataspace,
+ return DisplayRenderArea::create(displayWeak, Rect(), size, dataspace,
false /* useIdentityTransform */,
false /* captureSecureLayers */);
});
@@ -5606,12 +5609,16 @@
traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
};
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
- ui::PixelFormat::RGBA_8888, captureResults);
+ ScreenCaptureResults captureResults;
+ status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
+ ui::PixelFormat::RGBA_8888, captureResults);
+ captureResults.result = status;
+ captureListener->onScreenCaptureComplete(captureResults);
+ return status;
}
status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
status_t validate = validateScreenshotPermissions(args);
@@ -5720,8 +5727,12 @@
});
};
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
- args.pixelFormat, captureResults);
+ ScreenCaptureResults captureResults;
+ status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+ args.pixelFormat, captureResults);
+ captureResults.result = status;
+ captureListener->onScreenCaptureComplete(captureResults);
+ return status;
}
status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c53ae3e..fb79989 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -524,11 +524,11 @@
ISurfaceComposer::ConfigChanged configChanged =
ISurfaceComposer::eConfigChangedSuppress) override;
status_t captureDisplay(const DisplayCaptureArgs& args,
- ScreenCaptureResults& captureResults) override;
+ const sp<IScreenCaptureListener>& captureListener) override;
status_t captureDisplay(uint64_t displayOrLayerStack,
- ScreenCaptureResults& captureResults) override;
+ const sp<IScreenCaptureListener>& captureListener) override;
status_t captureLayers(const LayerCaptureArgs& args,
- ScreenCaptureResults& captureResults) override;
+ const sp<IScreenCaptureListener>& captureListener) override;
status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats) override;
status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) override;
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 10a517e..5128394 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -1,3 +1,23 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
#include <gtest/gtest.h>
#include <gui/ISurfaceComposer.h>
#include <gui/LayerDebugInfo.h>
@@ -7,8 +27,8 @@
#include <private/gui/ComposerService.h>
#include <ui/DisplayConfig.h>
#include <utils/String8.h>
-
#include <functional>
+#include "utils/ScreenshotUtils.h"
namespace android {
@@ -262,7 +282,7 @@
DisplayCaptureArgs captureArgs;
captureArgs.displayToken = display;
ScreenCaptureResults captureResults;
- return ScreenshotClient::captureDisplay(captureArgs, captureResults);
+ return ScreenCapture::captureDisplay(captureArgs, captureResults);
};
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
}
@@ -276,7 +296,7 @@
captureArgs.sourceCrop = {0, 0, 1, 1};
ScreenCaptureResults captureResults;
- return ScreenshotClient::captureLayers(captureArgs, captureResults);
+ return ScreenCapture::captureLayers(captureArgs, captureResults);
};
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
}
diff --git a/services/surfaceflinger/tests/InvalidHandles_test.cpp b/services/surfaceflinger/tests/InvalidHandles_test.cpp
index 300e9c7..cfec0d2 100644
--- a/services/surfaceflinger/tests/InvalidHandles_test.cpp
+++ b/services/surfaceflinger/tests/InvalidHandles_test.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
#include <binder/Binder.h>
#include <gtest/gtest.h>
@@ -22,6 +26,7 @@
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
#include <ui/Rect.h>
+#include "utils/ScreenshotUtils.h"
namespace android {
namespace {
@@ -56,13 +61,11 @@
}
TEST_F(InvalidHandleTest, captureLayersInvalidHandle) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-
LayerCaptureArgs args;
args.layerHandle = mNotSc->getHandle();
ScreenCaptureResults captureResults;
- ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
}
} // namespace
diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
index e3b9489..ab74c50 100644
--- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
@@ -167,7 +167,6 @@
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
sp<GraphicBuffer> outBuffer;
Transaction()
.setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
@@ -177,11 +176,12 @@
args.displayToken = mDisplay;
ScreenCaptureResults captureResults;
- ASSERT_EQ(PERMISSION_DENIED, composer->captureDisplay(args, captureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults));
Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
- ASSERT_EQ(NO_ERROR, composer->captureDisplay(args, captureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults));
}
+
TEST_P(LayerTypeTransactionTest, RefreshRateIsInitialized) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 690f758..962a0cf 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -84,14 +84,13 @@
Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
- ASSERT_EQ(PERMISSION_DENIED, composer->captureDisplay(mCaptureArgs, mCaptureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
UIDFaker f(AID_SYSTEM);
// By default the system can capture screenshots with secure layers but they
// will be blacked out
- ASSERT_EQ(NO_ERROR, composer->captureDisplay(mCaptureArgs, mCaptureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
{
SCOPED_TRACE("as system");
@@ -104,7 +103,7 @@
DisplayCaptureArgs args;
args.displayToken = mDisplay;
args.captureSecureLayers = true;
- ASSERT_EQ(NO_ERROR, composer->captureDisplay(args, mCaptureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
ScreenCapture sc(mCaptureResults.buffer);
sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
@@ -307,21 +306,17 @@
sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
SurfaceComposerClient::Transaction().show(child).apply(true);
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-
LayerCaptureArgs args;
args.layerHandle = child->getHandle();
ScreenCaptureResults captureResults;
- ASSERT_EQ(BAD_VALUE, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
}
TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
SurfaceComposerClient::Transaction().show(child).apply(true);
-
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
sp<GraphicBuffer> outBuffer;
LayerCaptureArgs args;
@@ -329,11 +324,11 @@
args.childrenOnly = false;
ScreenCaptureResults captureResults;
- ASSERT_EQ(BAD_VALUE, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
TransactionUtils::fillSurfaceRGBA8(child, Color::RED);
SurfaceComposerClient::Transaction().apply(true);
- ASSERT_EQ(NO_ERROR, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
ScreenCapture sc(captureResults.buffer);
sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
}
@@ -482,9 +477,8 @@
args.layerHandle = redLayerHandle;
ScreenCaptureResults captureResults;
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
// Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
- ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
}
TEST_F(ScreenCaptureTest, CaputureSecureLayer) {
@@ -505,15 +499,13 @@
.setLayer(redLayer, INT32_MAX)
.apply();
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-
LayerCaptureArgs args;
args.layerHandle = redLayerHandle;
args.childrenOnly = false;
ScreenCaptureResults captureResults;
// Call from outside system with secure layers will result in permission denied
- ASSERT_EQ(PERMISSION_DENIED, sf->captureLayers(args, captureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
UIDFaker f(AID_SYSTEM);
@@ -551,8 +543,7 @@
// From non system uid, can't request screenshot without a specified uid.
UIDFaker f(fakeUid);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
- ASSERT_EQ(PERMISSION_DENIED, composer->captureDisplay(captureArgs, mCaptureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(captureArgs, mCaptureResults));
// Make screenshot request with current uid set. No layers were created with the current
// uid so screenshot will be black.
@@ -604,8 +595,7 @@
// From non system uid, can't request screenshot without a specified uid.
std::unique_ptr<UIDFaker> uidFaker = std::make_unique<UIDFaker>(fakeUid);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
- ASSERT_EQ(PERMISSION_DENIED, composer->captureLayers(captureArgs, mCaptureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
// Make screenshot request with current uid set. No layers were created with the current
// uid so screenshot will be black.
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index 081d18b..fbf5ecf 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -17,28 +17,50 @@
#include <ui/Rect.h>
#include <utils/String8.h>
+#include <functional>
+#include <future>
#include "TransactionUtils.h"
namespace android {
namespace {
+class SyncScreenCaptureListener : public BnScreenCaptureListener {
+public:
+ status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override {
+ resultsPromise.set_value(captureResults);
+ return NO_ERROR;
+ }
+
+ ScreenCaptureResults waitForResults() {
+ std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
+ return resultsFuture.get();
+ }
+
+private:
+ std::promise<ScreenCaptureResults> resultsPromise;
+};
+
// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
// individual pixel values for testing purposes.
class ScreenCapture : public RefBase {
public:
- static void captureScreen(std::unique_ptr<ScreenCapture>* sc) {
- captureScreen(sc, SurfaceComposerClient::getInternalDisplayToken());
- }
-
- static void captureDisplay(std::unique_ptr<ScreenCapture>* sc,
- const DisplayCaptureArgs& captureArgs) {
+ static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
+ ScreenCaptureResults& captureResults) {
const auto sf = ComposerService::getComposerService();
SurfaceComposerClient::Transaction().apply(true);
- ScreenCaptureResults captureResults;
- ASSERT_EQ(NO_ERROR, sf->captureDisplay(captureArgs, captureResults));
- *sc = std::make_unique<ScreenCapture>(captureResults.buffer);
+ 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;
+ }
+
+ static void captureScreen(std::unique_ptr<ScreenCapture>* sc) {
+ captureScreen(sc, SurfaceComposerClient::getInternalDisplayToken());
}
static void captureScreen(std::unique_ptr<ScreenCapture>* sc, sp<IBinder> displayToken) {
@@ -47,13 +69,30 @@
captureDisplay(sc, args);
}
- static void captureLayers(std::unique_ptr<ScreenCapture>* sc,
- const LayerCaptureArgs& captureArgs) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ static void captureDisplay(std::unique_ptr<ScreenCapture>* sc,
+ DisplayCaptureArgs& captureArgs) {
+ ScreenCaptureResults captureResults;
+ ASSERT_EQ(NO_ERROR, captureDisplay(captureArgs, captureResults));
+ *sc = std::make_unique<ScreenCapture>(captureResults.buffer);
+ }
+
+ static status_t captureLayers(LayerCaptureArgs& captureArgs,
+ ScreenCaptureResults& captureResults) {
+ const auto sf = ComposerService::getComposerService();
SurfaceComposerClient::Transaction().apply(true);
+ const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
+ status_t status = sf->captureLayers(captureArgs, captureListener);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ captureResults = captureListener->waitForResults();
+ return captureResults.result;
+ }
+
+ static void captureLayers(std::unique_ptr<ScreenCapture>* sc, LayerCaptureArgs& captureArgs) {
ScreenCaptureResults captureResults;
- ASSERT_EQ(NO_ERROR, sf->captureLayers(captureArgs, captureResults));
+ ASSERT_EQ(NO_ERROR, captureLayers(captureArgs, captureResults));
*sc = std::make_unique<ScreenCapture>(captureResults.buffer);
}