1 /* 2 * Copyright (C) 2024 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 package android.platform.test.ravenwood; 18 19 import com.android.ravenwood.common.RavenwoodCommonUtils; 20 21 import java.util.Arrays; 22 import java.util.stream.Collectors; 23 import java.util.stream.Stream; 24 25 /** 26 * We use this class to load libandroid_runtime. 27 * In the future, we may load other native libraries. 28 */ 29 public final class RavenwoodNativeLoader { 30 public static final String CORE_NATIVE_CLASSES = "core_native_classes"; 31 public static final String ICU_DATA_PATH = "icu.data.path"; 32 public static final String KEYBOARD_PATHS = "keyboard_paths"; 33 public static final String GRAPHICS_NATIVE_CLASSES = "graphics_native_classes"; 34 35 public static final String LIBANDROID_RUNTIME_NAME = "android_runtime"; 36 37 /** 38 * Classes with native methods that are backed by libandroid_runtime. 39 * 40 * See frameworks/base/core/jni/platform/host/HostRuntime.cpp 41 */ 42 private static final Class<?>[] sLibandroidClasses = { 43 // android.util.Log.class, // Not using native log: b/377377826 44 android.os.Parcel.class, 45 android.os.Binder.class, 46 android.os.SystemProperties.class, 47 android.content.res.ApkAssets.class, 48 android.content.res.AssetManager.class, 49 android.content.res.StringBlock.class, 50 android.content.res.XmlBlock.class, 51 android.text.AndroidCharacter.class, 52 }; 53 54 /** 55 * Classes with native methods that are backed by libhwui. 56 * 57 * See frameworks/base/libs/hwui/apex/LayoutlibLoader.cpp 58 */ 59 private static final Class<?>[] sLibhwuiClasses = { 60 android.graphics.Interpolator.class, 61 android.graphics.Matrix.class, 62 android.graphics.Path.class, 63 android.graphics.Color.class, 64 android.graphics.ColorSpace.class, 65 android.graphics.Bitmap.class, 66 android.graphics.BitmapFactory.class, 67 android.graphics.BitmapRegionDecoder.class, 68 android.graphics.Camera.class, 69 android.graphics.Canvas.class, 70 android.graphics.CanvasProperty.class, 71 android.graphics.ColorFilter.class, 72 android.graphics.DrawFilter.class, 73 android.graphics.FontFamily.class, 74 android.graphics.Gainmap.class, 75 android.graphics.ImageDecoder.class, 76 android.graphics.MaskFilter.class, 77 android.graphics.NinePatch.class, 78 android.graphics.Paint.class, 79 android.graphics.PathEffect.class, 80 android.graphics.PathIterator.class, 81 android.graphics.PathMeasure.class, 82 android.graphics.Picture.class, 83 android.graphics.RecordingCanvas.class, 84 android.graphics.Region.class, 85 android.graphics.RenderNode.class, 86 android.graphics.Shader.class, 87 android.graphics.RenderEffect.class, 88 android.graphics.Typeface.class, 89 android.graphics.YuvImage.class, 90 android.graphics.fonts.Font.class, 91 android.graphics.fonts.FontFamily.class, 92 android.graphics.text.LineBreaker.class, 93 android.graphics.text.MeasuredText.class, 94 android.graphics.text.TextRunShaper.class, 95 android.graphics.text.GraphemeBreak.class, 96 android.util.PathParser.class, 97 }; 98 99 /** 100 * Extra strings needed to pass to register_android_graphics_classes(). 101 * 102 * Several entries are not actually a class, so we just hardcode them here. 103 */ 104 public final static String[] GRAPHICS_EXTRA_INIT_PARAMS = new String[] { 105 "android.graphics.Graphics", 106 "android.graphics.ByteBufferStreamAdaptor", 107 "android.graphics.CreateJavaOutputStreamAdaptor" 108 }; 109 RavenwoodNativeLoader()110 private RavenwoodNativeLoader() { 111 } 112 log(String message)113 private static void log(String message) { 114 System.out.println("RavenwoodNativeLoader: " + message); 115 } 116 log(String fmt, Object... args)117 private static void log(String fmt, Object... args) { 118 log(String.format(fmt, args)); 119 } 120 ensurePropertyNotSet(String key)121 private static void ensurePropertyNotSet(String key) { 122 if (System.getProperty(key) != null) { 123 throw new RuntimeException("System property \"" + key + "\" is set unexpectedly"); 124 } 125 } 126 setProperty(String key, String value)127 private static void setProperty(String key, String value) { 128 System.setProperty(key, value); 129 log("Property set: %s=\"%s\"", key, value); 130 } 131 dumpSystemProperties()132 private static void dumpSystemProperties() { 133 for (var prop : System.getProperties().entrySet()) { 134 log(" %s=\"%s\"", prop.getKey(), prop.getValue()); 135 } 136 } 137 138 /** 139 * libandroid_runtime uses Java's system properties to decide what JNI methods to set up. 140 * Set up these properties and load the native library 141 */ loadFrameworkNativeCode()142 public static void loadFrameworkNativeCode() { 143 if ("1".equals(System.getenv("RAVENWOOD_DUMP_PROPERTIES"))) { 144 log("Java system properties:"); 145 dumpSystemProperties(); 146 } 147 148 // Make sure these properties are not set. 149 ensurePropertyNotSet(CORE_NATIVE_CLASSES); 150 ensurePropertyNotSet(ICU_DATA_PATH); 151 ensurePropertyNotSet(KEYBOARD_PATHS); 152 ensurePropertyNotSet(GRAPHICS_NATIVE_CLASSES); 153 154 // Build the property values 155 final var joiner = Collectors.joining(","); 156 final var libandroidClasses = 157 Arrays.stream(sLibandroidClasses).map(Class::getName).collect(joiner); 158 final var libhwuiClasses = Stream.concat( 159 Arrays.stream(sLibhwuiClasses).map(Class::getName), 160 Arrays.stream(GRAPHICS_EXTRA_INIT_PARAMS) 161 ).collect(joiner); 162 163 // Load the libraries 164 setProperty(CORE_NATIVE_CLASSES, libandroidClasses); 165 setProperty(GRAPHICS_NATIVE_CLASSES, libhwuiClasses); 166 log("Loading " + LIBANDROID_RUNTIME_NAME + " for '" + libandroidClasses + "' and '" 167 + libhwuiClasses + "'"); 168 RavenwoodCommonUtils.loadJniLibrary(LIBANDROID_RUNTIME_NAME); 169 } 170 } 171