1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gui/WindowInfo.h> 18 19 #include "InputTarget.h" 20 21 #include "TouchState.h" 22 23 using android::gui::WindowInfo; 24 using android::gui::WindowInfoHandle; 25 26 namespace android::inputdispatcher { 27 reset()28void TouchState::reset() { 29 *this = TouchState(); 30 } 31 addOrUpdateWindow(const sp<WindowInfoHandle> & windowHandle,int32_t targetFlags,BitSet32 pointerIds)32void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags, 33 BitSet32 pointerIds) { 34 if (targetFlags & InputTarget::FLAG_SPLIT) { 35 split = true; 36 } 37 38 for (size_t i = 0; i < windows.size(); i++) { 39 TouchedWindow& touchedWindow = windows[i]; 40 if (touchedWindow.windowHandle == windowHandle) { 41 touchedWindow.targetFlags |= targetFlags; 42 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { 43 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS; 44 } 45 touchedWindow.pointerIds.value |= pointerIds.value; 46 return; 47 } 48 } 49 50 if (preventNewTargets) return; // Don't add new TouchedWindows. 51 52 TouchedWindow touchedWindow; 53 touchedWindow.windowHandle = windowHandle; 54 touchedWindow.targetFlags = targetFlags; 55 touchedWindow.pointerIds = pointerIds; 56 windows.push_back(touchedWindow); 57 } 58 removeWindowByToken(const sp<IBinder> & token)59void TouchState::removeWindowByToken(const sp<IBinder>& token) { 60 for (size_t i = 0; i < windows.size(); i++) { 61 if (windows[i].windowHandle->getToken() == token) { 62 windows.erase(windows.begin() + i); 63 return; 64 } 65 } 66 } 67 filterNonAsIsTouchWindows()68void TouchState::filterNonAsIsTouchWindows() { 69 for (size_t i = 0; i < windows.size();) { 70 TouchedWindow& window = windows[i]; 71 if (window.targetFlags & 72 (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) { 73 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK; 74 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS; 75 i += 1; 76 } else { 77 windows.erase(windows.begin() + i); 78 } 79 } 80 } 81 filterWindowsExcept(const sp<IBinder> & token)82void TouchState::filterWindowsExcept(const sp<IBinder>& token) { 83 std::erase_if(windows, 84 [&token](const TouchedWindow& w) { return w.windowHandle->getToken() != token; }); 85 } 86 getFirstForegroundWindowHandle() const87sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const { 88 for (size_t i = 0; i < windows.size(); i++) { 89 const TouchedWindow& window = windows[i]; 90 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { 91 return window.windowHandle; 92 } 93 } 94 return nullptr; 95 } 96 isSlippery() const97bool TouchState::isSlippery() const { 98 // Must have exactly one foreground window. 99 bool haveSlipperyForegroundWindow = false; 100 for (const TouchedWindow& window : windows) { 101 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { 102 if (haveSlipperyForegroundWindow || 103 !window.windowHandle->getInfo()->inputConfig.test( 104 WindowInfo::InputConfig::SLIPPERY)) { 105 return false; 106 } 107 haveSlipperyForegroundWindow = true; 108 } 109 } 110 return haveSlipperyForegroundWindow; 111 } 112 getWallpaperWindow() const113sp<WindowInfoHandle> TouchState::getWallpaperWindow() const { 114 for (size_t i = 0; i < windows.size(); i++) { 115 const TouchedWindow& window = windows[i]; 116 if (window.windowHandle->getInfo()->inputConfig.test( 117 gui::WindowInfo::InputConfig::IS_WALLPAPER)) { 118 return window.windowHandle; 119 } 120 } 121 return nullptr; 122 } 123 getWindow(const sp<IBinder> & token) const124sp<WindowInfoHandle> TouchState::getWindow(const sp<IBinder>& token) const { 125 for (const TouchedWindow& touchedWindow : windows) { 126 const auto& windowHandle = touchedWindow.windowHandle; 127 if (windowHandle->getToken() == token) { 128 return windowHandle; 129 } 130 } 131 return nullptr; 132 } 133 134 } // namespace android::inputdispatcher 135