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 #ifndef ANDROID_UI_GRAPHICS_ENV_H
18 #define ANDROID_UI_GRAPHICS_ENV_H 1
19 
20 #include <graphicsenv/GpuStatsInfo.h>
21 
22 #include <mutex>
23 #include <string>
24 #include <vector>
25 
26 struct android_namespace_t;
27 
28 namespace android {
29 
30 struct NativeLoaderNamespace;
31 
32 // The GraphicsEnv is a singleton per application process and is used to properly set up the
33 // graphics drivers for the application process during application starts. The architecture of
34 // the graphics driver loader does not support runtime switch and only supports switch to different
35 // graphics drivers when application process launches and hence the only way to switch to different
36 // graphics drivers is to completely kill the application process and relaunch the application.
37 class GraphicsEnv {
38 public:
39     static GraphicsEnv& getInstance();
40 
41     // Check if the process is debuggable. It returns false except in any of the
42     // following circumstances:
43     // 1. ANDROID_DEBUGGABLE is defined (global debuggable enabled).
44     // 2. android:debuggable="true" in the manifest for an individual app.
45     // 3. An app which explicitly calls prctl(PR_SET_DUMPABLE, 1).
46     // 4. GraphicsEnv calls prctl(PR_SET_DUMPABLE, 1) in the presence of
47     //    <meta-data android:name="com.android.graphics.injectLayers.enable"
48     //               android:value="true"/>
49     //    in the application manifest.
50     bool isDebuggable();
51 
52     /*
53      * Apis for updatable driver
54      */
55     // Set a search path for loading graphics drivers. The path is a list of
56     // directories separated by ':'. A directory can be contained in a zip file
57     // (drivers must be stored uncompressed and page aligned); such elements
58     // in the search path must have a '!' after the zip filename, e.g.
59     //     /data/app/com.example.driver/base.apk!/lib/arm64-v8a
60     // Also set additional required sphal libraries to the linker for loading
61     // graphics drivers. The string is a list of libraries separated by ':',
62     // which is required by android_link_namespaces.
63     void setDriverPathAndSphalLibraries(const std::string& path, const std::string& sphalLibraries);
64     // Get the updatable driver namespace.
65     android_namespace_t* getDriverNamespace();
66     std::string getDriverPath() const;
67 
68     /*
69      * Apis for GpuStats
70      */
71     // Hint there's real activity launching on the app process.
72     void hintActivityLaunch();
73     // Set the initial GpuStats.
74     void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
75                      uint64_t versionCode, int64_t driverBuildTime,
76                      const std::string& appPackageName, const int32_t vulkanVersion);
77     // Set stats for target GpuStatsInfo::Stats type.
78     void setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value = 0);
79     // Set array of stats for target GpuStatsInfo::Stats type.
80     void setTargetStatsArray(const GpuStatsInfo::Stats stats, const uint64_t* values,
81                              const uint32_t valueCount);
82     // Set which driver is intended to load.
83     void setDriverToLoad(GpuStatsInfo::Driver driver);
84     // Set which driver is actually loaded.
85     void setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);
86     // Set which instance extensions are enabled for the app.
87     void setVulkanInstanceExtensions(uint32_t enabledExtensionCount,
88                                      const char* const* ppEnabledExtensionNames);
89     // Set which device extensions are enabled for the app.
90     void setVulkanDeviceExtensions(uint32_t enabledExtensionCount,
91                                    const char* const* ppEnabledExtensionNames);
92     // Add the engine name passed in VkApplicationInfo during CreateInstance
93     void addVulkanEngineName(const char* engineName);
94 
95     /*
96      * Api for Vk/GL layer injection.  Presently, drivers enable certain
97      * profiling features when prctl(PR_GET_DUMPABLE) returns true.
98      * Calling this when layer injection metadata is present allows the driver
99      * to enable profiling even when in a non-debuggable app
100      */
101     bool setInjectLayersPrSetDumpable();
102 
103     /*
104      * Apis for ANGLE
105      */
106     // Check if this app process should use ANGLE.
107     bool shouldUseAngle();
108     // Set a search path for loading ANGLE libraries. The path is a list of
109     // directories separated by ':'. A directory can be contained in a zip file
110     // (libraries must be stored uncompressed and page aligned); such elements
111     // in the search path must have a '!' after the zip filename, e.g.
112     //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
113     // If the search patch is "system", then it means the system ANGLE should be used.
114     // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
115     // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
116     void setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
117                       const std::string& packageName, const std::vector<std::string> eglFeatures);
118     // Get the ANGLE driver namespace.
119     android_namespace_t* getAngleNamespace();
120     // Get the app package name.
121     std::string& getPackageName();
122     const std::vector<std::string>& getAngleEglFeatures();
123     // Set the persist.graphics.egl system property value.
124     void nativeToggleAngleAsSystemDriver(bool enabled);
125     bool shouldUseSystemAngle();
126     bool shouldUseNativeDriver();
127 
128     /*
129      * Apis for debug layer
130      */
131     // Set additional layer search paths.
132     void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string& layerPaths);
133     // Get the app namespace for loading layers.
134     NativeLoaderNamespace* getAppNamespace();
135     // Get additional layer search paths.
136     const std::string& getLayerPaths();
137     // Set the Vulkan debug layers.
138     void setDebugLayers(const std::string& layers);
139     // Set the GL debug layers.
140     void setDebugLayersGLES(const std::string& layers);
141     // Get the debug layers to load.
142     const std::string& getDebugLayers();
143     // Get the debug layers to load.
144     const std::string& getDebugLayersGLES();
145 
146 private:
147     // Link updatable driver namespace with llndk and vndk-sp libs.
148     bool linkDriverNamespaceLocked(android_namespace_t* destNamespace,
149                                    android_namespace_t* vndkNamespace,
150                                    const std::string& sharedSphalLibraries);
151     // Check whether this process is ready to send stats.
152     bool readyToSendGpuStatsLocked();
153     // Send the initial complete GpuStats to GpuService.
154     void sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);
155 
156     GraphicsEnv() = default;
157 
158     // This mutex protects the namespace creation.
159     std::mutex mNamespaceMutex;
160 
161     /**
162      * Updatable driver variables.
163      */
164     // Path to updatable driver libs.
165     std::string mDriverPath;
166     // Path to additional sphal libs linked to updatable driver namespace.
167     std::string mSphalLibraries;
168     // Updatable driver namespace.
169     android_namespace_t* mDriverNamespace = nullptr;
170 
171     /**
172      * ANGLE variables.
173      */
174     // Path to ANGLE libs.
175     std::string mAnglePath;
176     // App's package name.
177     std::string mPackageName;
178     // ANGLE EGL features;
179     std::vector<std::string> mAngleEglFeatures;
180     // Whether ANGLE should be used.
181     bool mShouldUseAngle = false;
182     // Whether loader should load system ANGLE.
183     bool mShouldUseSystemAngle = false;
184     // Whether loader should load native GLES driver.
185     bool mShouldUseNativeDriver = false;
186     // ANGLE namespace.
187     android_namespace_t* mAngleNamespace = nullptr;
188 
189     /**
190      * GPU metrics.
191      */
192     // This mutex protects mGpuStats and get gpuservice call.
193     std::mutex mStatsLock;
194     // Cache the activity launch info
195     bool mActivityLaunched = false;
196     // Information bookkept for GpuStats.
197     GpuStatsInfo mGpuStats;
198 
199     /**
200      * Debug layers.
201      */
202     // Vulkan debug layers libs.
203     std::string mDebugLayers;
204     // GL debug layers libs.
205     std::string mDebugLayersGLES;
206     // Additional debug layers search path.
207     std::string mLayerPaths;
208     // This App's namespace to open native libraries.
209     NativeLoaderNamespace* mAppNamespace = nullptr;
210 };
211 
212 } // namespace android
213 
214 #endif // ANDROID_UI_GRAPHICS_ENV_H
215