xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Tracing/LayerTracing.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
18*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "LayerTracing"
19*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include "LayerTracing.h"
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include "LayerDataSource.h"
24*38e8c45fSAndroid Build Coastguard Worker #include "Tracing/tools/LayerTraceGenerator.h"
25*38e8c45fSAndroid Build Coastguard Worker #include "TransactionTracing.h"
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <perfetto/tracing.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker namespace android {
33*38e8c45fSAndroid Build Coastguard Worker 
LayerTracing()34*38e8c45fSAndroid Build Coastguard Worker LayerTracing::LayerTracing() {
35*38e8c45fSAndroid Build Coastguard Worker     mTakeLayersSnapshotProto = [](uint32_t, const OnLayersSnapshotCallback&) {};
36*38e8c45fSAndroid Build Coastguard Worker     LayerDataSource::Initialize(*this);
37*38e8c45fSAndroid Build Coastguard Worker }
38*38e8c45fSAndroid Build Coastguard Worker 
LayerTracing(std::ostream & outStream)39*38e8c45fSAndroid Build Coastguard Worker LayerTracing::LayerTracing(std::ostream& outStream) : LayerTracing() {
40*38e8c45fSAndroid Build Coastguard Worker     mOutStream = std::ref(outStream);
41*38e8c45fSAndroid Build Coastguard Worker }
42*38e8c45fSAndroid Build Coastguard Worker 
~LayerTracing()43*38e8c45fSAndroid Build Coastguard Worker LayerTracing::~LayerTracing() {
44*38e8c45fSAndroid Build Coastguard Worker     LayerDataSource::UnregisterLayerTracing();
45*38e8c45fSAndroid Build Coastguard Worker }
46*38e8c45fSAndroid Build Coastguard Worker 
setTakeLayersSnapshotProtoFunction(const std::function<void (uint32_t,const OnLayersSnapshotCallback &)> & callback)47*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::setTakeLayersSnapshotProtoFunction(
48*38e8c45fSAndroid Build Coastguard Worker         const std::function<void(uint32_t, const OnLayersSnapshotCallback&)>& callback) {
49*38e8c45fSAndroid Build Coastguard Worker     mTakeLayersSnapshotProto = callback;
50*38e8c45fSAndroid Build Coastguard Worker }
51*38e8c45fSAndroid Build Coastguard Worker 
setTransactionTracing(TransactionTracing & transactionTracing)52*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::setTransactionTracing(TransactionTracing& transactionTracing) {
53*38e8c45fSAndroid Build Coastguard Worker     mTransactionTracing = &transactionTracing;
54*38e8c45fSAndroid Build Coastguard Worker }
55*38e8c45fSAndroid Build Coastguard Worker 
onStart(Mode mode,uint32_t flags)56*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::onStart(Mode mode, uint32_t flags) {
57*38e8c45fSAndroid Build Coastguard Worker     switch (mode) {
58*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_ACTIVE: {
59*38e8c45fSAndroid Build Coastguard Worker             mActiveTracingFlags.store(flags);
60*38e8c45fSAndroid Build Coastguard Worker             mIsActiveTracingStarted.store(true);
61*38e8c45fSAndroid Build Coastguard Worker             ALOGV("Starting active tracing (waiting for initial snapshot)");
62*38e8c45fSAndroid Build Coastguard Worker             // It might take a while before a layers change occurs and a "spontaneous" snapshot is
63*38e8c45fSAndroid Build Coastguard Worker             // taken. Let's manually take a snapshot, so that the trace's first entry will contain
64*38e8c45fSAndroid Build Coastguard Worker             // the current layers state.
65*38e8c45fSAndroid Build Coastguard Worker             auto onLayersSnapshot = [this](perfetto::protos::LayersSnapshotProto&& snapshot) {
66*38e8c45fSAndroid Build Coastguard Worker                 addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_ACTIVE);
67*38e8c45fSAndroid Build Coastguard Worker             };
68*38e8c45fSAndroid Build Coastguard Worker             mTakeLayersSnapshotProto(flags, onLayersSnapshot);
69*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Started active tracing (traced initial snapshot)");
70*38e8c45fSAndroid Build Coastguard Worker             break;
71*38e8c45fSAndroid Build Coastguard Worker         }
72*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_GENERATED: {
73*38e8c45fSAndroid Build Coastguard Worker             // This tracing mode processes the buffer of transactions (owned by TransactionTracing),
74*38e8c45fSAndroid Build Coastguard Worker             // generates layers snapshots and writes them to perfetto. This happens every time an
75*38e8c45fSAndroid Build Coastguard Worker             // OnFlush event is received.
76*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Started generated tracing (waiting for OnFlush event to generated layers)");
77*38e8c45fSAndroid Build Coastguard Worker             break;
78*38e8c45fSAndroid Build Coastguard Worker         }
79*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_GENERATED_BUGREPORT_ONLY: {
80*38e8c45fSAndroid Build Coastguard Worker             // Same as MODE_GENERATED, but only when the received OnFlush event is due to a
81*38e8c45fSAndroid Build Coastguard Worker             // bugreport being taken. This mode exists because the generated layers trace is very
82*38e8c45fSAndroid Build Coastguard Worker             // large (hundreds of MB), hence we want to include it only in bugreports and not in
83*38e8c45fSAndroid Build Coastguard Worker             // field uploads.
84*38e8c45fSAndroid Build Coastguard Worker             //
85*38e8c45fSAndroid Build Coastguard Worker             // Note that perfetto communicates only whether the OnFlush event is due to a bugreport
86*38e8c45fSAndroid Build Coastguard Worker             // or not, hence we need an additional "bugreport only" tracing mode.
87*38e8c45fSAndroid Build Coastguard Worker             // If perfetto had communicated when the OnFlush is due to a field upload, then we could
88*38e8c45fSAndroid Build Coastguard Worker             // have had a single "generated" tracing mode that would have been a noop in case of
89*38e8c45fSAndroid Build Coastguard Worker             // field uploads.
90*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Started 'generated bugreport only' tracing"
91*38e8c45fSAndroid Build Coastguard Worker                   " (waiting for bugreport's OnFlush event to generate layers)");
92*38e8c45fSAndroid Build Coastguard Worker             break;
93*38e8c45fSAndroid Build Coastguard Worker         }
94*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_DUMP: {
95*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Started dump tracing");
96*38e8c45fSAndroid Build Coastguard Worker             break;
97*38e8c45fSAndroid Build Coastguard Worker         }
98*38e8c45fSAndroid Build Coastguard Worker         default: {
99*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Started unknown tracing mode (0x%02x)", mode);
100*38e8c45fSAndroid Build Coastguard Worker         }
101*38e8c45fSAndroid Build Coastguard Worker     }
102*38e8c45fSAndroid Build Coastguard Worker }
103*38e8c45fSAndroid Build Coastguard Worker 
onFlush(Mode mode,uint32_t flags,bool isBugreport)104*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::onFlush(Mode mode, uint32_t flags, bool isBugreport) {
105*38e8c45fSAndroid Build Coastguard Worker     // In "generated" mode process the buffer of transactions (owned by TransactionTracing),
106*38e8c45fSAndroid Build Coastguard Worker     // generate layers snapshots and write them to perfetto.
107*38e8c45fSAndroid Build Coastguard Worker     if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
108*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Skipping layers trace generation (not a 'generated' tracing session)");
109*38e8c45fSAndroid Build Coastguard Worker         return;
110*38e8c45fSAndroid Build Coastguard Worker     }
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker     // In "generated bugreport only" mode skip the layers snapshot generation
113*38e8c45fSAndroid Build Coastguard Worker     // if the perfetto's OnFlush event is not due to a bugreport being taken.
114*38e8c45fSAndroid Build Coastguard Worker     if (mode == Mode::MODE_GENERATED_BUGREPORT_ONLY && !isBugreport) {
115*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Skipping layers trace generation (not a bugreport OnFlush event)");
116*38e8c45fSAndroid Build Coastguard Worker         return;
117*38e8c45fSAndroid Build Coastguard Worker     }
118*38e8c45fSAndroid Build Coastguard Worker 
119*38e8c45fSAndroid Build Coastguard Worker     if (!mTransactionTracing) {
120*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Skipping layers trace generation (transactions tracing disabled)");
121*38e8c45fSAndroid Build Coastguard Worker         return;
122*38e8c45fSAndroid Build Coastguard Worker     }
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker     auto transactionTrace = mTransactionTracing->writeToProto();
125*38e8c45fSAndroid Build Coastguard Worker     LayerTraceGenerator{}.generate(transactionTrace, flags, *this);
126*38e8c45fSAndroid Build Coastguard Worker     ALOGD("Flushed generated tracing");
127*38e8c45fSAndroid Build Coastguard Worker }
128*38e8c45fSAndroid Build Coastguard Worker 
onStop(Mode mode,uint32_t flags,std::function<void ()> && deferredStopDone)129*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::onStop(Mode mode, uint32_t flags, std::function<void()>&& deferredStopDone) {
130*38e8c45fSAndroid Build Coastguard Worker     switch (mode) {
131*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_ACTIVE: {
132*38e8c45fSAndroid Build Coastguard Worker             mIsActiveTracingStarted.store(false);
133*38e8c45fSAndroid Build Coastguard Worker             deferredStopDone();
134*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Stopped active tracing");
135*38e8c45fSAndroid Build Coastguard Worker             break;
136*38e8c45fSAndroid Build Coastguard Worker         }
137*38e8c45fSAndroid Build Coastguard Worker         case Mode::MODE_DUMP: {
138*38e8c45fSAndroid Build Coastguard Worker             auto onLayersSnapshot = [this, deferredStopDone = std::move(deferredStopDone)](
139*38e8c45fSAndroid Build Coastguard Worker                                             perfetto::protos::LayersSnapshotProto&& snapshot) {
140*38e8c45fSAndroid Build Coastguard Worker                 addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP);
141*38e8c45fSAndroid Build Coastguard Worker                 deferredStopDone();
142*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Stopped dump tracing (written single snapshot)");
143*38e8c45fSAndroid Build Coastguard Worker             };
144*38e8c45fSAndroid Build Coastguard Worker             mTakeLayersSnapshotProto(flags, onLayersSnapshot);
145*38e8c45fSAndroid Build Coastguard Worker             break;
146*38e8c45fSAndroid Build Coastguard Worker         }
147*38e8c45fSAndroid Build Coastguard Worker         default: {
148*38e8c45fSAndroid Build Coastguard Worker             deferredStopDone();
149*38e8c45fSAndroid Build Coastguard Worker         }
150*38e8c45fSAndroid Build Coastguard Worker     }
151*38e8c45fSAndroid Build Coastguard Worker }
152*38e8c45fSAndroid Build Coastguard Worker 
addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto && snapshot,Mode mode)153*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot,
154*38e8c45fSAndroid Build Coastguard Worker                                              Mode mode) {
155*38e8c45fSAndroid Build Coastguard Worker     SFTRACE_CALL();
156*38e8c45fSAndroid Build Coastguard Worker     if (mOutStream) {
157*38e8c45fSAndroid Build Coastguard Worker         writeSnapshotToStream(std::move(snapshot));
158*38e8c45fSAndroid Build Coastguard Worker     } else {
159*38e8c45fSAndroid Build Coastguard Worker         writeSnapshotToPerfetto(snapshot, mode);
160*38e8c45fSAndroid Build Coastguard Worker     }
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker 
isActiveTracingStarted() const163*38e8c45fSAndroid Build Coastguard Worker bool LayerTracing::isActiveTracingStarted() const {
164*38e8c45fSAndroid Build Coastguard Worker     return mIsActiveTracingStarted.load();
165*38e8c45fSAndroid Build Coastguard Worker }
166*38e8c45fSAndroid Build Coastguard Worker 
getActiveTracingFlags() const167*38e8c45fSAndroid Build Coastguard Worker uint32_t LayerTracing::getActiveTracingFlags() const {
168*38e8c45fSAndroid Build Coastguard Worker     return mActiveTracingFlags.load();
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker 
isActiveTracingFlagSet(Flag flag) const171*38e8c45fSAndroid Build Coastguard Worker bool LayerTracing::isActiveTracingFlagSet(Flag flag) const {
172*38e8c45fSAndroid Build Coastguard Worker     return (mActiveTracingFlags.load() & flag) != 0;
173*38e8c45fSAndroid Build Coastguard Worker }
174*38e8c45fSAndroid Build Coastguard Worker 
createTraceFileProto()175*38e8c45fSAndroid Build Coastguard Worker perfetto::protos::LayersTraceFileProto LayerTracing::createTraceFileProto() {
176*38e8c45fSAndroid Build Coastguard Worker     perfetto::protos::LayersTraceFileProto fileProto;
177*38e8c45fSAndroid Build Coastguard Worker     fileProto.set_magic_number(
178*38e8c45fSAndroid Build Coastguard Worker             static_cast<uint64_t>(perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H)
179*38e8c45fSAndroid Build Coastguard Worker                     << 32 |
180*38e8c45fSAndroid Build Coastguard Worker             perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
181*38e8c45fSAndroid Build Coastguard Worker     auto timeOffsetNs = static_cast<uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
182*38e8c45fSAndroid Build Coastguard Worker                                               systemTime(SYSTEM_TIME_MONOTONIC));
183*38e8c45fSAndroid Build Coastguard Worker     fileProto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);
184*38e8c45fSAndroid Build Coastguard Worker     return fileProto;
185*38e8c45fSAndroid Build Coastguard Worker }
186*38e8c45fSAndroid Build Coastguard Worker 
writeSnapshotToStream(perfetto::protos::LayersSnapshotProto && snapshot) const187*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& snapshot) const {
188*38e8c45fSAndroid Build Coastguard Worker     auto fileProto = createTraceFileProto();
189*38e8c45fSAndroid Build Coastguard Worker     *fileProto.add_entry() = std::move(snapshot);
190*38e8c45fSAndroid Build Coastguard Worker     mOutStream->get() << fileProto.SerializeAsString();
191*38e8c45fSAndroid Build Coastguard Worker }
192*38e8c45fSAndroid Build Coastguard Worker 
writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto & snapshot,Mode srcMode)193*38e8c45fSAndroid Build Coastguard Worker void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot,
194*38e8c45fSAndroid Build Coastguard Worker                                            Mode srcMode) {
195*38e8c45fSAndroid Build Coastguard Worker     const auto snapshotBytes = snapshot.SerializeAsString();
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     LayerDataSource::Trace([&](LayerDataSource::TraceContext context) {
198*38e8c45fSAndroid Build Coastguard Worker         auto dstMode = context.GetCustomTlsState()->mMode;
199*38e8c45fSAndroid Build Coastguard Worker         if (srcMode == Mode::MODE_GENERATED) {
200*38e8c45fSAndroid Build Coastguard Worker             // Layers snapshots produced by LayerTraceGenerator have srcMode == MODE_GENERATED
201*38e8c45fSAndroid Build Coastguard Worker             // and should be written to tracing sessions with MODE_GENERATED
202*38e8c45fSAndroid Build Coastguard Worker             // or MODE_GENERATED_BUGREPORT_ONLY.
203*38e8c45fSAndroid Build Coastguard Worker             if (dstMode != Mode::MODE_GENERATED && dstMode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
204*38e8c45fSAndroid Build Coastguard Worker                 return;
205*38e8c45fSAndroid Build Coastguard Worker             }
206*38e8c45fSAndroid Build Coastguard Worker         } else if (srcMode != dstMode) {
207*38e8c45fSAndroid Build Coastguard Worker             return;
208*38e8c45fSAndroid Build Coastguard Worker         }
209*38e8c45fSAndroid Build Coastguard Worker 
210*38e8c45fSAndroid Build Coastguard Worker         if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(srcMode, snapshot.vsync_id())) {
211*38e8c45fSAndroid Build Coastguard Worker             return;
212*38e8c45fSAndroid Build Coastguard Worker         }
213*38e8c45fSAndroid Build Coastguard Worker         {
214*38e8c45fSAndroid Build Coastguard Worker             auto packet = context.NewTracePacket();
215*38e8c45fSAndroid Build Coastguard Worker             packet->set_timestamp(static_cast<uint64_t>(snapshot.elapsed_realtime_nanos()));
216*38e8c45fSAndroid Build Coastguard Worker             packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
217*38e8c45fSAndroid Build Coastguard Worker             auto* snapshotProto = packet->set_surfaceflinger_layers_snapshot();
218*38e8c45fSAndroid Build Coastguard Worker             snapshotProto->AppendRawProtoBytes(snapshotBytes.data(), snapshotBytes.size());
219*38e8c45fSAndroid Build Coastguard Worker         }
220*38e8c45fSAndroid Build Coastguard Worker         {
221*38e8c45fSAndroid Build Coastguard Worker             // TODO (b/162206162): remove empty packet when perfetto bug is fixed.
222*38e8c45fSAndroid Build Coastguard Worker             //  It is currently needed in order not to lose the last trace entry.
223*38e8c45fSAndroid Build Coastguard Worker             context.NewTracePacket();
224*38e8c45fSAndroid Build Coastguard Worker         }
225*38e8c45fSAndroid Build Coastguard Worker     });
226*38e8c45fSAndroid Build Coastguard Worker }
227*38e8c45fSAndroid Build Coastguard Worker 
checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode,std::int64_t vsyncId)228*38e8c45fSAndroid Build Coastguard Worker bool LayerTracing::checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::int64_t vsyncId) {
229*38e8c45fSAndroid Build Coastguard Worker     // In some situations (e.g. two bugreports taken shortly one after the other) the generated
230*38e8c45fSAndroid Build Coastguard Worker     // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make
231*38e8c45fSAndroid Build Coastguard Worker     // sure that in generated tracing mode a given snapshot is written only once to perfetto.
232*38e8c45fSAndroid Build Coastguard Worker     if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
233*38e8c45fSAndroid Build Coastguard Worker         return true;
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker 
236*38e8c45fSAndroid Build Coastguard Worker     auto lastVsyncId = mLastVsyncIdWrittenToPerfetto.load();
237*38e8c45fSAndroid Build Coastguard Worker     while (lastVsyncId < vsyncId) {
238*38e8c45fSAndroid Build Coastguard Worker         if (mLastVsyncIdWrittenToPerfetto.compare_exchange_strong(lastVsyncId, vsyncId)) {
239*38e8c45fSAndroid Build Coastguard Worker             return true;
240*38e8c45fSAndroid Build Coastguard Worker         }
241*38e8c45fSAndroid Build Coastguard Worker     }
242*38e8c45fSAndroid Build Coastguard Worker 
243*38e8c45fSAndroid Build Coastguard Worker     return false;
244*38e8c45fSAndroid Build Coastguard Worker }
245*38e8c45fSAndroid Build Coastguard Worker 
246*38e8c45fSAndroid Build Coastguard Worker } // namespace android
247