Loading services/core/java/com/android/server/wm/AppWindowToken.java +1 −3 Original line number Diff line number Diff line Loading @@ -2015,9 +2015,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree clearThumbnail(); setClientHidden(isHidden() && hiddenRequested); if (mService.mInputMethodTarget != null && mService.mInputMethodTarget.mAppToken == this) { getDisplayContent().computeImeTarget(true /* updateImeTarget */); } getDisplayContent().computeImeTargetIfNeeded(this); if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this + ": reportedVisible=" + reportedVisible Loading services/core/java/com/android/server/wm/DisplayContent.java +31 −13 Original line number Diff line number Diff line Loading @@ -496,6 +496,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ WindowState mInputMethodWindow; /** * This just indicates the window the input method is on top of, not * necessarily the window its input is going to. */ WindowState mInputMethodTarget; /** If true hold off on modifying the animation layer of mInputMethodTarget */ boolean mInputMethodTargetWaitingAnim; private final PointerEventDispatcher mPointerEventDispatcher; private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { Loading Loading @@ -699,7 +708,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final Consumer<WindowState> mApplyPostLayoutPolicy = w -> mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), mService.mInputMethodTarget); mInputMethodTarget); private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> { final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; Loading Loading @@ -1928,7 +1937,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * rather than directly above their target. */ private boolean skipTraverseChild(WindowContainer child) { if (child == mImeWindowsContainers && mService.mInputMethodTarget != null if (child == mImeWindowsContainers && mInputMethodTarget != null && !hasSplitScreenPrimaryStack()) { return true; } Loading Loading @@ -2806,7 +2815,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (!focusFound) { final WindowState imWindow = mInputMethodWindow; if (imWindow != null) { final WindowState prevTarget = mService.mInputMethodTarget; final WindowState prevTarget = mInputMethodTarget; final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/); imWindowChanged = prevTarget != newTarget; Loading Loading @@ -2998,13 +3007,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // There isn't an IME so there shouldn't be a target...That was easy! if (updateImeTarget) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + mService.mInputMethodTarget + " to null since mInputMethodWindow is null"); setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim); + mInputMethodTarget + " to null since mInputMethodWindow is null"); setInputMethodTarget(null, mInputMethodTargetWaitingAnim); } return null; } final WindowState curTarget = mService.mInputMethodTarget; final WindowState curTarget = mInputMethodTarget; if (!canUpdateImeTarget()) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target"); return curTarget; Loading @@ -3031,7 +3040,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, "Proposed new IME target: " + target); "Proposed new IME target: " + target + " for display: " + getDisplayId()); // Now, a special case -- if the last target's window is in the process of exiting, but // not removed, and the new target is home, keep on the last target to avoid flicker. Loading @@ -3052,7 +3061,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : "")); setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim); setInputMethodTarget(null, mInputMethodTargetWaitingAnim); } return null; Loading Loading @@ -3091,14 +3100,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return target; } /** * Calling {@link #computeImeTarget(boolean)} to update the input method target window in * the candidate app window token if needed. */ void computeImeTargetIfNeeded(AppWindowToken candidate) { if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == candidate) { computeImeTarget(true /* updateImeTarget */); } } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { if (target == mService.mInputMethodTarget && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } mService.mInputMethodTarget = target; mService.mInputMethodTargetWaitingAnim = targetWaitingAnim; mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(false /* setLayoutNeeded */); } Loading Loading @@ -4487,7 +4505,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mTaskStackContainers.assignLayer(t, 1); mAboveAppWindowsContainers.assignLayer(t, 2); WindowState imeTarget = mService.mInputMethodTarget; final WindowState imeTarget = mInputMethodTarget; boolean needAssignIme = true; // In the case where we have an IME target that is not in split-screen Loading services/core/java/com/android/server/wm/WindowManagerService.java +7 −10 Original line number Diff line number Diff line Loading @@ -623,13 +623,6 @@ public class WindowManagerService extends IWindowManager.Stub */ final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper()); /** This just indicates the window the input method is on top of, not * necessarily the window its input is going to. */ WindowState mInputMethodTarget = null; /** If true hold off on modifying the animation layer of mInputMethodTarget */ boolean mInputMethodTargetWaitingAnim; boolean mHardKeyboardAvailable; WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; SettingsObserver mSettingsObserver; Loading Loading @@ -5930,9 +5923,13 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mGlobalConfiguration="); pw.println(mRoot.getConfiguration()); pw.print(" mHasPermanentDpad="); pw.println(mHasPermanentDpad); mRoot.dumpTopFocusedDisplayId(pw); if (mInputMethodTarget != null) { pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget); mRoot.forAllDisplays(dc -> { final WindowState inputMethodTarget = dc.mInputMethodTarget; if (inputMethodTarget != null) { pw.print(" mInputMethodTarget in display# "); pw.print(dc.getDisplayId()); pw.print(' '); pw.println(inputMethodTarget); } }); pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mLastDisplayFreezeDuration="); TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw); Loading services/core/java/com/android/server/wm/WindowState.java +5 −4 Original line number Diff line number Diff line Loading @@ -4476,8 +4476,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean needsZBoost() { if (mIsImWindow && mService.mInputMethodTarget != null) { final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken; final WindowState inputMethodTarget = getDisplayContent().mInputMethodTarget; if (mIsImWindow && inputMethodTarget != null) { final AppWindowToken appToken = inputMethodTarget.mAppToken; if (appToken != null) { return appToken.needsZBoost(); } Loading Loading @@ -4607,7 +4608,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // Likewise if we share a token with the Input method target and are ordered // above it but not necessarily a child (e.g. a Dialog) then we also need // this promotion. final WindowState imeTarget = mService.mInputMethodTarget; final WindowState imeTarget = getDisplayContent().mInputMethodTarget; boolean inTokenWithAndAboveImeTarget = imeTarget != null && imeTarget != this && imeTarget.mToken == mToken && imeTarget.compareTo(this) <= 0; return inTokenWithAndAboveImeTarget; Loading Loading @@ -4684,7 +4685,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override public boolean isInputMethodTarget() { return mService.mInputMethodTarget == this; return getDisplayContent().mInputMethodTarget == this; } long getFrameNumber() { Loading services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +32 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doNothing; Loading Loading @@ -108,7 +109,7 @@ public class DisplayContentTests extends WindowTestsBase { final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget"); mWm.mInputMethodTarget = imeAppTarget; mDisplayContent.mInputMethodTarget = imeAppTarget; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading @@ -124,8 +125,8 @@ public class DisplayContentTests extends WindowTestsBase { } @Test public void testForAllWindows_WithChildWindowImeTarget() { mWm.mInputMethodTarget = mChildAppWindowAbove; public void testForAllWindows_WithChildWindowImeTarget() throws Exception { mDisplayContent.mInputMethodTarget = mChildAppWindowAbove; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading @@ -140,8 +141,8 @@ public class DisplayContentTests extends WindowTestsBase { } @Test public void testForAllWindows_WithStatusBarImeTarget() { mWm.mInputMethodTarget = mStatusBarWindow; public void testForAllWindows_WithStatusBarImeTarget() throws Exception { mDisplayContent.mInputMethodTarget = mStatusBarWindow; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading Loading @@ -568,6 +569,32 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId())); } @Test public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() { final DisplayContent newDisplay = createNewDisplay(); final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin"); final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1"); appWin.setHasSurface(true); appWin1.setHasSurface(true); // Set current input method window on default display, make sure the input method target // is appWin & null on the other display. mDisplayContent.setInputMethodWindowLocked(mImeWindow); newDisplay.setInputMethodWindowLocked(null); assertTrue("appWin should be IME target window", appWin.equals(mDisplayContent.mInputMethodTarget)); assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget); // Switch input method window on new display & make sure the input method target also // switched as expected. newDisplay.setInputMethodWindowLocked(mImeWindow); mDisplayContent.setInputMethodWindowLocked(null); assertTrue("appWin1 should be IME target window", appWin1.equals(newDisplay.mInputMethodTarget)); assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget); } private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +1 −3 Original line number Diff line number Diff line Loading @@ -2015,9 +2015,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree clearThumbnail(); setClientHidden(isHidden() && hiddenRequested); if (mService.mInputMethodTarget != null && mService.mInputMethodTarget.mAppToken == this) { getDisplayContent().computeImeTarget(true /* updateImeTarget */); } getDisplayContent().computeImeTargetIfNeeded(this); if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this + ": reportedVisible=" + reportedVisible Loading
services/core/java/com/android/server/wm/DisplayContent.java +31 −13 Original line number Diff line number Diff line Loading @@ -496,6 +496,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ WindowState mInputMethodWindow; /** * This just indicates the window the input method is on top of, not * necessarily the window its input is going to. */ WindowState mInputMethodTarget; /** If true hold off on modifying the animation layer of mInputMethodTarget */ boolean mInputMethodTargetWaitingAnim; private final PointerEventDispatcher mPointerEventDispatcher; private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { Loading Loading @@ -699,7 +708,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final Consumer<WindowState> mApplyPostLayoutPolicy = w -> mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), mService.mInputMethodTarget); mInputMethodTarget); private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> { final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; Loading Loading @@ -1928,7 +1937,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * rather than directly above their target. */ private boolean skipTraverseChild(WindowContainer child) { if (child == mImeWindowsContainers && mService.mInputMethodTarget != null if (child == mImeWindowsContainers && mInputMethodTarget != null && !hasSplitScreenPrimaryStack()) { return true; } Loading Loading @@ -2806,7 +2815,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (!focusFound) { final WindowState imWindow = mInputMethodWindow; if (imWindow != null) { final WindowState prevTarget = mService.mInputMethodTarget; final WindowState prevTarget = mInputMethodTarget; final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/); imWindowChanged = prevTarget != newTarget; Loading Loading @@ -2998,13 +3007,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // There isn't an IME so there shouldn't be a target...That was easy! if (updateImeTarget) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + mService.mInputMethodTarget + " to null since mInputMethodWindow is null"); setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim); + mInputMethodTarget + " to null since mInputMethodWindow is null"); setInputMethodTarget(null, mInputMethodTargetWaitingAnim); } return null; } final WindowState curTarget = mService.mInputMethodTarget; final WindowState curTarget = mInputMethodTarget; if (!canUpdateImeTarget()) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target"); return curTarget; Loading @@ -3031,7 +3040,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, "Proposed new IME target: " + target); "Proposed new IME target: " + target + " for display: " + getDisplayId()); // Now, a special case -- if the last target's window is in the process of exiting, but // not removed, and the new target is home, keep on the last target to avoid flicker. Loading @@ -3052,7 +3061,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : "")); setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim); setInputMethodTarget(null, mInputMethodTargetWaitingAnim); } return null; Loading Loading @@ -3091,14 +3100,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return target; } /** * Calling {@link #computeImeTarget(boolean)} to update the input method target window in * the candidate app window token if needed. */ void computeImeTargetIfNeeded(AppWindowToken candidate) { if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == candidate) { computeImeTarget(true /* updateImeTarget */); } } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { if (target == mService.mInputMethodTarget && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } mService.mInputMethodTarget = target; mService.mInputMethodTargetWaitingAnim = targetWaitingAnim; mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(false /* setLayoutNeeded */); } Loading Loading @@ -4487,7 +4505,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mTaskStackContainers.assignLayer(t, 1); mAboveAppWindowsContainers.assignLayer(t, 2); WindowState imeTarget = mService.mInputMethodTarget; final WindowState imeTarget = mInputMethodTarget; boolean needAssignIme = true; // In the case where we have an IME target that is not in split-screen Loading
services/core/java/com/android/server/wm/WindowManagerService.java +7 −10 Original line number Diff line number Diff line Loading @@ -623,13 +623,6 @@ public class WindowManagerService extends IWindowManager.Stub */ final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper()); /** This just indicates the window the input method is on top of, not * necessarily the window its input is going to. */ WindowState mInputMethodTarget = null; /** If true hold off on modifying the animation layer of mInputMethodTarget */ boolean mInputMethodTargetWaitingAnim; boolean mHardKeyboardAvailable; WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; SettingsObserver mSettingsObserver; Loading Loading @@ -5930,9 +5923,13 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mGlobalConfiguration="); pw.println(mRoot.getConfiguration()); pw.print(" mHasPermanentDpad="); pw.println(mHasPermanentDpad); mRoot.dumpTopFocusedDisplayId(pw); if (mInputMethodTarget != null) { pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget); mRoot.forAllDisplays(dc -> { final WindowState inputMethodTarget = dc.mInputMethodTarget; if (inputMethodTarget != null) { pw.print(" mInputMethodTarget in display# "); pw.print(dc.getDisplayId()); pw.print(' '); pw.println(inputMethodTarget); } }); pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mLastDisplayFreezeDuration="); TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw); Loading
services/core/java/com/android/server/wm/WindowState.java +5 −4 Original line number Diff line number Diff line Loading @@ -4476,8 +4476,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean needsZBoost() { if (mIsImWindow && mService.mInputMethodTarget != null) { final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken; final WindowState inputMethodTarget = getDisplayContent().mInputMethodTarget; if (mIsImWindow && inputMethodTarget != null) { final AppWindowToken appToken = inputMethodTarget.mAppToken; if (appToken != null) { return appToken.needsZBoost(); } Loading Loading @@ -4607,7 +4608,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // Likewise if we share a token with the Input method target and are ordered // above it but not necessarily a child (e.g. a Dialog) then we also need // this promotion. final WindowState imeTarget = mService.mInputMethodTarget; final WindowState imeTarget = getDisplayContent().mInputMethodTarget; boolean inTokenWithAndAboveImeTarget = imeTarget != null && imeTarget != this && imeTarget.mToken == mToken && imeTarget.compareTo(this) <= 0; return inTokenWithAndAboveImeTarget; Loading Loading @@ -4684,7 +4685,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override public boolean isInputMethodTarget() { return mService.mInputMethodTarget == this; return getDisplayContent().mInputMethodTarget == this; } long getFrameNumber() { Loading
services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +32 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doNothing; Loading Loading @@ -108,7 +109,7 @@ public class DisplayContentTests extends WindowTestsBase { final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget"); mWm.mInputMethodTarget = imeAppTarget; mDisplayContent.mInputMethodTarget = imeAppTarget; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading @@ -124,8 +125,8 @@ public class DisplayContentTests extends WindowTestsBase { } @Test public void testForAllWindows_WithChildWindowImeTarget() { mWm.mInputMethodTarget = mChildAppWindowAbove; public void testForAllWindows_WithChildWindowImeTarget() throws Exception { mDisplayContent.mInputMethodTarget = mChildAppWindowAbove; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading @@ -140,8 +141,8 @@ public class DisplayContentTests extends WindowTestsBase { } @Test public void testForAllWindows_WithStatusBarImeTarget() { mWm.mInputMethodTarget = mStatusBarWindow; public void testForAllWindows_WithStatusBarImeTarget() throws Exception { mDisplayContent.mInputMethodTarget = mStatusBarWindow; assertForAllWindowsOrder(Arrays.asList( mWallpaperWindow, Loading Loading @@ -568,6 +569,32 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId())); } @Test public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() { final DisplayContent newDisplay = createNewDisplay(); final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin"); final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1"); appWin.setHasSurface(true); appWin1.setHasSurface(true); // Set current input method window on default display, make sure the input method target // is appWin & null on the other display. mDisplayContent.setInputMethodWindowLocked(mImeWindow); newDisplay.setInputMethodWindowLocked(null); assertTrue("appWin should be IME target window", appWin.equals(mDisplayContent.mInputMethodTarget)); assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget); // Switch input method window on new display & make sure the input method target also // switched as expected. newDisplay.setInputMethodWindowLocked(mImeWindow); mDisplayContent.setInputMethodWindowLocked(null); assertTrue("appWin1 should be IME target window", appWin1.equals(newDisplay.mInputMethodTarget)); assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget); } private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } Loading