Loading libs/surfaceflinger_client/tests/Surface_test.cpp +59 −6 Original line number Diff line number Diff line Loading @@ -15,22 +15,19 @@ */ #include <gtest/gtest.h> #include <binder/IMemory.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/Surface.h> #include <surfaceflinger/SurfaceComposerClient.h> #include <utils/String8.h> namespace android { class SurfaceTest : public ::testing::Test { protected: virtual sp<SurfaceComposerClient> getSurfaceComposerClient() { return sp<SurfaceComposerClient>(new SurfaceComposerClient); } virtual void SetUp() { mComposerClient = getSurfaceComposerClient(); mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); mSurfaceControl = mComposerClient->createSurface(getpid(), Loading Loading @@ -77,4 +74,60 @@ TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) { EXPECT_EQ(1, result); } // This test probably doesn't belong here. TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) { sp<ANativeWindow> anw(mSurface); // Verify the screenshot works with no protected buffers. sp<IMemoryHeap> heap; uint32_t w=0, h=0; PixelFormat fmt=0; sp<ISurfaceComposer> sf(ComposerService::getComposerService()); ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap != NULL); // Set the PROTECTED usage bit and verify that the screenshot fails. Note // that we need to dequeue a buffer in order for it to actually get // allocated in SurfaceFlinger. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), GRALLOC_USAGE_PROTECTED)); ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3)); android_native_buffer_t* buf = 0; for (int i = 0; i < 4; i++) { // Loop to make sure SurfaceFlinger has retired a protected buffer. ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf)); ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf)); } heap = 0; w = h = fmt = 0; ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap == NULL); // XXX: This should not be needed, but it seems that the new buffers don't // correctly show up after the upcoming dequeue/lock/queue loop without it. // We should look into this at some point. ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3)); // Un-set the PROTECTED usage bit and verify that the screenshot works // again. Note that we have to change the buffers geometry to ensure that // the buffers get reallocated, as the new usage bits are a subset of the // old. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0)); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0)); for (int i = 0; i < 4; i++) { // Loop to make sure SurfaceFlinger has retired a protected buffer. ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf)); ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf)); } heap = 0; w = h = fmt = 0; ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap != NULL); } } services/surfaceflinger/Layer.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ Layer::Layer(SurfaceFlinger* flinger, mNeedsDithering(false), mSecure(false), mProtectedByApp(false), mProtectedByDRM(false), mTextureManager(), mBufferManager(mTextureManager), mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false) Loading Loading @@ -191,7 +190,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 && (flags & ISurfaceComposer::eOpaque) == 0; Loading Loading @@ -392,6 +390,12 @@ bool Layer::needsFiltering() const return LayerBase::needsFiltering(); } bool Layer::isProtected() const { sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer()); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); } status_t Layer::setBufferCount(int bufferCount) { Loading Loading @@ -515,7 +519,7 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const // request EGLImage for all buffers usage |= GraphicBuffer::USAGE_HW_TEXTURE; } if (mProtectedByApp || mProtectedByDRM) { if (mProtectedByApp) { // need a hardware-protected path to external video sink usage |= GraphicBuffer::USAGE_PROTECTED; } Loading services/surfaceflinger/Layer.h +1 −3 Original line number Diff line number Diff line Loading @@ -80,8 +80,7 @@ public: virtual bool needsDithering() const { return mNeedsDithering; } virtual bool needsFiltering() const; virtual bool isSecure() const { return mSecure; } virtual bool isProtectedByApp() const { return mProtectedByApp; } virtual bool isProtectedByDRM() const { return mProtectedByDRM; } virtual bool isProtected() const; virtual sp<Surface> createSurface() const; virtual status_t ditch(); virtual void onRemoved(); Loading Loading @@ -222,7 +221,6 @@ private: // page-flip thread (currently main thread) bool mSecure; // no screenshots bool mProtectedByApp; // application requires protected path to external sink bool mProtectedByDRM; // DRM agent requires protected path to external sink Region mPostedDirtyRegion; // page-flip thread and transaction thread (currently main thread) Loading services/surfaceflinger/LayerBase.h +3 −9 Original line number Diff line number Diff line Loading @@ -197,16 +197,10 @@ public: virtual bool isSecure() const { return false; } /** * isProtectedByApp - true if application says this surface is protected, that * is if it requires a hardware-protected data path to an external sink. * isProtected - true if the layer may contain protected content in the * GRALLOC_USAGE_PROTECTED sense. */ virtual bool isProtectedByApp() const { return false; } /** * isProtectedByDRM - true if DRM agent says this surface is protected, that * is if it requires a hardware-protected data path to an external sink. */ virtual bool isProtectedByDRM() const { return false; } virtual bool isProtected() const { return false; } /** Called from the main thread, when the surface is removed from the * draw list */ Loading services/surfaceflinger/SurfaceFlinger.cpp +13 −2 Original line number Diff line number Diff line Loading @@ -2169,6 +2169,19 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) return BAD_VALUE; // make sure none of the layers are protected const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const uint32_t z = layer->drawingState().z; if (z >= minLayerZ && z <= maxLayerZ) { if (layer->isProtected()) { return INVALID_OPERATION; } } } if (!GLExtensions::getInstance().haveFramebufferObject()) return INVALID_OPERATION; Loading Loading @@ -2217,8 +2230,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const uint32_t z = layer->drawingState().z; Loading Loading
libs/surfaceflinger_client/tests/Surface_test.cpp +59 −6 Original line number Diff line number Diff line Loading @@ -15,22 +15,19 @@ */ #include <gtest/gtest.h> #include <binder/IMemory.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/Surface.h> #include <surfaceflinger/SurfaceComposerClient.h> #include <utils/String8.h> namespace android { class SurfaceTest : public ::testing::Test { protected: virtual sp<SurfaceComposerClient> getSurfaceComposerClient() { return sp<SurfaceComposerClient>(new SurfaceComposerClient); } virtual void SetUp() { mComposerClient = getSurfaceComposerClient(); mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); mSurfaceControl = mComposerClient->createSurface(getpid(), Loading Loading @@ -77,4 +74,60 @@ TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) { EXPECT_EQ(1, result); } // This test probably doesn't belong here. TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) { sp<ANativeWindow> anw(mSurface); // Verify the screenshot works with no protected buffers. sp<IMemoryHeap> heap; uint32_t w=0, h=0; PixelFormat fmt=0; sp<ISurfaceComposer> sf(ComposerService::getComposerService()); ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap != NULL); // Set the PROTECTED usage bit and verify that the screenshot fails. Note // that we need to dequeue a buffer in order for it to actually get // allocated in SurfaceFlinger. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), GRALLOC_USAGE_PROTECTED)); ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3)); android_native_buffer_t* buf = 0; for (int i = 0; i < 4; i++) { // Loop to make sure SurfaceFlinger has retired a protected buffer. ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf)); ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf)); } heap = 0; w = h = fmt = 0; ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap == NULL); // XXX: This should not be needed, but it seems that the new buffers don't // correctly show up after the upcoming dequeue/lock/queue loop without it. // We should look into this at some point. ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3)); // Un-set the PROTECTED usage bit and verify that the screenshot works // again. Note that we have to change the buffers geometry to ensure that // the buffers get reallocated, as the new usage bits are a subset of the // old. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0)); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0)); for (int i = 0; i < 4; i++) { // Loop to make sure SurfaceFlinger has retired a protected buffer. ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf)); ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf)); } heap = 0; w = h = fmt = 0; ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0, 40000)); ASSERT_TRUE(heap != NULL); } }
services/surfaceflinger/Layer.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ Layer::Layer(SurfaceFlinger* flinger, mNeedsDithering(false), mSecure(false), mProtectedByApp(false), mProtectedByDRM(false), mTextureManager(), mBufferManager(mTextureManager), mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false) Loading Loading @@ -191,7 +190,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 && (flags & ISurfaceComposer::eOpaque) == 0; Loading Loading @@ -392,6 +390,12 @@ bool Layer::needsFiltering() const return LayerBase::needsFiltering(); } bool Layer::isProtected() const { sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer()); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); } status_t Layer::setBufferCount(int bufferCount) { Loading Loading @@ -515,7 +519,7 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const // request EGLImage for all buffers usage |= GraphicBuffer::USAGE_HW_TEXTURE; } if (mProtectedByApp || mProtectedByDRM) { if (mProtectedByApp) { // need a hardware-protected path to external video sink usage |= GraphicBuffer::USAGE_PROTECTED; } Loading
services/surfaceflinger/Layer.h +1 −3 Original line number Diff line number Diff line Loading @@ -80,8 +80,7 @@ public: virtual bool needsDithering() const { return mNeedsDithering; } virtual bool needsFiltering() const; virtual bool isSecure() const { return mSecure; } virtual bool isProtectedByApp() const { return mProtectedByApp; } virtual bool isProtectedByDRM() const { return mProtectedByDRM; } virtual bool isProtected() const; virtual sp<Surface> createSurface() const; virtual status_t ditch(); virtual void onRemoved(); Loading Loading @@ -222,7 +221,6 @@ private: // page-flip thread (currently main thread) bool mSecure; // no screenshots bool mProtectedByApp; // application requires protected path to external sink bool mProtectedByDRM; // DRM agent requires protected path to external sink Region mPostedDirtyRegion; // page-flip thread and transaction thread (currently main thread) Loading
services/surfaceflinger/LayerBase.h +3 −9 Original line number Diff line number Diff line Loading @@ -197,16 +197,10 @@ public: virtual bool isSecure() const { return false; } /** * isProtectedByApp - true if application says this surface is protected, that * is if it requires a hardware-protected data path to an external sink. * isProtected - true if the layer may contain protected content in the * GRALLOC_USAGE_PROTECTED sense. */ virtual bool isProtectedByApp() const { return false; } /** * isProtectedByDRM - true if DRM agent says this surface is protected, that * is if it requires a hardware-protected data path to an external sink. */ virtual bool isProtectedByDRM() const { return false; } virtual bool isProtected() const { return false; } /** Called from the main thread, when the surface is removed from the * draw list */ Loading
services/surfaceflinger/SurfaceFlinger.cpp +13 −2 Original line number Diff line number Diff line Loading @@ -2169,6 +2169,19 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) return BAD_VALUE; // make sure none of the layers are protected const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const uint32_t z = layer->drawingState().z; if (z >= minLayerZ && z <= maxLayerZ) { if (layer->isProtected()) { return INVALID_OPERATION; } } } if (!GLExtensions::getInstance().haveFramebufferObject()) return INVALID_OPERATION; Loading Loading @@ -2217,8 +2230,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const uint32_t z = layer->drawingState().z; Loading