1 /*
2  * Copyright 2016 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 LOG_TAG "GraphicsEnvironment"
18 
19 #include <vector>
20 
21 #include <graphicsenv/GraphicsEnv.h>
22 #include <nativehelper/ScopedUtfChars.h>
23 #include <nativeloader/native_loader.h>
24 #include "core_jni_helpers.h"
25 
26 namespace {
27 
28 bool isDebuggable_native() {
29     return android::GraphicsEnv::getInstance().isDebuggable();
30 }
31 
32 void setDriverPathAndSphalLibraries_native(JNIEnv* env, jobject clazz, jstring path,
33                                            jstring sphalLibraries) {
34     ScopedUtfChars pathChars(env, path);
35     ScopedUtfChars sphalLibrariesChars(env, sphalLibraries);
36     android::GraphicsEnv::getInstance().setDriverPathAndSphalLibraries(pathChars.c_str(),
37                                                                        sphalLibrariesChars.c_str());
38 }
39 
40 void setGpuStats_native(JNIEnv* env, jobject clazz, jstring driverPackageName,
41                         jstring driverVersionName, jlong driverVersionCode,
42                         jlong driverBuildTime, jstring appPackageName, jint vulkanVersion) {
43     ScopedUtfChars driverPackageNameChars(env, driverPackageName);
44     ScopedUtfChars driverVersionNameChars(env, driverVersionName);
45     ScopedUtfChars appPackageNameChars(env, appPackageName);
46     android::GraphicsEnv::getInstance().setGpuStats(driverPackageNameChars.c_str(),
47                                                     driverVersionNameChars.c_str(),
48                                                     driverVersionCode, driverBuildTime,
49                                                     appPackageNameChars.c_str(), vulkanVersion);
50 }
51 
52 void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName,
53                          jstring devOptIn, jobjectArray featuresObj, jobject rulesFd,
54                          jlong rulesOffset, jlong rulesLength) {
55     ScopedUtfChars pathChars(env, path);
56     ScopedUtfChars appNameChars(env, appName);
57     ScopedUtfChars devOptInChars(env, devOptIn);
58 
59     std::vector<std::string> features;
60     if (featuresObj != nullptr) {
61         jsize length = env->GetArrayLength(featuresObj);
62         for (jsize i = 0; i < length; ++i) {
63             jstring jstr = static_cast<jstring>(env->GetObjectArrayElement(featuresObj, i));
64             // null entries are ignored
65             if (jstr == nullptr) {
66                 continue;
67             }
68             const char* cstr = env->GetStringUTFChars(jstr, nullptr);
69             if (cstr == nullptr) {
70                 continue;
71             }
72             features.emplace_back(cstr);
73             env->ReleaseStringUTFChars(jstr, cstr);
74         }
75     }
76 
77     int rulesFd_native = jniGetFDFromFileDescriptor(env, rulesFd);
78 
79     android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
80                                                      devOptInChars.c_str(), features,
81                                                      rulesFd_native, rulesOffset, rulesLength);
82 }
83 
84 bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) {
85     ScopedUtfChars appNameChars(env, appName);
86     return android::GraphicsEnv::getInstance().shouldUseAngle(appNameChars.c_str());
87 }
88 
89 void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
90     android::NativeLoaderNamespace* appNamespace = android::FindNativeLoaderNamespaceByClassLoader(
91         env, classLoader);
92     ScopedUtfChars layerPathsChars(env, layerPaths);
93     android::GraphicsEnv::getInstance().setLayerPaths(appNamespace, layerPathsChars.c_str());
94 }
95 
96 void setDebugLayers_native(JNIEnv* env, jobject clazz, jstring layers) {
97     if (layers != nullptr) {
98         ScopedUtfChars layersChars(env, layers);
99         android::GraphicsEnv::getInstance().setDebugLayers(layersChars.c_str());
100     }
101 }
102 
103 void setDebugLayersGLES_native(JNIEnv* env, jobject clazz, jstring layers) {
104     if (layers != nullptr) {
105         ScopedUtfChars layersChars(env, layers);
106         android::GraphicsEnv::getInstance().setDebugLayersGLES(layersChars.c_str());
107     }
108 }
109 
110 bool setInjectLayersPrSetDumpable_native() {
111     return android::GraphicsEnv::getInstance().setInjectLayersPrSetDumpable();
112 }
113 
114 void hintActivityLaunch_native(JNIEnv* env, jobject clazz) {
115     android::GraphicsEnv::getInstance().hintActivityLaunch();
116 }
117 
118 const JNINativeMethod g_methods[] = {
119         {"isDebuggable", "()Z", reinterpret_cast<void*>(isDebuggable_native)},
120         {"setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V",
121          reinterpret_cast<void*>(setDriverPathAndSphalLibraries_native)},
122         {"setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V",
123          reinterpret_cast<void*>(setGpuStats_native)},
124         {"setInjectLayersPrSetDumpable", "()Z",
125          reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)},
126         {"setAngleInfo",
127          "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/io/"
128          "FileDescriptor;JJ)V",
129          reinterpret_cast<void*>(setAngleInfo_native)},
130         {"getShouldUseAngle", "(Ljava/lang/String;)Z",
131          reinterpret_cast<void*>(shouldUseAngle_native)},
132         {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
133          reinterpret_cast<void*>(setLayerPaths_native)},
134         {"setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native)},
135         {"setDebugLayersGLES", "(Ljava/lang/String;)V",
136          reinterpret_cast<void*>(setDebugLayersGLES_native)},
137         {"hintActivityLaunch", "()V", reinterpret_cast<void*>(hintActivityLaunch_native)},
138 };
139 
140 const char* const kGraphicsEnvironmentName = "android/os/GraphicsEnvironment";
141 
142 } // anonymous namespace
143 
144 namespace android {
145 
146 int register_android_os_GraphicsEnvironment(JNIEnv* env) {
147     return RegisterMethodsOrDie(env, kGraphicsEnvironmentName, g_methods, NELEM(g_methods));
148 }
149 
150 } // namespace android
151