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