1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include <GraphicsJNI.h>
18*d57664e9SAndroid Build Coastguard Worker #include <SkGraphics.h>
19*d57664e9SAndroid Build Coastguard Worker
20*d57664e9SAndroid Build Coastguard Worker #include <unordered_map>
21*d57664e9SAndroid Build Coastguard Worker #include <vector>
22*d57664e9SAndroid Build Coastguard Worker
23*d57664e9SAndroid Build Coastguard Worker #include "Properties.h"
24*d57664e9SAndroid Build Coastguard Worker #include "android/graphics/jni_runtime.h"
25*d57664e9SAndroid Build Coastguard Worker #include "graphics_jni_helpers.h"
26*d57664e9SAndroid Build Coastguard Worker
27*d57664e9SAndroid Build Coastguard Worker using namespace std;
28*d57664e9SAndroid Build Coastguard Worker
29*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Bitmap(JNIEnv*);
30*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_BitmapFactory(JNIEnv*);
31*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
32*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_ByteBufferStreamAdaptor(JNIEnv* env);
33*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Camera(JNIEnv* env);
34*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
35*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Graphics(JNIEnv* env);
36*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_ImageDecoder(JNIEnv*);
37*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Interpolator(JNIEnv* env);
38*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_MaskFilter(JNIEnv* env);
39*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_NinePatch(JNIEnv*);
40*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_PathEffect(JNIEnv* env);
41*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Shader(JNIEnv* env);
42*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_RenderEffect(JNIEnv* env);
43*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Typeface(JNIEnv* env);
44*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_YuvImage(JNIEnv* env);
45*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env);
46*d57664e9SAndroid Build Coastguard Worker
47*d57664e9SAndroid Build Coastguard Worker namespace android {
48*d57664e9SAndroid Build Coastguard Worker
49*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Canvas(JNIEnv* env);
50*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_CanvasProperty(JNIEnv* env);
51*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Color(JNIEnv* env);
52*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_ColorFilter(JNIEnv* env);
53*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_ColorSpace(JNIEnv* env);
54*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_DrawFilter(JNIEnv* env);
55*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_FontFamily(JNIEnv* env);
56*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Gainmap(JNIEnv* env);
57*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env);
58*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_HardwareRendererObserver(JNIEnv* env);
59*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Matrix(JNIEnv* env);
60*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Mesh(JNIEnv* env);
61*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_MeshSpecification(JNIEnv* env);
62*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Paint(JNIEnv* env);
63*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Path(JNIEnv* env);
64*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_PathIterator(JNIEnv* env);
65*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_PathMeasure(JNIEnv* env);
66*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Picture(JNIEnv* env);
67*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_Region(JNIEnv* env);
68*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
69*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
70*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
71*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
72*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_fonts_Font(JNIEnv* env);
73*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
74*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_text_LineBreaker(JNIEnv* env);
75*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
76*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_text_TextShaper(JNIEnv* env);
77*d57664e9SAndroid Build Coastguard Worker extern int register_android_graphics_text_GraphemeBreak(JNIEnv* env);
78*d57664e9SAndroid Build Coastguard Worker
79*d57664e9SAndroid Build Coastguard Worker extern int register_android_util_PathParser(JNIEnv* env);
80*d57664e9SAndroid Build Coastguard Worker extern int register_android_view_DisplayListCanvas(JNIEnv* env);
81*d57664e9SAndroid Build Coastguard Worker extern int register_android_view_RenderNode(JNIEnv* env);
82*d57664e9SAndroid Build Coastguard Worker extern int register_android_view_ThreadedRenderer(JNIEnv* env);
83*d57664e9SAndroid Build Coastguard Worker
84*d57664e9SAndroid Build Coastguard Worker #define REG_JNI(name) { name }
85*d57664e9SAndroid Build Coastguard Worker struct RegJNIRec {
86*d57664e9SAndroid Build Coastguard Worker int (*mProc)(JNIEnv*);
87*d57664e9SAndroid Build Coastguard Worker };
88*d57664e9SAndroid Build Coastguard Worker
89*d57664e9SAndroid Build Coastguard Worker // Map of all possible class names to register to their corresponding JNI registration function pointer
90*d57664e9SAndroid Build Coastguard Worker // The actual list of registered classes will be determined at runtime via the 'native_classes' System property
91*d57664e9SAndroid Build Coastguard Worker static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
92*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Bitmap", REG_JNI(register_android_graphics_Bitmap)},
93*d57664e9SAndroid Build Coastguard Worker {"android.graphics.BitmapFactory", REG_JNI(register_android_graphics_BitmapFactory)},
94*d57664e9SAndroid Build Coastguard Worker {"android.graphics.BitmapRegionDecoder",
95*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_BitmapRegionDecoder)},
96*d57664e9SAndroid Build Coastguard Worker {"android.graphics.ByteBufferStreamAdaptor",
97*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_ByteBufferStreamAdaptor)},
98*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Camera", REG_JNI(register_android_graphics_Camera)},
99*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Canvas", REG_JNI(register_android_graphics_Canvas)},
100*d57664e9SAndroid Build Coastguard Worker {"android.graphics.CanvasProperty", REG_JNI(register_android_graphics_CanvasProperty)},
101*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Color", REG_JNI(register_android_graphics_Color)},
102*d57664e9SAndroid Build Coastguard Worker {"android.graphics.ColorFilter", REG_JNI(register_android_graphics_ColorFilter)},
103*d57664e9SAndroid Build Coastguard Worker {"android.graphics.ColorSpace", REG_JNI(register_android_graphics_ColorSpace)},
104*d57664e9SAndroid Build Coastguard Worker {"android.graphics.CreateJavaOutputStreamAdaptor",
105*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor)},
106*d57664e9SAndroid Build Coastguard Worker {"android.graphics.DrawFilter", REG_JNI(register_android_graphics_DrawFilter)},
107*d57664e9SAndroid Build Coastguard Worker {"android.graphics.FontFamily", REG_JNI(register_android_graphics_FontFamily)},
108*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Gainmap", REG_JNI(register_android_graphics_Gainmap)},
109*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Graphics", REG_JNI(register_android_graphics_Graphics)},
110*d57664e9SAndroid Build Coastguard Worker {"android.graphics.HardwareBufferRenderer",
111*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_HardwareBufferRenderer)},
112*d57664e9SAndroid Build Coastguard Worker {"android.graphics.HardwareRenderer", REG_JNI(register_android_view_ThreadedRenderer)},
113*d57664e9SAndroid Build Coastguard Worker {"android.graphics.HardwareRendererObserver",
114*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_HardwareRendererObserver)},
115*d57664e9SAndroid Build Coastguard Worker {"android.graphics.ImageDecoder", REG_JNI(register_android_graphics_ImageDecoder)},
116*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Interpolator", REG_JNI(register_android_graphics_Interpolator)},
117*d57664e9SAndroid Build Coastguard Worker {"android.graphics.MaskFilter", REG_JNI(register_android_graphics_MaskFilter)},
118*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Matrix", REG_JNI(register_android_graphics_Matrix)},
119*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Mesh", REG_JNI(register_android_graphics_Mesh)},
120*d57664e9SAndroid Build Coastguard Worker {"android.graphics.MeshSpecification",
121*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_MeshSpecification)},
122*d57664e9SAndroid Build Coastguard Worker {"android.graphics.NinePatch", REG_JNI(register_android_graphics_NinePatch)},
123*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Paint", REG_JNI(register_android_graphics_Paint)},
124*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Path", REG_JNI(register_android_graphics_Path)},
125*d57664e9SAndroid Build Coastguard Worker {"android.graphics.PathEffect", REG_JNI(register_android_graphics_PathEffect)},
126*d57664e9SAndroid Build Coastguard Worker {"android.graphics.PathIterator", REG_JNI(register_android_graphics_PathIterator)},
127*d57664e9SAndroid Build Coastguard Worker {"android.graphics.PathMeasure", REG_JNI(register_android_graphics_PathMeasure)},
128*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Picture", REG_JNI(register_android_graphics_Picture)},
129*d57664e9SAndroid Build Coastguard Worker {"android.graphics.RecordingCanvas", REG_JNI(register_android_view_DisplayListCanvas)},
130*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
131*d57664e9SAndroid Build Coastguard Worker {"android.graphics.RenderNode", REG_JNI(register_android_view_RenderNode)},
132*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
133*d57664e9SAndroid Build Coastguard Worker {"android.graphics.RenderEffect", REG_JNI(register_android_graphics_RenderEffect)},
134*d57664e9SAndroid Build Coastguard Worker {"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
135*d57664e9SAndroid Build Coastguard Worker {"android.graphics.YuvImage", REG_JNI(register_android_graphics_YuvImage)},
136*d57664e9SAndroid Build Coastguard Worker {"android.graphics.animation.NativeInterpolatorFactory",
137*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory)},
138*d57664e9SAndroid Build Coastguard Worker {"android.graphics.animation.RenderNodeAnimator",
139*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_animation_RenderNodeAnimator)},
140*d57664e9SAndroid Build Coastguard Worker {"android.graphics.drawable.AnimatedImageDrawable",
141*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable)},
142*d57664e9SAndroid Build Coastguard Worker {"android.graphics.drawable.AnimatedVectorDrawable",
143*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
144*d57664e9SAndroid Build Coastguard Worker {"android.graphics.drawable.VectorDrawable",
145*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_drawable_VectorDrawable)},
146*d57664e9SAndroid Build Coastguard Worker {"android.graphics.fonts.Font", REG_JNI(register_android_graphics_fonts_Font)},
147*d57664e9SAndroid Build Coastguard Worker {"android.graphics.fonts.FontFamily", REG_JNI(register_android_graphics_fonts_FontFamily)},
148*d57664e9SAndroid Build Coastguard Worker {"android.graphics.text.LineBreaker", REG_JNI(register_android_graphics_text_LineBreaker)},
149*d57664e9SAndroid Build Coastguard Worker {"android.graphics.text.MeasuredText",
150*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_text_MeasuredText)},
151*d57664e9SAndroid Build Coastguard Worker {"android.graphics.text.TextRunShaper", REG_JNI(register_android_graphics_text_TextShaper)},
152*d57664e9SAndroid Build Coastguard Worker {"android.graphics.text.GraphemeBreak",
153*d57664e9SAndroid Build Coastguard Worker REG_JNI(register_android_graphics_text_GraphemeBreak)},
154*d57664e9SAndroid Build Coastguard Worker {"android.util.PathParser", REG_JNI(register_android_util_PathParser)},
155*d57664e9SAndroid Build Coastguard Worker };
156*d57664e9SAndroid Build Coastguard Worker
register_jni_procs(const std::unordered_map<std::string,RegJNIRec> & jniRegMap,const vector<string> & classesToRegister,JNIEnv * env)157*d57664e9SAndroid Build Coastguard Worker static int register_jni_procs(const std::unordered_map<std::string, RegJNIRec>& jniRegMap,
158*d57664e9SAndroid Build Coastguard Worker const vector<string>& classesToRegister, JNIEnv* env) {
159*d57664e9SAndroid Build Coastguard Worker
160*d57664e9SAndroid Build Coastguard Worker for (const string& className : classesToRegister) {
161*d57664e9SAndroid Build Coastguard Worker if (jniRegMap.at(className).mProc(env) < 0) {
162*d57664e9SAndroid Build Coastguard Worker return -1;
163*d57664e9SAndroid Build Coastguard Worker }
164*d57664e9SAndroid Build Coastguard Worker }
165*d57664e9SAndroid Build Coastguard Worker return 0;
166*d57664e9SAndroid Build Coastguard Worker }
167*d57664e9SAndroid Build Coastguard Worker
parseCsv(const string & csvString)168*d57664e9SAndroid Build Coastguard Worker static vector<string> parseCsv(const string& csvString) {
169*d57664e9SAndroid Build Coastguard Worker vector<string> result;
170*d57664e9SAndroid Build Coastguard Worker istringstream stream(csvString);
171*d57664e9SAndroid Build Coastguard Worker string segment;
172*d57664e9SAndroid Build Coastguard Worker while(getline(stream, segment, ','))
173*d57664e9SAndroid Build Coastguard Worker {
174*d57664e9SAndroid Build Coastguard Worker result.push_back(segment);
175*d57664e9SAndroid Build Coastguard Worker }
176*d57664e9SAndroid Build Coastguard Worker return result;
177*d57664e9SAndroid Build Coastguard Worker }
178*d57664e9SAndroid Build Coastguard Worker
parseCsv(JNIEnv * env,jstring csvJString)179*d57664e9SAndroid Build Coastguard Worker static vector<string> parseCsv(JNIEnv* env, jstring csvJString) {
180*d57664e9SAndroid Build Coastguard Worker const char* charArray = env->GetStringUTFChars(csvJString, 0);
181*d57664e9SAndroid Build Coastguard Worker string csvString(charArray);
182*d57664e9SAndroid Build Coastguard Worker vector<string> result = parseCsv(csvString);
183*d57664e9SAndroid Build Coastguard Worker env->ReleaseStringUTFChars(csvJString, charArray);
184*d57664e9SAndroid Build Coastguard Worker return result;
185*d57664e9SAndroid Build Coastguard Worker }
186*d57664e9SAndroid Build Coastguard Worker
187*d57664e9SAndroid Build Coastguard Worker } // namespace android
188*d57664e9SAndroid Build Coastguard Worker
189*d57664e9SAndroid Build Coastguard Worker using namespace android;
190*d57664e9SAndroid Build Coastguard Worker using namespace android::uirenderer;
191*d57664e9SAndroid Build Coastguard Worker
init_android_graphics()192*d57664e9SAndroid Build Coastguard Worker void init_android_graphics() {
193*d57664e9SAndroid Build Coastguard Worker Properties::overrideRenderPipelineType(RenderPipelineType::SkiaCpu);
194*d57664e9SAndroid Build Coastguard Worker SkGraphics::Init();
195*d57664e9SAndroid Build Coastguard Worker }
196*d57664e9SAndroid Build Coastguard Worker
register_android_graphics_classes(JNIEnv * env)197*d57664e9SAndroid Build Coastguard Worker int register_android_graphics_classes(JNIEnv *env) {
198*d57664e9SAndroid Build Coastguard Worker JavaVM* vm = nullptr;
199*d57664e9SAndroid Build Coastguard Worker env->GetJavaVM(&vm);
200*d57664e9SAndroid Build Coastguard Worker GraphicsJNI::setJavaVM(vm);
201*d57664e9SAndroid Build Coastguard Worker
202*d57664e9SAndroid Build Coastguard Worker // Configuration is stored as java System properties.
203*d57664e9SAndroid Build Coastguard Worker // Get a reference to System.getProperty
204*d57664e9SAndroid Build Coastguard Worker jclass system = FindClassOrDie(env, "java/lang/System");
205*d57664e9SAndroid Build Coastguard Worker jmethodID getPropertyMethod = GetStaticMethodIDOrDie(env, system, "getProperty",
206*d57664e9SAndroid Build Coastguard Worker "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
207*d57664e9SAndroid Build Coastguard Worker
208*d57664e9SAndroid Build Coastguard Worker auto formatProperty = (jstring)env->CallStaticObjectMethod(
209*d57664e9SAndroid Build Coastguard Worker system, getPropertyMethod, env->NewStringUTF("method_binding_format"),
210*d57664e9SAndroid Build Coastguard Worker env->NewStringUTF(""));
211*d57664e9SAndroid Build Coastguard Worker const char* methodFormatChars = env->GetStringUTFChars(formatProperty, 0);
212*d57664e9SAndroid Build Coastguard Worker setJniMethodFormat(string(methodFormatChars));
213*d57664e9SAndroid Build Coastguard Worker env->ReleaseStringUTFChars(formatProperty, methodFormatChars);
214*d57664e9SAndroid Build Coastguard Worker
215*d57664e9SAndroid Build Coastguard Worker // Get the names of classes that need to register their native methods
216*d57664e9SAndroid Build Coastguard Worker auto nativesClassesJString = (jstring)env->CallStaticObjectMethod(
217*d57664e9SAndroid Build Coastguard Worker system, getPropertyMethod, env->NewStringUTF("graphics_native_classes"),
218*d57664e9SAndroid Build Coastguard Worker env->NewStringUTF(""));
219*d57664e9SAndroid Build Coastguard Worker vector<string> classesToRegister = parseCsv(env, nativesClassesJString);
220*d57664e9SAndroid Build Coastguard Worker
221*d57664e9SAndroid Build Coastguard Worker if (register_jni_procs(gRegJNIMap, classesToRegister, env) < 0) {
222*d57664e9SAndroid Build Coastguard Worker return JNI_ERR;
223*d57664e9SAndroid Build Coastguard Worker }
224*d57664e9SAndroid Build Coastguard Worker
225*d57664e9SAndroid Build Coastguard Worker return 0;
226*d57664e9SAndroid Build Coastguard Worker }
227*d57664e9SAndroid Build Coastguard Worker
zygote_preload_graphics()228*d57664e9SAndroid Build Coastguard Worker void zygote_preload_graphics() { }
229