Merge "Make IME source frame not smaller than nav bar frame" into rvc-dev am: cac4132055

Change-Id: I6e5dfa397426685f84a7940a36b0d217b13bc29f
This commit is contained in:
Tiger Huang
2020-05-16 03:21:00 +00:00
committed by Automerger Merge Worker
3 changed files with 56 additions and 1 deletions

View File

@@ -3317,7 +3317,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mInputMethodWindow.getDisplayId());
}
mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
null /* frameProvider */, null /* imeFrameProvider */);
mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
computeImeTarget(true /* updateImeTarget */);
updateImeControlTarget();
}

View File

@@ -1106,6 +1106,24 @@ public class DisplayPolicy {
}
}
TriConsumer<DisplayFrames, WindowState, Rect> getImeSourceFrameProvider() {
return (displayFrames, windowState, inOutFrame) -> {
if (mNavigationBar != null && navigationBarPosition(displayFrames.mDisplayWidth,
displayFrames.mDisplayHeight,
displayFrames.mRotation) == NAV_BAR_BOTTOM) {
// In gesture navigation, nav bar frame is larger than frame to calculate insets.
// IME should not provide frame which is smaller than the nav bar frame. Otherwise,
// nav bar might be overlapped with the content of the client when IME is shown.
sTmpRect.set(inOutFrame);
sTmpRect.intersectUnchecked(mNavigationBar.getFrameLw());
inOutFrame.inset(windowState.getGivenContentInsetsLw());
inOutFrame.union(sTmpRect);
} else {
inOutFrame.inset(windowState.getGivenContentInsetsLw());
}
};
}
private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) {
int count = 0;
for (int insetsType : insetsTypes) {

View File

@@ -16,7 +16,9 @@
package com.android.server.wm;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -56,7 +58,10 @@ import static org.mockito.Mockito.when;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.DisplayInfo;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.WindowInsets.Side;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
@@ -352,4 +357,36 @@ public class DisplayPolicyTests extends WindowTestsBase {
insetsPolicy.updateBarControlTarget(mAppWindow);
assertNull(displayPolicy.mInputConsumer);
}
@Test
public void testImeMinimalSourceFrame() {
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.logicalWidth = 1000;
displayInfo.logicalHeight = 2000;
displayInfo.rotation = ROTATION_0;
mDisplayContent.mDisplayFrames = new DisplayFrames(mDisplayContent.getDisplayId(),
displayInfo, null /* displayCutout */);
displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs);
mNavBarWindow.getControllableInsetProvider().setServerVisible(true);
mDisplayContent.setInputMethodWindowLocked(mImeWindow);
mImeWindow.mAttrs.setFitInsetsSides(Side.all() & ~Side.BOTTOM);
mImeWindow.getGivenContentInsetsLw().set(0, displayInfo.logicalHeight, 0, 0);
mImeWindow.getControllableInsetProvider().setServerVisible(true);
displayPolicy.beginLayoutLw(mDisplayContent.mDisplayFrames, 0 /* UI mode */);
displayPolicy.layoutWindowLw(mImeWindow, null, mDisplayContent.mDisplayFrames);
final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState();
final InsetsSource imeSource = state.peekSource(ITYPE_IME);
final InsetsSource navBarSource = state.peekSource(ITYPE_NAVIGATION_BAR);
assertNotNull(imeSource);
assertNotNull(navBarSource);
assertFalse(imeSource.getFrame().isEmpty());
assertFalse(navBarSource.getFrame().isEmpty());
assertTrue(imeSource.getFrame().contains(navBarSource.getFrame()));
}
}