Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab0c3198 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

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
parent 37d8c19a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ public:

    uint32_t                getLayerStack() const { return mLayerStack; }
    int32_t                 getDisplayType() const { return mType; }
    bool                    isPrimary() const { return mType == DISPLAY_PRIMARY; }
    int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
    const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }

+8 −0
Original line number Diff line number Diff line
@@ -166,6 +166,8 @@ public:

    virtual ~Layer();

    void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; }

    // the this layer's size and format
    status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);

@@ -249,6 +251,10 @@ public:
    uint32_t getTransactionFlags(uint32_t flags);
    uint32_t setTransactionFlags(uint32_t flags);

    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
        return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
    }

    void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
            bool useIdentityTransform) const;
    Rect computeBounds(const Region& activeTransparentRegion) const;
@@ -701,6 +707,8 @@ private:
    String8 mTransactionName; // A cached version of "TX - " + mName for systraces
    PixelFormat mFormat;

    bool mPrimaryDisplayOnly = false;

    // these are protected by an external lock
    State mCurrentState;
    State mDrawingState;
+20 −15
Original line number Diff line number Diff line
@@ -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<mDisplays.size() ; dpy++) {
                    sp<const DisplayDevice> 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<const DisplayDevice>& 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<const Layer>& layer, const Region& dirty) {
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        const sp<DisplayDevice>& 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<const DisplayDevice>&
    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",
+2 −2
Original line number Diff line number Diff line
@@ -494,7 +494,7 @@ private:

    // mark a region of a layer stack dirty. this updates the dirty
    // region of all screens presenting this layer stack.
    void invalidateLayerStack(uint32_t layerStack, const Region& dirty);
    void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);

#ifndef USE_HWC2
    int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type);
@@ -510,7 +510,7 @@ private:
     * Compositing
     */
    void invalidateHwcGeometry();
    void computeVisibleRegions(uint32_t layerStack,
    void computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
            Region& dirtyRegion, Region& opaqueRegion);

    void preComposition(nsecs_t refreshStartTime);
+7 −8
Original line number Diff line number Diff line
@@ -1361,8 +1361,7 @@ void SurfaceFlinger::rebuildLayerStacks() {
            const Transform& tr(hw->getTransform());
            const Rect bounds(hw->getBounds());
            if (hw->isDisplayOn()) {
                computeVisibleRegions(hw->getLayerStack(), dirtyRegion,
                        opaqueRegion);
                computeVisibleRegions(hw, dirtyRegion, opaqueRegion);

                mDrawingState.traverseInZOrder([&](Layer* layer) {
                    if (layer->getLayerStack() == hw->getLayerStack()) {
@@ -1863,7 +1862,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);
            }
        });
    }
@@ -1924,7 +1923,7 @@ void SurfaceFlinger::commitTransaction()
    mTransactionCV.broadcast();
}

void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
        Region& outDirtyRegion, Region& outOpaqueRegion)
{
    ATRACE_CALL();
@@ -1940,7 +1939,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->getLayerStack() != displayDevice->getLayerStack())
            return;

        /*
@@ -2055,8 +2054,8 @@ void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
    outOpaqueRegion = aboveOpaqueLayers;
}

void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
        const Region& dirty) {
void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
    uint32_t layerStack = layer->getLayerStack();
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        const sp<DisplayDevice>& hw(mDisplays[dpy]);
        if (hw->getLayerStack() == layerStack) {
@@ -2099,7 +2098,7 @@ bool SurfaceFlinger::handlePageFlip()
        Layer* layer = layersWithQueuedFrames[i];
        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
        layer->useSurfaceDamage();
        invalidateLayerStack(layer->getLayerStack(), dirty);
        invalidateLayerStack(layer, dirty);
    }

    mVisibleRegionsDirty |= visibleRegions;