From ab0c319824632c463ea624cee6f0bc3c8cd8a779 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 1 Aug 2017 11:29:00 -0700 Subject: libsurfaceflinger: handle WINDOW_TYPE_DONT_SCREENSHOT When a layer has type WINDOW_TYPE_DONT_SCREENSHOT, hide it from everywhere but the primary display. This should be reverted when we switch to use layer hierarchy properly. Bug: 63311708 Test: screencap, screenrecord, android.view.cts.SurfaceViewSyncTest Change-Id: I6a8d6b93399b0dc42832588f9a6c5e8879a8b754 --- services/surfaceflinger/SurfaceFlinger.cpp | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d435dbc3c3..494f34791f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1682,12 +1682,11 @@ void SurfaceFlinger::rebuildLayerStacks() { const Transform& tr(displayDevice->getTransform()); const Rect bounds(displayDevice->getBounds()); if (displayDevice->isDisplayOn()) { - computeVisibleRegions( - displayDevice->getLayerStack(), dirtyRegion, - opaqueRegion); + computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion); mDrawingState.traverseInZOrder([&](Layer* layer) { - if (layer->getLayerStack() == displayDevice->getLayerStack()) { + if (layer->belongsToDisplay(displayDevice->getLayerStack(), + displayDevice->isPrimary())) { Region drawRegion(tr.transform( layer->visibleNonTransparentRegion)); drawRegion.andSelf(bounds); @@ -2208,7 +2207,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) disp.clear(); for (size_t dpy=0 ; dpy hw(mDisplays[dpy]); - if (hw->getLayerStack() == currentlayerStack) { + if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) { if (disp == NULL) { disp = hw; } else { @@ -2257,7 +2256,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // TODO: we could cache the transformed region Region visibleReg; visibleReg.set(layer->computeScreenBounds()); - invalidateLayerStack(layer->getLayerStack(), visibleReg); + invalidateLayerStack(layer, visibleReg); } }); } @@ -2306,7 +2305,7 @@ void SurfaceFlinger::commitTransaction() mTransactionCV.broadcast(); } -void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack, +void SurfaceFlinger::computeVisibleRegions(const sp& displayDevice, Region& outDirtyRegion, Region& outOpaqueRegion) { ATRACE_CALL(); @@ -2323,7 +2322,7 @@ void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack, const Layer::State& s(layer->getDrawingState()); // only consider the layers on the given layer stack - if (layer->getLayerStack() != layerStack) + if (!layer->belongsToDisplay(displayDevice->getLayerStack(), displayDevice->isPrimary())) return; /* @@ -2438,11 +2437,10 @@ void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack, outOpaqueRegion = aboveOpaqueLayers; } -void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, - const Region& dirty) { +void SurfaceFlinger::invalidateLayerStack(const sp& layer, const Region& dirty) { for (size_t dpy=0 ; dpy& hw(mDisplays[dpy]); - if (hw->getLayerStack() == layerStack) { + if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) { hw->dirtyRegion.orSelf(dirty); } } @@ -2483,7 +2481,7 @@ bool SurfaceFlinger::handlePageFlip() for (auto& layer : mLayersWithQueuedFrames) { const Region dirty(layer->latchBuffer(visibleRegions, latchTime)); layer->useSurfaceDamage(); - invalidateLayerStack(layer->getLayerStack(), dirty); + invalidateLayerStack(layer, dirty); if (layer->isBufferLatched()) { newDataLatched = true; } @@ -3105,6 +3103,13 @@ status_t SurfaceFlinger::createLayer( return result; } + // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java + // TODO b/64227542 + if (windowType == 441731) { + windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL + layer->setPrimaryDisplayOnly(); + } + layer->setInfo(windowType, ownerUid); result = addClientLayer(client, *handle, *gbp, layer, *parent); @@ -4332,7 +4337,7 @@ void SurfaceFlinger::renderScreenImplLocked( // We loop through the first level of layers without traversing, // as we need to interpret min/max layer Z in the top level Z space. for (const auto& layer : mDrawingState.layersSortedByZ) { - if (layer->getLayerStack() != hw->getLayerStack()) { + if (!layer->belongsToDisplay(hw->getLayerStack(), false)) { continue; } const Layer::State& state(layer->getDrawingState()); @@ -4384,7 +4389,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(const sp& bool secureLayerIsVisible = false; for (const auto& layer : mDrawingState.layersSortedByZ) { const Layer::State& state(layer->getDrawingState()); - if ((layer->getLayerStack() != hw->getLayerStack()) || + if (layer->belongsToDisplay(hw->getLayerStack(), false) || (state.z < minLayerZ || state.z > maxLayerZ)) { continue; } @@ -4495,7 +4500,7 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v size_t i = 0; for (const auto& layer : mDrawingState.layersSortedByZ) { const Layer::State& state(layer->getDrawingState()); - if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ && + if (layer->belongsToDisplay(hw->getLayerStack(), false) && state.z >= minLayerZ && state.z <= maxLayerZ) { layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", -- cgit v1.2.3-59-g8ed1b