blob: 2ff9c3c7845fed8c2a3e1c4f4ecb0483f2531845 [file] [log] [blame]
Vishnu Nairc519ff72021-01-21 08:23:08 -08001/*
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#include <gtest/gtest.h>
18
19#include "../FocusResolver.h"
20
Vishnu Nair1dcad982021-02-24 14:38:25 -080021#define ASSERT_FOCUS_CHANGE(_changes, _oldFocus, _newFocus) \
22 { \
23 ASSERT_EQ(_oldFocus, _changes->oldFocus); \
24 ASSERT_EQ(_newFocus, _changes->newFocus); \
25 }
26
Vishnu Nairc519ff72021-01-21 08:23:08 -080027// atest inputflinger_tests:FocusResolverTest
28
chaviw3277faf2021-05-19 16:45:23 -050029using android::gui::FocusRequest;
30using android::gui::WindowInfoHandle;
31
Vishnu Nairc519ff72021-01-21 08:23:08 -080032namespace android::inputdispatcher {
33
Siarhei Vishniakouadeb6fa2023-05-26 09:11:06 -070034namespace {
35
chaviw3277faf2021-05-19 16:45:23 -050036class FakeWindowHandle : public WindowInfoHandle {
Vishnu Nairc519ff72021-01-21 08:23:08 -080037public:
38 FakeWindowHandle(const std::string& name, const sp<IBinder>& token, bool focusable,
39 bool visible) {
40 mInfo.token = token;
41 mInfo.name = name;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -080042 setFocusable(focusable);
43 setVisible(visible);
Vishnu Nairc519ff72021-01-21 08:23:08 -080044 }
45
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -080046 void setFocusable(bool focusable) {
47 mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_FOCUSABLE, !focusable);
48 }
49 void setVisible(bool visible) {
50 mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible);
51 }
Vishnu Nairc519ff72021-01-21 08:23:08 -080052};
53
Siarhei Vishniakouadeb6fa2023-05-26 09:11:06 -070054} // namespace
55
Vishnu Nairc519ff72021-01-21 08:23:08 -080056TEST(FocusResolverTest, SetFocusedWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070057 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
58 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
59 sp<IBinder> unfocusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -050060 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070061 windows.push_back(sp<FakeWindowHandle>::make("Focusable", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000062 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070063 windows.push_back(sp<FakeWindowHandle>::make("Invisible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000064 /*focusable=*/true, /*visible=*/false));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070065 windows.push_back(sp<FakeWindowHandle>::make("unfocusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000066 /*focusable=*/false, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -080067
68 // focusable window can get focused
69 FocusRequest request;
70 request.displayId = 42;
71 request.token = focusableWindowToken;
72 FocusResolver focusResolver;
73 std::optional<FocusResolver::FocusChanges> changes =
74 focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -080075 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ focusableWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -080076 ASSERT_EQ(request.displayId, changes->displayId);
77
78 // invisible window cannot get focused
79 request.token = invisibleWindowToken;
80 changes = focusResolver.setFocusedWindow(request, windows);
81 ASSERT_EQ(focusableWindowToken, changes->oldFocus);
82 ASSERT_EQ(nullptr, changes->newFocus);
Vishnu Nair1dcad982021-02-24 14:38:25 -080083 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -080084
85 // unfocusableWindowToken window cannot get focused
86 request.token = unfocusableWindowToken;
87 changes = focusResolver.setFocusedWindow(request, windows);
88 ASSERT_FALSE(changes);
89}
90
HQ Liu62105c72022-02-14 17:11:52 -080091TEST(FocusResolverTest, RemoveFocusFromFocusedWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070092 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
HQ Liu62105c72022-02-14 17:11:52 -080093 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070094 windows.push_back(sp<FakeWindowHandle>::make("Focusable", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000095 /*focusable=*/true, /*visible=*/true));
HQ Liu62105c72022-02-14 17:11:52 -080096
97 FocusRequest request;
98 request.displayId = 42;
99 request.token = focusableWindowToken;
100 FocusResolver focusResolver;
101 // Focusable window gets focus.
102 request.token = focusableWindowToken;
103 std::optional<FocusResolver::FocusChanges> changes =
104 focusResolver.setFocusedWindow(request, windows);
105 ASSERT_FOCUS_CHANGE(changes, nullptr, focusableWindowToken);
106
107 // Window token of a request is null, focus should be revoked.
108 request.token = NULL;
109 changes = focusResolver.setFocusedWindow(request, windows);
110 ASSERT_EQ(focusableWindowToken, changes->oldFocus);
111 ASSERT_EQ(nullptr, changes->newFocus);
112 ASSERT_FOCUS_CHANGE(changes, focusableWindowToken, nullptr);
113}
114
Vishnu Nairc519ff72021-01-21 08:23:08 -0800115TEST(FocusResolverTest, SetFocusedMirroredWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700116 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
117 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
118 sp<IBinder> unfocusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500119 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700120 windows.push_back(sp<FakeWindowHandle>::make("Mirror1", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000121 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700122 windows.push_back(sp<FakeWindowHandle>::make("Mirror1", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000123 /*focusable=*/true, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800124
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700125 windows.push_back(sp<FakeWindowHandle>::make("Mirror2Visible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000126 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700127 windows.push_back(sp<FakeWindowHandle>::make("Mirror2Invisible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000128 /*focusable=*/true, /*visible=*/false));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800129
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700130 windows.push_back(sp<FakeWindowHandle>::make("Mirror3Focusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000131 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700132 windows.push_back(sp<FakeWindowHandle>::make("Mirror3Unfocusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000133 /*focusable=*/false, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800134
135 // mirrored window can get focused
136 FocusRequest request;
137 request.displayId = 42;
138 request.token = focusableWindowToken;
139 FocusResolver focusResolver;
140 std::optional<FocusResolver::FocusChanges> changes =
141 focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800142 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ focusableWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800143
144 // mirrored window with one visible window can get focused
145 request.token = invisibleWindowToken;
146 changes = focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800147 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ invisibleWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800148
149 // mirrored window with one or more unfocusable window cannot get focused
150 request.token = unfocusableWindowToken;
151 changes = focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800152 ASSERT_FOCUS_CHANGE(changes, /*from*/ invisibleWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800153}
154
155TEST(FocusResolverTest, SetInputWindows) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700156 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500157 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700158 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000159 sp<FakeWindowHandle>::make("Focusable", focusableWindowToken, /*focusable=*/true,
160 /*visible=*/true);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800161 windows.push_back(window);
162
163 // focusable window can get focused
164 FocusRequest request;
165 request.displayId = 42;
166 request.token = focusableWindowToken;
167 FocusResolver focusResolver;
168 std::optional<FocusResolver::FocusChanges> changes =
169 focusResolver.setFocusedWindow(request, windows);
170 ASSERT_EQ(focusableWindowToken, changes->newFocus);
171
Vishnu Nair1dcad982021-02-24 14:38:25 -0800172 // Window visibility changes and the window loses focus
Vishnu Nairc519ff72021-01-21 08:23:08 -0800173 window->setVisible(false);
174 changes = focusResolver.setInputWindows(request.displayId, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800175 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800176}
177
178TEST(FocusResolverTest, FocusRequestsCanBePending) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700179 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500180 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nairc519ff72021-01-21 08:23:08 -0800181
182 sp<FakeWindowHandle> invisibleWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000183 sp<FakeWindowHandle>::make("Invisible", invisibleWindowToken, /*focusable=*/true,
184 /*visible=*/false);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800185 windows.push_back(invisibleWindow);
186
187 // invisible window cannot get focused
188 FocusRequest request;
189 request.displayId = 42;
190 request.token = invisibleWindowToken;
191 FocusResolver focusResolver;
192 std::optional<FocusResolver::FocusChanges> changes =
193 focusResolver.setFocusedWindow(request, windows);
194 ASSERT_FALSE(changes);
195
196 // Window visibility changes and the window gets focused
197 invisibleWindow->setVisible(true);
198 changes = focusResolver.setInputWindows(request.displayId, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800199 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ invisibleWindowToken);
200}
201
202TEST(FocusResolverTest, FocusRequestsArePersistent) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700203 sp<IBinder> windowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500204 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair1dcad982021-02-24 14:38:25 -0800205
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700206 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000207 sp<FakeWindowHandle>::make("Test Window", windowToken, /*focusable=*/false,
208 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800209 windows.push_back(window);
210
211 // non-focusable window cannot get focused
212 FocusRequest request;
213 request.displayId = 42;
214 request.token = windowToken;
215 FocusResolver focusResolver;
216 std::optional<FocusResolver::FocusChanges> changes =
217 focusResolver.setFocusedWindow(request, windows);
218 ASSERT_FALSE(changes);
219
220 // Focusability changes and the window gets focused
221 window->setFocusable(true);
222 changes = focusResolver.setInputWindows(request.displayId, windows);
223 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
224
225 // Visibility changes and the window loses focus
226 window->setVisible(false);
227 changes = focusResolver.setInputWindows(request.displayId, windows);
228 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
229
230 // Visibility changes and the window gets focused
231 window->setVisible(true);
232 changes = focusResolver.setInputWindows(request.displayId, windows);
233 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
234
235 // Window is gone and the window loses focus
236 changes = focusResolver.setInputWindows(request.displayId, {});
237 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
238
239 // Window returns and the window gains focus
240 changes = focusResolver.setInputWindows(request.displayId, windows);
241 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
242}
243
Chavi Weingarten847e8512023-03-29 00:26:09 +0000244TEST(FocusResolverTest, FocusTransferTarget) {
245 sp<IBinder> hostWindowToken = sp<BBinder>::make();
246 std::vector<sp<WindowInfoHandle>> windows;
247
248 sp<FakeWindowHandle> hostWindow =
249 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
250 /*visible=*/true);
251 windows.push_back(hostWindow);
252 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
253 sp<FakeWindowHandle> embeddedWindow =
254 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/false,
255 /*visible=*/true);
256 windows.push_back(embeddedWindow);
257
258 FocusRequest request;
259 request.displayId = 42;
260 request.token = hostWindowToken;
261
262 // Host wants to transfer touch to embedded.
263 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
264
265 FocusResolver focusResolver;
266 std::optional<FocusResolver::FocusChanges> changes =
267 focusResolver.setFocusedWindow(request, windows);
268 // Embedded was not focusable so host gains focus.
269 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ hostWindowToken);
270
271 // Embedded is now focusable so will gain focus
272 embeddedWindow->setFocusable(true);
273 changes = focusResolver.setInputWindows(request.displayId, windows);
274 ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
275
276 // Embedded is not visible so host will get focus
277 embeddedWindow->setVisible(false);
278 changes = focusResolver.setInputWindows(request.displayId, windows);
279 ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
280
281 // Embedded is now visible so will get focus
282 embeddedWindow->setVisible(true);
283 changes = focusResolver.setInputWindows(request.displayId, windows);
284 ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
285
286 // Remove focusTransferTarget from host. Host will gain focus.
287 hostWindow->editInfo()->focusTransferTarget = nullptr;
288 changes = focusResolver.setInputWindows(request.displayId, windows);
289 ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
290
291 // Set invalid token for focusTransferTarget. Host will remain focus
292 hostWindow->editInfo()->focusTransferTarget = sp<BBinder>::make();
293 changes = focusResolver.setInputWindows(request.displayId, windows);
294 ASSERT_FALSE(changes);
295}
296
297TEST(FocusResolverTest, FocusTransferMultipleInChain) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700298 sp<IBinder> hostWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500299 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair1dcad982021-02-24 14:38:25 -0800300
301 sp<FakeWindowHandle> hostWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000302 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
303 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800304 windows.push_back(hostWindow);
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700305 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
Vishnu Nair1dcad982021-02-24 14:38:25 -0800306 sp<FakeWindowHandle> embeddedWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000307 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/true,
308 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800309 windows.push_back(embeddedWindow);
310
Chavi Weingarten847e8512023-03-29 00:26:09 +0000311 sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
312 sp<FakeWindowHandle> embeddedWindow2 =
313 sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
314 /*visible=*/true);
315 windows.push_back(embeddedWindow2);
316
Vishnu Nair1dcad982021-02-24 14:38:25 -0800317 FocusRequest request;
318 request.displayId = 42;
319 request.token = hostWindowToken;
Chavi Weingarten847e8512023-03-29 00:26:09 +0000320
321 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
322 embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
323
Vishnu Nair1dcad982021-02-24 14:38:25 -0800324 FocusResolver focusResolver;
325 std::optional<FocusResolver::FocusChanges> changes =
326 focusResolver.setFocusedWindow(request, windows);
Chavi Weingarten847e8512023-03-29 00:26:09 +0000327 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800328}
Chavi Weingarten847e8512023-03-29 00:26:09 +0000329
330TEST(FocusResolverTest, FocusTransferTargetCycle) {
331 sp<IBinder> hostWindowToken = sp<BBinder>::make();
332 std::vector<sp<WindowInfoHandle>> windows;
333
334 sp<FakeWindowHandle> hostWindow =
335 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
336 /*visible=*/true);
337 windows.push_back(hostWindow);
338 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
339 sp<FakeWindowHandle> embeddedWindow =
340 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/true,
341 /*visible=*/true);
342 windows.push_back(embeddedWindow);
343
344 sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
345 sp<FakeWindowHandle> embeddedWindow2 =
346 sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
347 /*visible=*/true);
348 windows.push_back(embeddedWindow2);
349
350 FocusRequest request;
351 request.displayId = 42;
352 request.token = hostWindowToken;
353
354 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
355 embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
356 embeddedWindow2->editInfo()->focusTransferTarget = hostWindowToken;
357
358 FocusResolver focusResolver;
359 std::optional<FocusResolver::FocusChanges> changes =
360 focusResolver.setFocusedWindow(request, windows);
361 // Cycle will be detected and stop right before trying to transfer token to host again.
362 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
363}
364
Vishnu Nair599f1412021-06-21 10:39:58 -0700365TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700366 sp<IBinder> windowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500367 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair599f1412021-06-21 10:39:58 -0700368
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700369 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000370 sp<FakeWindowHandle>::make("Test Window", windowToken, /*focusable=*/true,
371 /*visible=*/true);
Vishnu Nair599f1412021-06-21 10:39:58 -0700372 windows.push_back(window);
373
374 FocusRequest request;
375 request.displayId = 42;
376 request.token = windowToken;
377 FocusResolver focusResolver;
378 std::optional<FocusResolver::FocusChanges> changes =
379 focusResolver.setFocusedWindow(request, windows);
380 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
381 ASSERT_EQ(request.displayId, changes->displayId);
382
383 // Start with a focused window
384 window->setFocusable(true);
385 changes = focusResolver.setInputWindows(request.displayId, windows);
386 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
387
388 // When a display is removed, all windows are removed from the display
389 // and our focused window loses focus
390 changes = focusResolver.setInputWindows(request.displayId, {});
391 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
392 focusResolver.displayRemoved(request.displayId);
393
394 // When a display is readded, the window does not get focus since the request was cleared.
395 changes = focusResolver.setInputWindows(request.displayId, windows);
396 ASSERT_FALSE(changes);
397}
Vishnu Nairc519ff72021-01-21 08:23:08 -0800398
399} // namespace android::inputdispatcher