1 /*
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 
17 #undef LOG_TAG
18 #define LOG_TAG "LibSurfaceFlingerUnittests"
19 #define LOG_NDEBUG 0
20 
21 #include <inttypes.h>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 
26 #include <log/log.h>
27 
28 #include "AsyncCallRecorder.h"
29 #include "Scheduler/DispSyncSource.h"
30 #include "mock/MockDispSync.h"
31 
32 namespace android {
33 namespace {
34 
35 using namespace std::chrono_literals;
36 using testing::Return;
37 
38 class DispSyncSourceTest : public testing::Test, private VSyncSource::Callback {
39 protected:
40     DispSyncSourceTest();
41     ~DispSyncSourceTest() override;
42 
43     void createDispSync();
44     void createDispSyncSource();
45 
46     void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) override;
47 
48     std::unique_ptr<mock::DispSync> mDispSync;
49     std::unique_ptr<DispSyncSource> mDispSyncSource;
50 
51     AsyncCallRecorder<void (*)(nsecs_t)> mVSyncEventCallRecorder;
52 
53     static constexpr std::chrono::nanoseconds mPhaseOffset = 6ms;
54     static constexpr int mIterations = 100;
55 };
56 
DispSyncSourceTest()57 DispSyncSourceTest::DispSyncSourceTest() {
58     const ::testing::TestInfo* const test_info =
59             ::testing::UnitTest::GetInstance()->current_test_info();
60     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
61 }
62 
~DispSyncSourceTest()63 DispSyncSourceTest::~DispSyncSourceTest() {
64     const ::testing::TestInfo* const test_info =
65             ::testing::UnitTest::GetInstance()->current_test_info();
66     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
67 }
68 
onVSyncEvent(nsecs_t when,nsecs_t)69 void DispSyncSourceTest::onVSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) {
70     ALOGD("onVSyncEvent: %" PRId64, when);
71 
72     mVSyncEventCallRecorder.recordCall(when);
73 }
74 
createDispSync()75 void DispSyncSourceTest::createDispSync() {
76     mDispSync = std::make_unique<mock::DispSync>();
77 }
78 
createDispSyncSource()79 void DispSyncSourceTest::createDispSyncSource() {
80     createDispSync();
81     mDispSyncSource = std::make_unique<DispSyncSource>(mDispSync.get(), mPhaseOffset.count(), true,
82                                                        "DispSyncSourceTest");
83     mDispSyncSource->setCallback(this);
84 }
85 
86 /* ------------------------------------------------------------------------
87  * Test cases
88  */
89 
TEST_F(DispSyncSourceTest,createDispSync)90 TEST_F(DispSyncSourceTest, createDispSync) {
91     createDispSync();
92     EXPECT_TRUE(mDispSync);
93 }
94 
TEST_F(DispSyncSourceTest,createDispSyncSource)95 TEST_F(DispSyncSourceTest, createDispSyncSource) {
96     createDispSyncSource();
97     EXPECT_TRUE(mDispSyncSource);
98 }
99 
TEST_F(DispSyncSourceTest,noCallbackAfterInit)100 TEST_F(DispSyncSourceTest, noCallbackAfterInit) {
101     createDispSyncSource();
102     EXPECT_TRUE(mDispSyncSource);
103 
104     // DispSyncSource starts with Vsync disabled
105     mDispSync->triggerCallback();
106     EXPECT_FALSE(mVSyncEventCallRecorder.waitForUnexpectedCall().has_value());
107 }
108 
TEST_F(DispSyncSourceTest,waitForCallbacks)109 TEST_F(DispSyncSourceTest, waitForCallbacks) {
110     createDispSyncSource();
111     EXPECT_TRUE(mDispSyncSource);
112 
113     mDispSyncSource->setVSyncEnabled(true);
114     EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count());
115 
116     for (int i = 0; i < mIterations; i++) {
117         mDispSync->triggerCallback();
118         EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value());
119     }
120 }
121 
TEST_F(DispSyncSourceTest,waitForCallbacksWithPhaseChange)122 TEST_F(DispSyncSourceTest, waitForCallbacksWithPhaseChange) {
123     createDispSyncSource();
124     EXPECT_TRUE(mDispSyncSource);
125 
126     mDispSyncSource->setVSyncEnabled(true);
127     EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count());
128 
129     for (int i = 0; i < mIterations; i++) {
130         mDispSync->triggerCallback();
131         EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value());
132     }
133 
134     EXPECT_CALL(*mDispSync, getPeriod()).Times(1).WillOnce(Return(16666666));
135     mDispSyncSource->setPhaseOffset((mPhaseOffset / 2).count());
136 
137     EXPECT_EQ(mDispSync->getCallbackPhase(), (mPhaseOffset / 2).count());
138 
139     for (int i = 0; i < mIterations; i++) {
140         mDispSync->triggerCallback();
141         EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value());
142     }
143 }
144 
145 } // namespace
146 } // namespace android
147