1 /*
2  * Copyright (C) 2021 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 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include <FrameMetricsObserver.h>
21 #include <FrameMetricsReporter.h>
22 #include <utils/TimeUtils.h>
23 
24 using namespace android;
25 using namespace android::uirenderer;
26 
27 using ::testing::NotNull;
28 
29 class TestFrameMetricsObserver : public FrameMetricsObserver {
30 public:
TestFrameMetricsObserver(bool waitForPresentTime)31     explicit TestFrameMetricsObserver(bool waitForPresentTime)
32             : FrameMetricsObserver(waitForPresentTime){};
33 
34     MOCK_METHOD(void, notify, (const int64_t* buffer), (override));
35 };
36 
37 // To make sure it is clear that something went wrong if no from frame is set (to make it easier
38 // to catch bugs were we forget to set the fromFrame).
TEST(FrameMetricsReporter,doesNotReportAnyFrameIfNoFromFrameIsSpecified)39 TEST(FrameMetricsReporter, doesNotReportAnyFrameIfNoFromFrameIsSpecified) {
40     auto reporter = std::make_shared<FrameMetricsReporter>();
41 
42     auto observer = sp<TestFrameMetricsObserver>::make(false /*waitForPresentTime*/);
43     EXPECT_CALL(*observer, notify).Times(0);
44 
45     reporter->addObserver(observer.get());
46 
47     const int64_t* stats;
48     bool hasPresentTime = false;
49     uint64_t frameNumber = 1;
50     int32_t surfaceControlId = 0;
51     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
52 
53     frameNumber = 10;
54     surfaceControlId = 0;
55     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
56 
57     frameNumber = 0;
58     surfaceControlId = 2;
59     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
60 
61     frameNumber = 10;
62     surfaceControlId = 2;
63     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
64 }
65 
TEST(FrameMetricsReporter,respectsWaitForPresentTimeUnset)66 TEST(FrameMetricsReporter, respectsWaitForPresentTimeUnset) {
67     const int64_t* stats;
68     bool hasPresentTime = false;
69     uint64_t frameNumber = 3;
70     int32_t surfaceControlId = 0;
71 
72     auto reporter = std::make_shared<FrameMetricsReporter>();
73 
74     auto observer = sp<TestFrameMetricsObserver>::make(hasPresentTime);
75     observer->reportMetricsFrom(frameNumber, surfaceControlId);
76     reporter->addObserver(observer.get());
77 
78     EXPECT_CALL(*observer, notify).Times(1);
79     hasPresentTime = false;
80     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
81 
82     EXPECT_CALL(*observer, notify).Times(0);
83     hasPresentTime = true;
84     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
85 }
86 
TEST(FrameMetricsReporter,respectsWaitForPresentTimeSet)87 TEST(FrameMetricsReporter, respectsWaitForPresentTimeSet) {
88     const int64_t* stats;
89     bool hasPresentTime = true;
90     uint64_t frameNumber = 3;
91     int32_t surfaceControlId = 0;
92 
93     auto reporter = std::make_shared<FrameMetricsReporter>();
94 
95     auto observer = sp<TestFrameMetricsObserver>::make(hasPresentTime);
96     observer->reportMetricsFrom(frameNumber, surfaceControlId);
97     reporter->addObserver(observer.get());
98 
99     EXPECT_CALL(*observer, notify).Times(0);
100     hasPresentTime = false;
101     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
102 
103     EXPECT_CALL(*observer, notify).Times(1);
104     hasPresentTime = true;
105     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
106 }
107 
TEST(FrameMetricsReporter,reportsAllFramesAfterSpecifiedFromFrame)108 TEST(FrameMetricsReporter, reportsAllFramesAfterSpecifiedFromFrame) {
109     const int64_t* stats;
110     bool hasPresentTime = false;
111 
112     std::vector<uint64_t> frameNumbers{0, 1, 10};
113     std::vector<int32_t> surfaceControlIds{0, 1, 10};
114     for (uint64_t frameNumber : frameNumbers) {
115         for (int32_t surfaceControlId : surfaceControlIds) {
116             auto reporter = std::make_shared<FrameMetricsReporter>();
117 
118             auto observer =
119                     sp<TestFrameMetricsObserver>::make(hasPresentTime /*waitForPresentTime*/);
120             observer->reportMetricsFrom(frameNumber, surfaceControlId);
121             reporter->addObserver(observer.get());
122 
123             EXPECT_CALL(*observer, notify).Times(8);
124             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
125             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 1, surfaceControlId);
126             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 10, surfaceControlId);
127             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId + 1);
128             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber - 1,
129                                          surfaceControlId + 1);
130             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 1,
131                                          surfaceControlId + 1);
132             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 10,
133                                          surfaceControlId + 1);
134             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 10,
135                                          surfaceControlId + 10);
136         }
137     }
138 }
139 
TEST(FrameMetricsReporter,doesNotReportsFramesBeforeSpecifiedFromFrame)140 TEST(FrameMetricsReporter, doesNotReportsFramesBeforeSpecifiedFromFrame) {
141     const int64_t* stats;
142     bool hasPresentTime = false;
143 
144     std::vector<uint64_t> frameNumbers{1, 10};
145     std::vector<int32_t> surfaceControlIds{0, 1, 10};
146     for (uint64_t frameNumber : frameNumbers) {
147         for (int32_t surfaceControlId : surfaceControlIds) {
148             auto reporter = std::make_shared<FrameMetricsReporter>();
149 
150             auto observer =
151                     sp<TestFrameMetricsObserver>::make(hasPresentTime /*waitForPresentTime*/);
152             observer->reportMetricsFrom(frameNumber, surfaceControlId);
153             reporter->addObserver(observer.get());
154 
155             EXPECT_CALL(*observer, notify).Times(0);
156             reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber - 1, surfaceControlId);
157             if (surfaceControlId > 0) {
158                 reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber,
159                                              surfaceControlId - 1);
160                 reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber - 1,
161                                              surfaceControlId - 1);
162             }
163         }
164     }
165 }
166 
TEST(FrameMetricsReporter,canRemoveObservers)167 TEST(FrameMetricsReporter, canRemoveObservers) {
168     const int64_t* stats;
169     bool hasPresentTime = false;
170     uint64_t frameNumber = 3;
171     int32_t surfaceControlId = 0;
172 
173     auto reporter = std::make_shared<FrameMetricsReporter>();
174 
175     auto observer = sp<TestFrameMetricsObserver>::make(hasPresentTime /*waitForPresentTime*/);
176 
177     observer->reportMetricsFrom(frameNumber, surfaceControlId);
178     reporter->addObserver(observer.get());
179 
180     EXPECT_CALL(*observer, notify).Times(1);
181     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
182 
183     ASSERT_TRUE(reporter->removeObserver(observer.get()));
184 
185     EXPECT_CALL(*observer, notify).Times(0);
186     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
187 }
188 
TEST(FrameMetricsReporter,canSupportMultipleObservers)189 TEST(FrameMetricsReporter, canSupportMultipleObservers) {
190     const int64_t* stats;
191     bool hasPresentTime = false;
192     uint64_t frameNumber = 3;
193     int32_t surfaceControlId = 0;
194 
195     auto reporter = std::make_shared<FrameMetricsReporter>();
196 
197     auto observer1 = sp<TestFrameMetricsObserver>::make(hasPresentTime /*waitForPresentTime*/);
198     auto observer2 = sp<TestFrameMetricsObserver>::make(hasPresentTime /*waitForPresentTime*/);
199     observer1->reportMetricsFrom(frameNumber, surfaceControlId);
200     observer2->reportMetricsFrom(frameNumber + 10, surfaceControlId + 1);
201     reporter->addObserver(observer1.get());
202     reporter->addObserver(observer2.get());
203 
204     EXPECT_CALL(*observer1, notify).Times(1);
205     EXPECT_CALL(*observer2, notify).Times(0);
206     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber, surfaceControlId);
207 
208     EXPECT_CALL(*observer1, notify).Times(1);
209     EXPECT_CALL(*observer2, notify).Times(1);
210     reporter->reportFrameMetrics(stats, hasPresentTime, frameNumber + 10, surfaceControlId + 1);
211 }
212