Loading services/core/java/com/android/server/wm/DisplayContent.java +52 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; import static com.android.server.wm.ProtoLogGroup.WM_ERROR; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; Loading Loading @@ -3416,6 +3417,57 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo && 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(); } /** * Finds the window which can host IME if IME target cannot host it. * e.g. IME target cannot host IME when it's display has a parent display OR when display * doesn't support IME/system decorations. * * @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()) { return target; } // host is in non-default display that doesn't support system decor, default to // default display's StatusBar to control IME. // TODO: (b/148234093)find a better host OR control IME animation/visibility directly // because it won't work when statusbar isn't available. return mWmService.getDefaultDisplayContentLocked().getDisplayPolicy().getStatusBar(); } boolean canShowIme() { if (isUntrustedVirtualDisplay()) { return false; } return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this) || mWmService.mForceDesktopModeOnExternalDisplays; } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; Loading services/core/java/com/android/server/wm/InsetsControlTarget.java +7 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,13 @@ import android.view.WindowInsets.Type.InsetsType; interface InsetsControlTarget { void notifyInsetsControlChanged(); /** * @return {@link WindowState} of this target, if any. */ default WindowState getWindow() { return null; } /** * Instructs the control target to show inset sources. * Loading services/core/java/com/android/server/wm/InsetsSourceProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,12 @@ class InsetsSourceProvider { // to control the window for now. return; } if (target != null && target.getWindow() != null) { // ime control target could be a different window. // Refer WindowState#getImeControlTarget(). target = target.getWindow().getImeControlTarget(); } if (mWin == null) { mControlTarget = target; return; Loading services/core/java/com/android/server/wm/WindowManagerService.java +19 −25 Original line number Diff line number Diff line Loading @@ -6991,8 +6991,15 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); } boolean show; final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null) { ProtoLog.w(WM_ERROR, "Attempted to get IME flag of a display that does not exist: %d", displayId); return false; } synchronized (mGlobalLock) { show = shouldShowImeSystemWindowUncheckedLocked(displayId); show = dc.canShowIme(); } return show; Loading Loading @@ -7405,15 +7412,13 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void showImePostLayout(IBinder imeTargetWindowToken) { synchronized (mGlobalLock) { final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); if (imeTarget == null) { return; } final int displayId = imeTarget.getDisplayId(); if (!shouldShowImeSystemWindowUncheckedLocked(displayId)) { return; } imeTarget = imeTarget.getImeControlTarget(); final int displayId = imeTarget.getDisplayId(); mRoot.getDisplayContent(displayId).getInsetsStateController().getImeSourceProvider() .scheduleShowImePostLayout(imeTarget); } Loading @@ -7423,12 +7428,16 @@ public class WindowManagerService extends IWindowManager.Stub public void hideIme(int displayId) { synchronized (mGlobalLock) { final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc != null && dc.mInputMethodTarget != null) { if (dc != null) { WindowState imeTarget = dc.getImeControlTarget(); if (imeTarget == null) { return; } // If there was a pending IME show(), reset it as IME has been // requested to be hidden. dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout(); dc.mInputMethodControlTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */); imeTarget.getDisplayContent().getInsetsStateController().getImeSourceProvider() .abortShowImePostLayout(); imeTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */); } } } Loading Loading @@ -7936,21 +7945,6 @@ public class WindowManagerService extends IWindowManager.Stub return true; } private boolean shouldShowImeSystemWindowUncheckedLocked(final int displayId) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { ProtoLog.w(WM_ERROR, "Attempted to get IME flag of a display that does not exist: %d", displayId); return false; } if (displayContent.isUntrustedVirtualDisplay()) { return false; } return mDisplayWindowSettings.shouldShowImeLocked(displayContent) || mForceDesktopModeOnExternalDisplays; } @Override public void getWindowInsets(WindowManager.LayoutParams attrs, int displayId, Rect outContentInsets, Rect outStableInsets, Loading services/core/java/com/android/server/wm/WindowState.java +23 −0 Original line number Diff line number Diff line Loading @@ -3517,6 +3517,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } @Override public WindowState getWindow() { return this; } @Override public void showInsets(@InsetsType int types, boolean fromIme) { try { Loading Loading @@ -5334,6 +5339,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } /** * Get IME target that should host IME when this window's display has a parent. * Note: IME is never hosted by a display that has a parent. * When window calling * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is unknown, * use {@link DisplayContent#getImeControlTarget()} instead. * * @return {@link WindowState} of host that controls the IME. * When window is doesn't have a parent, it is returned as-is. */ WindowState getImeControlTarget() { final DisplayContent dc = getDisplayContent(); final WindowState parentWindow = dc.getParentWindow(); // If target's display has a parent, IME is displayed in the parent display. return dc.getImeHostOrFallback(parentWindow != null ? parentWindow : this); } @Override void assignLayer(Transaction t, int layer) { // See comment in assignRelativeLayerForImeTargetChild Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +52 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; import static com.android.server.wm.ProtoLogGroup.WM_ERROR; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; Loading Loading @@ -3416,6 +3417,57 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo && 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(); } /** * Finds the window which can host IME if IME target cannot host it. * e.g. IME target cannot host IME when it's display has a parent display OR when display * doesn't support IME/system decorations. * * @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()) { return target; } // host is in non-default display that doesn't support system decor, default to // default display's StatusBar to control IME. // TODO: (b/148234093)find a better host OR control IME animation/visibility directly // because it won't work when statusbar isn't available. return mWmService.getDefaultDisplayContentLocked().getDisplayPolicy().getStatusBar(); } boolean canShowIme() { if (isUntrustedVirtualDisplay()) { return false; } return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this) || mWmService.mForceDesktopModeOnExternalDisplays; } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; Loading
services/core/java/com/android/server/wm/InsetsControlTarget.java +7 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,13 @@ import android.view.WindowInsets.Type.InsetsType; interface InsetsControlTarget { void notifyInsetsControlChanged(); /** * @return {@link WindowState} of this target, if any. */ default WindowState getWindow() { return null; } /** * Instructs the control target to show inset sources. * Loading
services/core/java/com/android/server/wm/InsetsSourceProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,12 @@ class InsetsSourceProvider { // to control the window for now. return; } if (target != null && target.getWindow() != null) { // ime control target could be a different window. // Refer WindowState#getImeControlTarget(). target = target.getWindow().getImeControlTarget(); } if (mWin == null) { mControlTarget = target; return; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +19 −25 Original line number Diff line number Diff line Loading @@ -6991,8 +6991,15 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); } boolean show; final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null) { ProtoLog.w(WM_ERROR, "Attempted to get IME flag of a display that does not exist: %d", displayId); return false; } synchronized (mGlobalLock) { show = shouldShowImeSystemWindowUncheckedLocked(displayId); show = dc.canShowIme(); } return show; Loading Loading @@ -7405,15 +7412,13 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void showImePostLayout(IBinder imeTargetWindowToken) { synchronized (mGlobalLock) { final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); if (imeTarget == null) { return; } final int displayId = imeTarget.getDisplayId(); if (!shouldShowImeSystemWindowUncheckedLocked(displayId)) { return; } imeTarget = imeTarget.getImeControlTarget(); final int displayId = imeTarget.getDisplayId(); mRoot.getDisplayContent(displayId).getInsetsStateController().getImeSourceProvider() .scheduleShowImePostLayout(imeTarget); } Loading @@ -7423,12 +7428,16 @@ public class WindowManagerService extends IWindowManager.Stub public void hideIme(int displayId) { synchronized (mGlobalLock) { final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc != null && dc.mInputMethodTarget != null) { if (dc != null) { WindowState imeTarget = dc.getImeControlTarget(); if (imeTarget == null) { return; } // If there was a pending IME show(), reset it as IME has been // requested to be hidden. dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout(); dc.mInputMethodControlTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */); imeTarget.getDisplayContent().getInsetsStateController().getImeSourceProvider() .abortShowImePostLayout(); imeTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */); } } } Loading Loading @@ -7936,21 +7945,6 @@ public class WindowManagerService extends IWindowManager.Stub return true; } private boolean shouldShowImeSystemWindowUncheckedLocked(final int displayId) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent == null) { ProtoLog.w(WM_ERROR, "Attempted to get IME flag of a display that does not exist: %d", displayId); return false; } if (displayContent.isUntrustedVirtualDisplay()) { return false; } return mDisplayWindowSettings.shouldShowImeLocked(displayContent) || mForceDesktopModeOnExternalDisplays; } @Override public void getWindowInsets(WindowManager.LayoutParams attrs, int displayId, Rect outContentInsets, Rect outStableInsets, Loading
services/core/java/com/android/server/wm/WindowState.java +23 −0 Original line number Diff line number Diff line Loading @@ -3517,6 +3517,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } @Override public WindowState getWindow() { return this; } @Override public void showInsets(@InsetsType int types, boolean fromIme) { try { Loading Loading @@ -5334,6 +5339,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } /** * Get IME target that should host IME when this window's display has a parent. * Note: IME is never hosted by a display that has a parent. * When window calling * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is unknown, * use {@link DisplayContent#getImeControlTarget()} instead. * * @return {@link WindowState} of host that controls the IME. * When window is doesn't have a parent, it is returned as-is. */ WindowState getImeControlTarget() { final DisplayContent dc = getDisplayContent(); final WindowState parentWindow = dc.getParentWindow(); // If target's display has a parent, IME is displayed in the parent display. return dc.getImeHostOrFallback(parentWindow != null ? parentWindow : this); } @Override void assignLayer(Transaction t, int layer) { // See comment in assignRelativeLayerForImeTargetChild Loading