blob: 5440a98db6676318a320c700a26f6891732870dc [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
chaviw3277faf2021-05-19 16:45:23 -050034class FakeWindowHandle : public WindowInfoHandle {
Vishnu Nairc519ff72021-01-21 08:23:08 -080035public:
36 FakeWindowHandle(const std::string& name, const sp<IBinder>& token, bool focusable,
37 bool visible) {
38 mInfo.token = token;
39 mInfo.name = name;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -080040 setFocusable(focusable);
41 setVisible(visible);
Vishnu Nairc519ff72021-01-21 08:23:08 -080042 }
43
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -080044 void setFocusable(bool focusable) {
45 mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_FOCUSABLE, !focusable);
46 }
47 void setVisible(bool visible) {
48 mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible);
49 }
Vishnu Nairc519ff72021-01-21 08:23:08 -080050};
51
52TEST(FocusResolverTest, SetFocusedWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070053 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
54 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
55 sp<IBinder> unfocusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -050056 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070057 windows.push_back(sp<FakeWindowHandle>::make("Focusable", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000058 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070059 windows.push_back(sp<FakeWindowHandle>::make("Invisible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000060 /*focusable=*/true, /*visible=*/false));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070061 windows.push_back(sp<FakeWindowHandle>::make("unfocusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000062 /*focusable=*/false, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -080063
64 // focusable window can get focused
65 FocusRequest request;
66 request.displayId = 42;
67 request.token = focusableWindowToken;
68 FocusResolver focusResolver;
69 std::optional<FocusResolver::FocusChanges> changes =
70 focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -080071 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ focusableWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -080072 ASSERT_EQ(request.displayId, changes->displayId);
73
74 // invisible window cannot get focused
75 request.token = invisibleWindowToken;
76 changes = focusResolver.setFocusedWindow(request, windows);
77 ASSERT_EQ(focusableWindowToken, changes->oldFocus);
78 ASSERT_EQ(nullptr, changes->newFocus);
Vishnu Nair1dcad982021-02-24 14:38:25 -080079 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -080080
81 // unfocusableWindowToken window cannot get focused
82 request.token = unfocusableWindowToken;
83 changes = focusResolver.setFocusedWindow(request, windows);
84 ASSERT_FALSE(changes);
85}
86
HQ Liu62105c72022-02-14 17:11:52 -080087TEST(FocusResolverTest, RemoveFocusFromFocusedWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070088 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
HQ Liu62105c72022-02-14 17:11:52 -080089 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070090 windows.push_back(sp<FakeWindowHandle>::make("Focusable", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +000091 /*focusable=*/true, /*visible=*/true));
HQ Liu62105c72022-02-14 17:11:52 -080092
93 FocusRequest request;
94 request.displayId = 42;
95 request.token = focusableWindowToken;
96 FocusResolver focusResolver;
97 // Focusable window gets focus.
98 request.token = focusableWindowToken;
99 std::optional<FocusResolver::FocusChanges> changes =
100 focusResolver.setFocusedWindow(request, windows);
101 ASSERT_FOCUS_CHANGE(changes, nullptr, focusableWindowToken);
102
103 // Window token of a request is null, focus should be revoked.
104 request.token = NULL;
105 changes = focusResolver.setFocusedWindow(request, windows);
106 ASSERT_EQ(focusableWindowToken, changes->oldFocus);
107 ASSERT_EQ(nullptr, changes->newFocus);
108 ASSERT_FOCUS_CHANGE(changes, focusableWindowToken, nullptr);
109}
110
Vishnu Nairc519ff72021-01-21 08:23:08 -0800111TEST(FocusResolverTest, SetFocusedMirroredWindow) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700112 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
113 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
114 sp<IBinder> unfocusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500115 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700116 windows.push_back(sp<FakeWindowHandle>::make("Mirror1", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000117 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700118 windows.push_back(sp<FakeWindowHandle>::make("Mirror1", focusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000119 /*focusable=*/true, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800120
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700121 windows.push_back(sp<FakeWindowHandle>::make("Mirror2Visible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000122 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700123 windows.push_back(sp<FakeWindowHandle>::make("Mirror2Invisible", invisibleWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000124 /*focusable=*/true, /*visible=*/false));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800125
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700126 windows.push_back(sp<FakeWindowHandle>::make("Mirror3Focusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000127 /*focusable=*/true, /*visible=*/true));
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700128 windows.push_back(sp<FakeWindowHandle>::make("Mirror3Unfocusable", unfocusableWindowToken,
Harry Cutts33476232023-01-30 19:57:29 +0000129 /*focusable=*/false, /*visible=*/true));
Vishnu Nairc519ff72021-01-21 08:23:08 -0800130
131 // mirrored window can get focused
132 FocusRequest request;
133 request.displayId = 42;
134 request.token = focusableWindowToken;
135 FocusResolver focusResolver;
136 std::optional<FocusResolver::FocusChanges> changes =
137 focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800138 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ focusableWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800139
140 // mirrored window with one visible window can get focused
141 request.token = invisibleWindowToken;
142 changes = focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800143 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ invisibleWindowToken);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800144
145 // mirrored window with one or more unfocusable window cannot get focused
146 request.token = unfocusableWindowToken;
147 changes = focusResolver.setFocusedWindow(request, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800148 ASSERT_FOCUS_CHANGE(changes, /*from*/ invisibleWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800149}
150
151TEST(FocusResolverTest, SetInputWindows) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700152 sp<IBinder> focusableWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500153 std::vector<sp<WindowInfoHandle>> windows;
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700154 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000155 sp<FakeWindowHandle>::make("Focusable", focusableWindowToken, /*focusable=*/true,
156 /*visible=*/true);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800157 windows.push_back(window);
158
159 // focusable window can get focused
160 FocusRequest request;
161 request.displayId = 42;
162 request.token = focusableWindowToken;
163 FocusResolver focusResolver;
164 std::optional<FocusResolver::FocusChanges> changes =
165 focusResolver.setFocusedWindow(request, windows);
166 ASSERT_EQ(focusableWindowToken, changes->newFocus);
167
Vishnu Nair1dcad982021-02-24 14:38:25 -0800168 // Window visibility changes and the window loses focus
Vishnu Nairc519ff72021-01-21 08:23:08 -0800169 window->setVisible(false);
170 changes = focusResolver.setInputWindows(request.displayId, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800171 ASSERT_FOCUS_CHANGE(changes, /*from*/ focusableWindowToken, /*to*/ nullptr);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800172}
173
174TEST(FocusResolverTest, FocusRequestsCanBePending) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700175 sp<IBinder> invisibleWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500176 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nairc519ff72021-01-21 08:23:08 -0800177
178 sp<FakeWindowHandle> invisibleWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000179 sp<FakeWindowHandle>::make("Invisible", invisibleWindowToken, /*focusable=*/true,
180 /*visible=*/false);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800181 windows.push_back(invisibleWindow);
182
183 // invisible window cannot get focused
184 FocusRequest request;
185 request.displayId = 42;
186 request.token = invisibleWindowToken;
187 FocusResolver focusResolver;
188 std::optional<FocusResolver::FocusChanges> changes =
189 focusResolver.setFocusedWindow(request, windows);
190 ASSERT_FALSE(changes);
191
192 // Window visibility changes and the window gets focused
193 invisibleWindow->setVisible(true);
194 changes = focusResolver.setInputWindows(request.displayId, windows);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800195 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ invisibleWindowToken);
196}
197
198TEST(FocusResolverTest, FocusRequestsArePersistent) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700199 sp<IBinder> windowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500200 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair1dcad982021-02-24 14:38:25 -0800201
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700202 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000203 sp<FakeWindowHandle>::make("Test Window", windowToken, /*focusable=*/false,
204 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800205 windows.push_back(window);
206
207 // non-focusable window cannot get focused
208 FocusRequest request;
209 request.displayId = 42;
210 request.token = windowToken;
211 FocusResolver focusResolver;
212 std::optional<FocusResolver::FocusChanges> changes =
213 focusResolver.setFocusedWindow(request, windows);
214 ASSERT_FALSE(changes);
215
216 // Focusability changes and the window gets focused
217 window->setFocusable(true);
218 changes = focusResolver.setInputWindows(request.displayId, windows);
219 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
220
221 // Visibility changes and the window loses focus
222 window->setVisible(false);
223 changes = focusResolver.setInputWindows(request.displayId, windows);
224 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
225
226 // Visibility changes and the window gets focused
227 window->setVisible(true);
228 changes = focusResolver.setInputWindows(request.displayId, windows);
229 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
230
231 // Window is gone and the window loses focus
232 changes = focusResolver.setInputWindows(request.displayId, {});
233 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
234
235 // Window returns and the window gains focus
236 changes = focusResolver.setInputWindows(request.displayId, windows);
237 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
238}
239
Chavi Weingarten847e8512023-03-29 00:26:09 +0000240TEST(FocusResolverTest, FocusTransferTarget) {
241 sp<IBinder> hostWindowToken = sp<BBinder>::make();
242 std::vector<sp<WindowInfoHandle>> windows;
243
244 sp<FakeWindowHandle> hostWindow =
245 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
246 /*visible=*/true);
247 windows.push_back(hostWindow);
248 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
249 sp<FakeWindowHandle> embeddedWindow =
250 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/false,
251 /*visible=*/true);
252 windows.push_back(embeddedWindow);
253
254 FocusRequest request;
255 request.displayId = 42;
256 request.token = hostWindowToken;
257
258 // Host wants to transfer touch to embedded.
259 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
260
261 FocusResolver focusResolver;
262 std::optional<FocusResolver::FocusChanges> changes =
263 focusResolver.setFocusedWindow(request, windows);
264 // Embedded was not focusable so host gains focus.
265 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ hostWindowToken);
266
267 // Embedded is now focusable so will gain focus
268 embeddedWindow->setFocusable(true);
269 changes = focusResolver.setInputWindows(request.displayId, windows);
270 ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
271
272 // Embedded is not visible so host will get focus
273 embeddedWindow->setVisible(false);
274 changes = focusResolver.setInputWindows(request.displayId, windows);
275 ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
276
277 // Embedded is now visible so will get focus
278 embeddedWindow->setVisible(true);
279 changes = focusResolver.setInputWindows(request.displayId, windows);
280 ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
281
282 // Remove focusTransferTarget from host. Host will gain focus.
283 hostWindow->editInfo()->focusTransferTarget = nullptr;
284 changes = focusResolver.setInputWindows(request.displayId, windows);
285 ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
286
287 // Set invalid token for focusTransferTarget. Host will remain focus
288 hostWindow->editInfo()->focusTransferTarget = sp<BBinder>::make();
289 changes = focusResolver.setInputWindows(request.displayId, windows);
290 ASSERT_FALSE(changes);
291}
292
293TEST(FocusResolverTest, FocusTransferMultipleInChain) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700294 sp<IBinder> hostWindowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500295 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair1dcad982021-02-24 14:38:25 -0800296
297 sp<FakeWindowHandle> hostWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000298 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
299 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800300 windows.push_back(hostWindow);
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700301 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
Vishnu Nair1dcad982021-02-24 14:38:25 -0800302 sp<FakeWindowHandle> embeddedWindow =
Harry Cutts33476232023-01-30 19:57:29 +0000303 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/true,
304 /*visible=*/true);
Vishnu Nair1dcad982021-02-24 14:38:25 -0800305 windows.push_back(embeddedWindow);
306
Chavi Weingarten847e8512023-03-29 00:26:09 +0000307 sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
308 sp<FakeWindowHandle> embeddedWindow2 =
309 sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
310 /*visible=*/true);
311 windows.push_back(embeddedWindow2);
312
Vishnu Nair1dcad982021-02-24 14:38:25 -0800313 FocusRequest request;
314 request.displayId = 42;
315 request.token = hostWindowToken;
Chavi Weingarten847e8512023-03-29 00:26:09 +0000316
317 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
318 embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
319
Vishnu Nair1dcad982021-02-24 14:38:25 -0800320 FocusResolver focusResolver;
321 std::optional<FocusResolver::FocusChanges> changes =
322 focusResolver.setFocusedWindow(request, windows);
Chavi Weingarten847e8512023-03-29 00:26:09 +0000323 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
Vishnu Nairc519ff72021-01-21 08:23:08 -0800324}
Chavi Weingarten847e8512023-03-29 00:26:09 +0000325
326TEST(FocusResolverTest, FocusTransferTargetCycle) {
327 sp<IBinder> hostWindowToken = sp<BBinder>::make();
328 std::vector<sp<WindowInfoHandle>> windows;
329
330 sp<FakeWindowHandle> hostWindow =
331 sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
332 /*visible=*/true);
333 windows.push_back(hostWindow);
334 sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
335 sp<FakeWindowHandle> embeddedWindow =
336 sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/true,
337 /*visible=*/true);
338 windows.push_back(embeddedWindow);
339
340 sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
341 sp<FakeWindowHandle> embeddedWindow2 =
342 sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
343 /*visible=*/true);
344 windows.push_back(embeddedWindow2);
345
346 FocusRequest request;
347 request.displayId = 42;
348 request.token = hostWindowToken;
349
350 hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
351 embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
352 embeddedWindow2->editInfo()->focusTransferTarget = hostWindowToken;
353
354 FocusResolver focusResolver;
355 std::optional<FocusResolver::FocusChanges> changes =
356 focusResolver.setFocusedWindow(request, windows);
357 // Cycle will be detected and stop right before trying to transfer token to host again.
358 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
359}
360
Vishnu Nair599f1412021-06-21 10:39:58 -0700361TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700362 sp<IBinder> windowToken = sp<BBinder>::make();
chaviw3277faf2021-05-19 16:45:23 -0500363 std::vector<sp<WindowInfoHandle>> windows;
Vishnu Nair599f1412021-06-21 10:39:58 -0700364
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700365 sp<FakeWindowHandle> window =
Harry Cutts33476232023-01-30 19:57:29 +0000366 sp<FakeWindowHandle>::make("Test Window", windowToken, /*focusable=*/true,
367 /*visible=*/true);
Vishnu Nair599f1412021-06-21 10:39:58 -0700368 windows.push_back(window);
369
370 FocusRequest request;
371 request.displayId = 42;
372 request.token = windowToken;
373 FocusResolver focusResolver;
374 std::optional<FocusResolver::FocusChanges> changes =
375 focusResolver.setFocusedWindow(request, windows);
376 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
377 ASSERT_EQ(request.displayId, changes->displayId);
378
379 // Start with a focused window
380 window->setFocusable(true);
381 changes = focusResolver.setInputWindows(request.displayId, windows);
382 ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
383
384 // When a display is removed, all windows are removed from the display
385 // and our focused window loses focus
386 changes = focusResolver.setInputWindows(request.displayId, {});
387 ASSERT_FOCUS_CHANGE(changes, /*from*/ windowToken, /*to*/ nullptr);
388 focusResolver.displayRemoved(request.displayId);
389
390 // When a display is readded, the window does not get focus since the request was cleared.
391 changes = focusResolver.setInputWindows(request.displayId, windows);
392 ASSERT_FALSE(changes);
393}
Vishnu Nairc519ff72021-01-21 08:23:08 -0800394
395} // namespace android::inputdispatcher