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

Commit 5931b2d1 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge changes Ie6bebede,I21ebbfb0

* changes:
  Fixed Dimmer test
  Each dimmer can only have one dim layer at a time.
parents ee714474 f20bd225
Loading
Loading
Loading
Loading
+46 −39
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.wm;

import android.util.ArrayMap;
import android.view.SurfaceControl;
import android.graphics.Rect;

@@ -124,17 +123,30 @@ class Dimmer {
        }
    }

    @VisibleForTesting
    ArrayMap<WindowContainer, DimState> mDimLayerUsers = new ArrayMap<>();

    /**
     * The {@link WindowContainer} that our Dim's are bounded to. We may be dimming on behalf of the
     * host, some controller of it, or one of the hosts children.
     */
    private WindowContainer mHost;
    private WindowContainer mLastRequestedDimContainer;
    @VisibleForTesting
    DimState mDimState;

    private final SurfaceAnimatorStarter mSurfaceAnimatorStarter;

    @VisibleForTesting
    interface SurfaceAnimatorStarter {
        void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
                AnimationAdapter anim, boolean hidden);
    }

    Dimmer(WindowContainer host) {
        this(host, SurfaceAnimator::startAnimation);
    }

    Dimmer(WindowContainer host, SurfaceAnimatorStarter surfaceAnimatorStarter) {
        mHost = host;
        mSurfaceAnimatorStarter = surfaceAnimatorStarter;
    }

    private SurfaceControl makeDimLayer() {
@@ -146,29 +158,32 @@ class Dimmer {
    }

    /**
     * Retreive the DimState for a given child of the host.
     * Retrieve the DimState, creating one if it doesn't exist.
     */
    private DimState getDimState(WindowContainer container) {
        DimState state = mDimLayerUsers.get(container);
        if (state == null) {
        if (mDimState == null) {
            final SurfaceControl ctl = makeDimLayer();
            state = new DimState(ctl);
            mDimState = new DimState(ctl);
            /**
             * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's
             * via state resetting for Dim's with containers.
             */
            if (container == null) {
                state.mDontReset = true;
                mDimState.mDontReset = true;
            }
            mDimLayerUsers.put(container, state);
        }
        return state;

        mLastRequestedDimContainer = container;
        return mDimState;
    }

    private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer,
            float alpha) {
        final DimState d = getDimState(container);
        if (container != null) {
            // The dim method is called from WindowState.prepareSurfaces(), which is always called
            // in the correct Z from lowest Z to highest. This ensures that the dim layer is always
            // relative to the highest Z layer with a dim.
            t.setRelativeLayer(d.mDimLayer, container.getSurfaceControl(), relativeLayer);
        } else {
            t.setLayer(d.mDimLayer, Integer.MAX_VALUE);
@@ -237,11 +252,8 @@ class Dimmer {
     * a chance to request dims to continue.
     */
    void resetDimStates() {
        for (int i = mDimLayerUsers.size() - 1; i >= 0; i--) {
            final DimState state = mDimLayerUsers.valueAt(i);
            if (!state.mDontReset) {
                state.mDimming = false;
            }
        if (mDimState != null && !mDimState.mDontReset) {
            mDimState.mDimming = false;
        }
    }

@@ -254,30 +266,25 @@ class Dimmer {
     * @return true if any Dims were updated.
     */
    boolean updateDims(SurfaceControl.Transaction t, Rect bounds) {
        boolean didSomething = false;
        for (int i = mDimLayerUsers.size() - 1; i >= 0; i--) {
            DimState state = mDimLayerUsers.valueAt(i);
            WindowContainer container = mDimLayerUsers.keyAt(i);

            // TODO: We want to animate the addition and removal of Dim's instead of immediately
            // acting. When we do this we need to take care to account for the "Replacing Windows"
            // case (and seamless dim transfer).
            if (!state.mDimming) {
                mDimLayerUsers.removeAt(i);
                startDimExit(container, state.mSurfaceAnimator, t);
        if (mDimState == null) {
            return false;
        }

        if (!mDimState.mDimming) {
            startDimExit(mLastRequestedDimContainer, mDimState.mSurfaceAnimator, t);
            mDimState = null;
            return false;
        } else {
                didSomething = true;
            // TODO: Once we use geometry from hierarchy this falls away.
                t.setSize(state.mDimLayer, bounds.width(), bounds.height());
                t.setPosition(state.mDimLayer, bounds.left, bounds.top);
                if (!state.isVisible) {
                    state.isVisible = true;
                    t.show(state.mDimLayer);
                    startDimEnter(container, state.mSurfaceAnimator, t);
                }
            t.setSize(mDimState.mDimLayer, bounds.width(), bounds.height());
            t.setPosition(mDimState.mDimLayer, bounds.left, bounds.top);
            if (!mDimState.isVisible) {
                mDimState.isVisible = true;
                t.show(mDimState.mDimLayer);
                startDimEnter(mLastRequestedDimContainer, mDimState.mSurfaceAnimator, t);
            }
            return true;
        }
        return didSomething;
    }

    private void startDimEnter(WindowContainer container, SurfaceAnimator animator,
@@ -292,7 +299,7 @@ class Dimmer {

    private void startAnim(WindowContainer container, SurfaceAnimator animator,
            SurfaceControl.Transaction t, float startAlpha, float endAlpha) {
        animator.startAnimation(t, new LocalAnimationAdapter(
        mSurfaceAnimatorStarter.startAnimation(animator, t, new LocalAnimationAdapter(
                new AlphaAnimationSpec(startAlpha, endAlpha, getDimDuration(container)),
                mHost.mService.mSurfaceAnimationRunner), false /* hidden */);
    }
+2 −1
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ class SurfaceAnimator {
    SurfaceControl mLeash;
    private final Animatable mAnimatable;
    private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
    private final Runnable mAnimationFinishedCallback;
    @VisibleForTesting
    final Runnable mAnimationFinishedCallback;
    private boolean mAnimationStartDelayed;

    /**
+3 −10
Original line number Diff line number Diff line
@@ -904,16 +904,9 @@ public class WindowManagerService extends IWindowManager.Stub
    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
            WindowManagerPolicy policy) {
        return main(context, im, haveInputMethods, showBootMsgs, onlyCore, policy,
                new SurfaceAnimationRunner());
    }

    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
            WindowManagerPolicy policy, SurfaceAnimationRunner surfaceAnimationRunner) {
        DisplayThread.getHandler().runWithScissors(() ->
                sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
                        onlyCore, policy, surfaceAnimationRunner), 0);
                        onlyCore, policy), 0);
        return sInstance;
    }

@@ -936,7 +929,7 @@ public class WindowManagerService extends IWindowManager.Stub

    private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
            WindowManagerPolicy policy, SurfaceAnimationRunner surfaceAnimationRunner) {
            WindowManagerPolicy policy) {
        installLock(this, INDEX_WINDOW);
        mContext = context;
        mHaveInputMethods = haveInputMethods;
@@ -1063,7 +1056,7 @@ public class WindowManagerService extends IWindowManager.Stub
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
        mHoldingScreenWakeLock.setReferenceCounted(false);

        mSurfaceAnimationRunner = surfaceAnimationRunner;
        mSurfaceAnimationRunner = new SurfaceAnimationRunner();

        mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
+54 −53
Original line number Diff line number Diff line
@@ -18,11 +18,9 @@ package com.android.server.wm;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.graphics.Rect;
@@ -32,24 +30,17 @@ import android.view.SurfaceControl;
import android.view.SurfaceSession;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.stubbing.Answer;

/**
 * Build/Install/Run:
 * atest FrameworksServicesTests:com.android.server.wm.DimmerTests;
 */
@Presubmit
@Ignore("b/72450130")
@RunWith(AndroidJUnit4.class)
public class DimmerTests extends WindowTestsBase {

    public DimmerTests() {
        super(spy(new SurfaceAnimationRunner()));
    }

    private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
        final SurfaceControl mControl = mock(SurfaceControl.class);
        final SurfaceControl.Transaction mTransaction = mock(SurfaceControl.Transaction.class);
@@ -71,14 +62,11 @@ public class DimmerTests extends WindowTestsBase {

    private class MockSurfaceBuildingContainer extends WindowContainer<TestWindowContainer> {
        final SurfaceSession mSession = new SurfaceSession();
        final SurfaceControl mHostControl = mock(SurfaceControl.class);
        final SurfaceControl.Transaction mHostTransaction = mock(SurfaceControl.Transaction.class);

        MockSurfaceBuildingContainer() {
            super(sWm);
            mSurfaceControl = sWm.makeSurfaceBuilder(mSession)
                    .setName("test surface")
                    .setSize(1, 1)
                    .build();
        }

        class MockSurfaceBuilder extends SurfaceControl.Builder {
@@ -88,23 +76,18 @@ public class DimmerTests extends WindowTestsBase {

            @Override
            public SurfaceControl build() {
                return spy(sWm.makeSurfaceBuilder(mSession)
                        .setName("test surface")
                        .setSize(1, 1)
                        .build());
                return mock(SurfaceControl.class);
            }
        }

        @Override
        SurfaceControl.Builder makeSurface() {
            return sWm.makeSurfaceBuilder(mSession)
                    .setName("test surface")
                    .setSize(1, 1);
        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
            return new MockSurfaceBuilder(mSession);
        }

        @Override
        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
            return new MockSurfaceBuilder(mSession);
        public SurfaceControl getSurfaceControl() {
            return mHostControl;
        }

        @Override
@@ -113,9 +96,9 @@ public class DimmerTests extends WindowTestsBase {
        }
    }

    MockSurfaceBuildingContainer mHost;
    Dimmer mDimmer;
    SurfaceControl.Transaction mTransaction;
    private MockSurfaceBuildingContainer mHost;
    private Dimmer mDimmer;
    private SurfaceControl.Transaction mTransaction;

    @Before
    public void setUp() throws Exception {
@@ -123,13 +106,9 @@ public class DimmerTests extends WindowTestsBase {
        mHost = new MockSurfaceBuildingContainer();

        mTransaction = mock(SurfaceControl.Transaction.class);
        mDimmer = new Dimmer(mHost);

        doAnswer((Answer<Void>) invocation -> {
            Runnable runnable = invocation.getArgument(3);
            runnable.run();
            return null;
        }).when(sWm.mSurfaceAnimationRunner).startAnimation(any(), any(), any(), any());
        mDimmer = new Dimmer(mHost,
                (surfaceAnimator, t, anim, hidden) -> surfaceAnimator.mAnimationFinishedCallback
                        .run());
    }

    @Test
@@ -137,7 +116,7 @@ public class DimmerTests extends WindowTestsBase {
        final float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, alpha);

        SurfaceControl dimLayer = getDimLayer(null);
        SurfaceControl dimLayer = getDimLayer();

        assertNotNull("Dimmer should have created a surface", dimLayer);

@@ -149,12 +128,12 @@ public class DimmerTests extends WindowTestsBase {
    public void testDimAboveNoChildRedundantlyUpdatesAlphaOnExistingSurface() throws Exception {
        float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, alpha);
        final SurfaceControl firstSurface = getDimLayer(null);
        final SurfaceControl firstSurface = getDimLayer();

        alpha = 0.9f;
        mDimmer.dimAbove(mTransaction, alpha);

        assertEquals(firstSurface, getDimLayer(null));
        assertEquals(firstSurface, getDimLayer());
        verify(mTransaction).setAlpha(firstSurface, 0.9f);
    }

@@ -167,18 +146,18 @@ public class DimmerTests extends WindowTestsBase {
        Rect bounds = new Rect(0, 0, width, height);
        mDimmer.updateDims(mTransaction, bounds);

        verify(mTransaction).setSize(getDimLayer(null), width, height);
        verify(mTransaction).show(getDimLayer(null));
        verify(mTransaction).setSize(getDimLayer(), width, height);
        verify(mTransaction).show(getDimLayer());
    }

    @Test
    public void testDimAboveNoChildNotReset() throws Exception {
        mDimmer.dimAbove(mTransaction, 0.8f);
        SurfaceControl dimLayer = getDimLayer(null);
        SurfaceControl dimLayer = getDimLayer();
        mDimmer.resetDimStates();

        mDimmer.updateDims(mTransaction, new Rect());
        verify(mTransaction).show(getDimLayer(null));
        verify(mTransaction).show(getDimLayer());
        verify(dimLayer, never()).destroy();
    }

@@ -189,12 +168,12 @@ public class DimmerTests extends WindowTestsBase {

        final float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, child, alpha);
        SurfaceControl mDimLayer = getDimLayer(child);
        SurfaceControl dimLayer = getDimLayer();

        assertNotNull("Dimmer should have created a surface", mDimLayer);
        assertNotNull("Dimmer should have created a surface", dimLayer);

        verify(mTransaction).setAlpha(mDimLayer, alpha);
        verify(mTransaction).setRelativeLayer(mDimLayer, child.mControl, 1);
        verify(mTransaction).setAlpha(dimLayer, alpha);
        verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, 1);
    }

    @Test
@@ -204,12 +183,12 @@ public class DimmerTests extends WindowTestsBase {

        final float alpha = 0.8f;
        mDimmer.dimBelow(mTransaction, child, alpha);
        SurfaceControl mDimLayer = getDimLayer(child);
        SurfaceControl dimLayer = getDimLayer();

        assertNotNull("Dimmer should have created a surface", mDimLayer);
        assertNotNull("Dimmer should have created a surface", dimLayer);

        verify(mTransaction).setAlpha(mDimLayer, alpha);
        verify(mTransaction).setRelativeLayer(mDimLayer, child.mControl, -1);
        verify(mTransaction).setAlpha(dimLayer, alpha);
        verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1);
    }

    @Test
@@ -219,7 +198,7 @@ public class DimmerTests extends WindowTestsBase {

        final float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, child, alpha);
        SurfaceControl dimLayer = getDimLayer(child);
        SurfaceControl dimLayer = getDimLayer();
        mDimmer.resetDimStates();

        mDimmer.updateDims(mTransaction, new Rect());
@@ -233,7 +212,7 @@ public class DimmerTests extends WindowTestsBase {

        final float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, child, alpha);
        SurfaceControl dimLayer = getDimLayer(child);
        SurfaceControl dimLayer = getDimLayer();
        mDimmer.resetDimStates();
        mDimmer.dimAbove(mTransaction, child, alpha);

@@ -242,7 +221,29 @@ public class DimmerTests extends WindowTestsBase {
        verify(dimLayer, never()).destroy();
    }

    private SurfaceControl getDimLayer(WindowContainer windowContainer) {
        return mDimmer.mDimLayerUsers.get(windowContainer).mDimLayer;
    @Test
    public void testDimUpdateWhileDimming() throws Exception {
        Rect bounds = new Rect();
        TestWindowContainer child = new TestWindowContainer();
        mHost.addChild(child, 0);

        final float alpha = 0.8f;
        mDimmer.dimAbove(mTransaction, child, alpha);

        SurfaceControl dimLayer = getDimLayer();
        bounds.set(0, 0, 10, 10);
        mDimmer.updateDims(mTransaction, bounds);
        verify(mTransaction, times(1)).show(dimLayer);
        verify(mTransaction).setSize(dimLayer, bounds.width(), bounds.height());
        verify(mTransaction).setPosition(dimLayer, 0, 0);

        bounds.set(10, 10, 30, 30);
        mDimmer.updateDims(mTransaction, bounds);
        verify(mTransaction).setSize(dimLayer, bounds.width(), bounds.height());
        verify(mTransaction).setPosition(dimLayer, 10, 10);
    }

    private SurfaceControl getDimLayer() {
        return mDimmer.mDimState.mDimLayer;
    }
}
+1 −6
Original line number Diff line number Diff line
@@ -69,11 +69,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
    private Runnable mRunnableWhenAddingSplashScreen;

    static synchronized WindowManagerService getWindowManagerService(Context context) {
        return getWindowManagerService(context, new SurfaceAnimationRunner());
    }

    static synchronized WindowManagerService getWindowManagerService(Context context,
            SurfaceAnimationRunner surfaceAnimationRunner) {
        if (sWm == null) {
            // We only want to do this once for the test process as we don't want WM to try to
            // register a bunch of local services again.
@@ -111,7 +106,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
            }

            sWm = WindowManagerService.main(context, ims, true, false,
                    false, new TestWindowManagerPolicy(), surfaceAnimationRunner);
                    false, new TestWindowManagerPolicy());
        }
        return sWm;
    }
Loading