Loading core/java/android/view/InsetsSource.java +1 −1 Original line number Diff line number Diff line Loading @@ -198,7 +198,7 @@ public class InsetsSource implements Parcelable { return "InsetsSource: {" + "mType=" + InsetsState.typeToString(mType) + ", mFrame=" + mFrame.toShortString() + ", mVisible" + mVisible + ", mVisible=" + mVisible + "}"; } Loading core/java/android/view/WindowInsetsController.java +1 −3 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.view; import static android.view.WindowInsets.Type.ime; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading services/core/java/com/android/server/wm/InsetsPolicy.java +21 −19 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.view.ViewRootImpl; import android.view.WindowInsetsAnimationCallback; import android.view.WindowInsetsAnimationControlListener; import com.android.internal.annotations.VisibleForTesting; import com.android.server.DisplayThread; /** Loading Loading @@ -107,11 +108,11 @@ class InsetsPolicy { changed = true; } if (changed) { startAnimation(mShowingTransientTypes, true, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mPolicy.getStatusBarManagerInternal().showTransient( mDisplayContent.getDisplayId(), mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(), mShowingTransientTypes.toArray()); updateBarControlTarget(mFocusedWin); startAnimation(true /* show */, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mStateController.notifyInsetsChanged(); } }); Loading @@ -122,7 +123,7 @@ class InsetsPolicy { if (mShowingTransientTypes.size() == 0) { return; } startAnimation(mShowingTransientTypes, false, () -> { startAnimation(false /* show */, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mShowingTransientTypes.clear(); mStateController.notifyInsetsChanged(); Loading Loading @@ -268,18 +269,20 @@ class InsetsPolicy { return isDockedStackVisible || isFreeformStackVisible || isResizing; } private void startAnimation(IntArray internalTypes, boolean show, Runnable callback) { @VisibleForTesting void startAnimation(boolean show, Runnable callback) { int typesReady = 0; final SparseArray<InsetsSourceControl> controls = new SparseArray<>(); updateBarControlTarget(mFocusedWin); for (int i = internalTypes.size() - 1; i >= 0; i--) { final IntArray showingTransientTypes = mShowingTransientTypes; for (int i = showingTransientTypes.size() - 1; i >= 0; i--) { InsetsSourceProvider provider = mStateController.getSourceProvider(internalTypes.get(i)); if (provider == null) continue; InsetsSourceControl control = provider.getControl(provider.getControlTarget()); if (control == null || control.getLeash() == null) continue; typesReady |= InsetsState.toPublicType(internalTypes.get(i)); controls.put(control.getType(), control); mStateController.getSourceProvider(showingTransientTypes.get(i)); InsetsSourceControl control = provider.getControl(mTransientControlTarget); if (control == null || control.getLeash() == null) { continue; } typesReady |= InsetsState.toPublicType(showingTransientTypes.get(i)); controls.put(control.getType(), new InsetsSourceControl(control)); } controlAnimationUnchecked(typesReady, controls, show, callback); } Loading Loading @@ -335,7 +338,6 @@ class InsetsPolicy { private InsetsPolicyAnimationControlListener mListener; InsetsPolicyAnimationControlCallbacks(InsetsPolicyAnimationControlListener listener) { super(); mListener = listener; } Loading @@ -353,9 +355,11 @@ class InsetsPolicy { InsetsController.INTERPOLATOR, true, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN); SurfaceAnimationThread.getHandler().post( () -> mListener.onReady(mAnimationControl, typesReady)); } /** Called on SurfaceAnimationThread lock without global WM lock held. */ /** Called on SurfaceAnimationThread without global WM lock held. */ @Override public void scheduleApplyChangeInsets() { InsetsState state = getState(); Loading Loading @@ -384,7 +388,7 @@ class InsetsPolicy { return overrideState; } /** Called on SurfaceAnimationThread lock without global WM lock held. */ /** Called on SurfaceAnimationThread without global WM lock held. */ @Override public void applySurfaceParams( final SyncRtSurfaceTransactionApplier.SurfaceParams... params) { Loading @@ -396,14 +400,12 @@ class InsetsPolicy { t.apply(); } /** Called on SurfaceAnimationThread lock without global WM lock held. */ @Override public void startAnimation(InsetsAnimationControlImpl controller, WindowInsetsAnimationControlListener listener, int types, WindowInsetsAnimationCallback.InsetsAnimation animation, WindowInsetsAnimationCallback.AnimationBounds bounds, int layoutDuringAnimation) { SurfaceAnimationThread.getHandler().post(() -> listener.onReady(controller, types)); } } } Loading services/core/java/com/android/server/wm/InsetsStateController.java +13 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; Loading Loading @@ -89,6 +90,12 @@ class InsetsStateController { if (type == ITYPE_NAVIGATION_BAR) { state.removeSource(ITYPE_IME); state.removeSource(ITYPE_STATUS_BAR); state.removeSource(ITYPE_CAPTION_BAR); } // Status bar doesn't get influenced by caption bar if (type == ITYPE_STATUS_BAR) { state.removeSource(ITYPE_CAPTION_BAR); } // IME needs different frames for certain cases (e.g. navigation bar in gesture nav). Loading Loading @@ -212,18 +219,18 @@ class InsetsStateController { /** * Called when the focused window that is able to control the system bars changes. * * @param topControlling The target that is now able to control the top bar appearance * @param statusControlling The target that is now able to control the status bar appearance * and visibility. * @param navControlling The target that is now able to control the nav bar appearance * and visibility. */ void onBarControlTargetChanged(@Nullable InsetsControlTarget topControlling, @Nullable InsetsControlTarget fakeTopControlling, void onBarControlTargetChanged(@Nullable InsetsControlTarget statusControlling, @Nullable InsetsControlTarget fakeStatusControlling, @Nullable InsetsControlTarget navControlling, @Nullable InsetsControlTarget fakeNavControlling) { onControlChanged(ITYPE_STATUS_BAR, topControlling); onControlChanged(ITYPE_STATUS_BAR, statusControlling); onControlChanged(ITYPE_NAVIGATION_BAR, navControlling); onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeTopControlling); onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeStatusControlling); onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling); notifyPendingInsetsControlChanged(); } Loading services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +15 −10 Original line number Diff line number Diff line Loading @@ -29,12 +29,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; import android.util.IntArray; Loading Loading @@ -122,13 +123,13 @@ public class InsetsPolicyTest extends WindowTestsBase { // TODO: adjust this test if we pretend to the app that it's still able to control it. @Test public void testControlsForDispatch_forceStatusBarVisible() { addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |= addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); // The app must not control the top bar. // The app must not control the status bar. assertNotNull(controls); assertEquals(1, controls.length); } Loading @@ -137,6 +138,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_statusBarForceShowNavigation() { addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading Loading @@ -169,7 +171,8 @@ public class InsetsPolicyTest extends WindowTestsBase { .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); Loading @@ -184,7 +187,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test public void testShowTransientBars_topCanBeTransient_appGetsTopFakeControl() { public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() { // Adding app window before setting source visibility is to prevent the visibility from // being cleared by InsetsSourceProvider.updateVisibility. final WindowState app = addWindow(TYPE_APPLICATION, "app"); Loading @@ -194,14 +197,15 @@ public class InsetsPolicyTest extends WindowTestsBase { addWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource().setVisible(true); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); // The app must get the fake control of the top bar, and must get the real control of the // The app must get the fake control of the status bar, and must get the real control of the // navigation bar. assertEquals(2, controls.length); for (int i = controls.length - 1; i >= 0; i--) { Loading @@ -222,7 +226,8 @@ public class InsetsPolicyTest extends WindowTestsBase { .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); Loading Loading
core/java/android/view/InsetsSource.java +1 −1 Original line number Diff line number Diff line Loading @@ -198,7 +198,7 @@ public class InsetsSource implements Parcelable { return "InsetsSource: {" + "mType=" + InsetsState.typeToString(mType) + ", mFrame=" + mFrame.toShortString() + ", mVisible" + mVisible + ", mVisible=" + mVisible + "}"; } Loading
core/java/android/view/WindowInsetsController.java +1 −3 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.view; import static android.view.WindowInsets.Type.ime; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading
services/core/java/com/android/server/wm/InsetsPolicy.java +21 −19 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.view.ViewRootImpl; import android.view.WindowInsetsAnimationCallback; import android.view.WindowInsetsAnimationControlListener; import com.android.internal.annotations.VisibleForTesting; import com.android.server.DisplayThread; /** Loading Loading @@ -107,11 +108,11 @@ class InsetsPolicy { changed = true; } if (changed) { startAnimation(mShowingTransientTypes, true, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mPolicy.getStatusBarManagerInternal().showTransient( mDisplayContent.getDisplayId(), mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(), mShowingTransientTypes.toArray()); updateBarControlTarget(mFocusedWin); startAnimation(true /* show */, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mStateController.notifyInsetsChanged(); } }); Loading @@ -122,7 +123,7 @@ class InsetsPolicy { if (mShowingTransientTypes.size() == 0) { return; } startAnimation(mShowingTransientTypes, false, () -> { startAnimation(false /* show */, () -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { mShowingTransientTypes.clear(); mStateController.notifyInsetsChanged(); Loading Loading @@ -268,18 +269,20 @@ class InsetsPolicy { return isDockedStackVisible || isFreeformStackVisible || isResizing; } private void startAnimation(IntArray internalTypes, boolean show, Runnable callback) { @VisibleForTesting void startAnimation(boolean show, Runnable callback) { int typesReady = 0; final SparseArray<InsetsSourceControl> controls = new SparseArray<>(); updateBarControlTarget(mFocusedWin); for (int i = internalTypes.size() - 1; i >= 0; i--) { final IntArray showingTransientTypes = mShowingTransientTypes; for (int i = showingTransientTypes.size() - 1; i >= 0; i--) { InsetsSourceProvider provider = mStateController.getSourceProvider(internalTypes.get(i)); if (provider == null) continue; InsetsSourceControl control = provider.getControl(provider.getControlTarget()); if (control == null || control.getLeash() == null) continue; typesReady |= InsetsState.toPublicType(internalTypes.get(i)); controls.put(control.getType(), control); mStateController.getSourceProvider(showingTransientTypes.get(i)); InsetsSourceControl control = provider.getControl(mTransientControlTarget); if (control == null || control.getLeash() == null) { continue; } typesReady |= InsetsState.toPublicType(showingTransientTypes.get(i)); controls.put(control.getType(), new InsetsSourceControl(control)); } controlAnimationUnchecked(typesReady, controls, show, callback); } Loading Loading @@ -335,7 +338,6 @@ class InsetsPolicy { private InsetsPolicyAnimationControlListener mListener; InsetsPolicyAnimationControlCallbacks(InsetsPolicyAnimationControlListener listener) { super(); mListener = listener; } Loading @@ -353,9 +355,11 @@ class InsetsPolicy { InsetsController.INTERPOLATOR, true, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN); SurfaceAnimationThread.getHandler().post( () -> mListener.onReady(mAnimationControl, typesReady)); } /** Called on SurfaceAnimationThread lock without global WM lock held. */ /** Called on SurfaceAnimationThread without global WM lock held. */ @Override public void scheduleApplyChangeInsets() { InsetsState state = getState(); Loading Loading @@ -384,7 +388,7 @@ class InsetsPolicy { return overrideState; } /** Called on SurfaceAnimationThread lock without global WM lock held. */ /** Called on SurfaceAnimationThread without global WM lock held. */ @Override public void applySurfaceParams( final SyncRtSurfaceTransactionApplier.SurfaceParams... params) { Loading @@ -396,14 +400,12 @@ class InsetsPolicy { t.apply(); } /** Called on SurfaceAnimationThread lock without global WM lock held. */ @Override public void startAnimation(InsetsAnimationControlImpl controller, WindowInsetsAnimationControlListener listener, int types, WindowInsetsAnimationCallback.InsetsAnimation animation, WindowInsetsAnimationCallback.AnimationBounds bounds, int layoutDuringAnimation) { SurfaceAnimationThread.getHandler().post(() -> listener.onReady(controller, types)); } } } Loading
services/core/java/com/android/server/wm/InsetsStateController.java +13 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; Loading Loading @@ -89,6 +90,12 @@ class InsetsStateController { if (type == ITYPE_NAVIGATION_BAR) { state.removeSource(ITYPE_IME); state.removeSource(ITYPE_STATUS_BAR); state.removeSource(ITYPE_CAPTION_BAR); } // Status bar doesn't get influenced by caption bar if (type == ITYPE_STATUS_BAR) { state.removeSource(ITYPE_CAPTION_BAR); } // IME needs different frames for certain cases (e.g. navigation bar in gesture nav). Loading Loading @@ -212,18 +219,18 @@ class InsetsStateController { /** * Called when the focused window that is able to control the system bars changes. * * @param topControlling The target that is now able to control the top bar appearance * @param statusControlling The target that is now able to control the status bar appearance * and visibility. * @param navControlling The target that is now able to control the nav bar appearance * and visibility. */ void onBarControlTargetChanged(@Nullable InsetsControlTarget topControlling, @Nullable InsetsControlTarget fakeTopControlling, void onBarControlTargetChanged(@Nullable InsetsControlTarget statusControlling, @Nullable InsetsControlTarget fakeStatusControlling, @Nullable InsetsControlTarget navControlling, @Nullable InsetsControlTarget fakeNavControlling) { onControlChanged(ITYPE_STATUS_BAR, topControlling); onControlChanged(ITYPE_STATUS_BAR, statusControlling); onControlChanged(ITYPE_NAVIGATION_BAR, navControlling); onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeTopControlling); onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeStatusControlling); onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling); notifyPendingInsetsControlChanged(); } Loading
services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +15 −10 Original line number Diff line number Diff line Loading @@ -29,12 +29,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; import android.util.IntArray; Loading Loading @@ -122,13 +123,13 @@ public class InsetsPolicyTest extends WindowTestsBase { // TODO: adjust this test if we pretend to the app that it's still able to control it. @Test public void testControlsForDispatch_forceStatusBarVisible() { addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |= addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); // The app must not control the top bar. // The app must not control the status bar. assertNotNull(controls); assertEquals(1, controls.length); } Loading @@ -137,6 +138,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_statusBarForceShowNavigation() { addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading Loading @@ -169,7 +171,8 @@ public class InsetsPolicyTest extends WindowTestsBase { .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); Loading @@ -184,7 +187,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test public void testShowTransientBars_topCanBeTransient_appGetsTopFakeControl() { public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() { // Adding app window before setting source visibility is to prevent the visibility from // being cleared by InsetsSourceProvider.updateVisibility. final WindowState app = addWindow(TYPE_APPLICATION, "app"); Loading @@ -194,14 +197,15 @@ public class InsetsPolicyTest extends WindowTestsBase { addWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource().setVisible(true); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); // The app must get the fake control of the top bar, and must get the real control of the // The app must get the fake control of the status bar, and must get the real control of the // navigation bar. assertEquals(2, controls.length); for (int i = controls.length - 1; i >= 0; i--) { Loading @@ -222,7 +226,8 @@ public class InsetsPolicyTest extends WindowTestsBase { .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); final InsetsPolicy policy = mDisplayContent.getInsetsPolicy(); final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any()); policy.updateBarControlTarget(app); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); Loading