• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 
19 //#define LOG_NDEBUG 1
20 #define LOG_TAG "GraphicsEnv"
21 
22 #include <graphicsenv/GraphicsEnv.h>
23 
24 #include <dlfcn.h>
25 #include <unistd.h>
26 
27 #include <android-base/file.h>
28 #include <android-base/properties.h>
29 #include <android-base/strings.h>
30 #include <android/dlext.h>
31 #include <binder/IServiceManager.h>
32 #include <graphicsenv/IGpuService.h>
33 #include <log/log.h>
34 #include <nativeloader/dlext_namespaces.h>
35 #include <sys/prctl.h>
36 #include <utils/Trace.h>
37 
38 #include <memory>
39 #include <string>
40 #include <thread>
41 
42 // TODO(b/159240322): Extend this to x86 ABI.
43 #if defined(__LP64__)
44 #define UPDATABLE_DRIVER_ABI "arm64-v8a"
45 #else
46 #define UPDATABLE_DRIVER_ABI "armeabi-v7a"
47 #endif // defined(__LP64__)
48 
49 // TODO(ianelliott@): Get the following from an ANGLE header:
50 #define CURRENT_ANGLE_API_VERSION 2 // Current API verion we are targetting
51 // Version-2 API:
52 typedef bool (*fpANGLEGetFeatureSupportUtilAPIVersion)(unsigned int* versionToUse);
53 typedef bool (*fpANGLEAndroidParseRulesString)(const char* rulesString, void** rulesHandle,
54                                                int* rulesVersion);
55 typedef bool (*fpANGLEGetSystemInfo)(void** handle);
56 typedef bool (*fpANGLEAddDeviceInfoToSystemInfo)(const char* deviceMfr, const char* deviceModel,
57                                                  void* handle);
58 typedef bool (*fpANGLEShouldBeUsedForApplication)(void* rulesHandle, int rulesVersion,
59                                                   void* systemInfoHandle, const char* appName);
60 typedef bool (*fpANGLEFreeRulesHandle)(void* handle);
61 typedef bool (*fpANGLEFreeSystemInfoHandle)(void* handle);
62 
63 namespace android {
64 
65 enum NativeLibrary {
66     LLNDK = 0,
67     VNDKSP = 1,
68 };
69 
70 static constexpr const char* kNativeLibrariesSystemConfigPath[] =
71         {"/apex/com.android.vndk.v{}/etc/llndk.libraries.{}.txt",
72          "/apex/com.android.vndk.v{}/etc/vndksp.libraries.{}.txt"};
73 
vndkVersionStr()74 static std::string vndkVersionStr() {
75 #ifdef __BIONIC__
76     return base::GetProperty("ro.vndk.version", "");
77 #endif
78     return "";
79 }
80 
insertVndkVersionStr(std::string * fileName)81 static void insertVndkVersionStr(std::string* fileName) {
82     LOG_ALWAYS_FATAL_IF(!fileName, "fileName should never be nullptr");
83     std::string version = vndkVersionStr();
84     size_t pos = fileName->find("{}");
85     while (pos != std::string::npos) {
86         fileName->replace(pos, 2, version);
87         pos = fileName->find("{}", pos + version.size());
88     }
89 }
90 
readConfig(const std::string & configFile,std::vector<std::string> * soNames)91 static bool readConfig(const std::string& configFile, std::vector<std::string>* soNames) {
92     // Read list of public native libraries from the config file.
93     std::string fileContent;
94     if (!base::ReadFileToString(configFile, &fileContent)) {
95         return false;
96     }
97 
98     std::vector<std::string> lines = base::Split(fileContent, "\n");
99 
100     for (auto& line : lines) {
101         auto trimmedLine = base::Trim(line);
102         if (!trimmedLine.empty()) {
103             soNames->push_back(trimmedLine);
104         }
105     }
106 
107     return true;
108 }
109 
getSystemNativeLibraries(NativeLibrary type)110 static const std::string getSystemNativeLibraries(NativeLibrary type) {
111     std::string nativeLibrariesSystemConfig = kNativeLibrariesSystemConfigPath[type];
112     insertVndkVersionStr(&nativeLibrariesSystemConfig);
113 
114     std::vector<std::string> soNames;
115     if (!readConfig(nativeLibrariesSystemConfig, &soNames)) {
116         ALOGE("Failed to retrieve library names from %s", nativeLibrariesSystemConfig.c_str());
117         return "";
118     }
119 
120     return base::Join(soNames, ':');
121 }
122 
getGpuService()123 static sp<IGpuService> getGpuService() {
124     static const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
125     if (!binder) {
126         ALOGE("Failed to get gpu service");
127         return nullptr;
128     }
129 
130     return interface_cast<IGpuService>(binder);
131 }
132 
getInstance()133 /*static*/ GraphicsEnv& GraphicsEnv::getInstance() {
134     static GraphicsEnv env;
135     return env;
136 }
137 
isDebuggable()138 bool GraphicsEnv::isDebuggable() {
139     // This flag determines if the application is marked debuggable
140     bool appDebuggable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) > 0;
141 
142     // This flag is set only in `debuggable` builds of the platform
143 #if defined(ANDROID_DEBUGGABLE)
144     bool platformDebuggable = true;
145 #else
146     bool platformDebuggable = false;
147 #endif
148 
149     ALOGV("GraphicsEnv::isDebuggable returning appDebuggable=%s || platformDebuggable=%s",
150           appDebuggable ? "true" : "false", platformDebuggable ? "true" : "false");
151 
152     return appDebuggable || platformDebuggable;
153 }
154 
155 /**
156  * APIs for updatable graphics drivers
157  */
158 
setDriverPathAndSphalLibraries(const std::string & path,const std::string & sphalLibraries)159 void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string& path,
160                                                  const std::string& sphalLibraries) {
161     if (!mDriverPath.empty() || !mSphalLibraries.empty()) {
162         ALOGV("ignoring attempt to change driver path from '%s' to '%s' or change sphal libraries "
163               "from '%s' to '%s'",
164               mDriverPath.c_str(), path.c_str(), mSphalLibraries.c_str(), sphalLibraries.c_str());
165         return;
166     }
167     ALOGV("setting driver path to '%s' and sphal libraries to '%s'", path.c_str(),
168           sphalLibraries.c_str());
169     mDriverPath = path;
170     mSphalLibraries = sphalLibraries;
171 }
172 
173 // Return true if all the required libraries from vndk and sphal namespace are
174 // linked to the driver namespace correctly.
linkDriverNamespaceLocked(android_namespace_t * destNamespace,android_namespace_t * vndkNamespace,const std::string & sharedSphalLibraries)175 bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* destNamespace,
176                                             android_namespace_t* vndkNamespace,
177                                             const std::string& sharedSphalLibraries) {
178     const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
179     if (llndkLibraries.empty()) {
180         return false;
181     }
182     if (!android_link_namespaces(destNamespace, nullptr, llndkLibraries.c_str())) {
183         ALOGE("Failed to link default namespace[%s]", dlerror());
184         return false;
185     }
186 
187     const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP);
188     if (vndkspLibraries.empty()) {
189         return false;
190     }
191     if (!android_link_namespaces(destNamespace, vndkNamespace, vndkspLibraries.c_str())) {
192         ALOGE("Failed to link vndk namespace[%s]", dlerror());
193         return false;
194     }
195 
196     if (sharedSphalLibraries.empty()) {
197         return true;
198     }
199 
200     // Make additional libraries in sphal to be accessible
201     auto sphalNamespace = android_get_exported_namespace("sphal");
202     if (!sphalNamespace) {
203         ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace",
204               sharedSphalLibraries.c_str());
205         return false;
206     }
207 
208     if (!android_link_namespaces(destNamespace, sphalNamespace, sharedSphalLibraries.c_str())) {
209         ALOGE("Failed to link sphal namespace[%s]", dlerror());
210         return false;
211     }
212 
213     return true;
214 }
215 
getDriverNamespace()216 android_namespace_t* GraphicsEnv::getDriverNamespace() {
217     std::lock_guard<std::mutex> lock(mNamespaceMutex);
218 
219     if (mDriverNamespace) {
220         return mDriverNamespace;
221     }
222 
223     if (mDriverPath.empty()) {
224         // For an application process, driver path is empty means this application is not opted in
225         // to use updatable driver. Application process doesn't have the ability to set up
226         // environment variables and hence before `getenv` call will return.
227         // For a process that is not an application process, if it's run from an environment,
228         // for example shell, where environment variables can be set, then it can opt into using
229         // udpatable driver by setting UPDATABLE_GFX_DRIVER to 1. By setting to 1 the developer
230         // driver will be used currently.
231         // TODO(b/159240322) Support the production updatable driver.
232         const char* id = getenv("UPDATABLE_GFX_DRIVER");
233         if (id == nullptr || std::strcmp(id, "1") != 0) {
234             return nullptr;
235         }
236         const sp<IGpuService> gpuService = getGpuService();
237         if (!gpuService) {
238             return nullptr;
239         }
240         mDriverPath = gpuService->getUpdatableDriverPath();
241         if (mDriverPath.empty()) {
242             return nullptr;
243         }
244         mDriverPath.append(UPDATABLE_DRIVER_ABI);
245         ALOGI("Driver path is setup via UPDATABLE_GFX_DRIVER: %s", mDriverPath.c_str());
246     }
247 
248     auto vndkNamespace = android_get_exported_namespace("vndk");
249     if (!vndkNamespace) {
250         return nullptr;
251     }
252 
253     mDriverNamespace = android_create_namespace("updatable gfx driver",
254                                                 mDriverPath.c_str(), // ld_library_path
255                                                 mDriverPath.c_str(), // default_library_path
256                                                 ANDROID_NAMESPACE_TYPE_ISOLATED,
257                                                 nullptr, // permitted_when_isolated_path
258                                                 nullptr);
259 
260     if (!linkDriverNamespaceLocked(mDriverNamespace, vndkNamespace, mSphalLibraries)) {
261         mDriverNamespace = nullptr;
262     }
263 
264     return mDriverNamespace;
265 }
266 
getDriverPath() const267 std::string GraphicsEnv::getDriverPath() const {
268     return mDriverPath;
269 }
270 
271 /**
272  * APIs for GpuStats
273  */
274 
hintActivityLaunch()275 void GraphicsEnv::hintActivityLaunch() {
276     ATRACE_CALL();
277 
278     {
279         std::lock_guard<std::mutex> lock(mStatsLock);
280         if (mActivityLaunched) return;
281         mActivityLaunched = true;
282     }
283 
284     std::thread trySendGpuStatsThread([this]() {
285         // If there's already graphics driver preloaded in the process, just send
286         // the stats info to GpuStats directly through async binder.
287         std::lock_guard<std::mutex> lock(mStatsLock);
288         if (mGpuStats.glDriverToSend) {
289             mGpuStats.glDriverToSend = false;
290             sendGpuStatsLocked(GpuStatsInfo::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
291         }
292         if (mGpuStats.vkDriverToSend) {
293             mGpuStats.vkDriverToSend = false;
294             sendGpuStatsLocked(GpuStatsInfo::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
295         }
296     });
297     trySendGpuStatsThread.detach();
298 }
299 
setGpuStats(const std::string & driverPackageName,const std::string & driverVersionName,uint64_t driverVersionCode,int64_t driverBuildTime,const std::string & appPackageName,const int vulkanVersion)300 void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
301                               const std::string& driverVersionName, uint64_t driverVersionCode,
302                               int64_t driverBuildTime, const std::string& appPackageName,
303                               const int vulkanVersion) {
304     ATRACE_CALL();
305 
306     std::lock_guard<std::mutex> lock(mStatsLock);
307     ALOGV("setGpuStats:\n"
308           "\tdriverPackageName[%s]\n"
309           "\tdriverVersionName[%s]\n"
310           "\tdriverVersionCode[%" PRIu64 "]\n"
311           "\tdriverBuildTime[%" PRId64 "]\n"
312           "\tappPackageName[%s]\n"
313           "\tvulkanVersion[%d]\n",
314           driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
315           appPackageName.c_str(), vulkanVersion);
316 
317     mGpuStats.driverPackageName = driverPackageName;
318     mGpuStats.driverVersionName = driverVersionName;
319     mGpuStats.driverVersionCode = driverVersionCode;
320     mGpuStats.driverBuildTime = driverBuildTime;
321     mGpuStats.appPackageName = appPackageName;
322     mGpuStats.vulkanVersion = vulkanVersion;
323 }
324 
setDriverToLoad(GpuStatsInfo::Driver driver)325 void GraphicsEnv::setDriverToLoad(GpuStatsInfo::Driver driver) {
326     ATRACE_CALL();
327 
328     std::lock_guard<std::mutex> lock(mStatsLock);
329     switch (driver) {
330         case GpuStatsInfo::Driver::GL:
331         case GpuStatsInfo::Driver::GL_UPDATED:
332         case GpuStatsInfo::Driver::ANGLE: {
333             if (mGpuStats.glDriverToLoad == GpuStatsInfo::Driver::NONE ||
334                 mGpuStats.glDriverToLoad == GpuStatsInfo::Driver::GL) {
335                 mGpuStats.glDriverToLoad = driver;
336                 break;
337             }
338 
339             if (mGpuStats.glDriverFallback == GpuStatsInfo::Driver::NONE) {
340                 mGpuStats.glDriverFallback = driver;
341             }
342             break;
343         }
344         case GpuStatsInfo::Driver::VULKAN:
345         case GpuStatsInfo::Driver::VULKAN_UPDATED: {
346             if (mGpuStats.vkDriverToLoad == GpuStatsInfo::Driver::NONE ||
347                 mGpuStats.vkDriverToLoad == GpuStatsInfo::Driver::VULKAN) {
348                 mGpuStats.vkDriverToLoad = driver;
349                 break;
350             }
351 
352             if (mGpuStats.vkDriverFallback == GpuStatsInfo::Driver::NONE) {
353                 mGpuStats.vkDriverFallback = driver;
354             }
355             break;
356         }
357         default:
358             break;
359     }
360 }
361 
setDriverLoaded(GpuStatsInfo::Api api,bool isDriverLoaded,int64_t driverLoadingTime)362 void GraphicsEnv::setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded,
363                                   int64_t driverLoadingTime) {
364     ATRACE_CALL();
365 
366     std::lock_guard<std::mutex> lock(mStatsLock);
367     if (api == GpuStatsInfo::Api::API_GL) {
368         mGpuStats.glDriverToSend = true;
369         mGpuStats.glDriverLoadingTime = driverLoadingTime;
370     } else {
371         mGpuStats.vkDriverToSend = true;
372         mGpuStats.vkDriverLoadingTime = driverLoadingTime;
373     }
374 
375     sendGpuStatsLocked(api, isDriverLoaded, driverLoadingTime);
376 }
377 
378 // Hash function to calculate hash for null-terminated Vulkan extension names
379 // We store hash values of the extensions, rather than the actual names or
380 // indices to be able to support new extensions easily, avoid creating
381 // a table of 'known' extensions inside Android and reduce the runtime overhead.
calculateExtensionHash(const char * word)382 static uint64_t calculateExtensionHash(const char* word) {
383     if (!word) {
384         return 0;
385     }
386     const size_t wordLen = strlen(word);
387     const uint32_t seed = 167;
388     uint64_t hash = 0;
389     for (size_t i = 0; i < wordLen; i++) {
390         hash = (hash * seed) + word[i];
391     }
392     return hash;
393 }
394 
setVulkanInstanceExtensions(uint32_t enabledExtensionCount,const char * const * ppEnabledExtensionNames)395 void GraphicsEnv::setVulkanInstanceExtensions(uint32_t enabledExtensionCount,
396                                               const char* const* ppEnabledExtensionNames) {
397     ATRACE_CALL();
398     if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) {
399         return;
400     }
401 
402     const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS;
403     uint64_t extensionHashes[maxNumStats];
404     const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats);
405     for(uint32_t i = 0; i < numStats; i++) {
406         extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]);
407     }
408     setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
409                         extensionHashes, numStats);
410 }
411 
setVulkanDeviceExtensions(uint32_t enabledExtensionCount,const char * const * ppEnabledExtensionNames)412 void GraphicsEnv::setVulkanDeviceExtensions(uint32_t enabledExtensionCount,
413                                             const char* const* ppEnabledExtensionNames) {
414     ATRACE_CALL();
415     if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) {
416         return;
417     }
418 
419     const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS;
420     uint64_t extensionHashes[maxNumStats];
421     const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats);
422     for(uint32_t i = 0; i < numStats; i++) {
423         extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]);
424     }
425     setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
426                         extensionHashes, numStats);
427 }
428 
readyToSendGpuStatsLocked()429 bool GraphicsEnv::readyToSendGpuStatsLocked() {
430     // Only send stats for processes having at least one activity launched and that process doesn't
431     // skip the GraphicsEnvironment setup.
432     return mActivityLaunched && !mGpuStats.appPackageName.empty();
433 }
434 
setTargetStats(const GpuStatsInfo::Stats stats,const uint64_t value)435 void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value) {
436     return setTargetStatsArray(stats, &value, 1);
437 }
438 
setTargetStatsArray(const GpuStatsInfo::Stats stats,const uint64_t * values,const uint32_t valueCount)439 void GraphicsEnv::setTargetStatsArray(const GpuStatsInfo::Stats stats, const uint64_t* values,
440                                       const uint32_t valueCount) {
441     ATRACE_CALL();
442 
443     std::lock_guard<std::mutex> lock(mStatsLock);
444     if (!readyToSendGpuStatsLocked()) return;
445 
446     const sp<IGpuService> gpuService = getGpuService();
447     if (gpuService) {
448         gpuService->setTargetStatsArray(mGpuStats.appPackageName, mGpuStats.driverVersionCode,
449                                         stats, values, valueCount);
450     }
451 }
452 
sendGpuStatsLocked(GpuStatsInfo::Api api,bool isDriverLoaded,int64_t driverLoadingTime)453 void GraphicsEnv::sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded,
454                                      int64_t driverLoadingTime) {
455     ATRACE_CALL();
456 
457     if (!readyToSendGpuStatsLocked()) return;
458 
459     ALOGV("sendGpuStats:\n"
460           "\tdriverPackageName[%s]\n"
461           "\tdriverVersionName[%s]\n"
462           "\tdriverVersionCode[%" PRIu64 "]\n"
463           "\tdriverBuildTime[%" PRId64 "]\n"
464           "\tappPackageName[%s]\n"
465           "\tvulkanVersion[%d]\n"
466           "\tapi[%d]\n"
467           "\tisDriverLoaded[%d]\n"
468           "\tdriverLoadingTime[%" PRId64 "]",
469           mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
470           mGpuStats.driverVersionCode, mGpuStats.driverBuildTime, mGpuStats.appPackageName.c_str(),
471           mGpuStats.vulkanVersion, static_cast<int32_t>(api), isDriverLoaded, driverLoadingTime);
472 
473     GpuStatsInfo::Driver driver = GpuStatsInfo::Driver::NONE;
474     bool isIntendedDriverLoaded = false;
475     if (api == GpuStatsInfo::Api::API_GL) {
476         driver = mGpuStats.glDriverToLoad;
477         isIntendedDriverLoaded =
478                 isDriverLoaded && (mGpuStats.glDriverFallback == GpuStatsInfo::Driver::NONE);
479     } else {
480         driver = mGpuStats.vkDriverToLoad;
481         isIntendedDriverLoaded =
482                 isDriverLoaded && (mGpuStats.vkDriverFallback == GpuStatsInfo::Driver::NONE);
483     }
484 
485     const sp<IGpuService> gpuService = getGpuService();
486     if (gpuService) {
487         gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
488                                 mGpuStats.driverVersionCode, mGpuStats.driverBuildTime,
489                                 mGpuStats.appPackageName, mGpuStats.vulkanVersion, driver,
490                                 isIntendedDriverLoaded, driverLoadingTime);
491     }
492 }
493 
setInjectLayersPrSetDumpable()494 bool GraphicsEnv::setInjectLayersPrSetDumpable() {
495     if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
496         return false;
497     }
498     return true;
499 }
500 
501 /**
502  * APIs for ANGLE
503  */
504 
shouldUseAngle()505 bool GraphicsEnv::shouldUseAngle() {
506     // Make sure we are init'ed
507     if (mPackageName.empty()) {
508         ALOGV("Package name is empty. setAngleInfo() has not been called to enable ANGLE.");
509         return false;
510     }
511 
512     return mShouldUseAngle;
513 }
514 
515 // Set ANGLE information.
516 // If path is "system", it means system ANGLE must be used for the process.
517 // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
518 // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
setAngleInfo(const std::string & path,const bool shouldUseNativeDriver,const std::string & packageName,const std::vector<std::string> eglFeatures)519 void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
520                                const std::string& packageName,
521                                const std::vector<std::string> eglFeatures) {
522     if (mShouldUseAngle) {
523         // ANGLE is already set up for this application process, even if the application
524         // needs to switch from apk to system or vice versa, the application process must
525         // be killed and relaunch so that the loader can properly load ANGLE again.
526         // The architecture does not support runtime switch between drivers, so just return.
527         ALOGE("ANGLE is already set for %s", packageName.c_str());
528         return;
529     }
530 
531     mAngleEglFeatures = std::move(eglFeatures);
532     ALOGV("setting ANGLE path to '%s'", path.c_str());
533     mAnglePath = std::move(path);
534     ALOGV("setting app package name to '%s'", packageName.c_str());
535     mPackageName = std::move(packageName);
536     if (mAnglePath == "system") {
537         mShouldUseSystemAngle = true;
538     }
539     if (!mAnglePath.empty()) {
540         mShouldUseAngle = true;
541     }
542     mShouldUseNativeDriver = shouldUseNativeDriver;
543 }
544 
getPackageName()545 std::string& GraphicsEnv::getPackageName() {
546     return mPackageName;
547 }
548 
getAngleEglFeatures()549 const std::vector<std::string>& GraphicsEnv::getAngleEglFeatures() {
550     return mAngleEglFeatures;
551 }
552 
getAngleNamespace()553 android_namespace_t* GraphicsEnv::getAngleNamespace() {
554     std::lock_guard<std::mutex> lock(mNamespaceMutex);
555 
556     if (mAngleNamespace) {
557         return mAngleNamespace;
558     }
559 
560     if (mAnglePath.empty() && !mShouldUseSystemAngle) {
561         ALOGV("mAnglePath is empty and not using system ANGLE, abort creating ANGLE namespace");
562         return nullptr;
563     }
564 
565     // Construct the search paths for system ANGLE.
566     const char* const defaultLibraryPaths =
567 #if defined(__LP64__)
568             "/vendor/lib64/egl:/system/lib64/egl";
569 #else
570             "/vendor/lib/egl:/system/lib/egl";
571 #endif
572 
573     // If the application process will run on top of system ANGLE, construct the namespace
574     // with sphal namespace being the parent namespace so that search paths and libraries
575     // are properly inherited.
576     mAngleNamespace =
577             android_create_namespace("ANGLE",
578                                      mShouldUseSystemAngle ? defaultLibraryPaths
579                                                            : mAnglePath.c_str(), // ld_library_path
580                                      mShouldUseSystemAngle
581                                              ? defaultLibraryPaths
582                                              : mAnglePath.c_str(), // default_library_path
583                                      ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED,
584                                      nullptr, // permitted_when_isolated_path
585                                      mShouldUseSystemAngle ? android_get_exported_namespace("sphal")
586                                                            : nullptr); // parent
587 
588     ALOGD_IF(!mAngleNamespace, "Could not create ANGLE namespace from default");
589 
590     if (!mShouldUseSystemAngle) {
591         return mAngleNamespace;
592     }
593 
594     auto vndkNamespace = android_get_exported_namespace("vndk");
595     if (!vndkNamespace) {
596         return nullptr;
597     }
598 
599     if (!linkDriverNamespaceLocked(mAngleNamespace, vndkNamespace, "")) {
600         mAngleNamespace = nullptr;
601     }
602 
603     return mAngleNamespace;
604 }
605 
nativeToggleAngleAsSystemDriver(bool enabled)606 void GraphicsEnv::nativeToggleAngleAsSystemDriver(bool enabled) {
607     const sp<IGpuService> gpuService = getGpuService();
608     if (!gpuService) {
609         ALOGE("No GPU service");
610         return;
611     }
612     gpuService->toggleAngleAsSystemDriver(enabled);
613 }
614 
shouldUseSystemAngle()615 bool GraphicsEnv::shouldUseSystemAngle() {
616     return mShouldUseSystemAngle;
617 }
618 
shouldUseNativeDriver()619 bool GraphicsEnv::shouldUseNativeDriver() {
620     return mShouldUseNativeDriver;
621 }
622 
623 /**
624  * APIs for debuggable layers
625  */
626 
setLayerPaths(NativeLoaderNamespace * appNamespace,const std::string & layerPaths)627 void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace,
628                                 const std::string& layerPaths) {
629     if (mLayerPaths.empty()) {
630         mLayerPaths = layerPaths;
631         mAppNamespace = appNamespace;
632     } else {
633         ALOGV("Vulkan layer search path already set, not clobbering with '%s' for namespace %p'",
634               layerPaths.c_str(), appNamespace);
635     }
636 }
637 
getAppNamespace()638 NativeLoaderNamespace* GraphicsEnv::getAppNamespace() {
639     return mAppNamespace;
640 }
641 
getLayerPaths()642 const std::string& GraphicsEnv::getLayerPaths() {
643     return mLayerPaths;
644 }
645 
getDebugLayers()646 const std::string& GraphicsEnv::getDebugLayers() {
647     return mDebugLayers;
648 }
649 
getDebugLayersGLES()650 const std::string& GraphicsEnv::getDebugLayersGLES() {
651     return mDebugLayersGLES;
652 }
653 
setDebugLayers(const std::string & layers)654 void GraphicsEnv::setDebugLayers(const std::string& layers) {
655     mDebugLayers = layers;
656 }
657 
setDebugLayersGLES(const std::string & layers)658 void GraphicsEnv::setDebugLayersGLES(const std::string& layers) {
659     mDebugLayersGLES = layers;
660 }
661 
662 } // namespace android
663