blob: 7981224b5c31323a727e8d77c4f88d587aea38ad [file] [log] [blame]
Vishnu Nair7891e962021-11-11 12:07:21 -08001/*
2 * Copyright 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 <gui/SurfaceComposerClient.h>
Vishnu Nair81750622023-03-08 15:02:06 -080021#include <cstdint>
22#include "Client.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080023
Vishnu Naircb565332023-03-14 21:10:55 -070024#include <layerproto/LayerProtoHeader.h>
Vishnu Nair81750622023-03-08 15:02:06 -080025#include "FrontEnd/LayerCreationArgs.h"
26#include "FrontEnd/Update.h"
Vishnu Naircb565332023-03-14 21:10:55 -070027#include "Tracing/LayerTracing.h"
Vishnu Nair7891e962021-11-11 12:07:21 -080028#include "Tracing/TransactionTracing.h"
29
30using namespace android::surfaceflinger;
31
32namespace android {
33
34class TransactionTracingTest : public testing::Test {
35protected:
Vishnu Nair0cc69e12021-11-18 09:05:49 -080036 static constexpr size_t SMALL_BUFFER_SIZE = 1024;
Dominik Laskowski46471e62022-01-14 15:34:03 -080037 TransactionTracing mTracing;
Vishnu Nair7891e962021-11-11 12:07:21 -080038
Vishnu Naird1f74982023-06-15 20:16:51 -070039 void flush() { mTracing.flush(); }
Kean Mariotti4ba343c2023-04-19 13:31:02 +000040 perfetto::protos::TransactionTraceFile writeToProto() { return mTracing.writeToProto(); }
Vishnu Nair7891e962021-11-11 12:07:21 -080041
Kean Mariotti4ba343c2023-04-19 13:31:02 +000042 perfetto::protos::TransactionTraceEntry bufferFront() {
Dominik Laskowski46471e62022-01-14 15:34:03 -080043 std::scoped_lock<std::mutex> lock(mTracing.mTraceLock);
Kean Mariotti4ba343c2023-04-19 13:31:02 +000044 perfetto::protos::TransactionTraceEntry entry;
Dominik Laskowski46471e62022-01-14 15:34:03 -080045 entry.ParseFromString(mTracing.mBuffer.front());
Vishnu Nair62863552021-12-10 13:34:48 -080046 return entry;
Vishnu Nair7891e962021-11-11 12:07:21 -080047 }
48
Vishnu Nair0cc69e12021-11-18 09:05:49 -080049 void queueAndCommitTransaction(int64_t vsyncId) {
Vishnu Nair81750622023-03-08 15:02:06 -080050 frontend::Update update;
Vishnu Nair0cc69e12021-11-18 09:05:49 -080051 TransactionState transaction;
52 transaction.id = static_cast<uint64_t>(vsyncId * 3);
53 transaction.originUid = 1;
54 transaction.originPid = 2;
Dominik Laskowski46471e62022-01-14 15:34:03 -080055 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -080056 std::vector<TransactionState> transactions;
Vishnu Nair81750622023-03-08 15:02:06 -080057 update.transactions.emplace_back(transaction);
58 mTracing.addCommittedTransactions(vsyncId, 0, update, {}, false);
Vishnu Naird1f74982023-06-15 20:16:51 -070059 flush();
Vishnu Nair7891e962021-11-11 12:07:21 -080060 }
61
Kean Mariotti4ba343c2023-04-19 13:31:02 +000062 void verifyEntry(const perfetto::protos::TransactionTraceEntry& actualProto,
Dominik Laskowski46471e62022-01-14 15:34:03 -080063 const std::vector<TransactionState>& expectedTransactions,
Vishnu Nair7891e962021-11-11 12:07:21 -080064 int64_t expectedVsyncId) {
65 EXPECT_EQ(actualProto.vsync_id(), expectedVsyncId);
Vishnu Nair81750622023-03-08 15:02:06 -080066 ASSERT_EQ(actualProto.transactions().size(),
Vishnu Nair7891e962021-11-11 12:07:21 -080067 static_cast<int32_t>(expectedTransactions.size()));
68 for (uint32_t i = 0; i < expectedTransactions.size(); i++) {
Pablo Gamito23780be2023-04-18 08:30:00 +000069 const auto expectedTransaction = expectedTransactions[i];
70 const auto protoTransaction = actualProto.transactions(static_cast<int32_t>(i));
71 EXPECT_EQ(protoTransaction.transaction_id(), expectedTransaction.id);
72 EXPECT_EQ(protoTransaction.pid(), expectedTransaction.originPid);
73 for (uint32_t i = 0; i < expectedTransaction.mergedTransactionIds.size(); i++) {
74 EXPECT_EQ(protoTransaction.merged_transaction_ids(static_cast<int32_t>(i)),
75 expectedTransaction.mergedTransactionIds[i]);
76 }
Vishnu Nair7891e962021-11-11 12:07:21 -080077 }
78 }
Vishnu Nair81750622023-03-08 15:02:06 -080079
80 LayerCreationArgs getLayerCreationArgs(uint32_t layerId, uint32_t parentId,
81 uint32_t layerIdToMirror, uint32_t flags,
82 bool addToRoot) {
83 LayerCreationArgs args;
84 args.sequence = layerId;
85 args.parentId = parentId;
86 args.layerIdToMirror = layerIdToMirror;
87 args.flags = flags;
88 args.addToRoot = addToRoot;
89 return args;
90 }
Vishnu Nair7891e962021-11-11 12:07:21 -080091};
92
Vishnu Nair7891e962021-11-11 12:07:21 -080093TEST_F(TransactionTracingTest, addTransactions) {
Vishnu Nair7891e962021-11-11 12:07:21 -080094 std::vector<TransactionState> transactions;
95 transactions.reserve(100);
96 for (uint64_t i = 0; i < 100; i++) {
97 TransactionState transaction;
98 transaction.id = i;
99 transaction.originPid = static_cast<int32_t>(i);
Pablo Gamito23780be2023-04-18 08:30:00 +0000100 transaction.mergedTransactionIds = std::vector<uint64_t>{i + 100, i + 102};
Vishnu Nair7891e962021-11-11 12:07:21 -0800101 transactions.emplace_back(transaction);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800102 mTracing.addQueuedTransaction(transaction);
Vishnu Nair7891e962021-11-11 12:07:21 -0800103 }
104
105 // Split incoming transactions into two and commit them in reverse order to test out of order
106 // commits.
Vishnu Nair7891e962021-11-11 12:07:21 -0800107 int64_t firstTransactionSetVsyncId = 42;
Vishnu Nair81750622023-03-08 15:02:06 -0800108 frontend::Update firstUpdate;
109 firstUpdate.transactions =
110 std::vector<TransactionState>(transactions.begin() + 50, transactions.end());
111 mTracing.addCommittedTransactions(firstTransactionSetVsyncId, 0, firstUpdate, {}, false);
Vishnu Nair7891e962021-11-11 12:07:21 -0800112
113 int64_t secondTransactionSetVsyncId = 43;
Vishnu Nair81750622023-03-08 15:02:06 -0800114 frontend::Update secondUpdate;
115 secondUpdate.transactions =
Vishnu Nair7891e962021-11-11 12:07:21 -0800116 std::vector<TransactionState>(transactions.begin(), transactions.begin() + 50);
Vishnu Nair81750622023-03-08 15:02:06 -0800117 mTracing.addCommittedTransactions(secondTransactionSetVsyncId, 0, secondUpdate, {}, false);
Vishnu Naird1f74982023-06-15 20:16:51 -0700118 flush();
Vishnu Nair7891e962021-11-11 12:07:21 -0800119
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000120 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair81750622023-03-08 15:02:06 -0800121 ASSERT_EQ(proto.entry().size(), 2);
122 verifyEntry(proto.entry(0), firstUpdate.transactions, firstTransactionSetVsyncId);
123 verifyEntry(proto.entry(1), secondUpdate.transactions, secondTransactionSetVsyncId);
Vishnu Nair7891e962021-11-11 12:07:21 -0800124}
125
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800126class TransactionTracingLayerHandlingTest : public TransactionTracingTest {
127protected:
128 void SetUp() override {
Dominik Laskowski46471e62022-01-14 15:34:03 -0800129 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800130
Vishnu Nair81750622023-03-08 15:02:06 -0800131 // add layers and add some layer transaction
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800132 {
Vishnu Nair81750622023-03-08 15:02:06 -0800133 frontend::Update update;
134 update.layerCreationArgs.emplace_back(std::move(
135 getLayerCreationArgs(mParentLayerId, /*parentId=*/UNASSIGNED_LAYER_ID,
136 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/123,
137 /*addToRoot=*/true)));
138 update.layerCreationArgs.emplace_back(std::move(
139 getLayerCreationArgs(mChildLayerId, mParentLayerId,
140 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/456,
141 /*addToRoot=*/true)));
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800142 TransactionState transaction;
143 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000144 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800145 layerState.layerId = mParentLayerId;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800146 layerState.state.what = layer_state_t::eLayerChanged;
147 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000148 transaction.states.emplace_back(layerState);
149 ResolvedComposerState childState;
Vishnu Nair81750622023-03-08 15:02:06 -0800150 childState.layerId = mChildLayerId;
Vishnu Nair473838d2021-12-08 09:46:02 -0800151 childState.state.what = layer_state_t::eLayerChanged;
152 childState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000153 transaction.states.emplace_back(childState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800154 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800155
Vishnu Nair81750622023-03-08 15:02:06 -0800156 update.transactions.emplace_back(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800157 VSYNC_ID_FIRST_LAYER_CHANGE = ++mVsyncId;
Vishnu Nair81750622023-03-08 15:02:06 -0800158 mTracing.addCommittedTransactions(VSYNC_ID_FIRST_LAYER_CHANGE, 0, update, {}, false);
159
Vishnu Naird1f74982023-06-15 20:16:51 -0700160 flush();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800161 }
162
163 // add transactions that modify the layer state further so we can test that layer state
164 // gets merged
165 {
166 TransactionState transaction;
167 transaction.id = 51;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000168 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800169 layerState.layerId = mParentLayerId;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800170 layerState.state.what = layer_state_t::eLayerChanged | layer_state_t::ePositionChanged;
171 layerState.state.z = 41;
172 layerState.state.x = 22;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000173 transaction.states.emplace_back(layerState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800174 mTracing.addQueuedTransaction(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800175
Vishnu Nair81750622023-03-08 15:02:06 -0800176 frontend::Update update;
177 update.transactions.emplace_back(transaction);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800178 VSYNC_ID_SECOND_LAYER_CHANGE = ++mVsyncId;
Vishnu Nair81750622023-03-08 15:02:06 -0800179 mTracing.addCommittedTransactions(VSYNC_ID_SECOND_LAYER_CHANGE, 0, update, {}, false);
Vishnu Naird1f74982023-06-15 20:16:51 -0700180 flush();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800181 }
182
183 // remove child layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800184 mTracing.onLayerRemoved(2);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800185 VSYNC_ID_CHILD_LAYER_REMOVED = ++mVsyncId;
186 queueAndCommitTransaction(VSYNC_ID_CHILD_LAYER_REMOVED);
187
188 // remove layer
Dominik Laskowski46471e62022-01-14 15:34:03 -0800189 mTracing.onLayerRemoved(1);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800190 queueAndCommitTransaction(++mVsyncId);
191 }
192
Vishnu Nair81750622023-03-08 15:02:06 -0800193 uint32_t mParentLayerId = 1;
194 uint32_t mChildLayerId = 2;
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800195 int64_t mVsyncId = 0;
196 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
197 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
198 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
199};
200
201TEST_F(TransactionTracingLayerHandlingTest, addStartingState) {
202 // add transactions until we drop the transaction with the first layer change
203 while (bufferFront().vsync_id() <= VSYNC_ID_FIRST_LAYER_CHANGE) {
204 queueAndCommitTransaction(++mVsyncId);
205 }
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000206 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800207 // verify we can still retrieve the layer change from the first entry containing starting
208 // states.
209 EXPECT_GT(proto.entry().size(), 0);
Vishnu Nair685cfef2022-02-02 10:01:25 -0800210 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
211 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
Vishnu Nair473838d2021-12-08 09:46:02 -0800212 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
213 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800214 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 42);
Vishnu Nair473838d2021-12-08 09:46:02 -0800215 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).layer_id(), mChildLayerId);
216 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800217}
218
219TEST_F(TransactionTracingLayerHandlingTest, updateStartingState) {
220 // add transactions until we drop the transaction with the second layer change
221 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
222 queueAndCommitTransaction(++mVsyncId);
223 }
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000224 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800225 // verify starting states are updated correctly
226 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 41);
227}
228
229TEST_F(TransactionTracingLayerHandlingTest, removeStartingState) {
230 // add transactions until we drop the transaction which removes the child layer
231 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
232 queueAndCommitTransaction(++mVsyncId);
233 }
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000234 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800235 // verify the child layer has been removed from the trace
236 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);
237 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
238}
239
240TEST_F(TransactionTracingLayerHandlingTest, startingStateSurvivesBufferFlush) {
241 // add transactions until we drop the transaction with the second layer change
242 while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {
243 queueAndCommitTransaction(++mVsyncId);
244 }
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000245 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair0cc69e12021-11-18 09:05:49 -0800246 // verify we have two starting states
247 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
248
249 // Continue adding transactions until child layer is removed
250 while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {
251 queueAndCommitTransaction(++mVsyncId);
252 }
253 proto = writeToProto();
254 // verify we still have the parent layer state
255 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);
256 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
257}
258
Vishnu Nair84125ac2021-12-02 08:47:48 -0800259class TransactionTracingMirrorLayerTest : public TransactionTracingTest {
260protected:
261 void SetUp() override {
Dominik Laskowski46471e62022-01-14 15:34:03 -0800262 mTracing.setBufferSize(SMALL_BUFFER_SIZE);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800263
Vishnu Nair81750622023-03-08 15:02:06 -0800264 // add layers and some layer transaction
Vishnu Nair84125ac2021-12-02 08:47:48 -0800265 {
Vishnu Nair81750622023-03-08 15:02:06 -0800266 frontend::Update update;
267 update.layerCreationArgs.emplace_back(
268 getLayerCreationArgs(mLayerId, /*parentId=*/UNASSIGNED_LAYER_ID,
269 /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/123,
270 /*addToRoot=*/true));
271 update.layerCreationArgs.emplace_back(
272 getLayerCreationArgs(mMirrorLayerId, UNASSIGNED_LAYER_ID,
273 /*layerIdToMirror=*/mLayerId, /*flags=*/0,
274 /*addToRoot=*/false));
275
Vishnu Nair84125ac2021-12-02 08:47:48 -0800276 TransactionState transaction;
277 transaction.id = 50;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000278 ResolvedComposerState layerState;
Vishnu Nair81750622023-03-08 15:02:06 -0800279 layerState.layerId = mLayerId;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800280 layerState.state.what = layer_state_t::eLayerChanged;
281 layerState.state.z = 42;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000282 transaction.states.emplace_back(layerState);
283 ResolvedComposerState mirrorState;
Vishnu Nair81750622023-03-08 15:02:06 -0800284 mirrorState.layerId = mMirrorLayerId;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800285 mirrorState.state.what = layer_state_t::eLayerChanged;
286 mirrorState.state.z = 43;
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000287 transaction.states.emplace_back(mirrorState);
Dominik Laskowski46471e62022-01-14 15:34:03 -0800288 mTracing.addQueuedTransaction(transaction);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800289
Vishnu Nair81750622023-03-08 15:02:06 -0800290 update.transactions.emplace_back(transaction);
291 mTracing.addCommittedTransactions(mVsyncId, 0, update, {}, false);
Vishnu Naird1f74982023-06-15 20:16:51 -0700292 flush();
Vishnu Nair84125ac2021-12-02 08:47:48 -0800293 }
294 }
295
Vishnu Nair81750622023-03-08 15:02:06 -0800296 uint32_t mLayerId = 5;
297 uint32_t mMirrorLayerId = 55;
Vishnu Nair84125ac2021-12-02 08:47:48 -0800298 int64_t mVsyncId = 0;
299 int64_t VSYNC_ID_FIRST_LAYER_CHANGE;
300 int64_t VSYNC_ID_SECOND_LAYER_CHANGE;
301 int64_t VSYNC_ID_CHILD_LAYER_REMOVED;
302};
303
304TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000305 perfetto::protos::TransactionTraceFile proto = writeToProto();
Vishnu Nair84125ac2021-12-02 08:47:48 -0800306 // We don't have any starting states since no layer was removed from.
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800307 EXPECT_EQ(proto.entry().size(), 1);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800308
309 // Verify the mirror layer was added
Vishnu Nairb8f2a2d2022-01-13 08:10:10 -0800310 EXPECT_EQ(proto.entry(0).transactions().size(), 1);
311 EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
312 EXPECT_EQ(proto.entry(0).added_layers(1).layer_id(), mMirrorLayerId);
313 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
314 EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
Vishnu Nair84125ac2021-12-02 08:47:48 -0800315}
Vishnu Naircb565332023-03-14 21:10:55 -0700316
317// Verify we can write the layers traces by entry to reduce mem pressure
318// on the system when generating large traces.
319TEST(LayerTraceTest, canStreamLayersTrace) {
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000320 perfetto::protos::LayersTraceFileProto inProto = LayerTracing::createTraceFileProto();
Vishnu Naircb565332023-03-14 21:10:55 -0700321 inProto.add_entry();
322 inProto.add_entry();
323
324 std::string output;
325 inProto.SerializeToString(&output);
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000326 perfetto::protos::LayersTraceFileProto inProto2 = LayerTracing::createTraceFileProto();
Vishnu Naircb565332023-03-14 21:10:55 -0700327 inProto2.add_entry();
328 std::string output2;
329 inProto2.SerializeToString(&output2);
330
Kean Mariotti4ba343c2023-04-19 13:31:02 +0000331 perfetto::protos::LayersTraceFileProto outProto;
Vishnu Naircb565332023-03-14 21:10:55 -0700332 outProto.ParseFromString(output + output2);
333 // magic?
334 EXPECT_EQ(outProto.entry().size(), 3);
335}
Vishnu Nair7891e962021-11-11 12:07:21 -0800336} // namespace android