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