Loading include/ui/InputDispatcher.h +11 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,14 @@ public: */ virtual void setInputDispatchMode(bool enabled, bool frozen) = 0; /* Transfers touch focus from the window associated with one channel to the * window associated with the other channel. * * Returns true on success. False if the window did not actually have touch focus. */ virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) = 0; /* Registers or unregister input channels that may be used as targets for input events. * If monitor is true, the channel will receive a copy of all input events. * Loading Loading @@ -409,6 +417,9 @@ public: virtual void setFocusedApplication(const InputApplication* inputApplication); virtual void setInputDispatchMode(bool enabled, bool frozen); virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel); virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor); virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel); Loading libs/ui/InputDispatcher.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -2464,6 +2464,70 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { } } bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) { #if DEBUG_FOCUS LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s", fromChannel->getName().string(), toChannel->getName().string()); #endif { // acquire lock AutoMutex _l(mLock); const InputWindow* fromWindow = getWindowLocked(fromChannel); const InputWindow* toWindow = getWindowLocked(toChannel); if (! fromWindow || ! toWindow) { #if DEBUG_FOCUS LOGD("Cannot transfer focus because from or to window not found."); #endif return false; } if (fromWindow == toWindow) { #if DEBUG_FOCUS LOGD("Trivial transfer to same window."); #endif return true; } bool found = false; for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; if (touchedWindow.window == fromWindow) { int32_t oldTargetFlags = touchedWindow.targetFlags; BitSet32 pointerIds = touchedWindow.pointerIds; mTouchState.windows.removeAt(i); int32_t newTargetFlags = 0; if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) { newTargetFlags |= InputTarget::FLAG_FOREGROUND; if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) { newTargetFlags |= InputTarget::FLAG_SPLIT; } } mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds); found = true; break; } } if (! found) { #if DEBUG_FOCUS LOGD("Focus transfer failed because from window did not have focus."); #endif return false; } #if DEBUG_FOCUS logDispatchStateLocked(); #endif } // release lock // Wake up poll loop since it may need to make new input dispatching choices. mLooper->wake(); return true; } void InputDispatcher::logDispatchStateLocked() { String8 dump; dumpDispatchStateLocked(dump); Loading services/java/com/android/server/InputManager.java +25 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ public class InputManager { private static native InputDevice nativeGetInputDevice(int deviceId); private static native void nativeGetInputConfiguration(Configuration configuration); private static native int[] nativeGetInputDeviceIds(); private static native boolean nativeTransferTouchFocus(InputChannel fromChannel, InputChannel toChannel); private static native String nativeDump(); // Input event injection constants defined in InputDispatcher.h. Loading Loading @@ -320,6 +322,29 @@ public class InputManager { nativeSetInputDispatchMode(enabled, frozen); } /** * Atomically transfers touch focus from one window to another as identified by * their input channels. It is possible for multiple windows to have * touch focus if they support split touch dispatch * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this * method only transfers touch focus of the specified window without affecting * other windows that may also have touch focus at the same time. * @param fromChannel The channel of a window that currently has touch focus. * @param toChannel The channel of the window that should receive touch focus in * place of the first. * @return True if the transfer was successful. False if the window with the * specified channel did not actually have touch focus at the time of the request. */ public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) { if (fromChannel == null) { throw new IllegalArgumentException("fromChannel must not be null."); } if (toChannel == null) { throw new IllegalArgumentException("toChannel must not be null."); } return nativeTransferTouchFocus(fromChannel, toChannel); } public void dump(PrintWriter pw) { String dumpStr = nativeDump(); if (dumpStr != null) { Loading services/jni/com_android_server_InputManager.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -1286,6 +1286,25 @@ static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env, env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation); } static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env, jclass clazz, jobject fromChannelObj, jobject toChannelObj) { if (checkInputManagerUnitialized(env)) { return false; } sp<InputChannel> fromChannel = android_view_InputChannel_getInputChannel(env, fromChannelObj); sp<InputChannel> toChannel = android_view_InputChannel_getInputChannel(env, toChannelObj); if (fromChannel == NULL || toChannel == NULL) { return false; } return gNativeInputManager->getInputManager()->getDispatcher()-> transferTouchFocus(fromChannel, toChannel); } static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) { if (checkInputManagerUnitialized(env)) { return NULL; Loading Loading @@ -1334,6 +1353,8 @@ static JNINativeMethod gInputManagerMethods[] = { (void*) android_server_InputManager_nativeGetInputDeviceIds }, { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V", (void*) android_server_InputManager_nativeGetInputConfiguration }, { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z", (void*) android_server_InputManager_nativeTransferTouchFocus }, { "nativeDump", "()Ljava/lang/String;", (void*) android_server_InputManager_nativeDump }, }; Loading Loading
include/ui/InputDispatcher.h +11 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,14 @@ public: */ virtual void setInputDispatchMode(bool enabled, bool frozen) = 0; /* Transfers touch focus from the window associated with one channel to the * window associated with the other channel. * * Returns true on success. False if the window did not actually have touch focus. */ virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) = 0; /* Registers or unregister input channels that may be used as targets for input events. * If monitor is true, the channel will receive a copy of all input events. * Loading Loading @@ -409,6 +417,9 @@ public: virtual void setFocusedApplication(const InputApplication* inputApplication); virtual void setInputDispatchMode(bool enabled, bool frozen); virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel); virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor); virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel); Loading
libs/ui/InputDispatcher.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -2464,6 +2464,70 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { } } bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) { #if DEBUG_FOCUS LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s", fromChannel->getName().string(), toChannel->getName().string()); #endif { // acquire lock AutoMutex _l(mLock); const InputWindow* fromWindow = getWindowLocked(fromChannel); const InputWindow* toWindow = getWindowLocked(toChannel); if (! fromWindow || ! toWindow) { #if DEBUG_FOCUS LOGD("Cannot transfer focus because from or to window not found."); #endif return false; } if (fromWindow == toWindow) { #if DEBUG_FOCUS LOGD("Trivial transfer to same window."); #endif return true; } bool found = false; for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; if (touchedWindow.window == fromWindow) { int32_t oldTargetFlags = touchedWindow.targetFlags; BitSet32 pointerIds = touchedWindow.pointerIds; mTouchState.windows.removeAt(i); int32_t newTargetFlags = 0; if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) { newTargetFlags |= InputTarget::FLAG_FOREGROUND; if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) { newTargetFlags |= InputTarget::FLAG_SPLIT; } } mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds); found = true; break; } } if (! found) { #if DEBUG_FOCUS LOGD("Focus transfer failed because from window did not have focus."); #endif return false; } #if DEBUG_FOCUS logDispatchStateLocked(); #endif } // release lock // Wake up poll loop since it may need to make new input dispatching choices. mLooper->wake(); return true; } void InputDispatcher::logDispatchStateLocked() { String8 dump; dumpDispatchStateLocked(dump); Loading
services/java/com/android/server/InputManager.java +25 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ public class InputManager { private static native InputDevice nativeGetInputDevice(int deviceId); private static native void nativeGetInputConfiguration(Configuration configuration); private static native int[] nativeGetInputDeviceIds(); private static native boolean nativeTransferTouchFocus(InputChannel fromChannel, InputChannel toChannel); private static native String nativeDump(); // Input event injection constants defined in InputDispatcher.h. Loading Loading @@ -320,6 +322,29 @@ public class InputManager { nativeSetInputDispatchMode(enabled, frozen); } /** * Atomically transfers touch focus from one window to another as identified by * their input channels. It is possible for multiple windows to have * touch focus if they support split touch dispatch * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this * method only transfers touch focus of the specified window without affecting * other windows that may also have touch focus at the same time. * @param fromChannel The channel of a window that currently has touch focus. * @param toChannel The channel of the window that should receive touch focus in * place of the first. * @return True if the transfer was successful. False if the window with the * specified channel did not actually have touch focus at the time of the request. */ public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) { if (fromChannel == null) { throw new IllegalArgumentException("fromChannel must not be null."); } if (toChannel == null) { throw new IllegalArgumentException("toChannel must not be null."); } return nativeTransferTouchFocus(fromChannel, toChannel); } public void dump(PrintWriter pw) { String dumpStr = nativeDump(); if (dumpStr != null) { Loading
services/jni/com_android_server_InputManager.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -1286,6 +1286,25 @@ static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env, env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation); } static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env, jclass clazz, jobject fromChannelObj, jobject toChannelObj) { if (checkInputManagerUnitialized(env)) { return false; } sp<InputChannel> fromChannel = android_view_InputChannel_getInputChannel(env, fromChannelObj); sp<InputChannel> toChannel = android_view_InputChannel_getInputChannel(env, toChannelObj); if (fromChannel == NULL || toChannel == NULL) { return false; } return gNativeInputManager->getInputManager()->getDispatcher()-> transferTouchFocus(fromChannel, toChannel); } static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) { if (checkInputManagerUnitialized(env)) { return NULL; Loading Loading @@ -1334,6 +1353,8 @@ static JNINativeMethod gInputManagerMethods[] = { (void*) android_server_InputManager_nativeGetInputDeviceIds }, { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V", (void*) android_server_InputManager_nativeGetInputConfiguration }, { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z", (void*) android_server_InputManager_nativeTransferTouchFocus }, { "nativeDump", "()Ljava/lang/String;", (void*) android_server_InputManager_nativeDump }, }; Loading