1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2016 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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18*38e8c45fSAndroid Build Coastguard Worker
19*38e8c45fSAndroid Build Coastguard Worker #include "gpuservice/GpuService.h"
20*38e8c45fSAndroid Build Coastguard Worker
21*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/IResultReceiver.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <binder/PermissionCache.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <gpumem/GpuMem.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <gpuwork/GpuWork.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <gpustats/GpuStats.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <tracing/GpuMemTracer.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <utils/String8.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <vkjson.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <vkprofiles.h>
37*38e8c45fSAndroid Build Coastguard Worker
38*38e8c45fSAndroid Build Coastguard Worker #include <thread>
39*38e8c45fSAndroid Build Coastguard Worker #include <memory>
40*38e8c45fSAndroid Build Coastguard Worker
41*38e8c45fSAndroid Build Coastguard Worker namespace android {
42*38e8c45fSAndroid Build Coastguard Worker
43*38e8c45fSAndroid Build Coastguard Worker using base::StringAppendF;
44*38e8c45fSAndroid Build Coastguard Worker
45*38e8c45fSAndroid Build Coastguard Worker namespace {
46*38e8c45fSAndroid Build Coastguard Worker status_t cmdHelp(int out);
47*38e8c45fSAndroid Build Coastguard Worker status_t cmdVkjson(int out, int err);
48*38e8c45fSAndroid Build Coastguard Worker status_t cmdVkprofiles(int out, int err);
49*38e8c45fSAndroid Build Coastguard Worker void dumpGameDriverInfo(std::string* result);
50*38e8c45fSAndroid Build Coastguard Worker } // namespace
51*38e8c45fSAndroid Build Coastguard Worker
52*38e8c45fSAndroid Build Coastguard Worker const String16 sDump("android.permission.DUMP");
53*38e8c45fSAndroid Build Coastguard Worker const String16 sAccessGpuServicePermission("android.permission.ACCESS_GPU_SERVICE");
54*38e8c45fSAndroid Build Coastguard Worker const std::string sAngleGlesDriverSuffix = "angle";
55*38e8c45fSAndroid Build Coastguard Worker
56*38e8c45fSAndroid Build Coastguard Worker const char* const GpuService::SERVICE_NAME = "gpu";
57*38e8c45fSAndroid Build Coastguard Worker
GpuService()58*38e8c45fSAndroid Build Coastguard Worker GpuService::GpuService()
59*38e8c45fSAndroid Build Coastguard Worker : mGpuMem(std::make_shared<GpuMem>()),
60*38e8c45fSAndroid Build Coastguard Worker mGpuWork(std::make_shared<gpuwork::GpuWork>()),
61*38e8c45fSAndroid Build Coastguard Worker mGpuStats(std::make_unique<GpuStats>()),
62*38e8c45fSAndroid Build Coastguard Worker mGpuMemTracer(std::make_unique<GpuMemTracer>()) {
63*38e8c45fSAndroid Build Coastguard Worker
64*38e8c45fSAndroid Build Coastguard Worker mGpuMemAsyncInitThread = std::make_unique<std::thread>([this] (){
65*38e8c45fSAndroid Build Coastguard Worker mGpuMem->initialize();
66*38e8c45fSAndroid Build Coastguard Worker mGpuMemTracer->initialize(mGpuMem);
67*38e8c45fSAndroid Build Coastguard Worker });
68*38e8c45fSAndroid Build Coastguard Worker
69*38e8c45fSAndroid Build Coastguard Worker mGpuWorkAsyncInitThread = std::make_unique<std::thread>([this]() {
70*38e8c45fSAndroid Build Coastguard Worker mGpuWork->initialize();
71*38e8c45fSAndroid Build Coastguard Worker });
72*38e8c45fSAndroid Build Coastguard Worker };
73*38e8c45fSAndroid Build Coastguard Worker
~GpuService()74*38e8c45fSAndroid Build Coastguard Worker GpuService::~GpuService() {
75*38e8c45fSAndroid Build Coastguard Worker mGpuMem->stop();
76*38e8c45fSAndroid Build Coastguard Worker mGpuWork->stop();
77*38e8c45fSAndroid Build Coastguard Worker
78*38e8c45fSAndroid Build Coastguard Worker mGpuWorkAsyncInitThread->join();
79*38e8c45fSAndroid Build Coastguard Worker mGpuMemAsyncInitThread->join();
80*38e8c45fSAndroid Build Coastguard Worker }
81*38e8c45fSAndroid Build Coastguard Worker
setGpuStats(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)82*38e8c45fSAndroid Build Coastguard Worker void GpuService::setGpuStats(const std::string& driverPackageName,
83*38e8c45fSAndroid Build Coastguard Worker const std::string& driverVersionName, uint64_t driverVersionCode,
84*38e8c45fSAndroid Build Coastguard Worker int64_t driverBuildTime, const std::string& appPackageName,
85*38e8c45fSAndroid Build Coastguard Worker const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
86*38e8c45fSAndroid Build Coastguard Worker bool isDriverLoaded, int64_t driverLoadingTime) {
87*38e8c45fSAndroid Build Coastguard Worker mGpuStats->insertDriverStats(driverPackageName, driverVersionName, driverVersionCode,
88*38e8c45fSAndroid Build Coastguard Worker driverBuildTime, appPackageName, vulkanVersion, driver,
89*38e8c45fSAndroid Build Coastguard Worker isDriverLoaded, driverLoadingTime);
90*38e8c45fSAndroid Build Coastguard Worker }
91*38e8c45fSAndroid Build Coastguard Worker
setTargetStats(const std::string & appPackageName,const uint64_t driverVersionCode,const GpuStatsInfo::Stats stats,const uint64_t value)92*38e8c45fSAndroid Build Coastguard Worker void GpuService::setTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode,
93*38e8c45fSAndroid Build Coastguard Worker const GpuStatsInfo::Stats stats, const uint64_t value) {
94*38e8c45fSAndroid Build Coastguard Worker mGpuStats->insertTargetStats(appPackageName, driverVersionCode, stats, value);
95*38e8c45fSAndroid Build Coastguard Worker }
96*38e8c45fSAndroid Build Coastguard Worker
setTargetStatsArray(const std::string & appPackageName,const uint64_t driverVersionCode,const GpuStatsInfo::Stats stats,const uint64_t * values,const uint32_t valueCount)97*38e8c45fSAndroid Build Coastguard Worker void GpuService::setTargetStatsArray(const std::string& appPackageName,
98*38e8c45fSAndroid Build Coastguard Worker const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats,
99*38e8c45fSAndroid Build Coastguard Worker const uint64_t* values, const uint32_t valueCount) {
100*38e8c45fSAndroid Build Coastguard Worker mGpuStats->insertTargetStatsArray(appPackageName, driverVersionCode, stats, values, valueCount);
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker
addVulkanEngineName(const std::string & appPackageName,const uint64_t driverVersionCode,const char * engineName)103*38e8c45fSAndroid Build Coastguard Worker void GpuService::addVulkanEngineName(const std::string& appPackageName,
104*38e8c45fSAndroid Build Coastguard Worker const uint64_t driverVersionCode,
105*38e8c45fSAndroid Build Coastguard Worker const char* engineName) {
106*38e8c45fSAndroid Build Coastguard Worker mGpuStats->addVulkanEngineName(appPackageName, driverVersionCode, engineName);
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker
toggleAngleAsSystemDriver(bool enabled)109*38e8c45fSAndroid Build Coastguard Worker void GpuService::toggleAngleAsSystemDriver(bool enabled) {
110*38e8c45fSAndroid Build Coastguard Worker IPCThreadState* ipc = IPCThreadState::self();
111*38e8c45fSAndroid Build Coastguard Worker const int pid = ipc->getCallingPid();
112*38e8c45fSAndroid Build Coastguard Worker const int uid = ipc->getCallingUid();
113*38e8c45fSAndroid Build Coastguard Worker
114*38e8c45fSAndroid Build Coastguard Worker // only system_server with the ACCESS_GPU_SERVICE permission is allowed to set
115*38e8c45fSAndroid Build Coastguard Worker // persist.graphics.egl
116*38e8c45fSAndroid Build Coastguard Worker if (uid != AID_SYSTEM ||
117*38e8c45fSAndroid Build Coastguard Worker !PermissionCache::checkPermission(sAccessGpuServicePermission, pid, uid)) {
118*38e8c45fSAndroid Build Coastguard Worker ALOGE("Permission Denial: can't set persist.graphics.egl from setAngleAsSystemDriver() "
119*38e8c45fSAndroid Build Coastguard Worker "pid=%d, uid=%d\n", pid, uid);
120*38e8c45fSAndroid Build Coastguard Worker return;
121*38e8c45fSAndroid Build Coastguard Worker }
122*38e8c45fSAndroid Build Coastguard Worker
123*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
124*38e8c45fSAndroid Build Coastguard Worker if (enabled) {
125*38e8c45fSAndroid Build Coastguard Worker android::base::SetProperty("persist.graphics.egl", sAngleGlesDriverSuffix);
126*38e8c45fSAndroid Build Coastguard Worker } else {
127*38e8c45fSAndroid Build Coastguard Worker android::base::SetProperty("persist.graphics.egl", "");
128*38e8c45fSAndroid Build Coastguard Worker }
129*38e8c45fSAndroid Build Coastguard Worker }
130*38e8c45fSAndroid Build Coastguard Worker
131*38e8c45fSAndroid Build Coastguard Worker
setUpdatableDriverPath(const std::string & driverPath)132*38e8c45fSAndroid Build Coastguard Worker void GpuService::setUpdatableDriverPath(const std::string& driverPath) {
133*38e8c45fSAndroid Build Coastguard Worker IPCThreadState* ipc = IPCThreadState::self();
134*38e8c45fSAndroid Build Coastguard Worker const int pid = ipc->getCallingPid();
135*38e8c45fSAndroid Build Coastguard Worker const int uid = ipc->getCallingUid();
136*38e8c45fSAndroid Build Coastguard Worker
137*38e8c45fSAndroid Build Coastguard Worker // only system_server is allowed to set updatable driver path
138*38e8c45fSAndroid Build Coastguard Worker if (uid != AID_SYSTEM) {
139*38e8c45fSAndroid Build Coastguard Worker ALOGE("Permission Denial: can't set updatable driver path from pid=%d, uid=%d\n", pid, uid);
140*38e8c45fSAndroid Build Coastguard Worker return;
141*38e8c45fSAndroid Build Coastguard Worker }
142*38e8c45fSAndroid Build Coastguard Worker
143*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
144*38e8c45fSAndroid Build Coastguard Worker mDeveloperDriverPath = driverPath;
145*38e8c45fSAndroid Build Coastguard Worker }
146*38e8c45fSAndroid Build Coastguard Worker
getUpdatableDriverPath()147*38e8c45fSAndroid Build Coastguard Worker std::string GpuService::getUpdatableDriverPath() {
148*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
149*38e8c45fSAndroid Build Coastguard Worker return mDeveloperDriverPath;
150*38e8c45fSAndroid Build Coastguard Worker }
151*38e8c45fSAndroid Build Coastguard Worker
shellCommand(int,int out,int err,std::vector<String16> & args)152*38e8c45fSAndroid Build Coastguard Worker status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
153*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
154*38e8c45fSAndroid Build Coastguard Worker
155*38e8c45fSAndroid Build Coastguard Worker ALOGV("shellCommand");
156*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0, n = args.size(); i < n; i++)
157*38e8c45fSAndroid Build Coastguard Worker ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).c_str());
158*38e8c45fSAndroid Build Coastguard Worker
159*38e8c45fSAndroid Build Coastguard Worker if (args.size() >= 1) {
160*38e8c45fSAndroid Build Coastguard Worker if (args[0] == String16("vkjson")) return cmdVkjson(out, err);
161*38e8c45fSAndroid Build Coastguard Worker if (args[0] == String16("vkprofiles")) return cmdVkprofiles(out, err);
162*38e8c45fSAndroid Build Coastguard Worker if (args[0] == String16("help")) return cmdHelp(out);
163*38e8c45fSAndroid Build Coastguard Worker }
164*38e8c45fSAndroid Build Coastguard Worker // no command, or unrecognized command
165*38e8c45fSAndroid Build Coastguard Worker cmdHelp(err);
166*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
167*38e8c45fSAndroid Build Coastguard Worker }
168*38e8c45fSAndroid Build Coastguard Worker
doDump(int fd,const Vector<String16> & args,bool)169*38e8c45fSAndroid Build Coastguard Worker status_t GpuService::doDump(int fd, const Vector<String16>& args, bool /*asProto*/) {
170*38e8c45fSAndroid Build Coastguard Worker std::string result;
171*38e8c45fSAndroid Build Coastguard Worker
172*38e8c45fSAndroid Build Coastguard Worker IPCThreadState* ipc = IPCThreadState::self();
173*38e8c45fSAndroid Build Coastguard Worker const int pid = ipc->getCallingPid();
174*38e8c45fSAndroid Build Coastguard Worker const int uid = ipc->getCallingUid();
175*38e8c45fSAndroid Build Coastguard Worker
176*38e8c45fSAndroid Build Coastguard Worker if ((uid != AID_SHELL) && !PermissionCache::checkPermission(sDump, pid, uid)) {
177*38e8c45fSAndroid Build Coastguard Worker StringAppendF(&result, "Permission Denial: can't dump gpu from pid=%d, uid=%d\n", pid, uid);
178*38e8c45fSAndroid Build Coastguard Worker } else {
179*38e8c45fSAndroid Build Coastguard Worker bool dumpAll = true;
180*38e8c45fSAndroid Build Coastguard Worker bool dumpDriverInfo = false;
181*38e8c45fSAndroid Build Coastguard Worker bool dumpMem = false;
182*38e8c45fSAndroid Build Coastguard Worker bool dumpStats = false;
183*38e8c45fSAndroid Build Coastguard Worker bool dumpWork = false;
184*38e8c45fSAndroid Build Coastguard Worker size_t numArgs = args.size();
185*38e8c45fSAndroid Build Coastguard Worker
186*38e8c45fSAndroid Build Coastguard Worker if (numArgs) {
187*38e8c45fSAndroid Build Coastguard Worker for (size_t index = 0; index < numArgs; ++index) {
188*38e8c45fSAndroid Build Coastguard Worker if (args[index] == String16("--gpustats")) {
189*38e8c45fSAndroid Build Coastguard Worker dumpStats = true;
190*38e8c45fSAndroid Build Coastguard Worker } else if (args[index] == String16("--gpudriverinfo")) {
191*38e8c45fSAndroid Build Coastguard Worker dumpDriverInfo = true;
192*38e8c45fSAndroid Build Coastguard Worker } else if (args[index] == String16("--gpumem")) {
193*38e8c45fSAndroid Build Coastguard Worker dumpMem = true;
194*38e8c45fSAndroid Build Coastguard Worker } else if (args[index] == String16("--gpuwork")) {
195*38e8c45fSAndroid Build Coastguard Worker dumpWork = true;
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker dumpAll = !(dumpDriverInfo || dumpMem || dumpStats || dumpWork);
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker
201*38e8c45fSAndroid Build Coastguard Worker if (dumpAll || dumpDriverInfo) {
202*38e8c45fSAndroid Build Coastguard Worker dumpGameDriverInfo(&result);
203*38e8c45fSAndroid Build Coastguard Worker result.append("\n");
204*38e8c45fSAndroid Build Coastguard Worker }
205*38e8c45fSAndroid Build Coastguard Worker if (dumpAll || dumpMem) {
206*38e8c45fSAndroid Build Coastguard Worker mGpuMem->dump(args, &result);
207*38e8c45fSAndroid Build Coastguard Worker result.append("\n");
208*38e8c45fSAndroid Build Coastguard Worker }
209*38e8c45fSAndroid Build Coastguard Worker if (dumpAll || dumpStats) {
210*38e8c45fSAndroid Build Coastguard Worker mGpuStats->dump(args, &result);
211*38e8c45fSAndroid Build Coastguard Worker result.append("\n");
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker if (dumpAll || dumpWork) {
214*38e8c45fSAndroid Build Coastguard Worker mGpuWork->dump(args, &result);
215*38e8c45fSAndroid Build Coastguard Worker result.append("\n");
216*38e8c45fSAndroid Build Coastguard Worker }
217*38e8c45fSAndroid Build Coastguard Worker }
218*38e8c45fSAndroid Build Coastguard Worker
219*38e8c45fSAndroid Build Coastguard Worker write(fd, result.c_str(), result.size());
220*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
221*38e8c45fSAndroid Build Coastguard Worker }
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker namespace {
224*38e8c45fSAndroid Build Coastguard Worker
cmdHelp(int out)225*38e8c45fSAndroid Build Coastguard Worker status_t cmdHelp(int out) {
226*38e8c45fSAndroid Build Coastguard Worker FILE* outs = fdopen(out, "w");
227*38e8c45fSAndroid Build Coastguard Worker if (!outs) {
228*38e8c45fSAndroid Build Coastguard Worker ALOGE("gpuservice: failed to create out stream: %s (%d)", strerror(errno), errno);
229*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
230*38e8c45fSAndroid Build Coastguard Worker }
231*38e8c45fSAndroid Build Coastguard Worker fprintf(outs,
232*38e8c45fSAndroid Build Coastguard Worker "GPU Service commands:\n"
233*38e8c45fSAndroid Build Coastguard Worker " vkjson dump Vulkan properties as JSON\n"
234*38e8c45fSAndroid Build Coastguard Worker " vkprofiles print support for select Vulkan profiles\n");
235*38e8c45fSAndroid Build Coastguard Worker fclose(outs);
236*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker
cmdVkjson(int out,int)239*38e8c45fSAndroid Build Coastguard Worker status_t cmdVkjson(int out, int /*err*/) {
240*38e8c45fSAndroid Build Coastguard Worker dprintf(out, "%s\n", VkJsonInstanceToJson(VkJsonGetInstance()).c_str());
241*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
242*38e8c45fSAndroid Build Coastguard Worker }
243*38e8c45fSAndroid Build Coastguard Worker
cmdVkprofiles(int out,int)244*38e8c45fSAndroid Build Coastguard Worker status_t cmdVkprofiles(int out, int /*err*/) {
245*38e8c45fSAndroid Build Coastguard Worker dprintf(out, "%s\n", android::vkprofiles::vkProfiles().c_str());
246*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
247*38e8c45fSAndroid Build Coastguard Worker }
248*38e8c45fSAndroid Build Coastguard Worker
dumpGameDriverInfo(std::string * result)249*38e8c45fSAndroid Build Coastguard Worker void dumpGameDriverInfo(std::string* result) {
250*38e8c45fSAndroid Build Coastguard Worker if (!result) return;
251*38e8c45fSAndroid Build Coastguard Worker
252*38e8c45fSAndroid Build Coastguard Worker char stableGameDriver[PROPERTY_VALUE_MAX] = {};
253*38e8c45fSAndroid Build Coastguard Worker property_get("ro.gfx.driver.0", stableGameDriver, "unsupported");
254*38e8c45fSAndroid Build Coastguard Worker StringAppendF(result, "Stable Game Driver: %s\n", stableGameDriver);
255*38e8c45fSAndroid Build Coastguard Worker
256*38e8c45fSAndroid Build Coastguard Worker char preReleaseGameDriver[PROPERTY_VALUE_MAX] = {};
257*38e8c45fSAndroid Build Coastguard Worker property_get("ro.gfx.driver.1", preReleaseGameDriver, "unsupported");
258*38e8c45fSAndroid Build Coastguard Worker StringAppendF(result, "Pre-release Game Driver: %s\n", preReleaseGameDriver);
259*38e8c45fSAndroid Build Coastguard Worker }
260*38e8c45fSAndroid Build Coastguard Worker
261*38e8c45fSAndroid Build Coastguard Worker } // anonymous namespace
262*38e8c45fSAndroid Build Coastguard Worker
263*38e8c45fSAndroid Build Coastguard Worker } // namespace android
264