Restore ability of system to screenshot secure layers.
In previous iterations of the code the "secureLayerIsVisible" block
had a guard for "localProducer" which was set to true if the IGBP we
were screenshotting to was originally allocated by SurfaceFlinger. What
this means is that it came from a SurfaceControl, rather than just being
allocated on the client side. Note that the caller could still read the
Screenshot back out from the surface, so the old logic just ensured
you can't screenshot secure layers unless you have a SurfaceControl. Having
a SurfaceControl meant you had either the permission ACCESS_SURFACE_FLINGER,
were from AID_SYSTEM/AID_GRAPHICS, or had been granted a SurfaceControl. This
allowed the system server to screenshot secure layers for the screen rotation
animation. When switching to the GraphicBuffer based interface we eliminated
this permisivity. This CL reintroduces it in what is hopefully
a clearer way, by explicitly only granting the ability to system
components.
Bug: 70403018
Test: Manual
Change-Id: Icbc51e897f5d46838a68c1387e993b8e6a68cd1d
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7e308e8..db13b99 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4400,6 +4400,9 @@
int syncFd = -1;
std::optional<status_t> captureResult;
+ const int uid = IPCThreadState::self()->getCallingUid();
+ const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
+
sp<LambdaMessage> message = new LambdaMessage([&]() {
// If there is a refresh pending, bug out early and tell the binder thread to try again
// after the refresh.
@@ -4416,7 +4419,7 @@
{
Mutex::Autolock _l(mStateLock);
result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
- useIdentityTransform, &fd);
+ useIdentityTransform, forSystem, &fd);
}
{
@@ -4513,6 +4516,7 @@
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer,
bool useIdentityTransform,
+ bool forSystem,
int* outSyncFd) {
ATRACE_CALL();
@@ -4522,7 +4526,10 @@
secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && layer->isSecure());
});
- if (secureLayerIsVisible) {
+ // We allow the system server to take screenshots of secure layers for
+ // use in situations like the Screen-rotation animation and place
+ // the impetus on WindowManager to not persist them.
+ if (secureLayerIsVisible && !forSystem) {
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}