blob: 7a133801f5145fb2ca92764c5694b8ce20a7bbbf [file] [log] [blame]
Garfield Tanc15eb912019-08-05 16:47:40 -07001/*
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
Prabir Pradhan6c7aa6f2023-12-12 16:54:59 +000017#include <flag_macros.h>
Brandon Pollack015f5d92022-06-02 06:59:33 +000018#include <gmock/gmock.h>
19#include <gtest/gtest.h>
Garfield Tanc15eb912019-08-05 16:47:40 -070020#include <input/PointerController.h>
21#include <input/SpriteController.h>
22
23#include <atomic>
Garfield Tanc15eb912019-08-05 16:47:40 -070024#include <thread>
25
Brandon Pollack015f5d92022-06-02 06:59:33 +000026#include "input/Input.h"
27#include "mocks/MockSprite.h"
28#include "mocks/MockSpriteController.h"
29
Garfield Tanc15eb912019-08-05 16:47:40 -070030namespace android {
31
32enum TestCursorType {
33 CURSOR_TYPE_DEFAULT = 0,
34 CURSOR_TYPE_HOVER,
35 CURSOR_TYPE_TOUCH,
36 CURSOR_TYPE_ANCHOR,
Garfield Tane9c61512019-11-21 16:42:13 -080037 CURSOR_TYPE_ADDITIONAL,
38 CURSOR_TYPE_ADDITIONAL_ANIM,
Seunghwan Choi670b33d2023-01-13 21:12:59 +090039 CURSOR_TYPE_STYLUS,
Garfield Tanc15eb912019-08-05 16:47:40 -070040 CURSOR_TYPE_CUSTOM = -1,
41};
42
43using ::testing::AllOf;
44using ::testing::Field;
Prabir Pradhanca7d7232020-01-31 17:42:34 -080045using ::testing::NiceMock;
Garfield Tanc15eb912019-08-05 16:47:40 -070046using ::testing::Return;
47using ::testing::Test;
48
49std::pair<float, float> getHotSpotCoordinatesForType(int32_t type) {
50 return std::make_pair(type * 10, type * 10 + 5);
51}
52
53class MockPointerControllerPolicyInterface : public PointerControllerPolicyInterface {
54public:
Linnan Li0defadf2024-05-05 19:17:05 +080055 virtual void loadPointerIcon(SpriteIcon* icon, ui::LogicalDisplayId displayId) override;
56 virtual void loadPointerResources(PointerResources* outResources,
57 ui::LogicalDisplayId displayId) override;
Brandon Pollack015f5d92022-06-02 06:59:33 +000058 virtual void loadAdditionalMouseResources(
59 std::map<PointerIconStyle, SpriteIcon>* outResources,
60 std::map<PointerIconStyle, PointerAnimation>* outAnimationResources,
Linnan Li0defadf2024-05-05 19:17:05 +080061 ui::LogicalDisplayId displayId) override;
Brandon Pollack015f5d92022-06-02 06:59:33 +000062 virtual PointerIconStyle getDefaultPointerIconId() override;
Seunghwan Choi670b33d2023-01-13 21:12:59 +090063 virtual PointerIconStyle getDefaultStylusIconId() override;
Brandon Pollack015f5d92022-06-02 06:59:33 +000064 virtual PointerIconStyle getCustomPointerIconId() override;
Garfield Tanc15eb912019-08-05 16:47:40 -070065
Prabir Pradhanca7d7232020-01-31 17:42:34 -080066 bool allResourcesAreLoaded();
67 bool noResourcesAreLoaded();
68
Garfield Tanc15eb912019-08-05 16:47:40 -070069private:
70 void loadPointerIconForType(SpriteIcon* icon, int32_t cursorType);
Prabir Pradhanca7d7232020-01-31 17:42:34 -080071
72 bool pointerIconLoaded{false};
73 bool pointerResourcesLoaded{false};
74 bool additionalMouseResourcesLoaded{false};
Garfield Tanc15eb912019-08-05 16:47:40 -070075};
76
Linnan Li0defadf2024-05-05 19:17:05 +080077void MockPointerControllerPolicyInterface::loadPointerIcon(SpriteIcon* icon, ui::LogicalDisplayId) {
Garfield Tanc15eb912019-08-05 16:47:40 -070078 loadPointerIconForType(icon, CURSOR_TYPE_DEFAULT);
Prabir Pradhanca7d7232020-01-31 17:42:34 -080079 pointerIconLoaded = true;
Garfield Tanc15eb912019-08-05 16:47:40 -070080}
81
82void MockPointerControllerPolicyInterface::loadPointerResources(PointerResources* outResources,
Linnan Li0defadf2024-05-05 19:17:05 +080083 ui::LogicalDisplayId) {
Garfield Tanc15eb912019-08-05 16:47:40 -070084 loadPointerIconForType(&outResources->spotHover, CURSOR_TYPE_HOVER);
85 loadPointerIconForType(&outResources->spotTouch, CURSOR_TYPE_TOUCH);
86 loadPointerIconForType(&outResources->spotAnchor, CURSOR_TYPE_ANCHOR);
Prabir Pradhanca7d7232020-01-31 17:42:34 -080087 pointerResourcesLoaded = true;
Garfield Tanc15eb912019-08-05 16:47:40 -070088}
89
90void MockPointerControllerPolicyInterface::loadAdditionalMouseResources(
Brandon Pollack015f5d92022-06-02 06:59:33 +000091 std::map<PointerIconStyle, SpriteIcon>* outResources,
Linnan Li0defadf2024-05-05 19:17:05 +080092 std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, ui::LogicalDisplayId) {
Garfield Tanc15eb912019-08-05 16:47:40 -070093 SpriteIcon icon;
94 PointerAnimation anim;
95
Garfield Tane9c61512019-11-21 16:42:13 -080096 // CURSOR_TYPE_ADDITIONAL doesn't have animation resource.
97 int32_t cursorType = CURSOR_TYPE_ADDITIONAL;
98 loadPointerIconForType(&icon, cursorType);
Brandon Pollack015f5d92022-06-02 06:59:33 +000099 (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon;
Garfield Tane9c61512019-11-21 16:42:13 -0800100
101 // CURSOR_TYPE_ADDITIONAL_ANIM has animation resource.
102 cursorType = CURSOR_TYPE_ADDITIONAL_ANIM;
103 loadPointerIconForType(&icon, cursorType);
104 anim.animationFrames.push_back(icon);
105 anim.durationPerFrame = 10;
Brandon Pollack015f5d92022-06-02 06:59:33 +0000106 (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon;
107 (*outAnimationResources)[static_cast<PointerIconStyle>(cursorType)] = anim;
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800108
Seunghwan Choi670b33d2023-01-13 21:12:59 +0900109 // CURSOR_TYPE_STYLUS doesn't have animation resource.
110 cursorType = CURSOR_TYPE_STYLUS;
111 loadPointerIconForType(&icon, cursorType);
112 (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon;
113
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800114 additionalMouseResourcesLoaded = true;
Garfield Tanc15eb912019-08-05 16:47:40 -0700115}
116
Brandon Pollack015f5d92022-06-02 06:59:33 +0000117PointerIconStyle MockPointerControllerPolicyInterface::getDefaultPointerIconId() {
118 return static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT);
Garfield Tanc15eb912019-08-05 16:47:40 -0700119}
120
Seunghwan Choi670b33d2023-01-13 21:12:59 +0900121PointerIconStyle MockPointerControllerPolicyInterface::getDefaultStylusIconId() {
122 return static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS);
123}
124
Brandon Pollack015f5d92022-06-02 06:59:33 +0000125PointerIconStyle MockPointerControllerPolicyInterface::getCustomPointerIconId() {
126 return static_cast<PointerIconStyle>(CURSOR_TYPE_CUSTOM);
Garfield Tanc15eb912019-08-05 16:47:40 -0700127}
128
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800129bool MockPointerControllerPolicyInterface::allResourcesAreLoaded() {
130 return pointerIconLoaded && pointerResourcesLoaded && additionalMouseResourcesLoaded;
131}
132
133bool MockPointerControllerPolicyInterface::noResourcesAreLoaded() {
134 return !(pointerIconLoaded || pointerResourcesLoaded || additionalMouseResourcesLoaded);
135}
136
Garfield Tanc15eb912019-08-05 16:47:40 -0700137void MockPointerControllerPolicyInterface::loadPointerIconForType(SpriteIcon* icon, int32_t type) {
Brandon Pollack015f5d92022-06-02 06:59:33 +0000138 icon->style = static_cast<PointerIconStyle>(type);
Garfield Tanc15eb912019-08-05 16:47:40 -0700139 std::pair<float, float> hotSpot = getHotSpotCoordinatesForType(type);
140 icon->hotSpotX = hotSpot.first;
141 icon->hotSpotY = hotSpot.second;
142}
Prabir Pradhan0e3d6652022-03-10 14:39:46 +0000143
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700144class TestPointerController : public PointerController {
145public:
146 TestPointerController(sp<android::gui::WindowInfosListener>& registeredListener,
147 sp<PointerControllerPolicyInterface> policy, const sp<Looper>& looper,
148 SpriteController& spriteController)
149 : PointerController(
150 policy, looper, spriteController,
Linnan Li37c1b992023-11-24 13:05:13 +0800151 [&registeredListener](const sp<android::gui::WindowInfosListener>& listener)
Prabir Pradhanbdf93692024-01-23 18:08:28 +0000152 -> std::vector<gui::DisplayInfo> {
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700153 // Register listener
154 registeredListener = listener;
Linnan Li37c1b992023-11-24 13:05:13 +0800155 return {};
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700156 },
157 [&registeredListener](const sp<android::gui::WindowInfosListener>& listener) {
158 // Unregister listener
159 if (registeredListener == listener) registeredListener = nullptr;
160 }) {}
161 ~TestPointerController() override {}
162};
163
Garfield Tanc15eb912019-08-05 16:47:40 -0700164class PointerControllerTest : public Test {
165protected:
166 PointerControllerTest();
167 ~PointerControllerTest();
168
Linnan Li0defadf2024-05-05 19:17:05 +0800169 void ensureDisplayViewportIsSet(ui::LogicalDisplayId displayId = ui::ADISPLAY_ID_DEFAULT);
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800170
Garfield Tanc15eb912019-08-05 16:47:40 -0700171 sp<MockSprite> mPointerSprite;
172 sp<MockPointerControllerPolicyInterface> mPolicy;
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000173 std::unique_ptr<MockSpriteController> mSpriteController;
Michael Wrighta0bc6b12020-06-26 20:25:34 +0100174 std::shared_ptr<PointerController> mPointerController;
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700175 sp<android::gui::WindowInfosListener> mRegisteredListener;
Garfield Tanc15eb912019-08-05 16:47:40 -0700176
177private:
178 void loopThread();
179
180 std::atomic<bool> mRunning = true;
181 class MyLooper : public Looper {
182 public:
183 MyLooper() : Looper(false) {}
184 ~MyLooper() = default;
185 };
186 sp<MyLooper> mLooper;
187 std::thread mThread;
188};
189
190PointerControllerTest::PointerControllerTest() : mPointerSprite(new NiceMock<MockSprite>),
191 mLooper(new MyLooper), mThread(&PointerControllerTest::loopThread, this) {
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000192 mSpriteController.reset(new NiceMock<MockSpriteController>(mLooper));
Garfield Tanc15eb912019-08-05 16:47:40 -0700193 mPolicy = new MockPointerControllerPolicyInterface();
194
195 EXPECT_CALL(*mSpriteController, createSprite())
196 .WillOnce(Return(mPointerSprite));
197
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700198 mPointerController = std::make_unique<TestPointerController>(mRegisteredListener, mPolicy,
199 mLooper, *mSpriteController);
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800200}
Garfield Tanc15eb912019-08-05 16:47:40 -0700201
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800202PointerControllerTest::~PointerControllerTest() {
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700203 mPointerController.reset();
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800204 mRunning.store(false, std::memory_order_relaxed);
205 mThread.join();
206}
207
Linnan Li0defadf2024-05-05 19:17:05 +0800208void PointerControllerTest::ensureDisplayViewportIsSet(ui::LogicalDisplayId displayId) {
Garfield Tanc15eb912019-08-05 16:47:40 -0700209 DisplayViewport viewport;
Prabir Pradhan0e3d6652022-03-10 14:39:46 +0000210 viewport.displayId = displayId;
Garfield Tanc15eb912019-08-05 16:47:40 -0700211 viewport.logicalRight = 1600;
212 viewport.logicalBottom = 1200;
213 viewport.physicalRight = 800;
214 viewport.physicalBottom = 600;
215 viewport.deviceWidth = 400;
216 viewport.deviceHeight = 300;
217 mPointerController->setDisplayViewport(viewport);
Garfield Tanc15eb912019-08-05 16:47:40 -0700218}
219
220void PointerControllerTest::loopThread() {
221 Looper::setForThread(mLooper);
222
223 while (mRunning.load(std::memory_order_relaxed)) {
224 mLooper->pollOnce(100);
225 }
226}
227
228TEST_F(PointerControllerTest, useDefaultCursorTypeByDefault) {
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800229 ensureDisplayViewportIsSet();
Michael Wright6853fe62020-07-02 00:01:38 +0100230 mPointerController->unfade(PointerController::Transition::IMMEDIATE);
Garfield Tanc15eb912019-08-05 16:47:40 -0700231
232 std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_DEFAULT);
233 EXPECT_CALL(*mPointerSprite, setVisible(true));
234 EXPECT_CALL(*mPointerSprite, setAlpha(1.0f));
Brandon Pollack015f5d92022-06-02 06:59:33 +0000235 EXPECT_CALL(*mPointerSprite,
236 setIcon(AllOf(Field(&SpriteIcon::style,
237 static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT)),
238 Field(&SpriteIcon::hotSpotX, hotspot.first),
239 Field(&SpriteIcon::hotSpotY, hotspot.second))));
Garfield Tanc15eb912019-08-05 16:47:40 -0700240 mPointerController->reloadPointerResources();
241}
242
Seunghwan Choi670b33d2023-01-13 21:12:59 +0900243TEST_F(PointerControllerTest, useStylusTypeForStylusHover) {
244 ensureDisplayViewportIsSet();
245 mPointerController->setPresentation(PointerController::Presentation::STYLUS_HOVER);
246 mPointerController->unfade(PointerController::Transition::IMMEDIATE);
247 std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_STYLUS);
248 EXPECT_CALL(*mPointerSprite, setVisible(true));
249 EXPECT_CALL(*mPointerSprite, setAlpha(1.0f));
250 EXPECT_CALL(*mPointerSprite,
251 setIcon(AllOf(Field(&SpriteIcon::style,
252 static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS)),
253 Field(&SpriteIcon::hotSpotX, hotspot.first),
254 Field(&SpriteIcon::hotSpotY, hotspot.second))));
255 mPointerController->reloadPointerResources();
256}
257
Prabir Pradhan7dff1422024-05-03 23:33:28 +0000258TEST_F(PointerControllerTest, setPresentationBeforeDisplayViewportDoesNotLoadResources) {
Prabir Pradhan6c7aa6f2023-12-12 16:54:59 +0000259 // Setting the presentation mode before a display viewport is set will not load any resources.
260 mPointerController->setPresentation(PointerController::Presentation::POINTER);
261 ASSERT_TRUE(mPolicy->noResourcesAreLoaded());
262
263 // When the display is set, then the resources are loaded.
264 ensureDisplayViewportIsSet();
265 ASSERT_TRUE(mPolicy->allResourcesAreLoaded());
266}
267
Prabir Pradhan7dff1422024-05-03 23:33:28 +0000268TEST_F(PointerControllerTest, updatePointerIconWithChoreographer) {
Prabir Pradhan6c7aa6f2023-12-12 16:54:59 +0000269 // When PointerChoreographer is enabled, the presentation mode is set before the viewport.
270 mPointerController->setPresentation(PointerController::Presentation::POINTER);
271 ensureDisplayViewportIsSet();
272 mPointerController->unfade(PointerController::Transition::IMMEDIATE);
273
274 int32_t type = CURSOR_TYPE_ADDITIONAL;
275 std::pair<float, float> hotspot = getHotSpotCoordinatesForType(type);
276 EXPECT_CALL(*mPointerSprite, setVisible(true));
277 EXPECT_CALL(*mPointerSprite, setAlpha(1.0f));
278 EXPECT_CALL(*mPointerSprite,
279 setIcon(AllOf(Field(&SpriteIcon::style, static_cast<PointerIconStyle>(type)),
280 Field(&SpriteIcon::hotSpotX, hotspot.first),
281 Field(&SpriteIcon::hotSpotY, hotspot.second))));
282 mPointerController->updatePointerIcon(static_cast<PointerIconStyle>(type));
283}
284
Garfield Tanc15eb912019-08-05 16:47:40 -0700285TEST_F(PointerControllerTest, setCustomPointerIcon) {
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800286 ensureDisplayViewportIsSet();
Michael Wright6853fe62020-07-02 00:01:38 +0100287 mPointerController->unfade(PointerController::Transition::IMMEDIATE);
Garfield Tanc15eb912019-08-05 16:47:40 -0700288
289 int32_t style = CURSOR_TYPE_CUSTOM;
290 float hotSpotX = 15;
291 float hotSpotY = 20;
292
293 SpriteIcon icon;
Brandon Pollack015f5d92022-06-02 06:59:33 +0000294 icon.style = static_cast<PointerIconStyle>(style);
Garfield Tanc15eb912019-08-05 16:47:40 -0700295 icon.hotSpotX = hotSpotX;
296 icon.hotSpotY = hotSpotY;
297
298 EXPECT_CALL(*mPointerSprite, setVisible(true));
299 EXPECT_CALL(*mPointerSprite, setAlpha(1.0f));
Brandon Pollack015f5d92022-06-02 06:59:33 +0000300 EXPECT_CALL(*mPointerSprite,
301 setIcon(AllOf(Field(&SpriteIcon::style, static_cast<PointerIconStyle>(style)),
302 Field(&SpriteIcon::hotSpotX, hotSpotX),
303 Field(&SpriteIcon::hotSpotY, hotSpotY))));
Garfield Tanc15eb912019-08-05 16:47:40 -0700304 mPointerController->setCustomPointerIcon(icon);
305}
306
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800307TEST_F(PointerControllerTest, doesNotGetResourcesBeforeSettingViewport) {
Michael Wright6853fe62020-07-02 00:01:38 +0100308 mPointerController->setPresentation(PointerController::Presentation::POINTER);
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800309 mPointerController->setPosition(1.0f, 1.0f);
310 mPointerController->move(1.0f, 1.0f);
Michael Wright6853fe62020-07-02 00:01:38 +0100311 mPointerController->unfade(PointerController::Transition::IMMEDIATE);
312 mPointerController->fade(PointerController::Transition::IMMEDIATE);
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800313
314 EXPECT_TRUE(mPolicy->noResourcesAreLoaded());
315
316 ensureDisplayViewportIsSet();
317}
318
Arpit Singh80fd68a2024-03-26 18:41:06 +0000319TEST_F(PointerControllerTest, updatesSkipScreenshotFlagForTouchSpots) {
320 ensureDisplayViewportIsSet();
321
322 PointerCoords testSpotCoords;
323 testSpotCoords.clear();
324 testSpotCoords.setAxisValue(AMOTION_EVENT_AXIS_X, 1);
325 testSpotCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1);
326 BitSet32 testIdBits;
327 testIdBits.markBit(0);
328 std::array<uint32_t, MAX_POINTER_ID + 1> testIdToIndex;
329
330 sp<MockSprite> testSpotSprite(new NiceMock<MockSprite>);
331
332 // By default sprite is not marked secure
333 EXPECT_CALL(*mSpriteController, createSprite).WillOnce(Return(testSpotSprite));
334 EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(false));
335
336 // Update spots to sync state with sprite
337 mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits,
Linnan Li0defadf2024-05-05 19:17:05 +0800338 ui::ADISPLAY_ID_DEFAULT);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000339 testing::Mock::VerifyAndClearExpectations(testSpotSprite.get());
340
341 // Marking the display to skip screenshot should update sprite as well
Linnan Li0defadf2024-05-05 19:17:05 +0800342 mPointerController->setSkipScreenshot(ui::ADISPLAY_ID_DEFAULT, true);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000343 EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(true));
344
345 // Update spots to sync state with sprite
346 mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits,
Linnan Li0defadf2024-05-05 19:17:05 +0800347 ui::ADISPLAY_ID_DEFAULT);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000348 testing::Mock::VerifyAndClearExpectations(testSpotSprite.get());
349
350 // Reset flag and verify again
Linnan Li0defadf2024-05-05 19:17:05 +0800351 mPointerController->setSkipScreenshot(ui::ADISPLAY_ID_DEFAULT, false);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000352 EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(false));
353 mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits,
Linnan Li0defadf2024-05-05 19:17:05 +0800354 ui::ADISPLAY_ID_DEFAULT);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000355 testing::Mock::VerifyAndClearExpectations(testSpotSprite.get());
356}
357
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800358class PointerControllerWindowInfoListenerTest : public Test {};
359
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800360TEST_F(PointerControllerWindowInfoListenerTest,
361 doesNotCrashIfListenerCalledAfterPointerControllerDestroyed) {
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000362 sp<Looper> looper = new Looper(false);
363 auto spriteController = NiceMock<MockSpriteController>(looper);
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800364 sp<android::gui::WindowInfosListener> registeredListener;
365 sp<android::gui::WindowInfosListener> localListenerCopy;
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700366 sp<MockPointerControllerPolicyInterface> policy = new MockPointerControllerPolicyInterface();
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800367 {
Siarhei Vishniakoua4ea3002023-09-26 18:40:00 -0700368 TestPointerController pointerController(registeredListener, policy, looper,
369 spriteController);
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800370 ASSERT_NE(nullptr, registeredListener) << "WindowInfosListener was not registered";
371 localListenerCopy = registeredListener;
372 }
373 EXPECT_EQ(nullptr, registeredListener) << "WindowInfosListener was not unregistered";
Patrick Williams8e47a672023-05-01 11:30:37 -0500374 localListenerCopy->onWindowInfosChanged({{}, {}, 0, 0});
Prabir Pradhan5693cee2021-12-31 06:51:15 -0800375}
376
Garfield Tanc15eb912019-08-05 16:47:40 -0700377} // namespace android