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 <mutex>
21 #include <string>
22 #include <vector>
23 
24 struct android_namespace_t;
25 
26 namespace android {
27 
28 struct NativeLoaderNamespace;
29 
30 class GraphicsEnv {
31 public:
32     enum Api {
33         API_GL = 0,
34         API_VK = 1,
35     };
36 
37     enum Driver {
38         NONE = 0,
39         GL = 1,
40         GL_UPDATED = 2,
41         VULKAN = 3,
42         VULKAN_UPDATED = 4,
43         ANGLE = 5,
44     };
45 
46     enum Stats {
47         CPU_VULKAN_IN_USE = 0,
48     };
49 
50 private:
51     struct GpuStats {
52         std::string driverPackageName;
53         std::string driverVersionName;
54         uint64_t driverVersionCode;
55         int64_t driverBuildTime;
56         std::string appPackageName;
57         int32_t vulkanVersion;
58         Driver glDriverToLoad;
59         Driver glDriverFallback;
60         Driver vkDriverToLoad;
61         Driver vkDriverFallback;
62         bool glDriverToSend;
63         bool vkDriverToSend;
64         int64_t glDriverLoadingTime;
65         int64_t vkDriverLoadingTime;
66 
GpuStatsGpuStats67         GpuStats()
68               : driverPackageName(""),
69                 driverVersionName(""),
70                 driverVersionCode(0),
71                 driverBuildTime(0),
72                 appPackageName(""),
73                 vulkanVersion(0),
74                 glDriverToLoad(Driver::NONE),
75                 glDriverFallback(Driver::NONE),
76                 vkDriverToLoad(Driver::NONE),
77                 vkDriverFallback(Driver::NONE),
78                 glDriverToSend(false),
79                 vkDriverToSend(false),
80                 glDriverLoadingTime(0),
81                 vkDriverLoadingTime(0) {}
82     };
83 
84 public:
85     static GraphicsEnv& getInstance();
86 
87     // Check if the process is debuggable. It returns false except in any of the
88     // following circumstances:
89     // 1. ro.debuggable=1 (global debuggable enabled).
90     // 2. android:debuggable="true" in the manifest for an individual app.
91     // 3. An app which explicitly calls prctl(PR_SET_DUMPABLE, 1).
92     // 4. GraphicsEnv calls prctl(PR_SET_DUMPABLE, 1) in the presence of
93     //    <meta-data android:name="com.android.graphics.injectLayers.enable"
94     //               android:value="true"/>
95     //    in the application manifest.
96     bool isDebuggable();
97 
98     // Set a search path for loading graphics drivers. The path is a list of
99     // directories separated by ':'. A directory can be contained in a zip file
100     // (drivers must be stored uncompressed and page aligned); such elements
101     // in the search path must have a '!' after the zip filename, e.g.
102     //     /data/app/com.example.driver/base.apk!/lib/arm64-v8a
103     // Also set additional required sphal libraries to the linker for loading
104     // graphics drivers. The string is a list of libraries separated by ':',
105     // which is required by android_link_namespaces.
106     void setDriverPathAndSphalLibraries(const std::string path, const std::string sphalLibraries);
107     android_namespace_t* getDriverNamespace();
108     void hintActivityLaunch();
109     void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
110                      uint64_t versionCode, int64_t driverBuildTime,
111                      const std::string& appPackageName, const int32_t vulkanVersion);
112     void setTargetStats(const Stats stats, const uint64_t value = 0);
113     void setDriverToLoad(Driver driver);
114     void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
115     void sendGpuStatsLocked(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
116 
117     bool shouldUseAngle(std::string appName);
118     bool shouldUseAngle();
119     // Set a search path for loading ANGLE libraries. The path is a list of
120     // directories separated by ':'. A directory can be contained in a zip file
121     // (libraries must be stored uncompressed and page aligned); such elements
122     // in the search path must have a '!' after the zip filename, e.g.
123     //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
124     void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
125                       const int rulesFd, const long rulesOffset, const long rulesLength);
126     android_namespace_t* getAngleNamespace();
127     std::string& getAngleAppName();
128 
129     void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths);
130     NativeLoaderNamespace* getAppNamespace();
131 
132     const std::string& getLayerPaths();
133 
134     void setDebugLayers(const std::string layers);
135     void setDebugLayersGLES(const std::string layers);
136     const std::string& getDebugLayers();
137     const std::string& getDebugLayersGLES();
138 
139 private:
140     enum UseAngle { UNKNOWN, YES, NO };
141 
142     void* loadLibrary(std::string name);
143     bool checkAngleRules(void* so);
144     void updateUseAngle();
145     bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
146 
147     GraphicsEnv() = default;
148     std::string mDriverPath;
149     std::string mSphalLibraries;
150     std::mutex mStatsLock;
151     GpuStats mGpuStats;
152     std::string mAnglePath;
153     std::string mAngleAppName;
154     std::string mAngleDeveloperOptIn;
155     std::vector<char> mRulesBuffer;
156     UseAngle mUseAngle = UNKNOWN;
157     std::string mDebugLayers;
158     std::string mDebugLayersGLES;
159     std::string mLayerPaths;
160     std::mutex mNamespaceMutex;
161     android_namespace_t* mDriverNamespace = nullptr;
162     android_namespace_t* mAngleNamespace = nullptr;
163     NativeLoaderNamespace* mAppNamespace = nullptr;
164 };
165 
166 } // namespace android
167 
168 #endif // ANDROID_UI_GRAPHICS_ENV_H
169