blob: ea4666ed4b440469a26c5c1ef2464fc0d045a8c6 [file] [log] [blame]
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001/*
2 * Copyright 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
Ana Krulec0c8cd522018-08-31 12:27:28 -070017#include <gmock/gmock.h>
18#include <gtest/gtest.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070019#include <log/log.h>
20
Ana Krulece588e312018-09-18 12:32:24 -070021#include <mutex>
22
Ana Krulec0c8cd522018-08-31 12:27:28 -070023#include "Scheduler/EventThread.h"
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040024#include "Scheduler/RefreshRateSelector.h"
Dominik Laskowski98041832019-08-01 18:35:59 -070025#include "TestableScheduler.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070026#include "TestableSurfaceFlinger.h"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080027#include "mock/DisplayHardware/MockDisplayMode.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070028#include "mock/MockEventThread.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070029#include "mock/MockLayer.h"
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070030#include "mock/MockSchedulerCallback.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070031
Dominik Laskowski068173d2021-08-11 17:22:59 -070032namespace android::scheduler {
33
Dominik Laskowskib0054a22022-03-03 09:03:06 -080034using android::mock::createDisplayMode;
35
Ana Krulec0c8cd522018-08-31 12:27:28 -070036using testing::_;
37using testing::Return;
38
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070039namespace {
Ana Krulec0c8cd522018-08-31 12:27:28 -070040
Dominik Laskowski068173d2021-08-11 17:22:59 -070041using MockEventThread = android::mock::EventThread;
42using MockLayer = android::mock::MockLayer;
43
Ana Krulec0c8cd522018-08-31 12:27:28 -070044class SchedulerTest : public testing::Test {
45protected:
Ana Krulec85c39af2018-12-26 17:29:57 -080046 class MockEventThreadConnection : public android::EventThreadConnection {
Ana Krulec0c8cd522018-08-31 12:27:28 -070047 public:
Ana Krulec85c39af2018-12-26 17:29:57 -080048 explicit MockEventThreadConnection(EventThread* eventThread)
Ady Abrahamd11bade2022-08-01 16:18:03 -070049 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0),
50 ResyncCallback()) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070051 ~MockEventThreadConnection() = default;
52
Huihong Luo6fac5232021-11-22 16:05:23 -080053 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
54 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
55 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070056 };
57
Ana Krulec0c8cd522018-08-31 12:27:28 -070058 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070059
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040060 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
61 static inline const DisplayModePtr kDisplay1Mode60 =
62 createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz);
63 static inline const DisplayModePtr kDisplay1Mode120 =
64 createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz);
65 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
66
67 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
68 static inline const DisplayModePtr kDisplay2Mode60 =
69 createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz);
70 static inline const DisplayModePtr kDisplay2Mode120 =
71 createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz);
72 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
73
74 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
75 static inline const DisplayModePtr kDisplay3Mode60 =
76 createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz);
77 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +020078
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040079 std::shared_ptr<RefreshRateSelector> mSelector =
80 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
81 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -070082
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070083 mock::SchedulerCallback mSchedulerCallback;
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040084 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mSchedulerCallback};
Dominik Laskowski98041832019-08-01 18:35:59 -070085
Dominik Laskowski068173d2021-08-11 17:22:59 -070086 ConnectionHandle mConnectionHandle;
87 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -070088 sp<MockEventThreadConnection> mEventThreadConnection;
Ady Abraham564f9de2021-02-03 18:34:33 -080089
90 TestableSurfaceFlinger mFlinger;
Ana Krulec0c8cd522018-08-31 12:27:28 -070091};
92
93SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -070094 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -070095 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -080096 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
97
Ady Abrahamd11bade2022-08-01 16:18:03 -070098 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -070099
100 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
101 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700102 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700103 .WillRepeatedly(Return(mEventThreadConnection));
104
Ady Abrahama0a16272021-03-03 15:23:35 -0800105 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700106 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800107
108 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700109}
110
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700111} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700112
Ana Krulec0c8cd522018-08-31 12:27:28 -0700113TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700114 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700115
Ady Abrahama0a16272021-03-03 15:23:35 -0800116 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700117
Dominik Laskowski98041832019-08-01 18:35:59 -0700118 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800119 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700120
121 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
122 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400123 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700124
125 EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800126 mScheduler->onScreenAcquired(handle);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700127
128 EXPECT_CALL(*mEventThread, onScreenReleased()).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800129 mScheduler->onScreenReleased(handle);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700130
Dominik Laskowski98041832019-08-01 18:35:59 -0700131 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700132 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800133 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700134 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700135
Ady Abraham9c53ee72020-07-22 21:16:18 -0700136 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800137 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700138}
139
140TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700141 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800142 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700143
Dominik Laskowski98041832019-08-01 18:35:59 -0700144 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800145 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700146
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400147 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
148 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700149
150 EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800151 mScheduler->onScreenAcquired(mConnectionHandle);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700152
153 EXPECT_CALL(*mEventThread, onScreenReleased()).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800154 mScheduler->onScreenReleased(mConnectionHandle);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700155
Dominik Laskowski98041832019-08-01 18:35:59 -0700156 std::string output("dump");
157 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800158 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700159 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700160
Ady Abraham9c53ee72020-07-22 21:16:18 -0700161 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800162 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Alec Mouri717bcb62020-02-10 17:07:19 -0800163
164 static constexpr size_t kEventConnections = 5;
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700165 EXPECT_CALL(*mEventThread, getEventThreadConnectionCount()).WillOnce(Return(kEventConnections));
Ady Abrahama0a16272021-03-03 15:23:35 -0800166 EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700167}
Dominik Laskowski98041832019-08-01 18:35:59 -0700168
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200169TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
170 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700171 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700172
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200173 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700174 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Ady Abrahama0a16272021-03-03 15:23:35 -0800175 mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700176 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700177
Rachel Lee6a9731d2022-06-06 17:08:14 -0700178 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
179 mScheduler->setDisplayPowerMode(kPowerModeOn);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700180
181 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700182 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700183
ramindani69b58e82022-09-26 16:48:36 -0700184 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800185 mScheduler->chooseRefreshRateForContent();
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700186}
187
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200188TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700189 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700190 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700191 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200192
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400193 mScheduler->setRefreshRateSelector(
194 std::make_shared<RefreshRateSelector>(kDisplay1Modes, kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200195
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700196 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200197 mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700198 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200199}
200
Dominik Laskowski068173d2021-08-11 17:22:59 -0700201TEST_F(SchedulerTest, dispatchCachedReportedMode) {
202 mScheduler->clearCachedReportedMode();
203
Ady Abraham690f4612021-07-01 23:24:03 -0700204 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700205 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700206}
207
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100208TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700209 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
210 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400211 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700212 .setVsyncPeriod(111111)
213 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700214
215 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100216 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700217 ConnectionHandle invalidHandle = {.id = 123};
Ady Abraham690f4612021-07-01 23:24:03 -0700218 EXPECT_NO_FATAL_FAILURE(mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle, mode));
219 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700220}
221
Ady Abraham899dcdb2021-06-15 16:56:21 -0700222TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700223 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
224 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
225 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800226
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700227 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800228
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700229 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800230}
231
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200232MATCHER(Is120Hz, "") {
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400233 return isApproxEqual(arg.front().modePtr->getFps(), 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200234}
235
236TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400237 const auto selectorPtr =
238 std::make_shared<RefreshRateSelector>(kDisplay1Modes, kDisplay1Mode60->getId());
ramindani69b58e82022-09-26 16:48:36 -0700239
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400240 mScheduler->registerDisplay(kDisplayId1, selectorPtr);
241 mScheduler->setRefreshRateSelector(selectorPtr);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200242
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800243 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
244 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200245
246 mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer);
247
Rachel Lee6a9731d2022-06-06 17:08:14 -0700248 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
249 mScheduler->setDisplayPowerMode(kPowerModeOn);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200250
251 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700252 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200253
ramindani69b58e82022-09-26 16:48:36 -0700254 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200255 mScheduler->chooseRefreshRateForContent();
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800256
257 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700258 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800259 mScheduler->chooseRefreshRateForContent();
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200260}
261
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400262TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400263 mScheduler->registerDisplay(kDisplayId1,
264 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
265 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700266
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400267 std::vector<RefreshRateSelector::LayerRequirement> layers =
268 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700269 mScheduler->setContentRequirements(layers);
270 GlobalSignals globalSignals = {.idle = true};
271 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
272
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400273 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
274
275 auto modeChoices = mScheduler->chooseDisplayModes();
276 ASSERT_EQ(1u, modeChoices.size());
277
278 auto choice = modeChoices.get(kDisplayId1);
279 ASSERT_TRUE(choice);
280 EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode60, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700281
282 globalSignals = {.idle = false};
283 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400284
285 modeChoices = mScheduler->chooseDisplayModes();
286 ASSERT_EQ(1u, modeChoices.size());
287
288 choice = modeChoices.get(kDisplayId1);
289 ASSERT_TRUE(choice);
290 EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode120, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700291
292 globalSignals = {.touch = true};
293 mScheduler->replaceTouchTimer(10);
294 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700295
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400296 modeChoices = mScheduler->chooseDisplayModes();
297 ASSERT_EQ(1u, modeChoices.size());
298
299 choice = modeChoices.get(kDisplayId1);
300 ASSERT_TRUE(choice);
301 EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode120, globalSignals));
302
303 mScheduler->unregisterDisplay(kDisplayId1);
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400304 EXPECT_FALSE(mScheduler->hasRefreshRateSelectors());
ramindani69b58e82022-09-26 16:48:36 -0700305}
306
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400307TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400308 mScheduler->registerDisplay(kDisplayId1,
309 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
310 kDisplay1Mode60->getId()));
311 mScheduler->registerDisplay(kDisplayId2,
312 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
313 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700314
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400315 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
316 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700317
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400318 {
319 const GlobalSignals globalSignals = {.idle = true};
320 expectedChoices =
321 ftl::init::map<const PhysicalDisplayId&,
322 DisplayModeChoice>(kDisplayId1, kDisplay1Mode60,
323 globalSignals)(kDisplayId2, kDisplay2Mode60,
324 globalSignals);
325
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400326 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
327 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400328 mScheduler->setContentRequirements(layers);
329 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
330
331 const auto actualChoices = mScheduler->chooseDisplayModes();
332 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700333 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400334 {
335 const GlobalSignals globalSignals = {.idle = false};
336 expectedChoices =
337 ftl::init::map<const PhysicalDisplayId&,
338 DisplayModeChoice>(kDisplayId1, kDisplay1Mode120,
339 globalSignals)(kDisplayId2, kDisplay2Mode120,
340 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700341
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400342 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700343
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400344 const auto actualChoices = mScheduler->chooseDisplayModes();
345 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700346 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400347 {
348 const GlobalSignals globalSignals = {.touch = true};
349 mScheduler->replaceTouchTimer(10);
350 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700351
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400352 expectedChoices =
353 ftl::init::map<const PhysicalDisplayId&,
354 DisplayModeChoice>(kDisplayId1, kDisplay1Mode120,
355 globalSignals)(kDisplayId2, kDisplay2Mode120,
356 globalSignals);
357
358 const auto actualChoices = mScheduler->chooseDisplayModes();
359 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700360 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400361 {
362 // This display does not support 120 Hz, so we should choose 60 Hz despite the touch signal.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400363 mScheduler
364 ->registerDisplay(kDisplayId3,
365 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
366 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400367
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400368 const GlobalSignals globalSignals = {.touch = true};
369 mScheduler->replaceTouchTimer(10);
370 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700371
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400372 expectedChoices =
373 ftl::init::map<const PhysicalDisplayId&,
374 DisplayModeChoice>(kDisplayId1, kDisplay1Mode60,
375 globalSignals)(kDisplayId2, kDisplay2Mode60,
376 globalSignals)(kDisplayId3,
377 kDisplay3Mode60,
378 globalSignals);
379
380 const auto actualChoices = mScheduler->chooseDisplayModes();
381 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700382 }
ramindani69b58e82022-09-26 16:48:36 -0700383}
384
Dominik Laskowski068173d2021-08-11 17:22:59 -0700385} // namespace android::scheduler