1 /* 2 * Copyright (C) 2021 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 #pragma once 18 19 #include <stdint.h> 20 #include <optional> 21 #include <unordered_map> 22 23 #include <android/gui/FocusRequest.h> 24 #include <binder/Binder.h> 25 #include <gui/WindowInfo.h> 26 27 namespace android::inputdispatcher { 28 29 // Keeps track of the focused window per display. The class listens to updates from input dispatcher 30 // and provides focus changes. 31 // 32 // Focus Policy 33 // Window focusabilty - A window token can be focused if there is at least one window handle that 34 // is visible with the same token and all window handles with the same token are focusable. 35 // See FocusResolver::isTokenFocusable 36 // 37 // Focus request - Request will be granted if the window is focusable. If it's not 38 // focusable, then the request is persisted and granted when it becomes focusable. The currently 39 // focused window will lose focus and any pending keys will be added to a queue so it can be sent 40 // to the window when it gets focus. 41 // 42 // Condition focus request - Request with a focus token specified. Request will be granted if the 43 // window is focusable and the focus token is the currently focused. Otherwise, the request is 44 // dropped. Conditional focus requests are not persisted. The window will lose focus and go back 45 // to the focus token if it becomes not focusable. 46 // 47 // Window handle updates - Focus is lost when the currently focused window becomes not focusable. 48 // If the previous focus request is focusable, then we will try to grant that window focus. 49 class FocusResolver { 50 public: 51 // Returns the focused window token on the specified display. 52 sp<IBinder> getFocusedWindowToken(int32_t displayId) const; 53 54 struct FocusChanges { 55 sp<IBinder> oldFocus; 56 sp<IBinder> newFocus; 57 int32_t displayId; 58 std::string reason; 59 }; 60 std::optional<FocusResolver::FocusChanges> setInputWindows( 61 int32_t displayId, const std::vector<sp<android::gui::WindowInfoHandle>>& windows); 62 std::optional<FocusResolver::FocusChanges> setFocusedWindow( 63 const android::gui::FocusRequest& request, 64 const std::vector<sp<android::gui::WindowInfoHandle>>& windows); 65 66 // Display has been removed from the system, clean up old references. 67 void displayRemoved(int32_t displayId); 68 69 // exposed for debugging hasFocusedWindowTokens()70 bool hasFocusedWindowTokens() const { return !mFocusedWindowTokenByDisplay.empty(); } 71 std::string dumpFocusedWindows() const; 72 std::string dump() const; 73 74 private: 75 enum class Focusability { 76 OK, 77 NO_WINDOW, 78 NOT_FOCUSABLE, 79 NOT_VISIBLE, 80 81 ftl_last = NOT_VISIBLE 82 }; 83 84 // Checks if the window token can be focused on a display. The token can be focused if there is 85 // at least one window handle that is visible with the same token and all window handles with 86 // the same token are focusable. 87 // 88 // In the case of mirroring, two windows may share the same window token and their visibility 89 // might be different. Example, the mirrored window can cover the window its mirroring. However, 90 // we expect the focusability of the windows to match since its hard to reason why one window 91 // can receive focus events and the other cannot when both are backed by the same input channel. 92 // 93 static Focusability isTokenFocusable( 94 const sp<IBinder>& token, 95 const std::vector<sp<android::gui::WindowInfoHandle>>& windows); 96 97 // Focus tracking for keys, trackball, etc. A window token can be associated with one or 98 // more InputWindowHandles. If a window is mirrored, the window and its mirror will share 99 // the same token. Focus is tracked by the token per display and the events are dispatched 100 // to the channel associated by this token. 101 typedef std::pair<std::string /* name */, sp<IBinder>> NamedToken; 102 std::unordered_map<int32_t /* displayId */, NamedToken> mFocusedWindowTokenByDisplay; 103 104 // This map will store the focus request per display. When the input window handles are updated, 105 // the current request will be checked to see if it can be processed at that time. 106 std::unordered_map<int32_t /* displayId */, android::gui::FocusRequest> mFocusRequestByDisplay; 107 108 // Last reason for not granting a focus request. This is used to add more debug information 109 // in the event logs. 110 std::unordered_map<int32_t /* displayId */, Focusability> mLastFocusResultByDisplay; 111 112 std::optional<FocusResolver::FocusChanges> updateFocusedWindow( 113 int32_t displayId, const std::string& reason, const sp<IBinder>& token, 114 const std::string& tokenName = ""); 115 std::optional<android::gui::FocusRequest> getFocusRequest(int32_t displayId); 116 }; 117 118 } // namespace android::inputdispatcher 119