Loading core/java/android/view/IWindow.aidl +6 −29 Original line number Diff line number Diff line Loading @@ -71,33 +71,10 @@ oneway interface IWindow { void dispatchGetNewSurface(); /** * Tell the window that it is either gaining or losing focus. * * @param hasFocus {@code true} if window has focus, {@code false} otherwise. * @param inTouchMode {@code true} if screen is in touch mode, {@code false} otherwise. * @param reportToClient {@code true} when need to report to child view with * {@link View#onWindowFocusChanged(boolean)}, {@code false} otherwise. * <p> * Note: In the previous design, there is only one window focus state tracked by * WindowManagerService. * For multi-display, the window focus state is tracked by each display independently. * <p> * It will introduce a problem if the window was already focused on one display and then * switched to another display, since the window focus state on each display is independent, * there is no global window focus state in WindowManagerService, so the window focus state of * the former display remains unchanged. * <p> * When switched back to former display, some flows that rely on the global window focus state * in view root will be missed due to the window focus state remaining unchanged. * (i.e: Showing single IME window when switching between displays.) * <p> * To solve the problem, WindowManagerService tracks the top focused display change and then * callbacks to the client via this method to make sure that the client side will request the * IME on the top focused display, and then set {@param reportToClient} as {@code false} to * ignore reporting to the application, since its focus remains unchanged on its display. * * Tell the window that it is either gaining or losing focus. Keep it up * to date on the current state showing navigational focus (touch mode) too. */ void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient); void windowFocusChanged(boolean hasFocus, boolean inTouchMode); void closeSystemDialogs(String reason); Loading core/java/android/view/ViewRootImpl.java +9 −24 Original line number Diff line number Diff line Loading @@ -2765,7 +2765,7 @@ public final class ViewRootImpl implements ViewParent, } } private void handleWindowFocusChanged(boolean reportToClient) { private void handleWindowFocusChanged() { final boolean hasWindowFocus; final boolean inTouchMode; synchronized (this) { Loading Loading @@ -2800,9 +2800,8 @@ public final class ViewRootImpl implements ViewParent, } catch (RemoteException ex) { } // Retry in a bit. final Message msg = mHandler.obtainMessage(MSG_WINDOW_FOCUS_CHANGED); msg.arg1 = reportToClient ? 1 : 0; mHandler.sendMessageDelayed(msg, 500); mHandler.sendMessageDelayed(mHandler.obtainMessage( MSG_WINDOW_FOCUS_CHANGED), 500); return; } } Loading @@ -2819,15 +2818,8 @@ public final class ViewRootImpl implements ViewParent, } if (mView != null) { mAttachInfo.mKeyDispatchState.reset(); // We dispatch onWindowFocusChanged to child view only when window is gaining / // losing focus. // If the focus is updated from top display change but window focus on the display // remains unchanged, will not callback onWindowFocusChanged again since it may // be redundant & can affect the state when it callbacks. if (reportToClient) { mView.dispatchWindowFocusChanged(hasWindowFocus); mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus); } if (mAttachInfo.mTooltipHost != null) { mAttachInfo.mTooltipHost.hideTooltip(); } Loading Loading @@ -4428,7 +4420,7 @@ public final class ViewRootImpl implements ViewParent, } break; case MSG_WINDOW_FOCUS_CHANGED: { handleWindowFocusChanged(msg.arg1 != 0 /* reportToClient */); handleWindowFocusChanged(); } break; case MSG_DIE: doDie(); Loading Loading @@ -7372,7 +7364,7 @@ public final class ViewRootImpl implements ViewParent, } if (stage != null) { handleWindowFocusChanged(true /* reportToClient */); handleWindowFocusChanged(); stage.deliver(q); } else { finishInputEvent(q); Loading Loading @@ -7712,11 +7704,6 @@ public final class ViewRootImpl implements ViewParent, } public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { windowFocusChanged(hasFocus, inTouchMode, true /* reportToClient */); } public void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient) { synchronized (this) { mWindowFocusChanged = true; mUpcomingWindowFocus = hasFocus; Loading @@ -7724,7 +7711,6 @@ public final class ViewRootImpl implements ViewParent, } Message msg = Message.obtain(); msg.what = MSG_WINDOW_FOCUS_CHANGED; msg.arg1 = reportToClient ? 1 : 0; mHandler.sendMessage(msg); } Loading Loading @@ -8286,11 +8272,10 @@ public final class ViewRootImpl implements ViewParent, } @Override public void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient) { public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.windowFocusChanged(hasFocus, inTouchMode, reportToClient); viewAncestor.windowFocusChanged(hasFocus, inTouchMode); } } Loading core/java/com/android/internal/view/BaseIWindow.java +2 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,9 @@ import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IWindow; import android.view.IWindowSession; import android.view.PointerIcon; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.PointerIcon; import com.android.internal.os.IResultReceiver; Loading Loading @@ -76,7 +76,7 @@ public class BaseIWindow extends IWindow.Stub { } @Override public void windowFocusChanged(boolean hasFocus, boolean touchEnabled, boolean reportToClient) { public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { } @Override Loading core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2019,6 +2019,10 @@ This is intended to allow packaging drivers or tools for installation on a PC. --> <string translatable="false" name="config_isoImagePath"></string> <!-- Whether the system enables per-display focus. If the system has the input method for each display, this value should be true. --> <bool name="config_perDisplayFocusEnabled">false</bool> <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be autodetected from the Configuration. --> <bool name="config_showNavigationBar">false</bool> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1670,6 +1670,7 @@ <java-symbol type="bool" name="config_lockDayNightMode" /> <java-symbol type="bool" name="config_lockUiMode" /> <java-symbol type="bool" name="config_reverseDefaultRotation" /> <java-symbol type="bool" name="config_perDisplayFocusEnabled" /> <java-symbol type="bool" name="config_showNavigationBar" /> <java-symbol type="bool" name="config_supportAutoRotation" /> <java-symbol type="bool" name="target_honeycomb_needs_options_menu" /> Loading Loading
core/java/android/view/IWindow.aidl +6 −29 Original line number Diff line number Diff line Loading @@ -71,33 +71,10 @@ oneway interface IWindow { void dispatchGetNewSurface(); /** * Tell the window that it is either gaining or losing focus. * * @param hasFocus {@code true} if window has focus, {@code false} otherwise. * @param inTouchMode {@code true} if screen is in touch mode, {@code false} otherwise. * @param reportToClient {@code true} when need to report to child view with * {@link View#onWindowFocusChanged(boolean)}, {@code false} otherwise. * <p> * Note: In the previous design, there is only one window focus state tracked by * WindowManagerService. * For multi-display, the window focus state is tracked by each display independently. * <p> * It will introduce a problem if the window was already focused on one display and then * switched to another display, since the window focus state on each display is independent, * there is no global window focus state in WindowManagerService, so the window focus state of * the former display remains unchanged. * <p> * When switched back to former display, some flows that rely on the global window focus state * in view root will be missed due to the window focus state remaining unchanged. * (i.e: Showing single IME window when switching between displays.) * <p> * To solve the problem, WindowManagerService tracks the top focused display change and then * callbacks to the client via this method to make sure that the client side will request the * IME on the top focused display, and then set {@param reportToClient} as {@code false} to * ignore reporting to the application, since its focus remains unchanged on its display. * * Tell the window that it is either gaining or losing focus. Keep it up * to date on the current state showing navigational focus (touch mode) too. */ void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient); void windowFocusChanged(boolean hasFocus, boolean inTouchMode); void closeSystemDialogs(String reason); Loading
core/java/android/view/ViewRootImpl.java +9 −24 Original line number Diff line number Diff line Loading @@ -2765,7 +2765,7 @@ public final class ViewRootImpl implements ViewParent, } } private void handleWindowFocusChanged(boolean reportToClient) { private void handleWindowFocusChanged() { final boolean hasWindowFocus; final boolean inTouchMode; synchronized (this) { Loading Loading @@ -2800,9 +2800,8 @@ public final class ViewRootImpl implements ViewParent, } catch (RemoteException ex) { } // Retry in a bit. final Message msg = mHandler.obtainMessage(MSG_WINDOW_FOCUS_CHANGED); msg.arg1 = reportToClient ? 1 : 0; mHandler.sendMessageDelayed(msg, 500); mHandler.sendMessageDelayed(mHandler.obtainMessage( MSG_WINDOW_FOCUS_CHANGED), 500); return; } } Loading @@ -2819,15 +2818,8 @@ public final class ViewRootImpl implements ViewParent, } if (mView != null) { mAttachInfo.mKeyDispatchState.reset(); // We dispatch onWindowFocusChanged to child view only when window is gaining / // losing focus. // If the focus is updated from top display change but window focus on the display // remains unchanged, will not callback onWindowFocusChanged again since it may // be redundant & can affect the state when it callbacks. if (reportToClient) { mView.dispatchWindowFocusChanged(hasWindowFocus); mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus); } if (mAttachInfo.mTooltipHost != null) { mAttachInfo.mTooltipHost.hideTooltip(); } Loading Loading @@ -4428,7 +4420,7 @@ public final class ViewRootImpl implements ViewParent, } break; case MSG_WINDOW_FOCUS_CHANGED: { handleWindowFocusChanged(msg.arg1 != 0 /* reportToClient */); handleWindowFocusChanged(); } break; case MSG_DIE: doDie(); Loading Loading @@ -7372,7 +7364,7 @@ public final class ViewRootImpl implements ViewParent, } if (stage != null) { handleWindowFocusChanged(true /* reportToClient */); handleWindowFocusChanged(); stage.deliver(q); } else { finishInputEvent(q); Loading Loading @@ -7712,11 +7704,6 @@ public final class ViewRootImpl implements ViewParent, } public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { windowFocusChanged(hasFocus, inTouchMode, true /* reportToClient */); } public void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient) { synchronized (this) { mWindowFocusChanged = true; mUpcomingWindowFocus = hasFocus; Loading @@ -7724,7 +7711,6 @@ public final class ViewRootImpl implements ViewParent, } Message msg = Message.obtain(); msg.what = MSG_WINDOW_FOCUS_CHANGED; msg.arg1 = reportToClient ? 1 : 0; mHandler.sendMessage(msg); } Loading Loading @@ -8286,11 +8272,10 @@ public final class ViewRootImpl implements ViewParent, } @Override public void windowFocusChanged(boolean hasFocus, boolean inTouchMode, boolean reportToClient) { public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.windowFocusChanged(hasFocus, inTouchMode, reportToClient); viewAncestor.windowFocusChanged(hasFocus, inTouchMode); } } Loading
core/java/com/android/internal/view/BaseIWindow.java +2 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,9 @@ import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IWindow; import android.view.IWindowSession; import android.view.PointerIcon; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.PointerIcon; import com.android.internal.os.IResultReceiver; Loading Loading @@ -76,7 +76,7 @@ public class BaseIWindow extends IWindow.Stub { } @Override public void windowFocusChanged(boolean hasFocus, boolean touchEnabled, boolean reportToClient) { public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { } @Override Loading
core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2019,6 +2019,10 @@ This is intended to allow packaging drivers or tools for installation on a PC. --> <string translatable="false" name="config_isoImagePath"></string> <!-- Whether the system enables per-display focus. If the system has the input method for each display, this value should be true. --> <bool name="config_perDisplayFocusEnabled">false</bool> <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be autodetected from the Configuration. --> <bool name="config_showNavigationBar">false</bool> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1670,6 +1670,7 @@ <java-symbol type="bool" name="config_lockDayNightMode" /> <java-symbol type="bool" name="config_lockUiMode" /> <java-symbol type="bool" name="config_reverseDefaultRotation" /> <java-symbol type="bool" name="config_perDisplayFocusEnabled" /> <java-symbol type="bool" name="config_showNavigationBar" /> <java-symbol type="bool" name="config_supportAutoRotation" /> <java-symbol type="bool" name="target_honeycomb_needs_options_menu" /> Loading