1 /*
2 * Copyright 2023 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
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "Scheduler/VSyncDispatch.h"
24 #include "mock/MockVSyncDispatch.h"
25
26 using namespace testing;
27
28 namespace android::scheduler {
29
30 class VSyncCallbackRegistrationTest : public Test {
31 protected:
__anone41b1a070102(nsecs_t, nsecs_t, nsecs_t) 32 VSyncDispatch::Callback mCallback = [](nsecs_t, nsecs_t, nsecs_t) {};
33
34 std::shared_ptr<mock::VSyncDispatch> mVsyncDispatch = std::make_shared<mock::VSyncDispatch>();
35 VSyncDispatch::CallbackToken mCallbackToken{7};
36 std::string mCallbackName = "callback";
37
38 std::shared_ptr<mock::VSyncDispatch> mVsyncDispatch2 = std::make_shared<mock::VSyncDispatch>();
39 VSyncDispatch::CallbackToken mCallbackToken2{42};
40 std::string mCallbackName2 = "callback2";
41
assertDispatch(const VSyncCallbackRegistration & registration,std::shared_ptr<VSyncDispatch> dispatch)42 void assertDispatch(const VSyncCallbackRegistration& registration,
43 std::shared_ptr<VSyncDispatch> dispatch) {
44 ASSERT_EQ(registration.mDispatch, dispatch);
45 }
46
assertToken(const VSyncCallbackRegistration & registration,const std::optional<VSyncDispatch::CallbackToken> & token)47 void assertToken(const VSyncCallbackRegistration& registration,
48 const std::optional<VSyncDispatch::CallbackToken>& token) {
49 ASSERT_EQ(registration.mToken, token);
50 }
51 };
52
TEST_F(VSyncCallbackRegistrationTest,unregistersCallbackOnDestruction)53 TEST_F(VSyncCallbackRegistrationTest, unregistersCallbackOnDestruction) {
54 // TODO (b/279581095): With ftl::Function, `_` can be replaced with
55 // `mCallback`, here and in other calls to `registerCallback, since the
56 // ftl version has an operator==, unlike std::function.
57 EXPECT_CALL(*mVsyncDispatch, registerCallback(_, mCallbackName))
58 .WillOnce(Return(mCallbackToken));
59 EXPECT_CALL(*mVsyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
60
61 VSyncCallbackRegistration registration(mVsyncDispatch, mCallback, mCallbackName);
62 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration, mVsyncDispatch));
63 ASSERT_NO_FATAL_FAILURE(assertToken(registration, mCallbackToken));
64 }
65
TEST_F(VSyncCallbackRegistrationTest,unregistersCallbackOnPointerMove)66 TEST_F(VSyncCallbackRegistrationTest, unregistersCallbackOnPointerMove) {
67 {
68 InSequence seq;
69 EXPECT_CALL(*mVsyncDispatch, registerCallback(_, mCallbackName))
70 .WillOnce(Return(mCallbackToken));
71 EXPECT_CALL(*mVsyncDispatch2, registerCallback(_, mCallbackName2))
72 .WillOnce(Return(mCallbackToken2));
73 EXPECT_CALL(*mVsyncDispatch2, unregisterCallback(mCallbackToken2)).Times(1);
74 EXPECT_CALL(*mVsyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
75 }
76
77 auto registration =
78 std::make_unique<VSyncCallbackRegistration>(mVsyncDispatch, mCallback, mCallbackName);
79
80 auto registration2 =
81 std::make_unique<VSyncCallbackRegistration>(mVsyncDispatch2, mCallback, mCallbackName2);
82
83 registration2 = std::move(registration);
84
85 ASSERT_NO_FATAL_FAILURE(assertDispatch(*registration2.get(), mVsyncDispatch));
86 ASSERT_NO_FATAL_FAILURE(assertToken(*registration2.get(), mCallbackToken));
87 }
88
TEST_F(VSyncCallbackRegistrationTest,unregistersCallbackOnMoveOperator)89 TEST_F(VSyncCallbackRegistrationTest, unregistersCallbackOnMoveOperator) {
90 {
91 InSequence seq;
92 EXPECT_CALL(*mVsyncDispatch, registerCallback(_, mCallbackName))
93 .WillOnce(Return(mCallbackToken));
94 EXPECT_CALL(*mVsyncDispatch2, registerCallback(_, mCallbackName2))
95 .WillOnce(Return(mCallbackToken2));
96 EXPECT_CALL(*mVsyncDispatch2, unregisterCallback(mCallbackToken2)).Times(1);
97 EXPECT_CALL(*mVsyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
98 }
99
100 VSyncCallbackRegistration registration(mVsyncDispatch, mCallback, mCallbackName);
101
102 VSyncCallbackRegistration registration2(mVsyncDispatch2, mCallback, mCallbackName2);
103
104 registration2 = std::move(registration);
105
106 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration, nullptr));
107 ASSERT_NO_FATAL_FAILURE(assertToken(registration, std::nullopt));
108
109 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration2, mVsyncDispatch));
110 ASSERT_NO_FATAL_FAILURE(assertToken(registration2, mCallbackToken));
111 }
112
TEST_F(VSyncCallbackRegistrationTest,moveConstructor)113 TEST_F(VSyncCallbackRegistrationTest, moveConstructor) {
114 EXPECT_CALL(*mVsyncDispatch, registerCallback(_, mCallbackName))
115 .WillOnce(Return(mCallbackToken));
116 EXPECT_CALL(*mVsyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
117
118 VSyncCallbackRegistration registration(mVsyncDispatch, mCallback, mCallbackName);
119 VSyncCallbackRegistration registration2(std::move(registration));
120
121 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration, nullptr));
122 ASSERT_NO_FATAL_FAILURE(assertToken(registration, std::nullopt));
123
124 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration2, mVsyncDispatch));
125 ASSERT_NO_FATAL_FAILURE(assertToken(registration2, mCallbackToken));
126 }
127
TEST_F(VSyncCallbackRegistrationTest,moveOperatorEqualsSelf)128 TEST_F(VSyncCallbackRegistrationTest, moveOperatorEqualsSelf) {
129 EXPECT_CALL(*mVsyncDispatch, registerCallback(_, mCallbackName))
130 .WillOnce(Return(mCallbackToken));
131 EXPECT_CALL(*mVsyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
132
133 VSyncCallbackRegistration registration(mVsyncDispatch, mCallback, mCallbackName);
134
135 // Use a reference so the compiler doesn't realize that registration is
136 // being moved to itself.
137 VSyncCallbackRegistration& registrationRef = registration;
138 registration = std::move(registrationRef);
139
140 ASSERT_NO_FATAL_FAILURE(assertDispatch(registration, mVsyncDispatch));
141 ASSERT_NO_FATAL_FAILURE(assertToken(registration, mCallbackToken));
142 }
143
144 } // namespace android::scheduler
145