rk3568开启双屏异显异触摸时键盘焦点及分发事件固定在主屏
OS:Android11
需求描述:当app启用双屏异显双触摸,物理键盘只能固定在主屏有作用。
问题现象:双屏异显异触,带物理键盘输入。打开异显app,物理键盘的按键事件分发到主屏。 当触摸副屏的时候,物理键盘事件分发到副屏。当现再次触摸主屏,物理键盘的键事件分发到主屏。
问题分析:在之前3288 Android7上,没有该问题的。经了解是Android只支持一个屏的焦点事件,即默认是在主屏这边。Android10以后,支持多屏显示焦点事件,比如多个屏单独使用输入法等,这就导致触摸哪个屏,焦点事件就随着哪个屏走。
该需求最终实现是RK原厂提供的path:
涉及修改文件:frameworks/base core/java/android/view/IWindowManager.aidl core/res/res/values/config.xml services/core/java/com/android/server/policy/PhoneWindowManager.java services/core/java/com/android/server/wm/RootWindowContainer.java services/core/java/com/android/server/wm/WindowManagerService.java diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 5a32d283b17d..da90b9ca35e6 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -766,4 +766,10 @@ interface IWindowManager */ void requestScrollCapture(int displayId, IBinder behindClient, int taskId, IScrollCaptureController controller); + + /** + * Switch focus at defautl/external display. + * @hide + */ + void switchFocusedScreen(); } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 2ebd8bb36a03..f8ccec591465 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2025,7 +2025,7 @@ <!-- 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> + <bool name="config_perDisplayFocusEnabled">true</bool> <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be autodetected from the Configuration. --> diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5003fca4bada..a5a1d5bc702b 100755 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2859,6 +2859,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER); mHandler.post(mScreenshotRunnable); } + if(down){ + try{ + mWindowManager.switchFocusedScreen(); + } catch(RemoteException e){ + e.printStackTrace(); + } + } return -1; } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/andr oid/server/wm/RootWindowContainer.java index 197e2188c346..d41cd367b1b5 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -457,6 +457,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> int topFocusedDisplayId = INVALID_DISPLAY; for (int i = mChildren.size() - 1; i >= 0; --i) { final DisplayContent dc = mChildren.get(i); + if(mWindowManager.mFocusedInSecondDisplay&&dc.isDefaultDisplay){ + continue; + } + if(!mWindowManager.mFocusedInSecondDisplay&&!dc.isDefaultDisplay){ + continue; + } changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId); final WindowState newFocus = dc.mCurrentFocus; if (newFocus != null) { @@ -467,7 +473,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (topFocusedDisplayId == INVALID_DISPLAY) { topFocusedDisplayId = dc.getDisplayId(); } - } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) { + } else if ((topFocusedDisplayId == INVALID_DISPLAY) && dc.mFocusedApp != null) { // The top-most display that has a focused app should still be the top focused // display even when the app window is not ready yet (process not attached or // window not added yet). diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/and roid/server/wm/WindowManagerService.java index 1ae8e783e21b..deb2a2cfe9db 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -754,6 +754,8 @@ public class WindowManagerService extends IWindowManager.Stub SettingsObserver mSettingsObserver; final EmbeddedWindowController mEmbeddedWindowController; + boolean mFocusedInSecondDisplay = false; + @VisibleForTesting final class SettingsObserver extends ContentObserver { private final Uri mDisplayInversionEnabledUri = @@ -8337,4 +8339,26 @@ public class WindowManagerService extends IWindowManager.Stub Binder.restoreCallingIdentity(origId); } } + + /** + * Switch focus at default/second screen. + */ + public void switchFocusedScreen(){ + if (mFocusedInSecondDisplay){ + setFocusedInSecondDisplay(false); + } + else{ + setFocusedInSecondDisplay(true); + } + } + + /** + * if flag is equal to true, Focused would be at second screen. + * @param flag isFocusedInSecondScreen + */ + private void setFocusedInSecondDisplay(boolean flag){ + mFocusedInSecondDisplay = flag; + //refresh surface right now. + updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true); + } }
PhoneWindowManager.java中的path主要是可以通过按键事件input keyevent 120灵活切换主副屏的焦点,由于此补丁默认是在主屏的,使用不加也可满足需求。
frameworks/base/core/java/android/view/KeyEvent.java