diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 554fa43..a9fa1ef 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -327,6 +327,40 @@ void SurfaceFlinger::signal() const { const_cast<SurfaceFlinger*>(this)->signalEvent(); } +bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const { + Mutex::Autolock _l(mStateLock); + sp<IBinder> surfBinder(surface->asBinder()); + + // Check the visible layer list for the ISurface + const LayerVector& currentLayers = mCurrentState.layersSortedByZ; + size_t count = currentLayers.size(); + for (size_t i=0 ; i<count ; i++) { + const sp<LayerBase>& layer(currentLayers[i]); + sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); + if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) { + return true; + } + } + + // Check the layers in the purgatory. This check is here so that if a + // Surface gets destroyed before all the clients are done using it, the + // error will not be reported as "surface XYZ is not authenticated", but + // will instead fail later on when the client tries to use the surface, + // which should be reported as "surface XYZ returned an -ENODEV". The + // purgatorized layers are no less authentic than the visible ones, so this + // should not cause any harm. + size_t purgatorySize = mLayerPurgatory.size(); + for (size_t i=0 ; i<purgatorySize ; i++) { + const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); + sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); + if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) { + return true; + } + } + + return false; +} + status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime, uint32_t flags) { @@ -2135,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; @@ -2183,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; |