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