Merge "Force showing navigation bar while IME is visible" into sc-dev
This commit is contained in:
@@ -86,6 +86,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
|
||||
private final InsetsState mInitialInsetsState;
|
||||
private final @AnimationType int mAnimationType;
|
||||
private final @InsetsType int mTypes;
|
||||
private @InsetsType int mControllingTypes;
|
||||
private final InsetsAnimationControlCallbacks mController;
|
||||
private final WindowInsetsAnimation mAnimation;
|
||||
/** @see WindowInsetsAnimationController#hasZeroInsetsIme */
|
||||
@@ -112,6 +113,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
|
||||
mControls = controls;
|
||||
mListener = listener;
|
||||
mTypes = types;
|
||||
mControllingTypes = types;
|
||||
mController = controller;
|
||||
mInitialInsetsState = new InsetsState(state, true /* copySources */);
|
||||
if (frame != null) {
|
||||
@@ -186,6 +188,16 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
|
||||
return mTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControllingTypes() {
|
||||
return mControllingTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyControlRevoked(@InsetsType int types) {
|
||||
mControllingTypes &= ~types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @AnimationType int getAnimationType() {
|
||||
return mAnimationType;
|
||||
|
||||
@@ -29,10 +29,21 @@ import android.view.WindowInsets.Type.InsetsType;
|
||||
public interface InsetsAnimationControlRunner {
|
||||
|
||||
/**
|
||||
* @return The {@link InsetsType} the animation of this runner is controlling.
|
||||
* @return The {@link InsetsType} the animation of this runner controls.
|
||||
*/
|
||||
@InsetsType int getTypes();
|
||||
|
||||
/**
|
||||
* @return The {@link InsetsType} the animation of this runner is controlling. This can be
|
||||
* changed if a control is revoked.
|
||||
*/
|
||||
@InsetsType int getControllingTypes();
|
||||
|
||||
/**
|
||||
* Notifies {@link InsetsType types} of control are getting revoked.
|
||||
*/
|
||||
void notifyControlRevoked(@InsetsType int types);
|
||||
|
||||
/**
|
||||
* Cancels the animation.
|
||||
*/
|
||||
|
||||
@@ -139,6 +139,17 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
|
||||
return mControl.getTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public int getControllingTypes() {
|
||||
return mControl.getControllingTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyControlRevoked(@InsetsType int types) {
|
||||
mControl.notifyControlRevoked(types);
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void cancel() {
|
||||
|
||||
@@ -1224,9 +1224,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
}
|
||||
|
||||
void notifyControlRevoked(InsetsSourceConsumer consumer) {
|
||||
final @InsetsType int types = toPublicType(consumer.getType());
|
||||
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
|
||||
InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
|
||||
if ((control.getTypes() & toPublicType(consumer.getType())) != 0) {
|
||||
control.notifyControlRevoked(types);
|
||||
if (control.getControllingTypes() == 0) {
|
||||
cancelAnimation(control, true /* invokeCallback */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
|
||||
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
|
||||
@@ -207,7 +208,8 @@ class InsetsPolicy {
|
||||
*/
|
||||
InsetsState getInsetsForWindow(WindowState target) {
|
||||
final InsetsState originalState = mStateController.getInsetsForWindow(target);
|
||||
return adjustVisibilityForTransientTypes(originalState);
|
||||
final InsetsState state = adjustVisibilityForTransientTypes(originalState);
|
||||
return target.mIsImWindow ? adjustVisibilityForIme(state, state == originalState) : state;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,6 +239,20 @@ class InsetsPolicy {
|
||||
return state;
|
||||
}
|
||||
|
||||
// Navigation bar insets is always visible to IME.
|
||||
private static InsetsState adjustVisibilityForIme(InsetsState originalState,
|
||||
boolean copyState) {
|
||||
final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR);
|
||||
if (originalNavSource != null && !originalNavSource.isVisible()) {
|
||||
final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
|
||||
final InsetsSource navSource = new InsetsSource(originalNavSource);
|
||||
navSource.setVisible(true);
|
||||
state.addSource(navSource);
|
||||
return state;
|
||||
}
|
||||
return originalState;
|
||||
}
|
||||
|
||||
void onInsetsModified(InsetsControlTarget caller) {
|
||||
mStateController.onInsetsModified(caller);
|
||||
checkAbortTransient(caller);
|
||||
@@ -245,17 +261,21 @@ class InsetsPolicy {
|
||||
|
||||
/**
|
||||
* Called when a control target modified the insets state. If the target set a insets source to
|
||||
* visible while it is shown transiently, we need to abort the transient state.
|
||||
* visible while it is shown transiently, we need to abort the transient state. While IME is
|
||||
* requested visible, we also need to abort the transient state of navigation bar if it is shown
|
||||
* transiently.
|
||||
*
|
||||
* @param caller who changed the insets state.
|
||||
*/
|
||||
private void checkAbortTransient(InsetsControlTarget caller) {
|
||||
if (mShowingTransientTypes.size() != 0) {
|
||||
IntArray abortTypes = new IntArray();
|
||||
final IntArray abortTypes = new IntArray();
|
||||
final boolean imeRequestedVisible = caller.getRequestedVisibility(ITYPE_IME);
|
||||
for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
|
||||
final @InternalInsetsType int type = mShowingTransientTypes.get(i);
|
||||
if (mStateController.isFakeTarget(type, caller)
|
||||
&& caller.getRequestedVisibility(type)) {
|
||||
if ((mStateController.isFakeTarget(type, caller)
|
||||
&& caller.getRequestedVisibility(type))
|
||||
|| (type == ITYPE_NAVIGATION_BAR && imeRequestedVisible)) {
|
||||
mShowingTransientTypes.remove(i);
|
||||
abortTypes.add(type);
|
||||
}
|
||||
@@ -330,6 +350,11 @@ class InsetsPolicy {
|
||||
|
||||
private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin,
|
||||
boolean forceShowsSystemBarsForWindowingMode) {
|
||||
final WindowState imeWin = mDisplayContent.mInputMethodWindow;
|
||||
if (imeWin != null && imeWin.isVisible()) {
|
||||
// Force showing navigation bar while IME is visible.
|
||||
return null;
|
||||
}
|
||||
if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
|
||||
return mDummyControlTarget;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
@@ -78,6 +79,7 @@ import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputWindowHandle;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsState;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
@@ -880,6 +882,22 @@ public class WindowStateTests extends WindowTestsBase {
|
||||
verify(app).notifyInsetsChanged();
|
||||
}
|
||||
|
||||
@UseTestDisplay(addWindows = { W_INPUT_METHOD, W_ACTIVITY })
|
||||
@Test
|
||||
public void testImeAlwaysReceivesVisibleNavigationBarInsets() {
|
||||
final InsetsSource navSource = new InsetsSource(ITYPE_NAVIGATION_BAR);
|
||||
mImeWindow.mAboveInsetsState.addSource(navSource);
|
||||
mAppWindow.mAboveInsetsState.addSource(navSource);
|
||||
|
||||
navSource.setVisible(false);
|
||||
assertTrue(mImeWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
|
||||
assertFalse(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
|
||||
|
||||
navSource.setVisible(true);
|
||||
assertTrue(mImeWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
|
||||
assertTrue(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
|
||||
}
|
||||
|
||||
@UseTestDisplay(addWindows = { W_ACTIVITY })
|
||||
@Test
|
||||
public void testUpdateImeControlTargetWhenLeavingMultiWindow() {
|
||||
|
||||
Reference in New Issue
Block a user