Merge "SF: check secure layers in screenshot message handler" into nyc-dev
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index bdf8f74..e9cbbca 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -82,7 +82,6 @@
mFlags(),
mPageFlipCount(),
mIsSecure(isSecure),
- mSecureLayerVisible(false),
mLayerStack(NO_LAYER_STACK),
mOrientation(),
mPowerMode(HWC_POWER_MODE_OFF),
@@ -307,24 +306,12 @@
void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
mVisibleLayersSortedByZ = layers;
- mSecureLayerVisible = false;
- size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
- if (layer->isSecure()) {
- mSecureLayerVisible = true;
- }
- }
}
const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
return mVisibleLayersSortedByZ;
}
-bool DisplayDevice::getSecureLayerVisible() const {
- return mSecureLayerVisible;
-}
-
Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
Region dirty;
if (repaintEverything) {
@@ -506,13 +493,13 @@
result.appendFormat(
"+ DisplayDevice: %s\n"
" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
- "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
+ "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
mDisplayName.string(), mType, mHwcDisplayId,
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
mOrientation, tr.getType(), getPageFlipCount(),
- mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig,
+ mIsSecure, mPowerMode, mActiveConfig,
mVisibleLayersSortedByZ.size(),
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 8695a44..6d380d1 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -106,7 +106,6 @@
void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers);
const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const;
- bool getSecureLayerVisible() const;
Region getDirtyRegion(bool repaintEverything) const;
void setLayerStack(uint32_t stack);
@@ -202,10 +201,6 @@
// list of visible layers on that display
Vector< sp<Layer> > mVisibleLayersSortedByZ;
- // Whether we have a visible secure layer on this display
- bool mSecureLayerVisible;
-
-
/*
* Transaction state
*/
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1e33847..737cc82 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3183,14 +3183,7 @@
// if we have secure windows on this display, never allow the screen capture
// unless the producer interface is local (i.e.: we can take a screenshot for
// ourselves).
- if (!IInterface::asBinder(producer)->localBinder()) {
- Mutex::Autolock _l(mStateLock);
- sp<const DisplayDevice> hw(getDisplayDevice(display));
- if (hw->getSecureLayerVisible()) {
- ALOGW("FB is protected: PERMISSION_DENIED");
- return PERMISSION_DENIED;
- }
- }
+ bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
// Convert to surfaceflinger's internal rotation type.
Transform::orientation_flags rotationFlags;
@@ -3223,19 +3216,22 @@
bool useIdentityTransform;
Transform::orientation_flags rotation;
status_t result;
+ bool isLocalScreenshot;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform,
+ Transform::orientation_flags rotation,
+ bool isLocalScreenshot)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
- rotation(rotation),
- result(PERMISSION_DENIED)
+ rotation(rotation), result(PERMISSION_DENIED),
+ isLocalScreenshot(isLocalScreenshot)
{
}
status_t getResult() const {
@@ -3246,7 +3242,7 @@
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotation);
+ useIdentityTransform, rotation, isLocalScreenshot);
static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
return true;
}
@@ -3269,7 +3265,7 @@
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotationFlags);
+ useIdentityTransform, rotationFlags, isLocalScreenshot);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@@ -3353,7 +3349,8 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool isLocalScreenshot)
{
ATRACE_CALL();
@@ -3374,6 +3371,24 @@
reqWidth = (!reqWidth) ? hw_w : reqWidth;
reqHeight = (!reqHeight) ? hw_h : reqHeight;
+ bool secureLayerIsVisible = false;
+ const LayerVector& layers(mDrawingState.layersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i = 0 ; i < count ; ++i) {
+ const sp<Layer>& layer(layers[i]);
+ const Layer::State& state(layer->getDrawingState());
+ if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
+ state.z <= maxLayerZ && layer->isVisible() &&
+ layer->isSecure()) {
+ secureLayerIsVisible = true;
+ }
+ }
+
+ if (!isLocalScreenshot && secureLayerIsVisible) {
+ ALOGW("FB is protected: PERMISSION_DENIED");
+ return PERMISSION_DENIED;
+ }
+
// create a surface (because we're a producer, and we need to
// dequeue/queue a buffer)
sp<Surface> sur = new Surface(producer, false);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4e0160a..4101a70 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -329,7 +329,8 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation);
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool isLocalScreenshot);
/* ------------------------------------------------------------------------
* EGL