• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #undef LOG_TAG
2 #define LOG_TAG "SchedulerUnittests"
3 
4 #include <gmock/gmock.h>
5 #include <gtest/gtest.h>
6 
7 #include <log/log.h>
8 
9 #include <mutex>
10 
11 #include "Scheduler/EventControlThread.h"
12 #include "Scheduler/EventThread.h"
13 #include "Scheduler/Scheduler.h"
14 #include "mock/MockEventThread.h"
15 
16 using testing::_;
17 using testing::Return;
18 
19 namespace android {
20 
21 constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = 999;
22 
23 class SchedulerTest : public testing::Test {
24 protected:
25     class MockEventThreadConnection : public android::EventThreadConnection {
26     public:
MockEventThreadConnection(EventThread * eventThread)27         explicit MockEventThreadConnection(EventThread* eventThread)
28               : EventThreadConnection(eventThread, ResyncCallback()) {}
29         ~MockEventThreadConnection() = default;
30 
31         MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
32         MOCK_METHOD1(setVsyncRate, status_t(uint32_t count));
33         MOCK_METHOD0(requestNextVsync, void());
34     };
35 
36     scheduler::RefreshRateConfigs mRefreshRateConfigs;
37 
38     /**
39      * This mock Scheduler class uses implementation of mock::EventThread but keeps everything else
40      * the same.
41      */
42     class MockScheduler : public android::Scheduler {
43     public:
MockScheduler(const scheduler::RefreshRateConfigs & refreshRateConfigs,std::unique_ptr<EventThread> eventThread)44         MockScheduler(const scheduler::RefreshRateConfigs& refreshRateConfigs,
45                       std::unique_ptr<EventThread> eventThread)
46               : Scheduler([](bool) {}, refreshRateConfigs), mEventThread(std::move(eventThread)) {}
47 
makeEventThread(const char *,DispSync *,nsecs_t,impl::EventThread::InterceptVSyncsCallback)48         std::unique_ptr<EventThread> makeEventThread(
49                 const char* /* connectionName */, DispSync* /* dispSync */,
50                 nsecs_t /* phaseOffsetNs */,
51                 impl::EventThread::InterceptVSyncsCallback /* interceptCallback */) override {
52             return std::move(mEventThread);
53         }
54 
55         MockScheduler() = default;
56         ~MockScheduler() override = default;
57 
58         std::unique_ptr<EventThread> mEventThread;
59     };
60 
61     SchedulerTest();
62     ~SchedulerTest() override;
63 
64     sp<Scheduler::ConnectionHandle> mConnectionHandle;
65     mock::EventThread* mEventThread;
66     std::unique_ptr<MockScheduler> mScheduler;
67     sp<MockEventThreadConnection> mEventThreadConnection;
68 };
69 
SchedulerTest()70 SchedulerTest::SchedulerTest() {
71     const ::testing::TestInfo* const test_info =
72             ::testing::UnitTest::GetInstance()->current_test_info();
73     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
74 
75     std::unique_ptr<mock::EventThread> eventThread = std::make_unique<mock::EventThread>();
76     mEventThread = eventThread.get();
77     mScheduler = std::make_unique<MockScheduler>(mRefreshRateConfigs, std::move(eventThread));
78     EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
79 
80     mEventThreadConnection = new MockEventThreadConnection(mEventThread);
81 
82     // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
83     // sure that call gets executed and returns an EventThread::Connection object.
84     EXPECT_CALL(*mEventThread, createEventConnection(_))
85             .WillRepeatedly(Return(mEventThreadConnection));
86 
87     mConnectionHandle = mScheduler->createConnection("appConnection", 16, ResyncCallback(),
88                                                      impl::EventThread::InterceptVSyncsCallback());
89     EXPECT_TRUE(mConnectionHandle != nullptr);
90 }
91 
~SchedulerTest()92 SchedulerTest::~SchedulerTest() {
93     const ::testing::TestInfo* const test_info =
94             ::testing::UnitTest::GetInstance()->current_test_info();
95     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
96 }
97 
98 namespace {
99 /* ------------------------------------------------------------------------
100  * Test cases
101  */
102 
TEST_F(SchedulerTest,testNullPtr)103 TEST_F(SchedulerTest, testNullPtr) {
104     // Passing a null pointer for ConnectionHandle is a valid argument. The code doesn't throw any
105     // exceptions, just gracefully continues.
106     sp<IDisplayEventConnection> returnedValue;
107     ASSERT_NO_FATAL_FAILURE(
108             returnedValue = mScheduler->createDisplayEventConnection(nullptr, ResyncCallback()));
109     EXPECT_TRUE(returnedValue == nullptr);
110     EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr);
111     EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr);
112     ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(nullptr, PHYSICAL_DISPLAY_ID, false));
113     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(nullptr));
114     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(nullptr));
115     std::string testString;
116     ASSERT_NO_FATAL_FAILURE(mScheduler->dump(nullptr, testString));
117     EXPECT_TRUE(testString == "");
118     ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(nullptr, 10));
119 }
120 
TEST_F(SchedulerTest,invalidConnectionHandle)121 TEST_F(SchedulerTest, invalidConnectionHandle) {
122     // Passing an invalid ConnectionHandle is a valid argument. The code doesn't throw any
123     // exceptions, just gracefully continues.
124     sp<Scheduler::ConnectionHandle> connectionHandle = new Scheduler::ConnectionHandle(20);
125 
126     sp<IDisplayEventConnection> returnedValue;
127     ASSERT_NO_FATAL_FAILURE(
128             returnedValue =
129                     mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback()));
130     EXPECT_TRUE(returnedValue == nullptr);
131     EXPECT_TRUE(mScheduler->getEventThread(connectionHandle) == nullptr);
132     EXPECT_TRUE(mScheduler->getEventConnection(connectionHandle) == nullptr);
133 
134     // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
135     EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
136     ASSERT_NO_FATAL_FAILURE(
137             mScheduler->hotplugReceived(connectionHandle, PHYSICAL_DISPLAY_ID, false));
138 
139     EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0);
140     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(connectionHandle));
141 
142     EXPECT_CALL(*mEventThread, onScreenReleased()).Times(0);
143     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(connectionHandle));
144 
145     std::string testString;
146     EXPECT_CALL(*mEventThread, dump(_)).Times(0);
147     ASSERT_NO_FATAL_FAILURE(mScheduler->dump(connectionHandle, testString));
148     EXPECT_TRUE(testString == "");
149 
150     EXPECT_CALL(*mEventThread, setPhaseOffset(_)).Times(0);
151     ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(connectionHandle, 10));
152 }
153 
TEST_F(SchedulerTest,validConnectionHandle)154 TEST_F(SchedulerTest, validConnectionHandle) {
155     sp<IDisplayEventConnection> returnedValue;
156     ASSERT_NO_FATAL_FAILURE(
157             returnedValue =
158                     mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback()));
159     EXPECT_TRUE(returnedValue != nullptr);
160     ASSERT_EQ(returnedValue, mEventThreadConnection);
161 
162     EXPECT_TRUE(mScheduler->getEventThread(mConnectionHandle) != nullptr);
163     EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle) != nullptr);
164 
165     EXPECT_CALL(*mEventThread, onHotplugReceived(PHYSICAL_DISPLAY_ID, false)).Times(1);
166     ASSERT_NO_FATAL_FAILURE(
167             mScheduler->hotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false));
168 
169     EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1);
170     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle));
171 
172     EXPECT_CALL(*mEventThread, onScreenReleased()).Times(1);
173     ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(mConnectionHandle));
174 
175     std::string testString("dump");
176     EXPECT_CALL(*mEventThread, dump(testString)).Times(1);
177     ASSERT_NO_FATAL_FAILURE(mScheduler->dump(mConnectionHandle, testString));
178     EXPECT_TRUE(testString != "");
179 
180     EXPECT_CALL(*mEventThread, setPhaseOffset(10)).Times(1);
181     ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(mConnectionHandle, 10));
182 }
183 } // namespace
184 } // namespace android
185