blob: a72ab428664a42c4ee5d306301b08517727686d9 [file] [log] [blame]
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001/*
2 * Copyright 2018 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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010020#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080021
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080022#undef LOG_TAG
23#define LOG_TAG "LibSurfaceFlingerUnittests"
24
Mikael Pessa2e1608f2019-07-19 11:25:35 -070025#include <TimeStats/TimeStats.h>
Alec Mouri37384342020-01-02 17:23:37 -080026#include <android/util/ProtoOutputStream.h>
Alec Mourifb571ea2019-01-24 18:42:10 -080027#include <gmock/gmock.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080028#include <gtest/gtest.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080029#include <log/log.h>
30#include <utils/String16.h>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080031#include <utils/Vector.h>
32
Alec Mouri9519bf12019-11-15 16:54:44 -080033#include <chrono>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080034#include <random>
Alec Mourifb571ea2019-01-24 18:42:10 -080035#include <unordered_set>
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080036
Lloyd Pique067fe1e2018-12-06 19:44:13 -080037#include "libsurfaceflinger_unittest_main.h"
38
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080039using namespace android::surfaceflinger;
40using namespace google::protobuf;
Vishnu Nairabf97fd2020-02-03 13:51:16 -080041using namespace std::chrono_literals;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080042
43namespace android {
44namespace {
45
Alec Mouri8e2f31b2020-01-16 22:04:35 +000046using testing::_;
Alec Mouri37384342020-01-02 17:23:37 -080047using testing::AnyNumber;
Alec Mourifb571ea2019-01-24 18:42:10 -080048using testing::Contains;
Vishnu Nair9b079a22020-01-21 14:36:08 -080049using testing::HasSubstr;
Alec Mouri8e2f31b2020-01-16 22:04:35 +000050using testing::InSequence;
Alec Mouri56e63852021-03-09 18:17:25 -080051using testing::Not;
Alec Mourifb571ea2019-01-24 18:42:10 -080052using testing::SizeIs;
Alec Mouri37384342020-01-02 17:23:37 -080053using testing::StrEq;
Alec Mourifb571ea2019-01-24 18:42:10 -080054using testing::UnorderedElementsAre;
55
Peiyong Lin65248e02020-04-18 21:15:07 -070056using PowerMode = hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
57
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080058// clang-format off
Alec Mouri7d436ec2021-01-27 20:40:50 -080059#define FMT_PROTO true
60#define FMT_STRING false
61#define LAYER_ID_0 0
62#define LAYER_ID_1 1
63#define UID_0 123
64#define REFRESH_RATE_0 61
65#define RENDER_RATE_0 31
66#define REFRESH_RATE_BUCKET_0 60
67#define RENDER_RATE_BUCKET_0 30
68#define LAYER_ID_INVALID -1
69#define NUM_LAYERS 1
70#define NUM_LAYERS_INVALID "INVALID"
71
72const constexpr Fps kRefreshRate0 = Fps(static_cast<float>(REFRESH_RATE_0));
73const constexpr Fps kRenderRate0 = Fps(static_cast<float>(RENDER_RATE_0));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -080074
75enum InputCommand : int32_t {
76 ENABLE = 0,
77 DISABLE = 1,
78 CLEAR = 2,
79 DUMP_ALL = 3,
80 DUMP_MAXLAYERS_1 = 4,
81 DUMP_MAXLAYERS_INVALID = 5,
82 INPUT_COMMAND_BEGIN = ENABLE,
83 INPUT_COMMAND_END = DUMP_MAXLAYERS_INVALID,
84 INPUT_COMMAND_RANGE = INPUT_COMMAND_END - INPUT_COMMAND_BEGIN + 1,
85};
86
87enum TimeStamp : int32_t {
88 POST = 0,
89 ACQUIRE = 1,
90 ACQUIRE_FENCE = 2,
91 LATCH = 3,
92 DESIRED = 4,
93 PRESENT = 5,
94 PRESENT_FENCE = 6,
95 TIME_STAMP_BEGIN = POST,
96 TIME_STAMP_END = PRESENT,
97 TIME_STAMP_RANGE = TIME_STAMP_END - TIME_STAMP_BEGIN + 1,
98};
99
100static const TimeStamp NORMAL_SEQUENCE[] = {
101 TimeStamp::POST,
102 TimeStamp::ACQUIRE,
103 TimeStamp::LATCH,
104 TimeStamp::DESIRED,
105 TimeStamp::PRESENT,
106};
107
108static const TimeStamp NORMAL_SEQUENCE_2[] = {
109 TimeStamp::POST,
110 TimeStamp::ACQUIRE_FENCE,
111 TimeStamp::LATCH,
112 TimeStamp::DESIRED,
113 TimeStamp::PRESENT_FENCE,
114};
115
116static const TimeStamp UNORDERED_SEQUENCE[] = {
117 TimeStamp::ACQUIRE,
118 TimeStamp::LATCH,
119 TimeStamp::POST,
120 TimeStamp::DESIRED,
121 TimeStamp::PRESENT,
122};
123
124static const TimeStamp INCOMPLETE_SEQUENCE[] = {
125 TimeStamp::POST,
126};
127// clang-format on
128
129class TimeStatsTest : public testing::Test {
130public:
131 TimeStatsTest() {
132 const ::testing::TestInfo* const test_info =
133 ::testing::UnitTest::GetInstance()->current_test_info();
134 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
135 }
136
137 ~TimeStatsTest() {
138 const ::testing::TestInfo* const test_info =
139 ::testing::UnitTest::GetInstance()->current_test_info();
140 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
141 }
142
143 std::string inputCommand(InputCommand cmd, bool useProto);
144
145 void setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts);
146
147 int32_t genRandomInt32(int32_t begin, int32_t end);
148
149 template <size_t N>
150 void insertTimeRecord(const TimeStamp (&sequence)[N], int32_t id, uint64_t frameNumber,
151 nsecs_t ts) {
152 for (size_t i = 0; i < N; i++, ts += 1000000) {
153 setTimeStamp(sequence[i], id, frameNumber, ts);
154 }
155 }
156
157 std::mt19937 mRandomEngine = std::mt19937(std::random_device()());
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000158
159 class FakeStatsEventDelegate : public impl::TimeStats::StatsEventDelegate {
160 public:
161 FakeStatsEventDelegate() = default;
162 ~FakeStatsEventDelegate() override = default;
163
Tej Singh2a457b62020-01-31 16:16:10 -0800164 struct AStatsEvent* addStatsEventToPullData(AStatsEventList*) override {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000165 return mEvent;
166 }
Tej Singh38a4b212020-03-13 19:04:51 -0700167 void setStatsPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata*,
168 AStatsManager_PullAtomCallback callback,
169 void* cookie) override {
Alec Mouri37384342020-01-02 17:23:37 -0800170 mAtomTags.push_back(atom_tag);
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000171 mCallback = callback;
172 mCookie = cookie;
173 }
174
Tej Singh2a457b62020-01-31 16:16:10 -0800175 AStatsManager_PullAtomCallbackReturn makePullAtomCallback(int32_t atom_tag, void* cookie) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000176 return (*mCallback)(atom_tag, nullptr, cookie);
177 }
178
Tej Singh38a4b212020-03-13 19:04:51 -0700179 MOCK_METHOD1(clearStatsPullAtomCallback, void(int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800180 MOCK_METHOD2(statsEventSetAtomId, void(AStatsEvent*, uint32_t));
Alec Mouri717bcb62020-02-10 17:07:19 -0800181 MOCK_METHOD2(statsEventWriteInt32, void(AStatsEvent*, int32_t));
Tej Singh2a457b62020-01-31 16:16:10 -0800182 MOCK_METHOD2(statsEventWriteInt64, void(AStatsEvent*, int64_t));
183 MOCK_METHOD2(statsEventWriteString8, void(AStatsEvent*, const char*));
184 MOCK_METHOD3(statsEventWriteByteArray, void(AStatsEvent*, const uint8_t*, size_t));
185 MOCK_METHOD1(statsEventBuild, void(AStatsEvent*));
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000186
Tej Singh2a457b62020-01-31 16:16:10 -0800187 AStatsEvent* mEvent = AStatsEvent_obtain();
Alec Mouri37384342020-01-02 17:23:37 -0800188 std::vector<int32_t> mAtomTags;
Tej Singh2a457b62020-01-31 16:16:10 -0800189 AStatsManager_PullAtomCallback mCallback = nullptr;
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000190 void* mCookie = nullptr;
191 };
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000192 FakeStatsEventDelegate* mDelegate = new FakeStatsEventDelegate;
193 std::unique_ptr<TimeStats> mTimeStats =
Alec Mouri37384342020-01-02 17:23:37 -0800194 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
195 std::nullopt, std::nullopt);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800196};
197
198std::string TimeStatsTest::inputCommand(InputCommand cmd, bool useProto) {
Yiwei Zhang5434a782018-12-05 18:06:32 -0800199 std::string result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800200 Vector<String16> args;
201
202 switch (cmd) {
203 case InputCommand::ENABLE:
204 args.push_back(String16("-enable"));
205 break;
206 case InputCommand::DISABLE:
207 args.push_back(String16("-disable"));
208 break;
209 case InputCommand::CLEAR:
210 args.push_back(String16("-clear"));
211 break;
212 case InputCommand::DUMP_ALL:
213 args.push_back(String16("-dump"));
214 break;
215 case InputCommand::DUMP_MAXLAYERS_1:
216 args.push_back(String16("-dump"));
217 args.push_back(String16("-maxlayers"));
218 args.push_back(String16(std::to_string(NUM_LAYERS).c_str()));
219 break;
220 case InputCommand::DUMP_MAXLAYERS_INVALID:
221 args.push_back(String16("-dump"));
222 args.push_back(String16("-maxlayers"));
223 args.push_back(String16(NUM_LAYERS_INVALID));
224 break;
225 default:
226 ALOGD("Invalid control command");
227 }
228
Dominik Laskowskic2867142019-01-21 11:33:38 -0800229 EXPECT_NO_FATAL_FAILURE(mTimeStats->parseArgs(useProto, args, result));
Yiwei Zhang5434a782018-12-05 18:06:32 -0800230 return result;
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800231}
232
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800233static std::string genLayerName(int32_t layerId) {
Peiyong Lind8460c82020-07-28 16:04:22 -0700234 return (layerId < 0 ? "PopupWindow:b54fcd1#0" : "com.example.fake#") + std::to_string(layerId);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800235}
236
237void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts) {
238 switch (type) {
239 case TimeStamp::POST:
Alec Mouri9a29e672020-09-14 12:39:14 -0700240 ASSERT_NO_FATAL_FAILURE(
241 mTimeStats->setPostTime(id, frameNumber, genLayerName(id), UID_0, ts));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800242 break;
243 case TimeStamp::ACQUIRE:
244 ASSERT_NO_FATAL_FAILURE(mTimeStats->setAcquireTime(id, frameNumber, ts));
245 break;
246 case TimeStamp::ACQUIRE_FENCE:
247 ASSERT_NO_FATAL_FAILURE(
248 mTimeStats->setAcquireFence(id, frameNumber, std::make_shared<FenceTime>(ts)));
249 break;
250 case TimeStamp::LATCH:
251 ASSERT_NO_FATAL_FAILURE(mTimeStats->setLatchTime(id, frameNumber, ts));
252 break;
253 case TimeStamp::DESIRED:
254 ASSERT_NO_FATAL_FAILURE(mTimeStats->setDesiredTime(id, frameNumber, ts));
255 break;
256 case TimeStamp::PRESENT:
Alec Mouri7d436ec2021-01-27 20:40:50 -0800257 ASSERT_NO_FATAL_FAILURE(
258 mTimeStats->setPresentTime(id, frameNumber, ts, kRefreshRate0, kRenderRate0));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800259 break;
260 case TimeStamp::PRESENT_FENCE:
Alec Mouri7d436ec2021-01-27 20:40:50 -0800261 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPresentFence(id, frameNumber,
262 std::make_shared<FenceTime>(ts),
263 kRefreshRate0, kRenderRate0));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800264 break;
265 default:
266 ALOGD("Invalid timestamp type");
267 }
268}
269
270int32_t TimeStatsTest::genRandomInt32(int32_t begin, int32_t end) {
271 std::uniform_int_distribution<int32_t> distr(begin, end);
272 return distr(mRandomEngine);
273}
274
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000275TEST_F(TimeStatsTest, disabledByDefault) {
276 ASSERT_FALSE(mTimeStats->isEnabled());
277}
278
Tej Singh38a4b212020-03-13 19:04:51 -0700279TEST_F(TimeStatsTest, setsCallbacksAfterBoot) {
Alec Mouri8e2f31b2020-01-16 22:04:35 +0000280 mTimeStats->onBootFinished();
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800281 EXPECT_THAT(mDelegate->mAtomTags,
282 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
283 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
284}
285
Tej Singh38a4b212020-03-13 19:04:51 -0700286TEST_F(TimeStatsTest, clearsCallbacksOnDestruction) {
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800287 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700288 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800289 EXPECT_CALL(*mDelegate,
Tej Singh38a4b212020-03-13 19:04:51 -0700290 clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO));
Alec Mouri3ecd5cd2020-01-29 12:53:07 -0800291 mTimeStats.reset();
Alec Mourib3885ad2019-09-06 17:08:55 -0700292}
293
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800294TEST_F(TimeStatsTest, canEnableAndDisableTimeStats) {
295 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
296 ASSERT_TRUE(mTimeStats->isEnabled());
297
298 EXPECT_TRUE(inputCommand(InputCommand::DISABLE, FMT_STRING).empty());
299 ASSERT_FALSE(mTimeStats->isEnabled());
300}
301
302TEST_F(TimeStatsTest, canIncreaseGlobalStats) {
303 constexpr size_t TOTAL_FRAMES = 5;
304 constexpr size_t MISSED_FRAMES = 4;
305 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
306
307 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
308
309 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
310 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
311 }
312 for (size_t i = 0; i < MISSED_FRAMES; i++) {
313 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
314 }
315 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
316 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
317 }
318
319 SFTimeStatsGlobalProto globalProto;
320 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
321
322 ASSERT_TRUE(globalProto.has_total_frames());
323 EXPECT_EQ(TOTAL_FRAMES, globalProto.total_frames());
324 ASSERT_TRUE(globalProto.has_missed_frames());
325 EXPECT_EQ(MISSED_FRAMES, globalProto.missed_frames());
326 ASSERT_TRUE(globalProto.has_client_composition_frames());
327 EXPECT_EQ(CLIENT_COMPOSITION_FRAMES, globalProto.client_composition_frames());
328}
329
Alec Mouri91f6df32020-01-30 08:48:58 -0800330TEST_F(TimeStatsTest, canIncreaseLateAcquireFrames) {
331 // this stat is not in the proto so verify by checking the string dump
332 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
333
334 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
335
336 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
337 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
338 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
339 }
340 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
341
342 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
343 const std::string expectedResult = "lateAcquireFrames = " + std::to_string(LATE_ACQUIRE_FRAMES);
344 EXPECT_THAT(result, HasSubstr(expectedResult));
345}
346
347TEST_F(TimeStatsTest, canIncreaseBadDesiredPresent) {
348 // this stat is not in the proto so verify by checking the string dump
349 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 2;
350
351 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
352
353 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
354 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
355 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
356 }
357 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
358
359 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
360 const std::string expectedResult =
361 "badDesiredPresentFrames = " + std::to_string(BAD_DESIRED_PRESENT_FRAMES);
362 EXPECT_THAT(result, HasSubstr(expectedResult));
363}
364
Alec Mouri9a29e672020-09-14 12:39:14 -0700365TEST_F(TimeStatsTest, canIncreaseJankyFramesForLayer) {
366 // this stat is not in the proto so verify by checking the string dump
367 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
368
369 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
Alec Mouri363faf02021-01-29 16:34:55 -0800370 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
371 JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
372 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
373 JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
374 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
375 JankType::DisplayHAL, 1, 2, 3});
376 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
377 JankType::AppDeadlineMissed, 1, 2, 3});
378 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Adithya Srinivasanead17162021-02-18 02:17:37 +0000379 JankType::SurfaceFlingerScheduling, 1, 2, 3});
380 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
381 JankType::PredictionError, 1, 2, 3});
382 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
383 JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
384 3});
385 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Alec Mouri363faf02021-01-29 16:34:55 -0800386 JankType::None, 1, 2, 3});
Alec Mouri9a29e672020-09-14 12:39:14 -0700387
388 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
Alec Mouri7d436ec2021-01-27 20:40:50 -0800389 std::string expectedResult =
390 "displayRefreshRate = " + std::to_string(REFRESH_RATE_BUCKET_0) + " fps";
391 EXPECT_THAT(result, HasSubstr(expectedResult));
392 expectedResult = "renderRate = " + std::to_string(RENDER_RATE_BUCKET_0) + " fps";
393 EXPECT_THAT(result, HasSubstr(expectedResult));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000394 expectedResult = "totalTimelineFrames = " + std::to_string(8);
Alec Mouri9a29e672020-09-14 12:39:14 -0700395 EXPECT_THAT(result, HasSubstr(expectedResult));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000396 expectedResult = "jankyFrames = " + std::to_string(7);
Alec Mouri9a29e672020-09-14 12:39:14 -0700397 EXPECT_THAT(result, HasSubstr(expectedResult));
398 expectedResult = "sfLongCpuJankyFrames = " + std::to_string(1);
399 EXPECT_THAT(result, HasSubstr(expectedResult));
400 expectedResult = "sfLongGpuJankyFrames = " + std::to_string(1);
401 EXPECT_THAT(result, HasSubstr(expectedResult));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000402 expectedResult = "sfUnattributedJankyFrames = " + std::to_string(1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700403 EXPECT_THAT(result, HasSubstr(expectedResult));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000404 expectedResult = "appUnattributedJankyFrames = " + std::to_string(2);
405 EXPECT_THAT(result, HasSubstr(expectedResult));
406 expectedResult = "sfSchedulingJankyFrames = " + std::to_string(1);
407 EXPECT_THAT(result, HasSubstr(expectedResult));
408 expectedResult = "sfPredictionErrorJankyFrames = " + std::to_string(1);
409 EXPECT_THAT(result, HasSubstr(expectedResult));
410 expectedResult = "appBufferStuffingJankyFrames = " + std::to_string(1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700411 EXPECT_THAT(result, HasSubstr(expectedResult));
412}
413
Vishnu Nair9b079a22020-01-21 14:36:08 -0800414TEST_F(TimeStatsTest, canIncreaseClientCompositionReusedFrames) {
415 // this stat is not in the proto so verify by checking the string dump
416 constexpr size_t CLIENT_COMPOSITION_REUSED_FRAMES = 2;
417
418 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
419 for (size_t i = 0; i < CLIENT_COMPOSITION_REUSED_FRAMES; i++) {
420 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
421 }
422
423 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
424 const std::string expectedResult =
425 "clientCompositionReusedFrames = " + std::to_string(CLIENT_COMPOSITION_REUSED_FRAMES);
426 EXPECT_THAT(result, HasSubstr(expectedResult));
427}
428
Alec Mouri8de697e2020-03-19 10:52:01 -0700429TEST_F(TimeStatsTest, canIncreaseRefreshRateSwitches) {
430 // this stat is not in the proto so verify by checking the string dump
431 constexpr size_t REFRESH_RATE_SWITCHES = 2;
432
433 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
434 for (size_t i = 0; i < REFRESH_RATE_SWITCHES; i++) {
435 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
436 }
437
438 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
439 const std::string expectedResult =
440 "refreshRateSwitches = " + std::to_string(REFRESH_RATE_SWITCHES);
441 EXPECT_THAT(result, HasSubstr(expectedResult));
442}
443
Alec Mouri8f7a0102020-04-15 12:11:10 -0700444TEST_F(TimeStatsTest, canIncreaseCompositionStrategyChanges) {
445 // this stat is not in the proto so verify by checking the string dump
446 constexpr size_t COMPOSITION_STRATEGY_CHANGES = 2;
447
448 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
449 for (size_t i = 0; i < COMPOSITION_STRATEGY_CHANGES; i++) {
450 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
451 }
452
453 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
454 const std::string expectedResult =
455 "compositionStrategyChanges = " + std::to_string(COMPOSITION_STRATEGY_CHANGES);
456 EXPECT_THAT(result, HasSubstr(expectedResult));
457}
458
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800459TEST_F(TimeStatsTest, canAverageFrameDuration) {
460 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
Peiyong Lin65248e02020-04-18 21:15:07 -0700461 mTimeStats->setPowerMode(PowerMode::ON);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000462 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(1ms).count(),
463 std::chrono::nanoseconds(6ms).count());
464 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(1ms).count(),
465 std::chrono::nanoseconds(16ms).count());
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800466
467 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
468 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 10.000 ms"));
469}
470
471TEST_F(TimeStatsTest, canAverageRenderEngineTimings) {
472 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
Adithya Srinivasanead17162021-02-18 02:17:37 +0000473 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(1ms).count(),
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800474 std::make_shared<FenceTime>(
475 std::chrono::duration_cast<
476 std::chrono::nanoseconds>(3ms)
477 .count()));
478
Adithya Srinivasanead17162021-02-18 02:17:37 +0000479 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(4ms).count(),
480 std::chrono::nanoseconds(8ms).count());
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800481
Peiyong Lind8460c82020-07-28 16:04:22 -0700482 // Push a fake present fence to trigger flushing the RenderEngine timings.
Peiyong Lin65248e02020-04-18 21:15:07 -0700483 mTimeStats->setPowerMode(PowerMode::ON);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000484 mTimeStats->setPresentFenceGlobal(
485 std::make_shared<FenceTime>(std::chrono::nanoseconds(1ms).count()));
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800486
487 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
488 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 3.000 ms"));
489}
490
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800491TEST_F(TimeStatsTest, canInsertGlobalPresentToPresent) {
492 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
493
494 ASSERT_NO_FATAL_FAILURE(
495 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
496 ASSERT_NO_FATAL_FAILURE(
497 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
498
Peiyong Lin65248e02020-04-18 21:15:07 -0700499 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800500 ASSERT_NO_FATAL_FAILURE(
501 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000)));
502 ASSERT_NO_FATAL_FAILURE(
503 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000)));
504
Peiyong Lin65248e02020-04-18 21:15:07 -0700505 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::OFF));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800506 ASSERT_NO_FATAL_FAILURE(
507 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(6000000)));
508 ASSERT_NO_FATAL_FAILURE(
509 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(8000000)));
510
511 SFTimeStatsGlobalProto globalProto;
512 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
513
514 ASSERT_EQ(1, globalProto.present_to_present_size());
515 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.present_to_present().Get(0);
516 EXPECT_EQ(1, histogramProto.frame_count());
517 EXPECT_EQ(2, histogramProto.time_millis());
518}
519
Alec Mouri9519bf12019-11-15 16:54:44 -0800520TEST_F(TimeStatsTest, canInsertGlobalFrameDuration) {
521 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
522
Peiyong Lin65248e02020-04-18 21:15:07 -0700523 mTimeStats->setPowerMode(PowerMode::OFF);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000524 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(1ms).count(),
525 std::chrono::nanoseconds(5ms).count());
Peiyong Lin65248e02020-04-18 21:15:07 -0700526 mTimeStats->setPowerMode(PowerMode::ON);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000527 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(3ms).count(),
528 std::chrono::nanoseconds(6ms).count());
Alec Mouri9519bf12019-11-15 16:54:44 -0800529
530 SFTimeStatsGlobalProto globalProto;
531 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
532
533 ASSERT_EQ(1, globalProto.frame_duration_size());
534 const SFTimeStatsHistogramBucketProto& histogramProto = globalProto.frame_duration().Get(0);
535 EXPECT_EQ(1, histogramProto.frame_count());
536 EXPECT_EQ(3, histogramProto.time_millis());
537}
538
Alec Mourie4034bb2019-11-19 12:45:54 -0800539TEST_F(TimeStatsTest, canInsertGlobalRenderEngineTiming) {
540 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
541
Adithya Srinivasanead17162021-02-18 02:17:37 +0000542 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(1ms).count(),
Alec Mourie4034bb2019-11-19 12:45:54 -0800543 std::make_shared<FenceTime>(
544 std::chrono::duration_cast<
545 std::chrono::nanoseconds>(3ms)
546 .count()));
547
Adithya Srinivasanead17162021-02-18 02:17:37 +0000548 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(4ms).count(),
549 std::chrono::nanoseconds(6ms).count());
Alec Mourie4034bb2019-11-19 12:45:54 -0800550
551 // First verify that flushing RenderEngine durations did not occur yet.
552 SFTimeStatsGlobalProto preFlushProto;
553 ASSERT_TRUE(preFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
554 ASSERT_EQ(0, preFlushProto.render_engine_timing_size());
555
Peiyong Lind8460c82020-07-28 16:04:22 -0700556 // Push a fake present fence to trigger flushing the RenderEngine timings.
Peiyong Lin65248e02020-04-18 21:15:07 -0700557 mTimeStats->setPowerMode(PowerMode::ON);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000558 mTimeStats->setPresentFenceGlobal(
559 std::make_shared<FenceTime>(std::chrono::nanoseconds(1ms).count()));
Alec Mourie4034bb2019-11-19 12:45:54 -0800560
561 // Now we can verify that RenderEngine durations were flushed now.
562 SFTimeStatsGlobalProto postFlushProto;
563 ASSERT_TRUE(postFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
564
565 ASSERT_EQ(1, postFlushProto.render_engine_timing_size());
566 const SFTimeStatsHistogramBucketProto& histogramProto =
567 postFlushProto.render_engine_timing().Get(0);
568 EXPECT_EQ(2, histogramProto.frame_count());
569 EXPECT_EQ(2, histogramProto.time_millis());
570}
571
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800572TEST_F(TimeStatsTest, canInsertOneLayerTimeStats) {
573 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
574
575 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
576 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_0, 2, 2000000);
577
578 SFTimeStatsGlobalProto globalProto;
579 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
580
581 ASSERT_EQ(1, globalProto.stats_size());
582 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
583 ASSERT_TRUE(layerProto.has_layer_name());
584 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
585 ASSERT_TRUE(layerProto.has_total_frames());
586 EXPECT_EQ(1, layerProto.total_frames());
587 ASSERT_EQ(6, layerProto.deltas_size());
588 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
589 ASSERT_EQ(1, deltaProto.histograms_size());
590 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
591 EXPECT_EQ(1, histogramProto.frame_count());
592 if ("post2acquire" == deltaProto.delta_name()) {
593 EXPECT_EQ(1, histogramProto.time_millis());
594 } else if ("post2present" == deltaProto.delta_name()) {
595 EXPECT_EQ(4, histogramProto.time_millis());
596 } else if ("acquire2present" == deltaProto.delta_name()) {
597 EXPECT_EQ(3, histogramProto.time_millis());
598 } else if ("latch2present" == deltaProto.delta_name()) {
599 EXPECT_EQ(2, histogramProto.time_millis());
600 } else if ("desired2present" == deltaProto.delta_name()) {
601 EXPECT_EQ(1, histogramProto.time_millis());
602 } else if ("present2present" == deltaProto.delta_name()) {
603 EXPECT_EQ(1, histogramProto.time_millis());
604 } else {
605 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
606 }
607 }
608}
609
610TEST_F(TimeStatsTest, canNotInsertInvalidLayerNameTimeStats) {
611 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
612
613 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_INVALID, 1, 1000000);
614 insertTimeRecord(NORMAL_SEQUENCE_2, LAYER_ID_INVALID, 2, 2000000);
615
616 SFTimeStatsGlobalProto globalProto;
617 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
618
619 ASSERT_EQ(0, globalProto.stats_size());
620}
621
622TEST_F(TimeStatsTest, canInsertMultipleLayersTimeStats) {
623 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
624
625 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
626 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
627 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
628 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
629
630 SFTimeStatsGlobalProto globalProto;
631 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
632
633 EXPECT_EQ(2, globalProto.stats_size());
634}
635
636TEST_F(TimeStatsTest, canInsertUnorderedLayerTimeStats) {
637 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
638
639 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
640 insertTimeRecord(UNORDERED_SEQUENCE, LAYER_ID_0, 2, 2000000);
641
642 SFTimeStatsGlobalProto globalProto;
643 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
644
645 ASSERT_EQ(1, globalProto.stats_size());
646 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
647 ASSERT_TRUE(layerProto.has_layer_name());
648 EXPECT_EQ(genLayerName(LAYER_ID_0), layerProto.layer_name());
649 ASSERT_TRUE(layerProto.has_total_frames());
650 EXPECT_EQ(1, layerProto.total_frames());
651 ASSERT_EQ(6, layerProto.deltas_size());
652 for (const SFTimeStatsDeltaProto& deltaProto : layerProto.deltas()) {
653 ASSERT_EQ(1, deltaProto.histograms_size());
654 const SFTimeStatsHistogramBucketProto& histogramProto = deltaProto.histograms().Get(0);
655 EXPECT_EQ(1, histogramProto.frame_count());
656 if ("post2acquire" == deltaProto.delta_name()) {
657 EXPECT_EQ(0, histogramProto.time_millis());
658 } else if ("post2present" == deltaProto.delta_name()) {
659 EXPECT_EQ(2, histogramProto.time_millis());
660 } else if ("acquire2present" == deltaProto.delta_name()) {
661 EXPECT_EQ(2, histogramProto.time_millis());
662 } else if ("latch2present" == deltaProto.delta_name()) {
663 EXPECT_EQ(2, histogramProto.time_millis());
664 } else if ("desired2present" == deltaProto.delta_name()) {
665 EXPECT_EQ(1, histogramProto.time_millis());
666 } else if ("present2present" == deltaProto.delta_name()) {
667 EXPECT_EQ(1, histogramProto.time_millis());
668 } else {
669 FAIL() << "Unknown delta_name: " << deltaProto.delta_name();
670 }
671 }
672}
673
Alec Mourifb571ea2019-01-24 18:42:10 -0800674TEST_F(TimeStatsTest, recordRefreshRateNewConfigs) {
675 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
676
677 uint32_t fpsOne = 30;
678 uint32_t fpsTwo = 90;
679 uint64_t millisOne = 5000;
680 uint64_t millisTwo = 7000;
681
682 mTimeStats->recordRefreshRate(fpsOne, ms2ns(millisOne));
683 mTimeStats->recordRefreshRate(fpsTwo, ms2ns(millisTwo));
684
685 SFTimeStatsGlobalProto globalProto;
686 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
687
688 SFTimeStatsDisplayConfigBucketProto expectedBucketOne;
689 SFTimeStatsDisplayConfigProto* expectedConfigOne = expectedBucketOne.mutable_config();
690 expectedConfigOne->set_fps(fpsOne);
691 expectedBucketOne.set_duration_millis(millisOne);
692
693 SFTimeStatsDisplayConfigBucketProto expectedBucketTwo;
694 SFTimeStatsDisplayConfigProto* expectedConfigTwo = expectedBucketTwo.mutable_config();
695 expectedConfigTwo->set_fps(fpsTwo);
696 expectedBucketTwo.set_duration_millis(millisTwo);
697
698 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(2));
699
700 std::unordered_set<uint32_t> seen_fps;
701 for (const auto& bucket : globalProto.display_config_stats()) {
702 seen_fps.emplace(bucket.config().fps());
703 if (fpsOne == bucket.config().fps()) {
704 EXPECT_EQ(millisOne, bucket.duration_millis());
705 } else if (fpsTwo == bucket.config().fps()) {
706 EXPECT_EQ(millisTwo, bucket.duration_millis());
707 } else {
708 FAIL() << "Unknown fps: " << bucket.config().fps();
709 }
710 }
711 EXPECT_THAT(seen_fps, UnorderedElementsAre(fpsOne, fpsTwo));
712}
713
714TEST_F(TimeStatsTest, recordRefreshRateUpdatesConfig) {
715 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
716
717 uint32_t fps = 30;
718 uint64_t millisOne = 5000;
719 uint64_t millisTwo = 7000;
720
721 mTimeStats->recordRefreshRate(fps, ms2ns(millisOne));
722 mTimeStats->recordRefreshRate(fps, ms2ns(millisTwo));
723
724 SFTimeStatsGlobalProto globalProto;
725 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
726 EXPECT_THAT(globalProto.display_config_stats(), SizeIs(1));
727 EXPECT_EQ(fps, globalProto.display_config_stats().Get(0).config().fps());
728 EXPECT_EQ(millisOne + millisTwo, globalProto.display_config_stats().Get(0).duration_millis());
729}
730
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800731TEST_F(TimeStatsTest, canRemoveTimeRecord) {
732 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
733
734 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
735 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 2, 2000000);
736 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(0, 2));
737 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
738
739 SFTimeStatsGlobalProto globalProto;
740 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
741
742 ASSERT_EQ(1, globalProto.stats_size());
743 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
744 ASSERT_TRUE(layerProto.has_total_frames());
745 EXPECT_EQ(1, layerProto.total_frames());
746}
747
748TEST_F(TimeStatsTest, canRecoverFromIncompleteTimeRecordError) {
749 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
750
751 uint64_t frameNumber = 1;
752 nsecs_t ts = 1000000;
753 insertTimeRecord(INCOMPLETE_SEQUENCE, LAYER_ID_0, 1, 1000000);
Alec Mourifb571ea2019-01-24 18:42:10 -0800754 for (size_t i = 0; i < impl::TimeStats::MAX_NUM_TIME_RECORDS + 2; i++) {
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800755 frameNumber++;
756 ts += 1000000;
757 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, frameNumber, ts);
758 }
759
760 SFTimeStatsGlobalProto globalProto;
761 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
762
763 ASSERT_EQ(1, globalProto.stats_size());
764 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
765 ASSERT_TRUE(layerProto.has_total_frames());
766 EXPECT_EQ(1, layerProto.total_frames());
767}
768
769TEST_F(TimeStatsTest, layerTimeStatsOnDestroy) {
770 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
771
772 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
773 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
774 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(0));
775 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000);
776
777 SFTimeStatsGlobalProto globalProto;
778 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
779
780 ASSERT_EQ(1, globalProto.stats_size());
781 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
782 ASSERT_TRUE(layerProto.has_total_frames());
783 EXPECT_EQ(1, layerProto.total_frames());
784}
785
786TEST_F(TimeStatsTest, canClearTimeStats) {
787 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
788
789 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
790 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
791 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
Peiyong Lin65248e02020-04-18 21:15:07 -0700792 ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
Alec Mouri31ac64a2020-01-09 09:26:22 -0800793
Adithya Srinivasanead17162021-02-18 02:17:37 +0000794 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(3ms).count(),
795 std::chrono::nanoseconds(6ms).count());
796 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(4ms).count(),
797 std::chrono::nanoseconds(6ms).count());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800798 ASSERT_NO_FATAL_FAILURE(
799 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(1000000)));
800 ASSERT_NO_FATAL_FAILURE(
801 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
802 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
803 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
804
805 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
806
807 SFTimeStatsGlobalProto globalProto;
808 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
809
810 EXPECT_EQ(0, globalProto.total_frames());
811 EXPECT_EQ(0, globalProto.missed_frames());
812 EXPECT_EQ(0, globalProto.client_composition_frames());
813 EXPECT_EQ(0, globalProto.present_to_present_size());
Alec Mouri31ac64a2020-01-09 09:26:22 -0800814 EXPECT_EQ(0, globalProto.frame_duration_size());
815 EXPECT_EQ(0, globalProto.render_engine_timing_size());
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800816 EXPECT_EQ(0, globalProto.stats_size());
817}
818
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800819TEST_F(TimeStatsTest, canClearDumpOnlyTimeStats) {
820 // These stats are not in the proto so verify by checking the string dump.
Vishnu Nair9b079a22020-01-21 14:36:08 -0800821 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
822 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
Alec Mouri8de697e2020-03-19 10:52:01 -0700823 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
Alec Mouri8f7a0102020-04-15 12:11:10 -0700824 ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
Peiyong Lin65248e02020-04-18 21:15:07 -0700825 mTimeStats->setPowerMode(PowerMode::ON);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000826 mTimeStats->recordFrameDuration(std::chrono::nanoseconds(1ms).count(),
827 std::chrono::nanoseconds(5ms).count());
828 mTimeStats->recordRenderEngineDuration(std::chrono::nanoseconds(4ms).count(),
829 std::chrono::nanoseconds(6ms).count());
830 mTimeStats->setPresentFenceGlobal(
831 std::make_shared<FenceTime>(std::chrono::nanoseconds(1ms).count()));
Alec Mouri9a29e672020-09-14 12:39:14 -0700832
Alec Mouri363faf02021-01-29 16:34:55 -0800833 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
834 JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
835 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
836 JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
837 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
838 JankType::DisplayHAL, 1, 2, 3});
839 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
840 JankType::AppDeadlineMissed, 1, 2, 3});
841 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Adithya Srinivasanead17162021-02-18 02:17:37 +0000842 JankType::SurfaceFlingerScheduling, 1, 2, 3});
843 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
844 JankType::PredictionError, 1, 2, 3});
845 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
846 JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
847 3});
848 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Alec Mouri363faf02021-01-29 16:34:55 -0800849 JankType::None, 1, 2, 3});
Alec Mouri9a29e672020-09-14 12:39:14 -0700850
Vishnu Nair9b079a22020-01-21 14:36:08 -0800851 EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
852
853 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
854 EXPECT_THAT(result, HasSubstr("clientCompositionReusedFrames = 0"));
Alec Mouri8de697e2020-03-19 10:52:01 -0700855 EXPECT_THAT(result, HasSubstr("refreshRateSwitches = 0"));
Alec Mouri8f7a0102020-04-15 12:11:10 -0700856 EXPECT_THAT(result, HasSubstr("compositionStrategyChanges = 0"));
Vishnu Nairabf97fd2020-02-03 13:51:16 -0800857 EXPECT_THAT(result, HasSubstr("averageFrameDuration = 0.000 ms"));
858 EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 0.000 ms"));
Alec Mouri56e63852021-03-09 18:17:25 -0800859 std::string expectedResult = "totalTimelineFrames = " + std::to_string(0);
860 EXPECT_THAT(result, HasSubstr(expectedResult));
861 expectedResult = "jankyFrames = " + std::to_string(0);
862 EXPECT_THAT(result, HasSubstr(expectedResult));
863 expectedResult = "sfLongCpuJankyFrames = " + std::to_string(0);
864 EXPECT_THAT(result, HasSubstr(expectedResult));
865 expectedResult = "sfLongGpuJankyFrames = " + std::to_string(0);
866 EXPECT_THAT(result, HasSubstr(expectedResult));
867 expectedResult = "sfUnattributedJankyFrames = " + std::to_string(0);
868 EXPECT_THAT(result, HasSubstr(expectedResult));
869 expectedResult = "appUnattributedJankyFrames = " + std::to_string(0);
870 EXPECT_THAT(result, HasSubstr(expectedResult));
871 expectedResult = "sfSchedulingJankyFrames = " + std::to_string(0);
872 EXPECT_THAT(result, HasSubstr(expectedResult));
873 expectedResult = "sfPredictionErrorJankyFrames = " + std::to_string(0);
874 EXPECT_THAT(result, HasSubstr(expectedResult));
875 expectedResult = "appBufferStuffingJankyFrames = " + std::to_string(0);
876 EXPECT_THAT(result, HasSubstr(expectedResult));
Vishnu Nair9b079a22020-01-21 14:36:08 -0800877}
878
Yiwei Zhang16faa5d2018-11-13 18:12:59 -0800879TEST_F(TimeStatsTest, canDumpWithMaxLayers) {
880 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
881
882 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
883 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 1000000);
884 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
885 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 2000000);
886 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 3, 2000000);
887
888 SFTimeStatsGlobalProto globalProto;
889 ASSERT_TRUE(
890 globalProto.ParseFromString(inputCommand(InputCommand::DUMP_MAXLAYERS_1, FMT_PROTO)));
891
892 ASSERT_EQ(1, globalProto.stats_size());
893 const SFTimeStatsLayerProto& layerProto = globalProto.stats().Get(0);
894 ASSERT_TRUE(layerProto.has_layer_name());
895 EXPECT_EQ(genLayerName(LAYER_ID_1), layerProto.layer_name());
896 ASSERT_TRUE(layerProto.has_total_frames());
897 EXPECT_EQ(2, layerProto.total_frames());
898}
899
900TEST_F(TimeStatsTest, canDumpWithInvalidMaxLayers) {
901 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
902
903 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
904 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
905
906 SFTimeStatsGlobalProto globalProto;
907 ASSERT_TRUE(globalProto.ParseFromString(
908 inputCommand(InputCommand::DUMP_MAXLAYERS_INVALID, FMT_PROTO)));
909
910 ASSERT_EQ(0, globalProto.stats_size());
911}
912
Yiwei Zhangdd221b22020-06-12 11:06:19 -0700913TEST_F(TimeStatsTest, noInfInAverageFPS) {
914 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
915 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
916 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 1000000);
917
918 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
919 EXPECT_THAT(result, HasSubstr("averageFPS = 0.000"));
920}
921
Alec Mouri37384342020-01-02 17:23:37 -0800922namespace {
923std::string buildExpectedHistogramBytestring(const std::vector<int32_t>& times,
924 const std::vector<int32_t>& frameCounts) {
925 util::ProtoOutputStream proto;
926 for (int i = 0; i < times.size(); i++) {
927 ALOGE("Writing time: %d", times[i]);
928 proto.write(util::FIELD_TYPE_INT32 | util::FIELD_COUNT_REPEATED | 1 /* field id */,
929 (int32_t)times[i]);
930 ALOGE("Writing count: %d", frameCounts[i]);
931 proto.write(util::FIELD_TYPE_INT64 | util::FIELD_COUNT_REPEATED | 2 /* field id */,
932 (int64_t)frameCounts[i]);
933 }
934 std::string byteString;
935 proto.serializeToString(&byteString);
936 return byteString;
937}
938
Alec Mouri75de8f22021-01-20 14:53:44 -0800939std::string frameRateVoteToProtoByteString(float refreshRate, int frameRateCompatibility,
940 int seamlessness) {
941 util::ProtoOutputStream proto;
942 proto.write(android::util::FIELD_TYPE_FLOAT | 1 /* field id */, refreshRate);
943 proto.write(android::util::FIELD_TYPE_ENUM | 2 /* field id */, frameRateCompatibility);
944 proto.write(android::util::FIELD_TYPE_ENUM | 3 /* field id */, seamlessness);
945
946 std::string byteString;
947 proto.serializeToString(&byteString);
948 return byteString;
949}
950
Alec Mouri37384342020-01-02 17:23:37 -0800951std::string dumpByteStringHex(const std::string& str) {
952 std::stringstream ss;
953 ss << std::hex;
954 for (const char& c : str) {
955 ss << (int)c << " ";
956 }
957
958 return ss.str();
959}
960
961} // namespace
962
963MATCHER_P2(BytesEq, bytes, size, "") {
964 std::string expected;
965 expected.append((const char*)bytes, size);
966 std::string actual;
967 actual.append((const char*)arg, size);
968
969 *result_listener << "Bytes are not equal! \n";
970 *result_listener << "size: " << size << "\n";
971 *result_listener << "expected: " << dumpByteStringHex(expected).c_str() << "\n";
972 *result_listener << "actual: " << dumpByteStringHex(actual).c_str() << "\n";
973
974 return expected == actual;
975}
976
Alec Mouridfad9002020-02-12 17:49:09 -0800977TEST_F(TimeStatsTest, globalStatsCallback) {
978 constexpr size_t TOTAL_FRAMES = 5;
979 constexpr size_t MISSED_FRAMES = 4;
980 constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
981 constexpr size_t DISPLAY_EVENT_CONNECTIONS = 14;
982
983 mTimeStats->onBootFinished();
984 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
985
986 for (size_t i = 0; i < TOTAL_FRAMES; i++) {
987 mTimeStats->incrementTotalFrames();
988 }
989 for (size_t i = 0; i < MISSED_FRAMES; i++) {
990 mTimeStats->incrementMissedFrames();
991 }
992 for (size_t i = 0; i < CLIENT_COMPOSITION_FRAMES; i++) {
993 mTimeStats->incrementClientCompositionFrames();
994 }
995
Alec Mouri9a29e672020-09-14 12:39:14 -0700996 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
997
Alec Mouridfad9002020-02-12 17:49:09 -0800998 mTimeStats->recordDisplayEventConnectionCount(DISPLAY_EVENT_CONNECTIONS);
Peiyong Lin65248e02020-04-18 21:15:07 -0700999 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mouridfad9002020-02-12 17:49:09 -08001000 mTimeStats->recordFrameDuration(1000000, 3000000);
1001 mTimeStats->recordRenderEngineDuration(2000000, 4000000);
1002 mTimeStats->recordRenderEngineDuration(2000000, std::make_shared<FenceTime>(3000000));
1003
1004 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
1005 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
1006
Alec Mouri363faf02021-01-29 16:34:55 -08001007 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1008 JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
1009 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1010 JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
1011 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1012 JankType::DisplayHAL, 1, 2, 3});
1013 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1014 JankType::AppDeadlineMissed, 1, 2, 3});
1015 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Adithya Srinivasanead17162021-02-18 02:17:37 +00001016 JankType::SurfaceFlingerScheduling, 1, 2, 3});
1017 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1018 JankType::PredictionError, 1, 2, 3});
1019 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1020 JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
1021 3});
1022 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Alec Mouri363faf02021-01-29 16:34:55 -08001023 JankType::None, 1, 2, 3});
Alec Mouri9a29e672020-09-14 12:39:14 -07001024
Alec Mouridfad9002020-02-12 17:49:09 -08001025 EXPECT_THAT(mDelegate->mAtomTags,
1026 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1027 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1028 EXPECT_NE(nullptr, mDelegate->mCallback);
1029 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1030
1031 std::string expectedFrameDuration = buildExpectedHistogramBytestring({2}, {1});
1032 std::string expectedRenderEngineTiming = buildExpectedHistogramBytestring({1, 2}, {1, 1});
Alec Mouri75de8f22021-01-20 14:53:44 -08001033 std::string expectedEmptyHistogram = buildExpectedHistogramBytestring({}, {});
Adithya Srinivasanead17162021-02-18 02:17:37 +00001034 std::string expectedSfDeadlineMissed = buildExpectedHistogramBytestring({1}, {7});
1035 std::string expectedSfPredictionErrors = buildExpectedHistogramBytestring({2}, {7});
Alec Mouridfad9002020-02-12 17:49:09 -08001036
1037 {
1038 InSequence seq;
1039 EXPECT_CALL(*mDelegate,
1040 statsEventSetAtomId(mDelegate->mEvent,
1041 android::util::SURFACEFLINGER_STATS_GLOBAL_INFO));
1042 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, TOTAL_FRAMES));
1043 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, MISSED_FRAMES));
1044 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, CLIENT_COMPOSITION_FRAMES));
1045 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, _));
1046 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 2));
1047 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, DISPLAY_EVENT_CONNECTIONS));
1048 EXPECT_CALL(*mDelegate,
1049 statsEventWriteByteArray(mDelegate->mEvent,
1050 BytesEq((const uint8_t*)expectedFrameDuration.c_str(),
1051 expectedFrameDuration.size()),
1052 expectedFrameDuration.size()));
1053 EXPECT_CALL(*mDelegate,
1054 statsEventWriteByteArray(mDelegate->mEvent,
1055 BytesEq((const uint8_t*)
1056 expectedRenderEngineTiming.c_str(),
1057 expectedRenderEngineTiming.size()),
1058 expectedRenderEngineTiming.size()));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001059 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 8));
1060 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 7));
Alec Mouri9a29e672020-09-14 12:39:14 -07001061 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1062 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1063 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001064 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 2));
Alec Mouri9a29e672020-09-14 12:39:14 -07001065 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001066 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1067 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001068 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, REFRESH_RATE_BUCKET_0));
Alec Mouri75de8f22021-01-20 14:53:44 -08001069 EXPECT_CALL(*mDelegate,
1070 statsEventWriteByteArray(mDelegate->mEvent,
Alec Mouri363faf02021-01-29 16:34:55 -08001071 BytesEq((const uint8_t*)
1072 expectedSfDeadlineMissed.c_str(),
1073 expectedSfDeadlineMissed.size()),
1074 expectedSfDeadlineMissed.size()));
Alec Mouri75de8f22021-01-20 14:53:44 -08001075 EXPECT_CALL(*mDelegate,
1076 statsEventWriteByteArray(mDelegate->mEvent,
Alec Mouri363faf02021-01-29 16:34:55 -08001077 BytesEq((const uint8_t*)
1078 expectedSfPredictionErrors.c_str(),
1079 expectedSfPredictionErrors.size()),
1080 expectedSfPredictionErrors.size()));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001081 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, RENDER_RATE_BUCKET_0));
Alec Mouri75de8f22021-01-20 14:53:44 -08001082
Alec Mouridfad9002020-02-12 17:49:09 -08001083 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
1084 }
1085 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
1086 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1087 mDelegate->mCookie));
1088
1089 SFTimeStatsGlobalProto globalProto;
1090 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
1091
1092 EXPECT_EQ(0, globalProto.total_frames());
1093 EXPECT_EQ(0, globalProto.missed_frames());
1094 EXPECT_EQ(0, globalProto.client_composition_frames());
1095 EXPECT_EQ(0, globalProto.present_to_present_size());
Alec Mouri56e63852021-03-09 18:17:25 -08001096
1097 // also check dump-only stats: expect that global stats are indeed dropped but there should
1098 // still be stats for the layer
1099 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
1100 std::string expectedResult = "totalTimelineFrames = " + std::to_string(0);
1101 EXPECT_THAT(result, HasSubstr(expectedResult));
1102 expectedResult = "totalTimelineFrames = " + std::to_string(8);
1103 EXPECT_THAT(result, HasSubstr(expectedResult));
1104 expectedResult = "jankyFrames = " + std::to_string(0);
1105 EXPECT_THAT(result, HasSubstr(expectedResult));
1106 expectedResult = "jankyFrames = " + std::to_string(7);
1107 EXPECT_THAT(result, HasSubstr(expectedResult));
1108 expectedResult = "sfLongCpuJankyFrames = " + std::to_string(0);
1109 EXPECT_THAT(result, HasSubstr(expectedResult));
1110 expectedResult = "sfLongCpuJankyFrames = " + std::to_string(1);
1111 EXPECT_THAT(result, HasSubstr(expectedResult));
1112 expectedResult = "sfLongGpuJankyFrames = " + std::to_string(0);
1113 EXPECT_THAT(result, HasSubstr(expectedResult));
1114 expectedResult = "sfLongGpuJankyFrames = " + std::to_string(1);
1115 EXPECT_THAT(result, HasSubstr(expectedResult));
1116 expectedResult = "sfUnattributedJankyFrames = " + std::to_string(0);
1117 EXPECT_THAT(result, HasSubstr(expectedResult));
1118 expectedResult = "sfUnattributedJankyFrames = " + std::to_string(1);
1119 EXPECT_THAT(result, HasSubstr(expectedResult));
1120 expectedResult = "appUnattributedJankyFrames = " + std::to_string(0);
1121 EXPECT_THAT(result, HasSubstr(expectedResult));
1122 expectedResult = "appUnattributedJankyFrames = " + std::to_string(2);
1123 EXPECT_THAT(result, HasSubstr(expectedResult));
1124 expectedResult = "sfSchedulingJankyFrames = " + std::to_string(0);
1125 EXPECT_THAT(result, HasSubstr(expectedResult));
1126 expectedResult = "sfSchedulingJankyFrames = " + std::to_string(1);
1127 EXPECT_THAT(result, HasSubstr(expectedResult));
1128 expectedResult = "sfPredictionErrorJankyFrames = " + std::to_string(0);
1129 EXPECT_THAT(result, HasSubstr(expectedResult));
1130 expectedResult = "sfPredictionErrorJankyFrames = " + std::to_string(1);
1131 EXPECT_THAT(result, HasSubstr(expectedResult));
1132 expectedResult = "appBufferStuffingJankyFrames = " + std::to_string(0);
1133 EXPECT_THAT(result, HasSubstr(expectedResult));
1134 expectedResult = "appBufferStuffingJankyFrames = " + std::to_string(1);
1135 EXPECT_THAT(result, HasSubstr(expectedResult));
Alec Mouridfad9002020-02-12 17:49:09 -08001136}
1137
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -08001138TEST_F(TimeStatsTest, layerStatsCallback_pullsAllAndClears) {
1139 constexpr size_t LATE_ACQUIRE_FRAMES = 2;
1140 constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 3;
Alec Mouri37384342020-01-02 17:23:37 -08001141 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1142
1143 mTimeStats->onBootFinished();
1144
1145 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -08001146 for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
1147 mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
1148 }
1149 for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
1150 mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
1151 }
Alec Mouri37384342020-01-02 17:23:37 -08001152 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1153
Alec Mouri363faf02021-01-29 16:34:55 -08001154 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1155 JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
1156 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1157 JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
1158 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1159 JankType::DisplayHAL, 1, 2, 3});
1160 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1161 JankType::AppDeadlineMissed, 1, 2, 3});
1162 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Adithya Srinivasanead17162021-02-18 02:17:37 +00001163 JankType::SurfaceFlingerScheduling, 1, 2, 2});
1164 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1165 JankType::PredictionError, 1, 2, 2});
1166 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
1167 JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
1168 2});
1169 mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
Alec Mouri363faf02021-01-29 16:34:55 -08001170 JankType::None, 1, 2, 3});
Alec Mouri9a29e672020-09-14 12:39:14 -07001171
Alec Mouri37384342020-01-02 17:23:37 -08001172 EXPECT_THAT(mDelegate->mAtomTags,
1173 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1174 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1175 EXPECT_NE(nullptr, mDelegate->mCallback);
1176 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1177
1178 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {1});
1179 std::string expectedPostToPresent = buildExpectedHistogramBytestring({4}, {1});
1180 std::string expectedAcquireToPresent = buildExpectedHistogramBytestring({3}, {1});
1181 std::string expectedLatchToPresent = buildExpectedHistogramBytestring({2}, {1});
1182 std::string expectedDesiredToPresent = buildExpectedHistogramBytestring({1}, {1});
1183 std::string expectedPostToAcquire = buildExpectedHistogramBytestring({1}, {1});
Alec Mouri75de8f22021-01-20 14:53:44 -08001184 std::string expectedFrameRateOverride = frameRateVoteToProtoByteString(0.0, 0, 0);
Adithya Srinivasanead17162021-02-18 02:17:37 +00001185 std::string expectedAppDeadlineMissed = buildExpectedHistogramBytestring({3, 2}, {4, 3});
Alec Mouri37384342020-01-02 17:23:37 -08001186 {
1187 InSequence seq;
1188 EXPECT_CALL(*mDelegate,
1189 statsEventSetAtomId(mDelegate->mEvent,
1190 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1191 EXPECT_CALL(*mDelegate,
1192 statsEventWriteString8(mDelegate->mEvent,
1193 StrEq(genLayerName(LAYER_ID_0).c_str())));
1194 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 1));
1195 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 0));
1196 EXPECT_CALL(*mDelegate,
1197 statsEventWriteByteArray(mDelegate->mEvent,
1198 BytesEq((const uint8_t*)
1199 expectedPresentToPresent.c_str(),
1200 expectedPresentToPresent.size()),
1201 expectedPresentToPresent.size()));
1202 EXPECT_CALL(*mDelegate,
1203 statsEventWriteByteArray(mDelegate->mEvent,
1204 BytesEq((const uint8_t*)expectedPostToPresent.c_str(),
1205 expectedPostToPresent.size()),
1206 expectedPostToPresent.size()));
1207 EXPECT_CALL(*mDelegate,
1208 statsEventWriteByteArray(mDelegate->mEvent,
1209 BytesEq((const uint8_t*)
1210 expectedAcquireToPresent.c_str(),
1211 expectedAcquireToPresent.size()),
1212 expectedAcquireToPresent.size()));
1213 EXPECT_CALL(*mDelegate,
1214 statsEventWriteByteArray(mDelegate->mEvent,
1215 BytesEq((const uint8_t*)expectedLatchToPresent.c_str(),
1216 expectedLatchToPresent.size()),
1217 expectedLatchToPresent.size()));
1218 EXPECT_CALL(*mDelegate,
1219 statsEventWriteByteArray(mDelegate->mEvent,
1220 BytesEq((const uint8_t*)
1221 expectedDesiredToPresent.c_str(),
1222 expectedDesiredToPresent.size()),
1223 expectedDesiredToPresent.size()));
1224 EXPECT_CALL(*mDelegate,
1225 statsEventWriteByteArray(mDelegate->mEvent,
1226 BytesEq((const uint8_t*)expectedPostToAcquire.c_str(),
1227 expectedPostToAcquire.size()),
1228 expectedPostToAcquire.size()));
Yiwei Zhang7bfc75b2020-02-10 11:20:34 -08001229 EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, LATE_ACQUIRE_FRAMES));
1230 EXPECT_CALL(*mDelegate,
1231 statsEventWriteInt64(mDelegate->mEvent, BAD_DESIRED_PRESENT_FRAMES));
Alec Mouri9a29e672020-09-14 12:39:14 -07001232 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, UID_0));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001233 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 8));
1234 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 7));
Alec Mouri9a29e672020-09-14 12:39:14 -07001235 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1236 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1237 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001238 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 2));
Alec Mouri9a29e672020-09-14 12:39:14 -07001239 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Adithya Srinivasanead17162021-02-18 02:17:37 +00001240 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
1241 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, 1));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001242 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, REFRESH_RATE_BUCKET_0));
1243 EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, RENDER_RATE_BUCKET_0));
Alec Mouri75de8f22021-01-20 14:53:44 -08001244 EXPECT_CALL(*mDelegate,
1245 statsEventWriteByteArray(mDelegate->mEvent,
1246 BytesEq((const uint8_t*)
1247 expectedFrameRateOverride.c_str(),
1248 expectedFrameRateOverride.size()),
1249 expectedFrameRateOverride.size()));
1250 EXPECT_CALL(*mDelegate,
1251 statsEventWriteByteArray(mDelegate->mEvent,
Alec Mouri363faf02021-01-29 16:34:55 -08001252 BytesEq((const uint8_t*)
1253 expectedAppDeadlineMissed.c_str(),
1254 expectedAppDeadlineMissed.size()),
1255 expectedAppDeadlineMissed.size()));
Alec Mouri9a29e672020-09-14 12:39:14 -07001256
Alec Mouri37384342020-01-02 17:23:37 -08001257 EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
1258 }
Tej Singh2a457b62020-01-31 16:16:10 -08001259 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001260 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1261 mDelegate->mCookie));
1262
1263 SFTimeStatsGlobalProto globalProto;
1264 ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
1265
1266 EXPECT_EQ(0, globalProto.stats_size());
Alec Mouri56e63852021-03-09 18:17:25 -08001267
1268 // also check dump-only stats: expect that layer stats are indeed dropped but there should still
1269 // be global stats
1270 const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
1271 std::string expectedResult = "totalTimelineFrames = " + std::to_string(8);
1272 EXPECT_THAT(result, HasSubstr(expectedResult));
1273 expectedResult = "jankyFrames = " + std::to_string(7);
1274 EXPECT_THAT(result, HasSubstr(expectedResult));
1275 expectedResult = "sfLongCpuJankyFrames = " + std::to_string(1);
1276 EXPECT_THAT(result, HasSubstr(expectedResult));
1277 expectedResult = "sfLongGpuJankyFrames = " + std::to_string(1);
1278 EXPECT_THAT(result, HasSubstr(expectedResult));
1279 expectedResult = "sfUnattributedJankyFrames = " + std::to_string(1);
1280 EXPECT_THAT(result, HasSubstr(expectedResult));
1281 expectedResult = "appUnattributedJankyFrames = " + std::to_string(2);
1282 EXPECT_THAT(result, HasSubstr(expectedResult));
1283 expectedResult = "sfSchedulingJankyFrames = " + std::to_string(1);
1284 EXPECT_THAT(result, HasSubstr(expectedResult));
1285 expectedResult = "sfPredictionErrorJankyFrames = " + std::to_string(1);
1286 EXPECT_THAT(result, HasSubstr(expectedResult));
1287 expectedResult = "appBufferStuffingJankyFrames = " + std::to_string(1);
1288 EXPECT_THAT(result, HasSubstr(expectedResult));
1289
1290 std::string expectedMissing = "uid = " + std::to_string(UID_0);
1291 EXPECT_THAT(result, Not(HasSubstr(expectedMissing)));
Alec Mouri37384342020-01-02 17:23:37 -08001292}
1293
1294TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleLayers) {
1295 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1296
1297 mTimeStats->onBootFinished();
1298
1299 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1300 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1301 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1302 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1303
1304 EXPECT_THAT(mDelegate->mAtomTags,
1305 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1306 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1307 EXPECT_NE(nullptr, mDelegate->mCallback);
1308 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1309
1310 EXPECT_CALL(*mDelegate,
1311 statsEventSetAtomId(mDelegate->mEvent,
1312 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1313 .Times(2);
1314 EXPECT_CALL(*mDelegate,
1315 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_0).c_str())));
1316 EXPECT_CALL(*mDelegate,
1317 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001318 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001319 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1320 mDelegate->mCookie));
1321}
1322
1323TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleBuckets) {
1324 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1325
1326 mTimeStats->onBootFinished();
1327
1328 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1329 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1330 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1331 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1332
Tej Singh38a4b212020-03-13 19:04:51 -07001333 // Now make sure that TimeStats flushes global stats to set the callback.
Peiyong Lin65248e02020-04-18 21:15:07 -07001334 mTimeStats->setPowerMode(PowerMode::ON);
Alec Mouri37384342020-01-02 17:23:37 -08001335 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
1336 mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
1337 EXPECT_THAT(mDelegate->mAtomTags,
1338 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1339 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1340 EXPECT_NE(nullptr, mDelegate->mCallback);
1341 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1342
1343 EXPECT_THAT(mDelegate->mAtomTags,
1344 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1345 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1346 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1, 2}, {2, 1});
1347 {
1348 InSequence seq;
1349 EXPECT_CALL(*mDelegate,
1350 statsEventWriteByteArray(mDelegate->mEvent,
1351 BytesEq((const uint8_t*)
1352 expectedPresentToPresent.c_str(),
1353 expectedPresentToPresent.size()),
1354 expectedPresentToPresent.size()));
1355 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1356 .Times(AnyNumber());
1357 }
Tej Singh2a457b62020-01-31 16:16:10 -08001358 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001359 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1360 mDelegate->mCookie));
1361}
1362
1363TEST_F(TimeStatsTest, layerStatsCallback_limitsHistogramBuckets) {
1364 mDelegate = new FakeStatsEventDelegate;
1365 mTimeStats =
1366 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate),
1367 std::nullopt, 1);
1368 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1369
1370 mTimeStats->onBootFinished();
1371
1372 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1373 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1374 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 4000000);
1375 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
1376
1377 EXPECT_THAT(mDelegate->mAtomTags,
1378 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1379 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1380 EXPECT_NE(nullptr, mDelegate->mCallback);
1381 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1382
1383 EXPECT_THAT(mDelegate->mAtomTags,
1384 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1385 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1386 std::string expectedPresentToPresent = buildExpectedHistogramBytestring({1}, {2});
1387 {
1388 InSequence seq;
1389 EXPECT_CALL(*mDelegate,
1390 statsEventWriteByteArray(mDelegate->mEvent,
1391 BytesEq((const uint8_t*)
1392 expectedPresentToPresent.c_str(),
1393 expectedPresentToPresent.size()),
1394 expectedPresentToPresent.size()));
1395 EXPECT_CALL(*mDelegate, statsEventWriteByteArray(mDelegate->mEvent, _, _))
1396 .Times(AnyNumber());
1397 }
Tej Singh2a457b62020-01-31 16:16:10 -08001398 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001399 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1400 mDelegate->mCookie));
1401}
1402
1403TEST_F(TimeStatsTest, layerStatsCallback_limitsLayers) {
1404 mDelegate = new FakeStatsEventDelegate;
1405 mTimeStats =
1406 std::make_unique<impl::TimeStats>(std::unique_ptr<FakeStatsEventDelegate>(mDelegate), 1,
1407 std::nullopt);
1408 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1409
1410 mTimeStats->onBootFinished();
1411
1412 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
1413 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000);
1414 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 1, 2000000);
1415 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 2, 3000000);
1416 insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_1, 4, 5000000);
1417
1418 EXPECT_THAT(mDelegate->mAtomTags,
1419 UnorderedElementsAre(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
1420 android::util::SURFACEFLINGER_STATS_LAYER_INFO));
1421 EXPECT_NE(nullptr, mDelegate->mCallback);
1422 EXPECT_EQ(mTimeStats.get(), mDelegate->mCookie);
1423
1424 EXPECT_CALL(*mDelegate,
1425 statsEventSetAtomId(mDelegate->mEvent,
1426 android::util::SURFACEFLINGER_STATS_LAYER_INFO))
1427 .Times(1);
1428 EXPECT_CALL(*mDelegate,
1429 statsEventWriteString8(mDelegate->mEvent, StrEq(genLayerName(LAYER_ID_1).c_str())));
Tej Singh2a457b62020-01-31 16:16:10 -08001430 EXPECT_EQ(AStatsManager_PULL_SUCCESS,
Alec Mouri37384342020-01-02 17:23:37 -08001431 mDelegate->makePullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO,
1432 mDelegate->mCookie));
1433}
1434
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001435TEST_F(TimeStatsTest, canSurviveMonkey) {
Lloyd Pique067fe1e2018-12-06 19:44:13 -08001436 if (g_noSlowTests) {
1437 GTEST_SKIP();
1438 }
1439
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001440 EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
1441
1442 for (size_t i = 0; i < 10000000; ++i) {
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001443 const int32_t layerId = genRandomInt32(-1, 10);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001444 const int32_t frameNumber = genRandomInt32(1, 10);
1445 switch (genRandomInt32(0, 100)) {
1446 case 0:
1447 ALOGV("removeTimeRecord");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001448 ASSERT_NO_FATAL_FAILURE(mTimeStats->removeTimeRecord(layerId, frameNumber));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001449 continue;
1450 case 1:
1451 ALOGV("onDestroy");
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001452 ASSERT_NO_FATAL_FAILURE(mTimeStats->onDestroy(layerId));
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001453 continue;
1454 }
1455 TimeStamp type = static_cast<TimeStamp>(genRandomInt32(TIME_STAMP_BEGIN, TIME_STAMP_END));
1456 const int32_t ts = genRandomInt32(1, 1000000000);
Yiwei Zhang1a88c402019-11-18 10:43:58 -08001457 ALOGV("type[%d], layerId[%d], frameNumber[%d], ts[%d]", type, layerId, frameNumber, ts);
1458 setTimeStamp(type, layerId, frameNumber, ts);
Yiwei Zhang16faa5d2018-11-13 18:12:59 -08001459 }
1460}
1461
1462} // namespace
1463} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001464
1465// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001466#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"