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

Commit 367ff7fd authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Fix shared dim layer not cleared when all users removed

For secondary display, shared fullscreen dim layer user is
the only stack that is present on the display. When this stack
is removed the shared dim layer was not cleared. Because of
that it was crashing when trying to obtain DisplayContent from it.

Now when we're removing a dim layer user we check if we've removed
the last one and clear shared fullscreen dim layer if needed.

Bug: 34367817
Test: bit FrameworksServicesTests:com.android.server.wm.DimLayerControllerTests
Change-Id: I415196a345c491eddd26a55370bb819ce6485151
parent b922d1f9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -322,6 +322,9 @@ class DimLayerController {
            }
            mState.remove(dimLayerUser);
        }
        if (mState.isEmpty()) {
            mSharedFullScreenDimLayer = null;
        }
    }

    @VisibleForTesting
@@ -329,6 +332,11 @@ class DimLayerController {
        return mState.containsKey(dimLayerUser);
    }

    @VisibleForTesting
    boolean hasSharedFullScreenDimLayer() {
        return mSharedFullScreenDimLayer != null;
    }

    void applyDimBehind(DimLayer.DimLayerUser dimLayerUser, WindowStateAnimator animator) {
        applyDim(dimLayerUser, animator, false /* aboveApp */);
    }
+5 −0
Original line number Diff line number Diff line
@@ -627,6 +627,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    };

    /**
     * Create new {@link DisplayContent} instance, add itself to the root window container and
     * initialize direct children.
     * @param display May not be null.
     * @param service You know.
     * @param layersController window layer controller used to assign layer to the windows on this
@@ -661,6 +663,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        super.addChild(mTaskStackContainers, null);
        super.addChild(mAboveAppWindowsContainers, null);
        super.addChild(mImeWindowsContainers, null);

        // Add itself as a child to the root container.
        mService.mRoot.addChild(this, null);
    }

    int getDisplayId() {
+0 −1
Original line number Diff line number Diff line
@@ -213,7 +213,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
        final int displayId = display.getDisplayId();

        if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
        addChild(dc, null);

        final DisplayInfo displayInfo = dc.getDisplayInfo();
        final Rect rect = new Rect();
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.wm;

import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.hardware.display.DisplayManagerGlobal;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.Display;
import android.view.DisplayInfo;

import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests for the {@link DimLayerController} class.
 *
 * Build/Install/Run:
 *  bit FrameworksServicesTests:com.android.server.wm.DimLayerControllerTests
 */
@SmallTest
@Presubmit
@org.junit.runner.RunWith(AndroidJUnit4.class)
public class DimLayerControllerTests extends WindowTestsBase {

    /**
     * This tests if shared fullscreen dim layer is added when stack is added to display
     * and is removed when the only stack on the display is removed.
     */
    @Test
    public void testSharedFullScreenDimLayer() throws Exception {
        // Create a display.
        final DisplayContent dc = createNewDisplay();
        assertFalse(dc.mDimLayerController.hasSharedFullScreenDimLayer());

        // Add stack with activity.
        final TaskStack stack = createTaskStackOnDisplay(dc);
        assertTrue(dc.mDimLayerController.hasDimLayerUser(stack));
        assertTrue(dc.mDimLayerController.hasSharedFullScreenDimLayer());

        // Remove the only stack on the display and check if the shared dim layer clears.
        stack.removeImmediately();
        assertFalse(dc.mDimLayerController.hasDimLayerUser(stack));
        assertFalse(dc.mDimLayerController.hasSharedFullScreenDimLayer());
    }
}
+25 −8
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.view.DisplayInfo;

import java.util.ArrayList;

import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
@@ -215,13 +216,8 @@ public class DisplayContentTests extends WindowTestsBase {
     */
    @Test
    public void testMoveStackBetweenDisplays() throws Exception {
        // Create second display.
        final Display display = new Display(DisplayManagerGlobal.getInstance(),
                sDisplayContent.getDisplayId() + 1, new DisplayInfo(),
                DEFAULT_DISPLAY_ADJUSTMENTS);
        final DisplayContent dc = new DisplayContent(display, sWm, sLayersController,
                new WallpaperController(sWm));
        sWm.mRoot.addChild(dc, 1);
        // Create a second display.
        final DisplayContent dc = createNewDisplay();

        // Add stack with activity.
        final TaskStack stack = createTaskStackOnDisplay(dc);
@@ -261,10 +257,31 @@ public class DisplayContentTests extends WindowTestsBase {

        // Check that override config is applied.
        assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
    }

    /**
     * This tests global configuration updates when default display config is updated.
     */
    @Test
    public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();

        // Create new, slightly changed override configuration and apply it to the display.
        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
        newOverrideConfig.densityDpi += 120;
        newOverrideConfig.fontScale += 0.3;

        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);

        // Check that global configuration is updated, as we've updated default display's config.
        final Configuration globalConfig = sWm.mRoot.getConfiguration();
        Configuration globalConfig = sWm.mRoot.getConfiguration();
        assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
        assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);

        // Return back to original values.
        sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY);
        globalConfig = sWm.mRoot.getConfiguration();
        assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi);
        assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
    }
}
Loading