Merge "Fix ANR when switching the app task but IME selection dialog focused" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1181f3e9aa
@@ -116,8 +116,10 @@ public abstract class InputMethodManagerInternal {
|
|||||||
*
|
*
|
||||||
* @param windowToken the window token that is now in control, or {@code null} if no client
|
* @param windowToken the window token that is now in control, or {@code null} if no client
|
||||||
* window is in control of the IME.
|
* window is in control of the IME.
|
||||||
|
* @param imeParentChanged {@code true} when the window manager thoughts the IME surface parent
|
||||||
|
* will end up to change later, or {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public abstract void reportImeControl(@Nullable IBinder windowToken);
|
public abstract void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the IME surface.
|
* Destroys the IME surface.
|
||||||
@@ -176,7 +178,8 @@ public abstract class InputMethodManagerInternal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportImeControl(@Nullable IBinder windowToken) {
|
public void reportImeControl(@Nullable IBinder windowToken,
|
||||||
|
boolean imeParentChanged) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4937,13 +4937,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
|||||||
return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken);
|
return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportImeControl(@Nullable IBinder windowToken) {
|
private void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
|
||||||
synchronized (mMethodMap) {
|
synchronized (mMethodMap) {
|
||||||
if (mCurFocusedWindow != windowToken) {
|
if (mCurFocusedWindow != windowToken) {
|
||||||
// mCurPerceptible was set by the focused window, but it is no longer in control,
|
// mCurPerceptible was set by the focused window, but it is no longer in control,
|
||||||
// so we reset mCurPerceptible.
|
// so we reset mCurPerceptible.
|
||||||
mCurPerceptible = true;
|
mCurPerceptible = true;
|
||||||
}
|
}
|
||||||
|
if (imeParentChanged) {
|
||||||
|
// Hide the IME method menu earlier when the IME surface parent will change in
|
||||||
|
// case seeing the dialog dismiss flickering during the next focused window
|
||||||
|
// starting the input connection.
|
||||||
|
mMenuController.hideInputMethodMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5001,8 +5007,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportImeControl(@Nullable IBinder windowToken) {
|
public void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
|
||||||
mService.reportImeControl(windowToken);
|
mService.reportImeControl(windowToken, imeParentChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ public final class MultiClientInputMethodManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportImeControl(@Nullable IBinder windowToken) {
|
public void reportImeControl(@Nullable IBinder windowToken,
|
||||||
|
boolean imeParentChanged) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -729,12 +729,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
|
|
||||||
// When switching the app task, we keep the IME window visibility for better
|
// When switching the app task, we keep the IME window visibility for better
|
||||||
// transitioning experiences.
|
// transitioning experiences.
|
||||||
// However, in case IME created a child window without dismissing during the task
|
// However, in case IME created a child window or the IME selection dialog without
|
||||||
// switching to keep the window focus because IME window has higher window hierarchy,
|
// dismissing during the task switching to keep the window focus because IME window has
|
||||||
// we don't give it focus if the next IME layering target doesn't request IME visible.
|
// higher window hierarchy, we don't give it focus if the next IME layering target
|
||||||
if (w.mIsImWindow && w.isChildWindow() && (mImeLayeringTarget == null
|
// doesn't request IME visible.
|
||||||
|
if (w.mIsImWindow && (mImeLayeringTarget == null
|
||||||
|| !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) {
|
|| !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) {
|
||||||
return false;
|
if (w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w.isChildWindow()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ActivityRecord activity = w.mActivityRecord;
|
final ActivityRecord activity = w.mActivityRecord;
|
||||||
@@ -3978,7 +3985,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
// Update Ime parent when IME insets leash created or the new IME layering target might
|
// Update Ime parent when IME insets leash created or the new IME layering target might
|
||||||
// updated from setImeLayeringTarget, which is the best time that default IME visibility
|
// updated from setImeLayeringTarget, which is the best time that default IME visibility
|
||||||
// has been settled down after IME control target changed.
|
// has been settled down after IME control target changed.
|
||||||
if (prevImeControlTarget != mImeControlTarget || forceUpdateImeParent) {
|
final boolean imeParentChanged =
|
||||||
|
prevImeControlTarget != mImeControlTarget || forceUpdateImeParent;
|
||||||
|
if (imeParentChanged) {
|
||||||
updateImeParent();
|
updateImeParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3986,7 +3995,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
final IBinder token = win != null ? win.mClient.asBinder() : null;
|
final IBinder token = win != null ? win.mClient.asBinder() : null;
|
||||||
// Note: not allowed to call into IMMS with the WM lock held, hence the post.
|
// Note: not allowed to call into IMMS with the WM lock held, hence the post.
|
||||||
mWmService.mH.post(() ->
|
mWmService.mH.post(() ->
|
||||||
InputMethodManagerInternal.get().reportImeControl(token)
|
InputMethodManagerInternal.get().reportImeControl(token, imeParentChanged)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_
|
|||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||||
|
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
|
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_NOTIFICATION_SHADE;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
|
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
|
||||||
@@ -2201,6 +2202,31 @@ public class DisplayContentTests extends WindowTestsBase {
|
|||||||
assertNotEquals(imeChildWindow, mDisplayContent.findFocusedWindow());
|
assertNotEquals(imeChildWindow, mDisplayContent.findFocusedWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseTestDisplay(addWindows = W_INPUT_METHOD)
|
||||||
|
@Test
|
||||||
|
public void testImeMenuDialogFocusWhenImeLayeringTargetChanges() {
|
||||||
|
final WindowState imeMenuDialog =
|
||||||
|
createWindow(mImeWindow, TYPE_INPUT_METHOD_DIALOG, "imeMenuDialog");
|
||||||
|
makeWindowVisibleAndDrawn(imeMenuDialog, mImeWindow);
|
||||||
|
assertTrue(imeMenuDialog.canReceiveKeys());
|
||||||
|
mDisplayContent.setInputMethodWindowLocked(mImeWindow);
|
||||||
|
|
||||||
|
// Verify imeMenuDialog can be focused window if the next IME target requests IME visible.
|
||||||
|
final WindowState imeAppTarget =
|
||||||
|
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
|
||||||
|
mDisplayContent.setImeLayeringTarget(imeAppTarget);
|
||||||
|
spyOn(imeAppTarget);
|
||||||
|
doReturn(true).when(imeAppTarget).getRequestedVisibility(ITYPE_IME);
|
||||||
|
assertEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
|
||||||
|
|
||||||
|
// Verify imeMenuDialog doesn't be focused window if the next IME target does not
|
||||||
|
// request IME visible.
|
||||||
|
final WindowState nextImeAppTarget =
|
||||||
|
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "nextImeAppTarget");
|
||||||
|
mDisplayContent.setImeLayeringTarget(nextImeAppTarget);
|
||||||
|
assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
|
||||||
|
}
|
||||||
|
|
||||||
private void removeRootTaskTests(Runnable runnable) {
|
private void removeRootTaskTests(Runnable runnable) {
|
||||||
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
|
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
|
||||||
final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
|
final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
|
||||||
|
|||||||
Reference in New Issue
Block a user