Merge "Only give DisplayInsetsController control over IME in split-screen" into rvc-dev am: 7844ca2d72 am: 45047d66fc
Change-Id: I01cc87372ccdbce93a1438df698d96a95d5afdb2
This commit is contained in:
@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
@@ -141,6 +142,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ActivityInfo.ScreenOrientation;
|
||||
@@ -3370,34 +3372,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isImeControlledByApp() {
|
||||
return mInputMethodTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
|
||||
mInputMethodTarget.getWindowingMode());
|
||||
}
|
||||
|
||||
boolean isImeAttachedToApp() {
|
||||
return (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord != null
|
||||
return isImeControlledByApp()
|
||||
&& mInputMethodTarget.mActivityRecord != null
|
||||
&& mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
|
||||
// An activity with override bounds should be letterboxed inside its parent bounds,
|
||||
// so it doesn't fill the screen.
|
||||
&& mInputMethodTarget.mActivityRecord.matchParentBounds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IME target that should host IME when this display that is reparented to another
|
||||
* WindowState.
|
||||
* IME is never displayed in a child display.
|
||||
* Use {@link WindowState#getImeControlTarget()} when IME target window
|
||||
* which originally called
|
||||
* {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is known.
|
||||
*
|
||||
* @return {@link WindowState} of host that controls IME.
|
||||
* {@code null} when {@param dc} is not a virtual display.
|
||||
* @see DisplayContent#reparent
|
||||
*/
|
||||
@Nullable
|
||||
WindowState getImeControlTarget() {
|
||||
WindowState imeTarget = mInputMethodTarget;
|
||||
if (imeTarget != null) {
|
||||
return imeTarget.getImeControlTarget();
|
||||
}
|
||||
|
||||
return getInsetsStateController().getImeSourceProvider().getControlTarget().getWindow();
|
||||
&& mInputMethodTarget.mActivityRecord.matchParentBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3407,7 +3393,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
*
|
||||
* @param target current IME target.
|
||||
* @return {@link WindowState} that can host IME.
|
||||
* @see DisplayContent#getImeControlTarget()
|
||||
*/
|
||||
WindowState getImeHostOrFallback(WindowState target) {
|
||||
if (target != null && target.getDisplayContent().canShowIme()) {
|
||||
@@ -3448,8 +3433,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
/**
|
||||
* The IME input target is the window which receives input from IME. It is also a candidate
|
||||
* which controls the visibility and animation of the input method window.
|
||||
*
|
||||
* @param target the window that receives input from IME.
|
||||
*/
|
||||
void setInputMethodInputTarget(WindowState target) {
|
||||
if (mInputMethodInputTarget != target) {
|
||||
@@ -3459,12 +3442,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
|
||||
private void updateImeControlTarget() {
|
||||
if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) {
|
||||
mInputMethodControlTarget = mRemoteInsetsControlTarget;
|
||||
} else {
|
||||
// Otherwise, we just use the ime input target
|
||||
mInputMethodControlTarget = mInputMethodInputTarget;
|
||||
}
|
||||
mInputMethodControlTarget = computeImeControlTarget();
|
||||
mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
|
||||
}
|
||||
|
||||
@@ -3476,6 +3454,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the window where we hand IME control to.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
InsetsControlTarget computeImeControlTarget() {
|
||||
if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) {
|
||||
return mRemoteInsetsControlTarget;
|
||||
} else {
|
||||
// Otherwise, we just use the ime target as received from IME.
|
||||
return mInputMethodInputTarget;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the window the IME should be attached to.
|
||||
*/
|
||||
|
||||
@@ -65,6 +65,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -84,10 +85,13 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.Gravity;
|
||||
import android.view.IDisplayWindowInsetsController;
|
||||
import android.view.IDisplayWindowRotationCallback;
|
||||
import android.view.IDisplayWindowRotationController;
|
||||
import android.view.ISystemGestureExclusionListener;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
@@ -810,25 +814,19 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testComputeImeParent_app() throws Exception {
|
||||
try (final InsetsModeSession session =
|
||||
new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
|
||||
assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
|
||||
dc.computeImeParent());
|
||||
}
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
|
||||
assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
|
||||
dc.computeImeParent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeImeParent_app_notFullscreen() throws Exception {
|
||||
try (final InsetsModeSession session =
|
||||
new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
|
||||
dc.mInputMethodTarget.setWindowingMode(
|
||||
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
|
||||
}
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
|
||||
dc.mInputMethodTarget.setWindowingMode(
|
||||
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -843,12 +841,61 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testComputeImeParent_noApp() throws Exception {
|
||||
try (final InsetsModeSession session =
|
||||
new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
|
||||
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
|
||||
}
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
|
||||
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeImeControlTarget() throws Exception {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.setRemoteInsetsController(createDisplayWindowInsetsController());
|
||||
dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
|
||||
dc.mInputMethodTarget = dc.mInputMethodInputTarget;
|
||||
assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeImeControlTarget_splitscreen() throws Exception {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
|
||||
dc.mInputMethodInputTarget.setWindowingMode(
|
||||
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
dc.mInputMethodTarget = dc.mInputMethodInputTarget;
|
||||
dc.setRemoteInsetsController(createDisplayWindowInsetsController());
|
||||
assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeImeControlTarget_notMatchParentBounds() throws Exception {
|
||||
spyOn(mAppWindow.mActivityRecord);
|
||||
doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
|
||||
mDisplayContent.mInputMethodInputTarget = mAppWindow;
|
||||
mDisplayContent.mInputMethodTarget = mDisplayContent.mInputMethodInputTarget;
|
||||
mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
|
||||
assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
|
||||
}
|
||||
|
||||
private IDisplayWindowInsetsController createDisplayWindowInsetsController() {
|
||||
return new IDisplayWindowInsetsController.Stub() {
|
||||
|
||||
@Override
|
||||
public void insetsChanged(InsetsState insetsState) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insetsControlChanged(InsetsState insetsState,
|
||||
InsetsSourceControl[] insetsSourceControls) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showInsets(int i, boolean b) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideInsets(int i, boolean b) throws RemoteException {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user