Loading core/java/android/view/InsetsController.java +20 −6 Original line number Diff line number Diff line Loading @@ -737,7 +737,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } final boolean hasControl = mTmpControlArray.size() > 0; boolean requestedStateStale = false; final int[] showTypes = new int[1]; final int[] hideTypes = new int[1]; Loading @@ -754,9 +754,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Ensure to create source consumers if not available yet. for (int i = mTmpControlArray.size() - 1; i >= 0; i--) { final InsetsSourceControl control = mTmpControlArray.valueAt(i); InsetsSourceConsumer consumer = getSourceConsumer(control.getType()); final @InternalInsetsType int type = control.getType(); final InsetsSourceConsumer consumer = getSourceConsumer(type); consumer.setControl(control, showTypes, hideTypes); if (!requestedStateStale) { final boolean requestedVisible = consumer.isRequestedVisible(); // We might have changed our requested visibilities while we don't have the control, // so we need to update our requested state once we have control. Otherwise, our // requested state at the server side might be incorrect. final boolean requestedVisibilityChanged = requestedVisible != mRequestedState.getSourceOrDefaultVisibility(type); // The IME client visibility will be reset by insets source provider while updating // control, so if IME is requested visible, we need to send the request to server. final boolean imeRequestedVisible = type == ITYPE_IME && requestedVisible; requestedStateStale = requestedVisibilityChanged || imeRequestedVisible; } } mTmpControlArray.clear(); Loading @@ -772,10 +789,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (hideTypes[0] != 0) { applyAnimation(hideTypes[0], false /* show */, false /* fromIme */); } if (hasControl && mRequestedState.hasSources()) { // We might have changed our requested visibilities while we don't have the control, // so we need to update our requested state once we have control. Otherwise, our // requested state at the server side might be incorrect. if (requestedStateStale) { updateRequestedState(); } } Loading core/tests/coretests/src/android/view/InsetsControllerTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -691,18 +691,57 @@ public class InsetsControllerTest { @Test public void testRequestedState() { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // The modified state can be controlled when we have control. mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); mController.hide(statusBars()); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); mController.onControlsChanged(new InsetsSourceControl[0]); // The modified state won't be changed while losing control. mController.onControlsChanged(null /* activeControls */); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state won't be changed while state changed while we don't have control. InsetsState newState = new InsetsState(mController.getState(), true /* copySource */); mController.onStateChanged(newState); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state won't be changed while controlling an insets without having the // control. mController.show(statusBars()); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state can be updated while gaining control. mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); assertTrue(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state can still be updated if the local state and the requested state // are the same. mController.onControlsChanged(null /* activeControls */); mController.hide(statusBars()); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_STATUS_BAR).setVisible(false); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state will always be updated while receiving IME control if IME is // requested visible. mController.getSourceConsumer(ITYPE_IME).show(false /* fromIme */); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_IME).setVisible(true); newState.getSource(ITYPE_IME).setFrame(1, 2, 3, 4); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_IME).setVisible(true); newState.getSource(ITYPE_IME).setFrame(5, 6, 7, 8); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); }); } Loading Loading
core/java/android/view/InsetsController.java +20 −6 Original line number Diff line number Diff line Loading @@ -737,7 +737,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } final boolean hasControl = mTmpControlArray.size() > 0; boolean requestedStateStale = false; final int[] showTypes = new int[1]; final int[] hideTypes = new int[1]; Loading @@ -754,9 +754,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Ensure to create source consumers if not available yet. for (int i = mTmpControlArray.size() - 1; i >= 0; i--) { final InsetsSourceControl control = mTmpControlArray.valueAt(i); InsetsSourceConsumer consumer = getSourceConsumer(control.getType()); final @InternalInsetsType int type = control.getType(); final InsetsSourceConsumer consumer = getSourceConsumer(type); consumer.setControl(control, showTypes, hideTypes); if (!requestedStateStale) { final boolean requestedVisible = consumer.isRequestedVisible(); // We might have changed our requested visibilities while we don't have the control, // so we need to update our requested state once we have control. Otherwise, our // requested state at the server side might be incorrect. final boolean requestedVisibilityChanged = requestedVisible != mRequestedState.getSourceOrDefaultVisibility(type); // The IME client visibility will be reset by insets source provider while updating // control, so if IME is requested visible, we need to send the request to server. final boolean imeRequestedVisible = type == ITYPE_IME && requestedVisible; requestedStateStale = requestedVisibilityChanged || imeRequestedVisible; } } mTmpControlArray.clear(); Loading @@ -772,10 +789,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (hideTypes[0] != 0) { applyAnimation(hideTypes[0], false /* show */, false /* fromIme */); } if (hasControl && mRequestedState.hasSources()) { // We might have changed our requested visibilities while we don't have the control, // so we need to update our requested state once we have control. Otherwise, our // requested state at the server side might be incorrect. if (requestedStateStale) { updateRequestedState(); } } Loading
core/tests/coretests/src/android/view/InsetsControllerTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -691,18 +691,57 @@ public class InsetsControllerTest { @Test public void testRequestedState() { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // The modified state can be controlled when we have control. mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); mController.hide(statusBars()); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); mController.onControlsChanged(new InsetsSourceControl[0]); // The modified state won't be changed while losing control. mController.onControlsChanged(null /* activeControls */); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state won't be changed while state changed while we don't have control. InsetsState newState = new InsetsState(mController.getState(), true /* copySource */); mController.onStateChanged(newState); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state won't be changed while controlling an insets without having the // control. mController.show(statusBars()); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state can be updated while gaining control. mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); assertTrue(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state can still be updated if the local state and the requested state // are the same. mController.onControlsChanged(null /* activeControls */); mController.hide(statusBars()); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_STATUS_BAR).setVisible(false); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR)); assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible()); // The modified state will always be updated while receiving IME control if IME is // requested visible. mController.getSourceConsumer(ITYPE_IME).show(false /* fromIme */); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_IME).setVisible(true); newState.getSource(ITYPE_IME).setFrame(1, 2, 3, 4); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); newState = new InsetsState(mController.getState(), true /* copySource */); newState.getSource(ITYPE_IME).setVisible(true); newState.getSource(ITYPE_IME).setFrame(5, 6, 7, 8); mController.onStateChanged(newState); mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); }); } Loading