xref: /aosp_15_r20/frameworks/native/services/gpuservice/gpustats/GpuStats.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 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 #undef LOG_TAG
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "GpuStats"
18*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include "gpustats/GpuStats.h"
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <android/util/ProtoOutputStream.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <stats_event.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <statslog.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker #include <unordered_set>
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker namespace android {
32*38e8c45fSAndroid Build Coastguard Worker 
~GpuStats()33*38e8c45fSAndroid Build Coastguard Worker GpuStats::~GpuStats() {
34*38e8c45fSAndroid Build Coastguard Worker     if (mStatsdRegistered) {
35*38e8c45fSAndroid Build Coastguard Worker         AStatsManager_clearPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO);
36*38e8c45fSAndroid Build Coastguard Worker         AStatsManager_clearPullAtomCallback(android::util::GPU_STATS_APP_INFO);
37*38e8c45fSAndroid Build Coastguard Worker     }
38*38e8c45fSAndroid Build Coastguard Worker }
39*38e8c45fSAndroid Build Coastguard Worker 
addLoadingCount(GpuStatsInfo::Driver driver,bool isDriverLoaded,GpuStatsGlobalInfo * const outGlobalInfo)40*38e8c45fSAndroid Build Coastguard Worker static void addLoadingCount(GpuStatsInfo::Driver driver, bool isDriverLoaded,
41*38e8c45fSAndroid Build Coastguard Worker                             GpuStatsGlobalInfo* const outGlobalInfo) {
42*38e8c45fSAndroid Build Coastguard Worker     switch (driver) {
43*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::GL:
44*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::GL_UPDATED:
45*38e8c45fSAndroid Build Coastguard Worker             outGlobalInfo->glLoadingCount++;
46*38e8c45fSAndroid Build Coastguard Worker             if (!isDriverLoaded) outGlobalInfo->glLoadingFailureCount++;
47*38e8c45fSAndroid Build Coastguard Worker             break;
48*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::VULKAN:
49*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::VULKAN_UPDATED:
50*38e8c45fSAndroid Build Coastguard Worker             outGlobalInfo->vkLoadingCount++;
51*38e8c45fSAndroid Build Coastguard Worker             if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
52*38e8c45fSAndroid Build Coastguard Worker             break;
53*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::ANGLE:
54*38e8c45fSAndroid Build Coastguard Worker             outGlobalInfo->angleLoadingCount++;
55*38e8c45fSAndroid Build Coastguard Worker             if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
56*38e8c45fSAndroid Build Coastguard Worker             break;
57*38e8c45fSAndroid Build Coastguard Worker         default:
58*38e8c45fSAndroid Build Coastguard Worker             break;
59*38e8c45fSAndroid Build Coastguard Worker     }
60*38e8c45fSAndroid Build Coastguard Worker }
61*38e8c45fSAndroid Build Coastguard Worker 
addLoadingTime(GpuStatsInfo::Driver driver,int64_t driverLoadingTime,GpuStatsAppInfo * const outAppInfo)62*38e8c45fSAndroid Build Coastguard Worker static void addLoadingTime(GpuStatsInfo::Driver driver, int64_t driverLoadingTime,
63*38e8c45fSAndroid Build Coastguard Worker                            GpuStatsAppInfo* const outAppInfo) {
64*38e8c45fSAndroid Build Coastguard Worker     switch (driver) {
65*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::GL:
66*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::GL_UPDATED:
67*38e8c45fSAndroid Build Coastguard Worker             if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
68*38e8c45fSAndroid Build Coastguard Worker                 outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
69*38e8c45fSAndroid Build Coastguard Worker             }
70*38e8c45fSAndroid Build Coastguard Worker             break;
71*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::VULKAN:
72*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::VULKAN_UPDATED:
73*38e8c45fSAndroid Build Coastguard Worker             if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
74*38e8c45fSAndroid Build Coastguard Worker                 outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
75*38e8c45fSAndroid Build Coastguard Worker             }
76*38e8c45fSAndroid Build Coastguard Worker             break;
77*38e8c45fSAndroid Build Coastguard Worker         case GpuStatsInfo::Driver::ANGLE:
78*38e8c45fSAndroid Build Coastguard Worker             if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
79*38e8c45fSAndroid Build Coastguard Worker                 outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
80*38e8c45fSAndroid Build Coastguard Worker             }
81*38e8c45fSAndroid Build Coastguard Worker             break;
82*38e8c45fSAndroid Build Coastguard Worker         default:
83*38e8c45fSAndroid Build Coastguard Worker             break;
84*38e8c45fSAndroid Build Coastguard Worker     }
85*38e8c45fSAndroid Build Coastguard Worker }
86*38e8c45fSAndroid Build Coastguard Worker 
purgeOldDriverStats()87*38e8c45fSAndroid Build Coastguard Worker void GpuStats::purgeOldDriverStats() {
88*38e8c45fSAndroid Build Coastguard Worker     ALOG_ASSERT(mAppStats.size() == MAX_NUM_APP_RECORDS);
89*38e8c45fSAndroid Build Coastguard Worker 
90*38e8c45fSAndroid Build Coastguard Worker     struct GpuStatsApp {
91*38e8c45fSAndroid Build Coastguard Worker         // Key is <app package name>+<driver version code>.
92*38e8c45fSAndroid Build Coastguard Worker         const std::string *appStatsKey = nullptr;
93*38e8c45fSAndroid Build Coastguard Worker         const std::chrono::time_point<std::chrono::system_clock> *lastAccessTime = nullptr;
94*38e8c45fSAndroid Build Coastguard Worker     };
95*38e8c45fSAndroid Build Coastguard Worker     std::vector<GpuStatsApp> gpuStatsApps(MAX_NUM_APP_RECORDS);
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     // Create a list of pointers to package names and their last access times.
98*38e8c45fSAndroid Build Coastguard Worker     int index = 0;
99*38e8c45fSAndroid Build Coastguard Worker     for (const auto & [appStatsKey, gpuStatsAppInfo] : mAppStats) {
100*38e8c45fSAndroid Build Coastguard Worker         GpuStatsApp &gpuStatsApp = gpuStatsApps[index];
101*38e8c45fSAndroid Build Coastguard Worker         gpuStatsApp.appStatsKey = &appStatsKey;
102*38e8c45fSAndroid Build Coastguard Worker         gpuStatsApp.lastAccessTime = &gpuStatsAppInfo.lastAccessTime;
103*38e8c45fSAndroid Build Coastguard Worker         ++index;
104*38e8c45fSAndroid Build Coastguard Worker     }
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker     // Sort the list with the oldest access times at the front.
107*38e8c45fSAndroid Build Coastguard Worker     std::sort(gpuStatsApps.begin(), gpuStatsApps.end(), [](GpuStatsApp a, GpuStatsApp b) -> bool {
108*38e8c45fSAndroid Build Coastguard Worker         return *a.lastAccessTime < *b.lastAccessTime;
109*38e8c45fSAndroid Build Coastguard Worker     });
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     // Remove the oldest packages from mAppStats to make room for new apps.
112*38e8c45fSAndroid Build Coastguard Worker     for (int i = 0; i < APP_RECORD_HEADROOM; ++i) {
113*38e8c45fSAndroid Build Coastguard Worker         mAppStats.erase(*gpuStatsApps[i].appStatsKey);
114*38e8c45fSAndroid Build Coastguard Worker         gpuStatsApps[i].appStatsKey = nullptr;
115*38e8c45fSAndroid Build Coastguard Worker         gpuStatsApps[i].lastAccessTime = nullptr;
116*38e8c45fSAndroid Build Coastguard Worker     }
117*38e8c45fSAndroid Build Coastguard Worker }
118*38e8c45fSAndroid Build Coastguard Worker 
insertDriverStats(const std::string & driverPackageName,const std::string & driverVersionName,uint64_t driverVersionCode,int64_t driverBuildTime,const std::string & appPackageName,const int32_t vulkanVersion,GpuStatsInfo::Driver driver,bool isDriverLoaded,int64_t driverLoadingTime)119*38e8c45fSAndroid Build Coastguard Worker void GpuStats::insertDriverStats(const std::string& driverPackageName,
120*38e8c45fSAndroid Build Coastguard Worker                                  const std::string& driverVersionName, uint64_t driverVersionCode,
121*38e8c45fSAndroid Build Coastguard Worker                                  int64_t driverBuildTime, const std::string& appPackageName,
122*38e8c45fSAndroid Build Coastguard Worker                                  const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
123*38e8c45fSAndroid Build Coastguard Worker                                  bool isDriverLoaded, int64_t driverLoadingTime) {
124*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
125*38e8c45fSAndroid Build Coastguard Worker 
126*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
127*38e8c45fSAndroid Build Coastguard Worker     registerStatsdCallbacksIfNeeded();
128*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Received:\n"
129*38e8c45fSAndroid Build Coastguard Worker           "\tdriverPackageName[%s]\n"
130*38e8c45fSAndroid Build Coastguard Worker           "\tdriverVersionName[%s]\n"
131*38e8c45fSAndroid Build Coastguard Worker           "\tdriverVersionCode[%" PRIu64 "]\n"
132*38e8c45fSAndroid Build Coastguard Worker           "\tdriverBuildTime[%" PRId64 "]\n"
133*38e8c45fSAndroid Build Coastguard Worker           "\tappPackageName[%s]\n"
134*38e8c45fSAndroid Build Coastguard Worker           "\tvulkanVersion[%d]\n"
135*38e8c45fSAndroid Build Coastguard Worker           "\tdriver[%d]\n"
136*38e8c45fSAndroid Build Coastguard Worker           "\tisDriverLoaded[%d]\n"
137*38e8c45fSAndroid Build Coastguard Worker           "\tdriverLoadingTime[%" PRId64 "]",
138*38e8c45fSAndroid Build Coastguard Worker           driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
139*38e8c45fSAndroid Build Coastguard Worker           appPackageName.c_str(), vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded,
140*38e8c45fSAndroid Build Coastguard Worker           driverLoadingTime);
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker     if (!mGlobalStats.count(driverVersionCode)) {
143*38e8c45fSAndroid Build Coastguard Worker         GpuStatsGlobalInfo globalInfo;
144*38e8c45fSAndroid Build Coastguard Worker         addLoadingCount(driver, isDriverLoaded, &globalInfo);
145*38e8c45fSAndroid Build Coastguard Worker         globalInfo.driverPackageName = driverPackageName;
146*38e8c45fSAndroid Build Coastguard Worker         globalInfo.driverVersionName = driverVersionName;
147*38e8c45fSAndroid Build Coastguard Worker         globalInfo.driverVersionCode = driverVersionCode;
148*38e8c45fSAndroid Build Coastguard Worker         globalInfo.driverBuildTime = driverBuildTime;
149*38e8c45fSAndroid Build Coastguard Worker         globalInfo.vulkanVersion = vulkanVersion;
150*38e8c45fSAndroid Build Coastguard Worker         mGlobalStats.insert({driverVersionCode, globalInfo});
151*38e8c45fSAndroid Build Coastguard Worker     } else {
152*38e8c45fSAndroid Build Coastguard Worker         addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
153*38e8c45fSAndroid Build Coastguard Worker     }
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
156*38e8c45fSAndroid Build Coastguard Worker     if (!mAppStats.count(appStatsKey)) {
157*38e8c45fSAndroid Build Coastguard Worker         if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
158*38e8c45fSAndroid Build Coastguard Worker             ALOGV("GpuStatsAppInfo has reached maximum size. Removing old stats to make room.");
159*38e8c45fSAndroid Build Coastguard Worker             purgeOldDriverStats();
160*38e8c45fSAndroid Build Coastguard Worker         }
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker         GpuStatsAppInfo appInfo;
163*38e8c45fSAndroid Build Coastguard Worker         addLoadingTime(driver, driverLoadingTime, &appInfo);
164*38e8c45fSAndroid Build Coastguard Worker         appInfo.appPackageName = appPackageName;
165*38e8c45fSAndroid Build Coastguard Worker         appInfo.driverVersionCode = driverVersionCode;
166*38e8c45fSAndroid Build Coastguard Worker         appInfo.angleInUse =
167*38e8c45fSAndroid Build Coastguard Worker                 driver == GpuStatsInfo::Driver::ANGLE || driverPackageName == "angle";
168*38e8c45fSAndroid Build Coastguard Worker         appInfo.lastAccessTime = std::chrono::system_clock::now();
169*38e8c45fSAndroid Build Coastguard Worker         mAppStats.insert({appStatsKey, appInfo});
170*38e8c45fSAndroid Build Coastguard Worker     } else {
171*38e8c45fSAndroid Build Coastguard Worker         mAppStats[appStatsKey].angleInUse =
172*38e8c45fSAndroid Build Coastguard Worker                 driver == GpuStatsInfo::Driver::ANGLE || driverPackageName == "angle";
173*38e8c45fSAndroid Build Coastguard Worker         addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
174*38e8c45fSAndroid Build Coastguard Worker         mAppStats[appStatsKey].lastAccessTime = std::chrono::system_clock::now();
175*38e8c45fSAndroid Build Coastguard Worker     }
176*38e8c45fSAndroid Build Coastguard Worker }
177*38e8c45fSAndroid Build Coastguard Worker 
insertTargetStats(const std::string & appPackageName,const uint64_t driverVersionCode,const GpuStatsInfo::Stats stats,const uint64_t value)178*38e8c45fSAndroid Build Coastguard Worker void GpuStats::insertTargetStats(const std::string& appPackageName,
179*38e8c45fSAndroid Build Coastguard Worker                                  const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
180*38e8c45fSAndroid Build Coastguard Worker                                  const uint64_t value) {
181*38e8c45fSAndroid Build Coastguard Worker     return insertTargetStatsArray(appPackageName, driverVersionCode, stats, &value, 1);
182*38e8c45fSAndroid Build Coastguard Worker }
183*38e8c45fSAndroid Build Coastguard Worker 
addVulkanEngineName(const std::string & appPackageName,const uint64_t driverVersionCode,const char * engineNameCStr)184*38e8c45fSAndroid Build Coastguard Worker void GpuStats::addVulkanEngineName(const std::string& appPackageName,
185*38e8c45fSAndroid Build Coastguard Worker                                    const uint64_t driverVersionCode,
186*38e8c45fSAndroid Build Coastguard Worker                                    const char* engineNameCStr) {
187*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
188*38e8c45fSAndroid Build Coastguard Worker 
189*38e8c45fSAndroid Build Coastguard Worker     const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
190*38e8c45fSAndroid Build Coastguard Worker     const size_t engineNameLen = std::min(strlen(engineNameCStr),
191*38e8c45fSAndroid Build Coastguard Worker                                           GpuStatsAppInfo::MAX_VULKAN_ENGINE_NAME_LENGTH);
192*38e8c45fSAndroid Build Coastguard Worker     const std::string engineName{engineNameCStr, engineNameLen};
193*38e8c45fSAndroid Build Coastguard Worker 
194*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
195*38e8c45fSAndroid Build Coastguard Worker     registerStatsdCallbacksIfNeeded();
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     const auto foundApp = mAppStats.find(appStatsKey);
198*38e8c45fSAndroid Build Coastguard Worker     if (foundApp == mAppStats.end()) {
199*38e8c45fSAndroid Build Coastguard Worker         return;
200*38e8c45fSAndroid Build Coastguard Worker     }
201*38e8c45fSAndroid Build Coastguard Worker 
202*38e8c45fSAndroid Build Coastguard Worker     // Storing in std::set<> is not efficient for serialization tasks. Use
203*38e8c45fSAndroid Build Coastguard Worker     // vector instead and filter out dups
204*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::string>& engineNames = foundApp->second.vulkanEngineNames;
205*38e8c45fSAndroid Build Coastguard Worker     if (engineNames.size() < GpuStatsAppInfo::MAX_VULKAN_ENGINE_NAMES
206*38e8c45fSAndroid Build Coastguard Worker         && std::find(engineNames.cbegin(), engineNames.cend(), engineName) == engineNames.cend()) {
207*38e8c45fSAndroid Build Coastguard Worker         engineNames.push_back(engineName);
208*38e8c45fSAndroid Build Coastguard Worker     }
209*38e8c45fSAndroid Build Coastguard Worker }
210*38e8c45fSAndroid Build Coastguard Worker 
insertTargetStatsArray(const std::string & appPackageName,const uint64_t driverVersionCode,const GpuStatsInfo::Stats stats,const uint64_t * values,const uint32_t valueCount)211*38e8c45fSAndroid Build Coastguard Worker void GpuStats::insertTargetStatsArray(const std::string& appPackageName,
212*38e8c45fSAndroid Build Coastguard Worker                                  const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
213*38e8c45fSAndroid Build Coastguard Worker                                  const uint64_t* values, const uint32_t valueCount) {
214*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
215*38e8c45fSAndroid Build Coastguard Worker 
216*38e8c45fSAndroid Build Coastguard Worker     const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
217*38e8c45fSAndroid Build Coastguard Worker 
218*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
219*38e8c45fSAndroid Build Coastguard Worker     registerStatsdCallbacksIfNeeded();
220*38e8c45fSAndroid Build Coastguard Worker 
221*38e8c45fSAndroid Build Coastguard Worker     const auto foundApp = mAppStats.find(appStatsKey);
222*38e8c45fSAndroid Build Coastguard Worker     if (foundApp == mAppStats.end()) {
223*38e8c45fSAndroid Build Coastguard Worker         return;
224*38e8c45fSAndroid Build Coastguard Worker     }
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker     GpuStatsAppInfo& targetAppStats = foundApp->second;
227*38e8c45fSAndroid Build Coastguard Worker 
228*38e8c45fSAndroid Build Coastguard Worker     if (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION
229*38e8c45fSAndroid Build Coastguard Worker         || stats == GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION) {
230*38e8c45fSAndroid Build Coastguard Worker         // Handle extension arrays separately as we need to store a unique set of them
231*38e8c45fSAndroid Build Coastguard Worker         // in the stats vector. Storing in std::set<> is not efficient for serialization tasks.
232*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t>& targetVec =
233*38e8c45fSAndroid Build Coastguard Worker                                 (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION) ?
234*38e8c45fSAndroid Build Coastguard Worker                                 targetAppStats.vulkanInstanceExtensions :
235*38e8c45fSAndroid Build Coastguard Worker                                 targetAppStats.vulkanDeviceExtensions;
236*38e8c45fSAndroid Build Coastguard Worker         const bool addAll = (targetVec.size() == 0);
237*38e8c45fSAndroid Build Coastguard Worker         targetVec.reserve(valueCount);
238*38e8c45fSAndroid Build Coastguard Worker 
239*38e8c45fSAndroid Build Coastguard Worker         // Add new extensions into the set
240*38e8c45fSAndroid Build Coastguard Worker         for(uint32_t i = 0;
241*38e8c45fSAndroid Build Coastguard Worker             (i < valueCount) && (targetVec.size() < GpuStatsAppInfo::MAX_NUM_EXTENSIONS);
242*38e8c45fSAndroid Build Coastguard Worker             i++) {
243*38e8c45fSAndroid Build Coastguard Worker             const int32_t extVal = int32_t(values[i] & 0xFFFFFFFF);
244*38e8c45fSAndroid Build Coastguard Worker             if (addAll
245*38e8c45fSAndroid Build Coastguard Worker                 || std::find(targetVec.cbegin(), targetVec.cend(), extVal) == targetVec.cend()) {
246*38e8c45fSAndroid Build Coastguard Worker                 targetVec.push_back(extVal);
247*38e8c45fSAndroid Build Coastguard Worker             }
248*38e8c45fSAndroid Build Coastguard Worker         }
249*38e8c45fSAndroid Build Coastguard Worker     }
250*38e8c45fSAndroid Build Coastguard Worker     else {
251*38e8c45fSAndroid Build Coastguard Worker         // Handle other type of stats info events
252*38e8c45fSAndroid Build Coastguard Worker         for(uint32_t i = 0; i < valueCount; i++) {
253*38e8c45fSAndroid Build Coastguard Worker             const uint64_t value = values[i];
254*38e8c45fSAndroid Build Coastguard Worker             switch (stats) {
255*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE:
256*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.cpuVulkanInUse = true;
257*38e8c45fSAndroid Build Coastguard Worker                     break;
258*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::FALSE_PREROTATION:
259*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.falsePrerotation = true;
260*38e8c45fSAndroid Build Coastguard Worker                     break;
261*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::GLES_1_IN_USE:
262*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.gles1InUse = true;
263*38e8c45fSAndroid Build Coastguard Worker                     break;
264*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::CREATED_GLES_CONTEXT:
265*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.createdGlesContext = true;
266*38e8c45fSAndroid Build Coastguard Worker                     break;
267*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE:
268*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.createdVulkanDevice = true;
269*38e8c45fSAndroid Build Coastguard Worker                     break;
270*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION:
271*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.vulkanApiVersion = uint32_t(value & 0xffffffff);
272*38e8c45fSAndroid Build Coastguard Worker                     break;
273*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN:
274*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.createdVulkanSwapchain = true;
275*38e8c45fSAndroid Build Coastguard Worker                     break;
276*38e8c45fSAndroid Build Coastguard Worker                 case GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED:
277*38e8c45fSAndroid Build Coastguard Worker                     // Merge all requested feature bits together for this app
278*38e8c45fSAndroid Build Coastguard Worker                     targetAppStats.vulkanDeviceFeaturesEnabled |= value;
279*38e8c45fSAndroid Build Coastguard Worker                     break;
280*38e8c45fSAndroid Build Coastguard Worker                 default:
281*38e8c45fSAndroid Build Coastguard Worker                     break;
282*38e8c45fSAndroid Build Coastguard Worker             }
283*38e8c45fSAndroid Build Coastguard Worker         }
284*38e8c45fSAndroid Build Coastguard Worker     }
285*38e8c45fSAndroid Build Coastguard Worker }
286*38e8c45fSAndroid Build Coastguard Worker 
interceptSystemDriverStatsLocked()287*38e8c45fSAndroid Build Coastguard Worker void GpuStats::interceptSystemDriverStatsLocked() {
288*38e8c45fSAndroid Build Coastguard Worker     // Append cpuVulkanVersion and glesVersion to system driver stats
289*38e8c45fSAndroid Build Coastguard Worker     if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
290*38e8c45fSAndroid Build Coastguard Worker         return;
291*38e8c45fSAndroid Build Coastguard Worker     }
292*38e8c45fSAndroid Build Coastguard Worker 
293*38e8c45fSAndroid Build Coastguard Worker     mGlobalStats[0].cpuVulkanVersion = property_get_int32("ro.cpuvulkan.version", 0);
294*38e8c45fSAndroid Build Coastguard Worker     mGlobalStats[0].glesVersion = property_get_int32("ro.opengles.version", 0);
295*38e8c45fSAndroid Build Coastguard Worker }
296*38e8c45fSAndroid Build Coastguard Worker 
registerStatsdCallbacksIfNeeded()297*38e8c45fSAndroid Build Coastguard Worker void GpuStats::registerStatsdCallbacksIfNeeded() {
298*38e8c45fSAndroid Build Coastguard Worker     if (!mStatsdRegistered) {
299*38e8c45fSAndroid Build Coastguard Worker         AStatsManager_setPullAtomCallback(android::util::GPU_STATS_GLOBAL_INFO, nullptr,
300*38e8c45fSAndroid Build Coastguard Worker                                          GpuStats::pullAtomCallback, this);
301*38e8c45fSAndroid Build Coastguard Worker         AStatsManager_setPullAtomCallback(android::util::GPU_STATS_APP_INFO, nullptr,
302*38e8c45fSAndroid Build Coastguard Worker                                          GpuStats::pullAtomCallback, this);
303*38e8c45fSAndroid Build Coastguard Worker         mStatsdRegistered = true;
304*38e8c45fSAndroid Build Coastguard Worker     }
305*38e8c45fSAndroid Build Coastguard Worker }
306*38e8c45fSAndroid Build Coastguard Worker 
dump(const Vector<String16> & args,std::string * result)307*38e8c45fSAndroid Build Coastguard Worker void GpuStats::dump(const Vector<String16>& args, std::string* result) {
308*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
309*38e8c45fSAndroid Build Coastguard Worker 
310*38e8c45fSAndroid Build Coastguard Worker     if (!result) {
311*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Dump result shouldn't be nullptr.");
312*38e8c45fSAndroid Build Coastguard Worker         return;
313*38e8c45fSAndroid Build Coastguard Worker     }
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
316*38e8c45fSAndroid Build Coastguard Worker     bool dumpAll = true;
317*38e8c45fSAndroid Build Coastguard Worker 
318*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<std::string> argsSet;
319*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < args.size(); i++) {
320*38e8c45fSAndroid Build Coastguard Worker         argsSet.insert(String8(args[i]).c_str());
321*38e8c45fSAndroid Build Coastguard Worker     }
322*38e8c45fSAndroid Build Coastguard Worker 
323*38e8c45fSAndroid Build Coastguard Worker     const bool dumpGlobal = argsSet.count("--global") != 0;
324*38e8c45fSAndroid Build Coastguard Worker     if (dumpGlobal) {
325*38e8c45fSAndroid Build Coastguard Worker         dumpGlobalLocked(result);
326*38e8c45fSAndroid Build Coastguard Worker         dumpAll = false;
327*38e8c45fSAndroid Build Coastguard Worker     }
328*38e8c45fSAndroid Build Coastguard Worker 
329*38e8c45fSAndroid Build Coastguard Worker     const bool dumpApp = argsSet.count("--app") != 0;
330*38e8c45fSAndroid Build Coastguard Worker     if (dumpApp) {
331*38e8c45fSAndroid Build Coastguard Worker         dumpAppLocked(result);
332*38e8c45fSAndroid Build Coastguard Worker         dumpAll = false;
333*38e8c45fSAndroid Build Coastguard Worker     }
334*38e8c45fSAndroid Build Coastguard Worker 
335*38e8c45fSAndroid Build Coastguard Worker     if (dumpAll) {
336*38e8c45fSAndroid Build Coastguard Worker         dumpGlobalLocked(result);
337*38e8c45fSAndroid Build Coastguard Worker         dumpAppLocked(result);
338*38e8c45fSAndroid Build Coastguard Worker     }
339*38e8c45fSAndroid Build Coastguard Worker 
340*38e8c45fSAndroid Build Coastguard Worker     if (argsSet.count("--clear")) {
341*38e8c45fSAndroid Build Coastguard Worker         bool clearAll = true;
342*38e8c45fSAndroid Build Coastguard Worker 
343*38e8c45fSAndroid Build Coastguard Worker         if (dumpGlobal) {
344*38e8c45fSAndroid Build Coastguard Worker             mGlobalStats.clear();
345*38e8c45fSAndroid Build Coastguard Worker             clearAll = false;
346*38e8c45fSAndroid Build Coastguard Worker         }
347*38e8c45fSAndroid Build Coastguard Worker 
348*38e8c45fSAndroid Build Coastguard Worker         if (dumpApp) {
349*38e8c45fSAndroid Build Coastguard Worker             mAppStats.clear();
350*38e8c45fSAndroid Build Coastguard Worker             clearAll = false;
351*38e8c45fSAndroid Build Coastguard Worker         }
352*38e8c45fSAndroid Build Coastguard Worker 
353*38e8c45fSAndroid Build Coastguard Worker         if (clearAll) {
354*38e8c45fSAndroid Build Coastguard Worker             mGlobalStats.clear();
355*38e8c45fSAndroid Build Coastguard Worker             mAppStats.clear();
356*38e8c45fSAndroid Build Coastguard Worker         }
357*38e8c45fSAndroid Build Coastguard Worker     }
358*38e8c45fSAndroid Build Coastguard Worker }
359*38e8c45fSAndroid Build Coastguard Worker 
dumpGlobalLocked(std::string * result)360*38e8c45fSAndroid Build Coastguard Worker void GpuStats::dumpGlobalLocked(std::string* result) {
361*38e8c45fSAndroid Build Coastguard Worker     interceptSystemDriverStatsLocked();
362*38e8c45fSAndroid Build Coastguard Worker 
363*38e8c45fSAndroid Build Coastguard Worker     for (const auto& ele : mGlobalStats) {
364*38e8c45fSAndroid Build Coastguard Worker         result->append(ele.second.toString());
365*38e8c45fSAndroid Build Coastguard Worker         result->append("\n");
366*38e8c45fSAndroid Build Coastguard Worker     }
367*38e8c45fSAndroid Build Coastguard Worker }
368*38e8c45fSAndroid Build Coastguard Worker 
dumpAppLocked(std::string * result)369*38e8c45fSAndroid Build Coastguard Worker void GpuStats::dumpAppLocked(std::string* result) {
370*38e8c45fSAndroid Build Coastguard Worker     for (const auto& ele : mAppStats) {
371*38e8c45fSAndroid Build Coastguard Worker         result->append(ele.second.toString());
372*38e8c45fSAndroid Build Coastguard Worker         result->append("\n");
373*38e8c45fSAndroid Build Coastguard Worker     }
374*38e8c45fSAndroid Build Coastguard Worker }
375*38e8c45fSAndroid Build Coastguard Worker 
protoOutputStreamToByteString(android::util::ProtoOutputStream & proto)376*38e8c45fSAndroid Build Coastguard Worker static std::string protoOutputStreamToByteString(android::util::ProtoOutputStream& proto) {
377*38e8c45fSAndroid Build Coastguard Worker     if (!proto.size()) return "";
378*38e8c45fSAndroid Build Coastguard Worker 
379*38e8c45fSAndroid Build Coastguard Worker     std::string byteString;
380*38e8c45fSAndroid Build Coastguard Worker     sp<android::util::ProtoReader> reader = proto.data();
381*38e8c45fSAndroid Build Coastguard Worker     while (reader->readBuffer() != nullptr) {
382*38e8c45fSAndroid Build Coastguard Worker         const size_t toRead = reader->currentToRead();
383*38e8c45fSAndroid Build Coastguard Worker         byteString.append((char*)reader->readBuffer(), toRead);
384*38e8c45fSAndroid Build Coastguard Worker         reader->move(toRead);
385*38e8c45fSAndroid Build Coastguard Worker     }
386*38e8c45fSAndroid Build Coastguard Worker 
387*38e8c45fSAndroid Build Coastguard Worker     if (byteString.size() != proto.size()) return "";
388*38e8c45fSAndroid Build Coastguard Worker 
389*38e8c45fSAndroid Build Coastguard Worker     return byteString;
390*38e8c45fSAndroid Build Coastguard Worker }
391*38e8c45fSAndroid Build Coastguard Worker 
int64VectorToProtoByteString(const std::vector<int64_t> & value)392*38e8c45fSAndroid Build Coastguard Worker static std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
393*38e8c45fSAndroid Build Coastguard Worker     if (value.empty()) return "";
394*38e8c45fSAndroid Build Coastguard Worker 
395*38e8c45fSAndroid Build Coastguard Worker     android::util::ProtoOutputStream proto;
396*38e8c45fSAndroid Build Coastguard Worker     for (const auto& ele : value) {
397*38e8c45fSAndroid Build Coastguard Worker         proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
398*38e8c45fSAndroid Build Coastguard Worker                             1 /* field id */,
399*38e8c45fSAndroid Build Coastguard Worker                     (long long)ele);
400*38e8c45fSAndroid Build Coastguard Worker     }
401*38e8c45fSAndroid Build Coastguard Worker 
402*38e8c45fSAndroid Build Coastguard Worker     return protoOutputStreamToByteString(proto);
403*38e8c45fSAndroid Build Coastguard Worker }
404*38e8c45fSAndroid Build Coastguard Worker 
pullAppInfoAtom(AStatsEventList * data)405*38e8c45fSAndroid Build Coastguard Worker AStatsManager_PullAtomCallbackReturn GpuStats::pullAppInfoAtom(AStatsEventList* data) {
406*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
407*38e8c45fSAndroid Build Coastguard Worker 
408*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
409*38e8c45fSAndroid Build Coastguard Worker 
410*38e8c45fSAndroid Build Coastguard Worker     if (data) {
411*38e8c45fSAndroid Build Coastguard Worker         for (const auto& ele : mAppStats) {
412*38e8c45fSAndroid Build Coastguard Worker             std::string glDriverBytes = int64VectorToProtoByteString(
413*38e8c45fSAndroid Build Coastguard Worker                 ele.second.glDriverLoadingTime);
414*38e8c45fSAndroid Build Coastguard Worker             std::string vkDriverBytes = int64VectorToProtoByteString(
415*38e8c45fSAndroid Build Coastguard Worker                 ele.second.vkDriverLoadingTime);
416*38e8c45fSAndroid Build Coastguard Worker             std::string angleDriverBytes = int64VectorToProtoByteString(
417*38e8c45fSAndroid Build Coastguard Worker                 ele.second.angleDriverLoadingTime);
418*38e8c45fSAndroid Build Coastguard Worker 
419*38e8c45fSAndroid Build Coastguard Worker             std::vector<const char*> engineNames;
420*38e8c45fSAndroid Build Coastguard Worker             for (const std::string &engineName : ele.second.vulkanEngineNames) {
421*38e8c45fSAndroid Build Coastguard Worker                 engineNames.push_back(engineName.c_str());
422*38e8c45fSAndroid Build Coastguard Worker             }
423*38e8c45fSAndroid Build Coastguard Worker 
424*38e8c45fSAndroid Build Coastguard Worker             android::util::addAStatsEvent(
425*38e8c45fSAndroid Build Coastguard Worker                     data,
426*38e8c45fSAndroid Build Coastguard Worker                     android::util::GPU_STATS_APP_INFO,
427*38e8c45fSAndroid Build Coastguard Worker                     ele.second.appPackageName.c_str(),
428*38e8c45fSAndroid Build Coastguard Worker                     ele.second.driverVersionCode,
429*38e8c45fSAndroid Build Coastguard Worker                     android::util::BytesField(glDriverBytes.c_str(),
430*38e8c45fSAndroid Build Coastguard Worker                                               glDriverBytes.length()),
431*38e8c45fSAndroid Build Coastguard Worker                     android::util::BytesField(vkDriverBytes.c_str(),
432*38e8c45fSAndroid Build Coastguard Worker                                               vkDriverBytes.length()),
433*38e8c45fSAndroid Build Coastguard Worker                     android::util::BytesField(angleDriverBytes.c_str(),
434*38e8c45fSAndroid Build Coastguard Worker                                               angleDriverBytes.length()),
435*38e8c45fSAndroid Build Coastguard Worker                     ele.second.cpuVulkanInUse,
436*38e8c45fSAndroid Build Coastguard Worker                     ele.second.falsePrerotation,
437*38e8c45fSAndroid Build Coastguard Worker                     ele.second.gles1InUse,
438*38e8c45fSAndroid Build Coastguard Worker                     ele.second.angleInUse,
439*38e8c45fSAndroid Build Coastguard Worker                     ele.second.createdGlesContext,
440*38e8c45fSAndroid Build Coastguard Worker                     ele.second.createdVulkanDevice,
441*38e8c45fSAndroid Build Coastguard Worker                     ele.second.createdVulkanSwapchain,
442*38e8c45fSAndroid Build Coastguard Worker                     ele.second.vulkanApiVersion,
443*38e8c45fSAndroid Build Coastguard Worker                     ele.second.vulkanDeviceFeaturesEnabled,
444*38e8c45fSAndroid Build Coastguard Worker                     ele.second.vulkanInstanceExtensions,
445*38e8c45fSAndroid Build Coastguard Worker                     ele.second.vulkanDeviceExtensions,
446*38e8c45fSAndroid Build Coastguard Worker                     engineNames);
447*38e8c45fSAndroid Build Coastguard Worker         }
448*38e8c45fSAndroid Build Coastguard Worker     }
449*38e8c45fSAndroid Build Coastguard Worker 
450*38e8c45fSAndroid Build Coastguard Worker     mAppStats.clear();
451*38e8c45fSAndroid Build Coastguard Worker 
452*38e8c45fSAndroid Build Coastguard Worker     return AStatsManager_PULL_SUCCESS;
453*38e8c45fSAndroid Build Coastguard Worker }
454*38e8c45fSAndroid Build Coastguard Worker 
pullGlobalInfoAtom(AStatsEventList * data)455*38e8c45fSAndroid Build Coastguard Worker AStatsManager_PullAtomCallbackReturn GpuStats::pullGlobalInfoAtom(AStatsEventList* data) {
456*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mLock);
459*38e8c45fSAndroid Build Coastguard Worker     // flush cpuVulkanVersion and glesVersion to builtin driver stats
460*38e8c45fSAndroid Build Coastguard Worker     interceptSystemDriverStatsLocked();
461*38e8c45fSAndroid Build Coastguard Worker 
462*38e8c45fSAndroid Build Coastguard Worker     if (data) {
463*38e8c45fSAndroid Build Coastguard Worker         for (const auto& ele : mGlobalStats) {
464*38e8c45fSAndroid Build Coastguard Worker           android::util::addAStatsEvent(
465*38e8c45fSAndroid Build Coastguard Worker                   data,
466*38e8c45fSAndroid Build Coastguard Worker                   android::util::GPU_STATS_GLOBAL_INFO,
467*38e8c45fSAndroid Build Coastguard Worker                   ele.second.driverPackageName.c_str(),
468*38e8c45fSAndroid Build Coastguard Worker                   ele.second.driverVersionName.c_str(),
469*38e8c45fSAndroid Build Coastguard Worker                   ele.second.driverVersionCode,
470*38e8c45fSAndroid Build Coastguard Worker                   ele.second.driverBuildTime,
471*38e8c45fSAndroid Build Coastguard Worker                   ele.second.glLoadingCount,
472*38e8c45fSAndroid Build Coastguard Worker                   ele.second.glLoadingFailureCount,
473*38e8c45fSAndroid Build Coastguard Worker                   ele.second.vkLoadingCount,
474*38e8c45fSAndroid Build Coastguard Worker                   ele.second.vkLoadingFailureCount,
475*38e8c45fSAndroid Build Coastguard Worker                   ele.second.vulkanVersion,
476*38e8c45fSAndroid Build Coastguard Worker                   ele.second.cpuVulkanVersion,
477*38e8c45fSAndroid Build Coastguard Worker                   ele.second.glesVersion,
478*38e8c45fSAndroid Build Coastguard Worker                   ele.second.angleLoadingCount,
479*38e8c45fSAndroid Build Coastguard Worker                   ele.second.angleLoadingFailureCount);
480*38e8c45fSAndroid Build Coastguard Worker         }
481*38e8c45fSAndroid Build Coastguard Worker     }
482*38e8c45fSAndroid Build Coastguard Worker 
483*38e8c45fSAndroid Build Coastguard Worker     mGlobalStats.clear();
484*38e8c45fSAndroid Build Coastguard Worker 
485*38e8c45fSAndroid Build Coastguard Worker     return AStatsManager_PULL_SUCCESS;
486*38e8c45fSAndroid Build Coastguard Worker }
487*38e8c45fSAndroid Build Coastguard Worker 
pullAtomCallback(int32_t atomTag,AStatsEventList * data,void * cookie)488*38e8c45fSAndroid Build Coastguard Worker AStatsManager_PullAtomCallbackReturn GpuStats::pullAtomCallback(int32_t atomTag,
489*38e8c45fSAndroid Build Coastguard Worker                                                                 AStatsEventList* data,
490*38e8c45fSAndroid Build Coastguard Worker                                                                 void* cookie) {
491*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
492*38e8c45fSAndroid Build Coastguard Worker 
493*38e8c45fSAndroid Build Coastguard Worker     GpuStats* pGpuStats = reinterpret_cast<GpuStats*>(cookie);
494*38e8c45fSAndroid Build Coastguard Worker     if (atomTag == android::util::GPU_STATS_GLOBAL_INFO) {
495*38e8c45fSAndroid Build Coastguard Worker         return pGpuStats->pullGlobalInfoAtom(data);
496*38e8c45fSAndroid Build Coastguard Worker     } else if (atomTag == android::util::GPU_STATS_APP_INFO) {
497*38e8c45fSAndroid Build Coastguard Worker         return pGpuStats->pullAppInfoAtom(data);
498*38e8c45fSAndroid Build Coastguard Worker     }
499*38e8c45fSAndroid Build Coastguard Worker 
500*38e8c45fSAndroid Build Coastguard Worker     return AStatsManager_PULL_SKIP;
501*38e8c45fSAndroid Build Coastguard Worker }
502*38e8c45fSAndroid Build Coastguard Worker 
503*38e8c45fSAndroid Build Coastguard Worker } // namespace android
504