diff options
| author | 2018-01-19 17:09:15 -0800 | |
|---|---|---|
| committer | 2018-01-29 13:15:40 -0800 | |
| commit | 2fb06bc31f06ac046c94e41dbcaf019623052de8 (patch) | |
| tree | 08ee36b5da34dea71b6d81a0a88d165fec55572a | |
| parent | d55e3e7574863ec85dedc6d9a248ec23a3b22e49 (diff) | |
Added animations to dim layers
Added animations to dim layers when dims are set for
WindowState surfaces since they're controlled by the system.
Test: Dims for dialogs now animate.
Test: DimmerTests
Fixes: 71841698
Fixes: 69553362
Fixes: 71614627
Fixes: 72333587
Change-Id: I34f6f3d7885d5c9c0075a941e40d68bc5618a016
10 files changed, 303 insertions, 93 deletions
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 9fe16ae85cfb..b435605b654f 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -17,34 +17,115 @@ package com.android.server.wm; import android.util.ArrayMap; -import android.util.Slog; import android.view.SurfaceControl; import android.graphics.Rect; +import com.android.internal.annotations.VisibleForTesting; + /** * Utility class for use by a WindowContainer implementation to add "DimLayer" support, that is * black layers of varying opacity at various Z-levels which create the effect of a Dim. */ class Dimmer { private static final String TAG = "WindowManager"; + private static final int DEFAULT_DIM_ANIM_DURATION = 200; + + private class DimAnimatable implements SurfaceAnimator.Animatable { + private final SurfaceControl mDimLayer; + + private DimAnimatable(SurfaceControl dimLayer) { + mDimLayer = dimLayer; + } + + @Override + public SurfaceControl.Transaction getPendingTransaction() { + return mHost.getPendingTransaction(); + } + + @Override + public void commitPendingTransaction() { + mHost.commitPendingTransaction(); + } + + @Override + public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) { + } + + @Override + public void onAnimationLeashDestroyed(SurfaceControl.Transaction t) { + } + + @Override + public void destroyAfterPendingTransaction(SurfaceControl surface) { + mHost.destroyAfterPendingTransaction(surface); + } + + @Override + public SurfaceControl.Builder makeAnimationLeash() { + return mHost.makeAnimationLeash(); + } + + @Override + public SurfaceControl getAnimationLeashParent() { + return mHost.getSurfaceControl(); + } + + @Override + public SurfaceControl getSurfaceControl() { + return mDimLayer; + } + + @Override + public SurfaceControl getParentSurfaceControl() { + return mHost.getSurfaceControl(); + } + + @Override + public int getSurfaceWidth() { + // This will determine the size of the leash created. This should be the size of the + // host and not the dim layer since the dim layer may get bigger during animation. If + // that occurs, the leash size cannot change so we need to ensure the leash is big + // enough that the dim layer can grow. + // This works because the mHost will be a Task which has the display bounds. + return mHost.getSurfaceWidth(); + } + + @Override + public int getSurfaceHeight() { + // See getSurfaceWidth() above for explanation. + return mHost.getSurfaceHeight(); + } + } - private class DimState { - SurfaceControl mSurfaceControl; + @VisibleForTesting + class DimState { + /** + * The layer where property changes should be invoked on. + */ + SurfaceControl mDimLayer; boolean mDimming; + boolean isVisible; + SurfaceAnimator mSurfaceAnimator; /** - * Used for Dims not assosciated with a WindowContainer. See {@link Dimmer#dimAbove} for + * Used for Dims not associated with a WindowContainer. See {@link Dimmer#dimAbove} for * details on Dim lifecycle. */ boolean mDontReset; - DimState(SurfaceControl ctl) { - mSurfaceControl = ctl; + DimState(SurfaceControl dimLayer) { + mDimLayer = dimLayer; mDimming = true; + mSurfaceAnimator = new SurfaceAnimator(new DimAnimatable(dimLayer), () -> { + if (!mDimming) { + mDimLayer.destroy(); + } + }, mHost.mService.mAnimator::addAfterPrepareSurfacesRunnable, mHost.mService); } - }; + } - private ArrayMap<WindowContainer, DimState> mDimLayerUsers = new ArrayMap<>(); + @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 @@ -56,19 +137,18 @@ class Dimmer { mHost = host; } - SurfaceControl makeDimLayer() { - final SurfaceControl control = mHost.makeChildSurface(null) + private SurfaceControl makeDimLayer() { + return mHost.makeChildSurface(null) .setParent(mHost.getSurfaceControl()) .setColorLayer(true) .setName("Dim Layer for - " + mHost.getName()) .build(); - return control; } /** * Retreive the DimState for a given child of the host. */ - DimState getDimState(WindowContainer container) { + private DimState getDimState(WindowContainer container) { DimState state = mDimLayerUsers.get(container); if (state == null) { final SurfaceControl ctl = makeDimLayer(); @@ -88,14 +168,12 @@ class Dimmer { private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer, float alpha) { final DimState d = getDimState(container); - t.show(d.mSurfaceControl); if (container != null) { - t.setRelativeLayer(d.mSurfaceControl, - container.getSurfaceControl(), relativeLayer); + t.setRelativeLayer(d.mDimLayer, container.getSurfaceControl(), relativeLayer); } else { - t.setLayer(d.mSurfaceControl, Integer.MAX_VALUE); + t.setLayer(d.mDimLayer, Integer.MAX_VALUE); } - t.setAlpha(d.mSurfaceControl, alpha); + t.setAlpha(d.mDimLayer, alpha); d.mDimming = true; } @@ -107,16 +185,18 @@ class Dimmer { */ void stopDim(SurfaceControl.Transaction t) { DimState d = getDimState(null); - t.hide(d.mSurfaceControl); + t.hide(d.mDimLayer); + d.isVisible = false; d.mDontReset = false; } + /** * Place a Dim above the entire host container. The caller is responsible for calling stopDim to * remove this effect. If the Dim can be assosciated with a particular child of the host * consider using the other variant of dimAbove which ties the Dim lifetime to the child * lifetime more explicitly. * - * @param t A transaction in which to apply the Dim. + * @param t A transaction in which to apply the Dim. * @param alpha The alpha at which to Dim. */ void dimAbove(SurfaceControl.Transaction t, float alpha) { @@ -128,9 +208,9 @@ class Dimmer { * for each call to {@link WindowContainer#prepareSurfaces} the Dim state will be reset * and the child should call dimAbove again to request the Dim to continue. * - * @param t A transaction in which to apply the Dim. + * @param t A transaction in which to apply the Dim. * @param container The container which to dim above. Should be a child of our host. - * @param alpha The alpha at which to Dim. + * @param alpha The alpha at which to Dim. */ void dimAbove(SurfaceControl.Transaction t, WindowContainer container, float alpha) { dim(t, container, 1, alpha); @@ -139,9 +219,9 @@ class Dimmer { /** * Like {@link #dimAbove} but places the dim below the given container. * - * @param t A transaction in which to apply the Dim. + * @param t A transaction in which to apply the Dim. * @param container The container which to dim below. Should be a child of our host. - * @param alpha The alpha at which to Dim. + * @param alpha The alpha at which to Dim. */ void dimBelow(SurfaceControl.Transaction t, WindowContainer container, float alpha) { @@ -159,7 +239,7 @@ class Dimmer { void resetDimStates() { for (int i = mDimLayerUsers.size() - 1; i >= 0; i--) { final DimState state = mDimLayerUsers.valueAt(i); - if (state.mDontReset == false) { + if (!state.mDontReset) { state.mDimming = false; } } @@ -169,7 +249,7 @@ class Dimmer { * Call after invoking {@link WindowContainer#prepareSurfaces} on children as * described in {@link #resetDimStates}. * - * @param t A transaction in which to update the dims. + * @param t A transaction in which to update the dims. * @param bounds The bounds at which to dim. * @return true if any Dims were updated. */ @@ -177,19 +257,80 @@ class Dimmer { 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 == false) { + if (!state.mDimming) { mDimLayerUsers.removeAt(i); - state.mSurfaceControl.destroy(); + startDimExit(container, state.mSurfaceAnimator, t); } else { didSomething = true; // TODO: Once we use geometry from hierarchy this falls away. - t.setSize(state.mSurfaceControl, bounds.width(), bounds.height()); - t.setPosition(state.mSurfaceControl, bounds.left, bounds.top); + 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); + } } } return didSomething; } + + private void startDimEnter(WindowContainer container, SurfaceAnimator animator, + SurfaceControl.Transaction t) { + startAnim(container, animator, t, 0 /* startAlpha */, 1 /* endAlpha */); + } + + private void startDimExit(WindowContainer container, SurfaceAnimator animator, + SurfaceControl.Transaction t) { + startAnim(container, animator, t, 1 /* startAlpha */, 0 /* endAlpha */); + } + + private void startAnim(WindowContainer container, SurfaceAnimator animator, + SurfaceControl.Transaction t, float startAlpha, float endAlpha) { + animator.startAnimation(t, new LocalAnimationAdapter( + new AlphaAnimationSpec(startAlpha, endAlpha, getDimDuration(container)), + mHost.mService.mSurfaceAnimationRunner), false /* hidden */); + } + + private long getDimDuration(WindowContainer container) { + // If there's no container, then there isn't an animation occurring while dimming. Set the + // duration to 0 so it immediately dims to the set alpha. + if (container == null) { + return 0; + } + + // Otherwise use the same duration as the animation on the WindowContainer + AnimationAdapter animationAdapter = container.mSurfaceAnimator.getAnimation(); + return animationAdapter == null ? DEFAULT_DIM_ANIM_DURATION + : animationAdapter.getDurationHint(); + } + + private static class AlphaAnimationSpec implements LocalAnimationAdapter.AnimationSpec { + private final long mDuration; + private final float mFromAlpha; + private final float mToAlpha; + + AlphaAnimationSpec(float fromAlpha, float toAlpha, long duration) { + mFromAlpha = fromAlpha; + mToAlpha = toAlpha; + mDuration = duration; + } + + @Override + public long getDuration() { + return mDuration; + } + + @Override + public void apply(SurfaceControl.Transaction t, SurfaceControl sc, long currentPlayTime) { + float alpha = ((float) currentPlayTime / getDuration()) * (mToAlpha - mFromAlpha) + + mFromAlpha; + t.setAlpha(sc, alpha); + } + } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 3f49f0cd5c15..7674b5e9ed2c 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3599,6 +3599,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } private final class AboveAppWindowContainers extends NonAppWindowContainers { + private final Dimmer mDimmer = new Dimmer(this); + private final Rect mTmpDimBoundsRect = new Rect(); AboveAppWindowContainers(String name, WindowManagerService service) { super(name, service); } @@ -3630,6 +3632,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo imeContainer.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE); } } + + @Override + Dimmer getDimmer() { + return mDimmer; + } + + @Override + void prepareSurfaces() { + mDimmer.resetDimStates(); + super.prepareSurfaces(); + getBounds(mTmpDimBoundsRect); + + if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) { + scheduleAnimation(); + } + } } /** diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 0628436a4204..7d970d9a06b5 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -462,8 +462,8 @@ class Task extends WindowContainer<AppWindowToken> { } else { mStack.getBounds(mTmpRect); mTmpRect.intersect(getBounds()); + out.set(mTmpRect); } - out.set(mTmpRect); } else { out.set(getBounds()); } @@ -640,6 +640,7 @@ class Task extends WindowContainer<AppWindowToken> { mPreserveNonFloatingState = false; } + @Override Dimmer getDimmer() { return mDimmer; } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index bc0f9ad71a61..cf54b67e1229 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1722,6 +1722,7 @@ public class TaskStack extends WindowContainer<Task> implements || activityType == ACTIVITY_TYPE_ASSISTANT; } + @Override Dimmer getDimmer() { return mDimmer; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 1f9255a2b20f..d58f02c3fa56 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1219,4 +1219,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< outPos.offset(-parentBounds.left, -parentBounds.top); } } + + Dimmer getDimmer() { + if (mParent == null) { + return null; + } + return mParent.getDimmer(); + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4fb239085e5c..066e4e6a8c67 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -907,9 +907,16 @@ 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), 0); + onlyCore, policy, surfaceAnimationRunner), 0); return sInstance; } @@ -932,7 +939,7 @@ public class WindowManagerService extends IWindowManager.Stub private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore, - WindowManagerPolicy policy) { + WindowManagerPolicy policy, SurfaceAnimationRunner surfaceAnimationRunner) { installLock(this, INDEX_WINDOW); mContext = context; mHaveInputMethods = haveInputMethods; @@ -1059,7 +1066,7 @@ public class WindowManagerService extends IWindowManager.Stub PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM); mHoldingScreenWakeLock.setReferenceCounted(false); - mSurfaceAnimationRunner = new SurfaceAnimationRunner(); + mSurfaceAnimationRunner = surfaceAnimationRunner; mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 477dd2bb9633..55c982c174a6 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2138,18 +2138,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mInputWindowHandle.inputChannel = null; } - private Dimmer getDimmer() { - Task task = getTask(); - if (task != null) { - return task.getDimmer(); - } - TaskStack taskStack = getStack(); - if (taskStack != null) { - return taskStack.getDimmer(); - } - return null; - } - /** Returns true if the replacement window was removed. */ boolean removeReplacedWindowIfNeeded(WindowState replacement) { if (mWillReplaceWindow && mReplacementWindow == replacement && replacement.hasDrawnLw()) { @@ -4516,11 +4504,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private void applyDims(Dimmer dimmer) { if (!mAnimatingExit && mAppDied) { mIsDimming = true; - getDimmer().dimAbove(getPendingTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW); + dimmer.dimAbove(getPendingTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW); } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 - && !mAnimatingExit && isVisible()) { + && !mAnimatingExit && isVisible() && !mWinAnimator.mLastHidden) { mIsDimming = true; - getDimmer().dimBelow(getPendingTransaction(), this, mAttrs.dimAmount); + dimmer.dimBelow(getPendingTransaction(), this, mAttrs.dimAmount); } } @@ -4531,7 +4519,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (dimmer != null) { applyDims(dimmer); } - updateSurfacePosition(mPendingTransaction); mWinAnimator.prepareSurfaceLocked(true); diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java index 70906dfbdb14..396fef40466f 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java @@ -16,11 +16,14 @@ package com.android.server.wm; -import java.util.HashMap; - -import org.junit.Test; -import org.junit.Before; -import org.junit.runner.RunWith; +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.verify; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; @@ -28,22 +31,25 @@ import android.support.test.runner.AndroidJUnit4; import android.view.SurfaceControl; import android.view.SurfaceSession; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; +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: - * bit FrameworksServicesTests:com.android.server.wm.DimmerTests; + * 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); @@ -65,12 +71,14 @@ public class DimmerTests extends WindowTestsBase { private class MockSurfaceBuildingContainer extends WindowContainer<TestWindowContainer> { final SurfaceSession mSession = new SurfaceSession(); - SurfaceControl mBuiltSurface = null; - 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 { @@ -80,21 +88,23 @@ public class DimmerTests extends WindowTestsBase { @Override public SurfaceControl build() { - SurfaceControl sc = mock(SurfaceControl.class); - mBuiltSurface = sc; - return sc; + return spy(sWm.makeSurfaceBuilder(mSession) + .setName("test surface") + .setSize(1, 1) + .build()); } } - @Override - SurfaceControl.Builder makeChildSurface(WindowContainer child) { - return new MockSurfaceBuilder(mSession); + SurfaceControl.Builder makeSurface() { + return sWm.makeSurfaceBuilder(mSession) + .setName("test surface") + .setSize(1, 1); } @Override - public SurfaceControl getSurfaceControl() { - return mHostControl; + SurfaceControl.Builder makeChildSurface(WindowContainer child) { + return new MockSurfaceBuilder(mSession); } @Override @@ -114,29 +124,37 @@ public class DimmerTests extends WindowTestsBase { 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()); } @Test public void testDimAboveNoChildCreatesSurface() throws Exception { final float alpha = 0.8f; mDimmer.dimAbove(mTransaction, alpha); - assertNotNull("Dimmer should have created a surface", mHost.mBuiltSurface); - verify(mTransaction).setAlpha(mHost.mBuiltSurface, alpha); - verify(mTransaction).show(mHost.mBuiltSurface); - verify(mTransaction).setLayer(mHost.mBuiltSurface, Integer.MAX_VALUE); + SurfaceControl dimLayer = getDimLayer(null); + + assertNotNull("Dimmer should have created a surface", dimLayer); + + verify(mTransaction).setAlpha(dimLayer, alpha); + verify(mTransaction).setLayer(dimLayer, Integer.MAX_VALUE); } @Test public void testDimAboveNoChildRedundantlyUpdatesAlphaOnExistingSurface() throws Exception { float alpha = 0.8f; mDimmer.dimAbove(mTransaction, alpha); - final SurfaceControl firstSurface = mHost.mBuiltSurface; + final SurfaceControl firstSurface = getDimLayer(null); alpha = 0.9f; mDimmer.dimAbove(mTransaction, alpha); - assertEquals(firstSurface, mHost.mBuiltSurface); + assertEquals(firstSurface, getDimLayer(null)); verify(mTransaction).setAlpha(firstSurface, 0.9f); } @@ -148,16 +166,20 @@ public class DimmerTests extends WindowTestsBase { int height = 300; Rect bounds = new Rect(0, 0, width, height); mDimmer.updateDims(mTransaction, bounds); - verify(mTransaction).setSize(mHost.mBuiltSurface, width, height); + + verify(mTransaction).setSize(getDimLayer(null), width, height); + verify(mTransaction).show(getDimLayer(null)); } @Test public void testDimAboveNoChildNotReset() throws Exception { mDimmer.dimAbove(mTransaction, 0.8f); + SurfaceControl dimLayer = getDimLayer(null); mDimmer.resetDimStates(); mDimmer.updateDims(mTransaction, new Rect()); - verify(mHost.mBuiltSurface, never()).destroy(); + verify(mTransaction).show(getDimLayer(null)); + verify(dimLayer, never()).destroy(); } @Test @@ -167,11 +189,12 @@ public class DimmerTests extends WindowTestsBase { final float alpha = 0.8f; mDimmer.dimAbove(mTransaction, child, alpha); - assertNotNull("Dimmer should have created a surface", mHost.mBuiltSurface); + SurfaceControl mDimLayer = getDimLayer(child); + + assertNotNull("Dimmer should have created a surface", mDimLayer); - verify(mTransaction).setAlpha(mHost.mBuiltSurface, alpha); - verify(mTransaction).show(mHost.mBuiltSurface); - verify(mTransaction).setRelativeLayer(mHost.mBuiltSurface, child.mControl, 1); + verify(mTransaction).setAlpha(mDimLayer, alpha); + verify(mTransaction).setRelativeLayer(mDimLayer, child.mControl, 1); } @Test @@ -181,11 +204,12 @@ public class DimmerTests extends WindowTestsBase { final float alpha = 0.8f; mDimmer.dimBelow(mTransaction, child, alpha); - assertNotNull("Dimmer should have created a surface", mHost.mBuiltSurface); + SurfaceControl mDimLayer = getDimLayer(child); - verify(mTransaction).setAlpha(mHost.mBuiltSurface, alpha); - verify(mTransaction).show(mHost.mBuiltSurface); - verify(mTransaction).setRelativeLayer(mHost.mBuiltSurface, child.mControl, -1); + assertNotNull("Dimmer should have created a surface", mDimLayer); + + verify(mTransaction).setAlpha(mDimLayer, alpha); + verify(mTransaction).setRelativeLayer(mDimLayer, child.mControl, -1); } @Test @@ -195,9 +219,11 @@ public class DimmerTests extends WindowTestsBase { final float alpha = 0.8f; mDimmer.dimAbove(mTransaction, child, alpha); + SurfaceControl dimLayer = getDimLayer(child); mDimmer.resetDimStates(); + mDimmer.updateDims(mTransaction, new Rect()); - verify(mHost.mBuiltSurface).destroy(); + verify(dimLayer).destroy(); } @Test @@ -207,10 +233,16 @@ public class DimmerTests extends WindowTestsBase { final float alpha = 0.8f; mDimmer.dimAbove(mTransaction, child, alpha); + SurfaceControl dimLayer = getDimLayer(child); mDimmer.resetDimStates(); mDimmer.dimAbove(mTransaction, child, alpha); mDimmer.updateDims(mTransaction, new Rect()); - verify(mHost.mBuiltSurface, never()).destroy(); + verify(mTransaction).show(dimLayer); + verify(dimLayer, never()).destroy(); + } + + private SurfaceControl getDimLayer(WindowContainer windowContainer) { + return mDimmer.mDimLayerUsers.get(windowContainer).mDimLayer; } } diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java index 35ca493e909f..81fd889c82c2 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.spy; import android.os.PowerSaveState; import android.util.proto.ProtoOutputStream; @@ -68,6 +69,11 @@ 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. @@ -105,7 +111,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { } sWm = WindowManagerService.main(context, ims, true, false, - false, new TestWindowManagerPolicy()); + false, new TestWindowManagerPolicy(), surfaceAnimationRunner); } return sWm; } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java index 69b13787ef93..7918901f7e2d 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -84,6 +84,16 @@ class WindowTestsBase { WindowState mChildAppWindowBelow; HashSet<WindowState> mCommonWindows; + private final SurfaceAnimationRunner mSurfaceAnimationRunner; + + public WindowTestsBase() { + this(new SurfaceAnimationRunner()); + } + + public WindowTestsBase(SurfaceAnimationRunner surfaceAnimationRunner) { + mSurfaceAnimationRunner = surfaceAnimationRunner; + } + @Before public void setUp() throws Exception { if (!sOneTimeSetupDone) { @@ -98,7 +108,7 @@ class WindowTestsBase { final Context context = InstrumentationRegistry.getTargetContext(); AttributeCache.init(context); - sWm = TestWindowManagerPolicy.getWindowManagerService(context); + sWm = TestWindowManagerPolicy.getWindowManagerService(context, mSurfaceAnimationRunner); beforeCreateDisplay(); context.getDisplay().getDisplayInfo(mDisplayInfo); |