1 /* 2 * Copyright (C) 2008 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 com.android.tools.layoutlib.create; 18 19 import com.android.tools.layoutlib.annotations.LayoutlibDelegate; 20 import com.android.tools.layoutlib.java.AutoCloseable; 21 import com.android.tools.layoutlib.java.Charsets; 22 import com.android.tools.layoutlib.java.IntegralToString; 23 import com.android.tools.layoutlib.java.LinkedHashMap_Delegate; 24 import com.android.tools.layoutlib.java.Objects; 25 import com.android.tools.layoutlib.java.System_Delegate; 26 import com.android.tools.layoutlib.java.UnsafeByteSequence; 27 28 import java.util.Arrays; 29 import java.util.HashMap; 30 import java.util.HashSet; 31 import java.util.Map; 32 import java.util.Set; 33 34 /** 35 * Describes the work to be done by {@link AsmGenerator}. 36 */ 37 public final class CreateInfo implements ICreateInfo { 38 39 /** 40 * Returns the list of class from layoutlib_create to inject in layoutlib. 41 * The list can be empty but must not be null. 42 */ 43 @Override getInjectedClasses()44 public Class<?>[] getInjectedClasses() { 45 return INJECTED_CLASSES; 46 } 47 48 /** 49 * Returns the list of methods to rewrite as delegates. 50 * The list can be empty but must not be null. 51 */ 52 @Override getDelegateMethods()53 public String[] getDelegateMethods() { 54 return DELEGATE_METHODS; 55 } 56 57 /** 58 * Returns the list of classes on which to delegate all native methods. 59 * The list can be empty but must not be null. 60 */ 61 @Override getDelegateClassNatives()62 public String[] getDelegateClassNatives() { 63 return DELEGATE_CLASS_NATIVES; 64 } 65 66 /** 67 * Returns The list of methods to stub out. Each entry must be in the form 68 * "package.package.OuterClass$InnerClass#MethodName". 69 * The list can be empty but must not be null. 70 * <p/> 71 * This usage is deprecated. Please use method 'delegates' instead. 72 */ 73 @Override getOverriddenMethods()74 public String[] getOverriddenMethods() { 75 return OVERRIDDEN_METHODS; 76 } 77 78 /** 79 * Returns the list of classes to rename, must be an even list: the binary FQCN 80 * of class to replace followed by the new FQCN. 81 * The list can be empty but must not be null. 82 */ 83 @Override getRenamedClasses()84 public String[] getRenamedClasses() { 85 return RENAMED_CLASSES; 86 } 87 88 /** 89 * Returns the list of classes for which the methods returning them should be deleted. 90 * The array contains a list of null terminated section starting with the name of the class 91 * to rename in which the methods are deleted, followed by a list of return types identifying 92 * the methods to delete. 93 * The list can be empty but must not be null. 94 */ 95 @Override getDeleteReturns()96 public String[] getDeleteReturns() { 97 return DELETE_RETURNS; 98 } 99 100 /** 101 * Returns the list of classes to refactor, must be an even list: the binary FQCN of class to 102 * replace followed by the new FQCN. All references to the old class should be updated to the 103 * new class. The list can be empty but must not be null. 104 */ 105 @Override getJavaPkgClasses()106 public String[] getJavaPkgClasses() { 107 return JAVA_PKG_CLASSES; 108 } 109 110 @Override getExcludedClasses()111 public Set<String> getExcludedClasses() { 112 String[] refactoredClasses = getJavaPkgClasses(); 113 int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length; 114 Set<String> excludedClasses = new HashSet<>(count); 115 for (int i = 0; i < refactoredClasses.length; i+=2) { 116 excludedClasses.add(refactoredClasses[i]); 117 } 118 excludedClasses.addAll(Arrays.asList(EXCLUDED_CLASSES)); 119 return excludedClasses; 120 } 121 122 @Override getPromotedFields()123 public String[] getPromotedFields() { 124 return PROMOTED_FIELDS; 125 } 126 127 @Override getInjectedMethodsMap()128 public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { 129 return INJECTED_METHODS; 130 } 131 132 //----- 133 134 /** 135 * The list of class from layoutlib_create to inject in layoutlib. 136 */ 137 private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] { 138 OverrideMethod.class, 139 MethodListener.class, 140 MethodAdapter.class, 141 ICreateInfo.class, 142 CreateInfo.class, 143 LayoutlibDelegate.class, 144 InjectMethodRunnable.class, 145 InjectMethodRunnables.class, 146 /* Java package classes */ 147 IntegralToString.class, 148 UnsafeByteSequence.class, 149 System_Delegate.class, 150 LinkedHashMap_Delegate.class, 151 }; 152 153 /** 154 * The list of methods to rewrite as delegates. 155 */ 156 public final static String[] DELEGATE_METHODS = new String[] { 157 "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;", 158 "android.content.res.Resources#getAnimation", 159 "android.content.res.Resources#getBoolean", 160 "android.content.res.Resources#getColor", 161 "android.content.res.Resources#getColorStateList", 162 "android.content.res.Resources#getDimension", 163 "android.content.res.Resources#getDimensionPixelOffset", 164 "android.content.res.Resources#getDimensionPixelSize", 165 "android.content.res.Resources#getDrawable", 166 "android.content.res.Resources#getIntArray", 167 "android.content.res.Resources#getInteger", 168 "android.content.res.Resources#getLayout", 169 "android.content.res.Resources#getResourceEntryName", 170 "android.content.res.Resources#getResourceName", 171 "android.content.res.Resources#getResourcePackageName", 172 "android.content.res.Resources#getResourceTypeName", 173 "android.content.res.Resources#getString", 174 "android.content.res.Resources#getStringArray", 175 "android.content.res.Resources#getText", 176 "android.content.res.Resources#getTextArray", 177 "android.content.res.Resources#getValue", 178 "android.content.res.Resources#getXml", 179 "android.content.res.Resources#loadXmlResourceParser", 180 "android.content.res.Resources#obtainAttributes", 181 "android.content.res.Resources#obtainTypedArray", 182 "android.content.res.Resources#openRawResource", 183 "android.content.res.Resources#openRawResourceFd", 184 "android.content.res.Resources$Theme#obtainStyledAttributes", 185 "android.content.res.Resources$Theme#resolveAttribute", 186 "android.content.res.Resources$Theme#resolveAttributes", 187 "android.content.res.AssetManager#newTheme", 188 "android.content.res.AssetManager#deleteTheme", 189 "android.content.res.TypedArray#getValueAt", 190 "android.content.res.TypedArray#obtain", 191 "android.graphics.BitmapFactory#finishDecode", 192 "android.graphics.BitmapFactory#setDensityFromOptions", 193 "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget", 194 "android.graphics.drawable.GradientDrawable#buildRing", 195 "android.graphics.FontFamily#addFont", 196 "android.graphics.Typeface#getSystemFontConfigLocation", 197 "android.graphics.Typeface#makeFamilyFromParsed", 198 "android.os.Handler#sendMessageAtTime", 199 "android.os.HandlerThread#run", 200 "android.preference.Preference#getView", 201 "android.text.format.DateFormat#is24HourFormat", 202 "android.text.Hyphenator#getSystemHyphenatorLocation", 203 "android.util.Xml#newPullParser", 204 "android.view.Choreographer#getInstance", 205 "android.view.Choreographer#getRefreshRate", 206 "android.view.Choreographer#scheduleVsyncLocked", 207 "android.view.Display#updateDisplayInfoLocked", 208 "android.view.Display#getWindowManager", 209 "android.view.HandlerActionQueue#postDelayed", 210 "android.view.LayoutInflater#rInflate", 211 "android.view.LayoutInflater#parseInclude", 212 "android.view.View#getWindowToken", 213 "android.view.View#isInEditMode", 214 "android.view.ViewRootImpl#isInTouchMode", 215 "android.view.WindowManagerGlobal#getWindowManagerService", 216 "android.view.inputmethod.InputMethodManager#getInstance", 217 "android.view.MenuInflater#registerMenu", 218 "android.view.RenderNode#getMatrix", 219 "android.view.RenderNode#nCreate", 220 "android.view.RenderNode#nDestroyRenderNode", 221 "android.view.RenderNode#nSetElevation", 222 "android.view.RenderNode#nGetElevation", 223 "android.view.RenderNode#nSetTranslationX", 224 "android.view.RenderNode#nGetTranslationX", 225 "android.view.RenderNode#nSetTranslationY", 226 "android.view.RenderNode#nGetTranslationY", 227 "android.view.RenderNode#nSetTranslationZ", 228 "android.view.RenderNode#nGetTranslationZ", 229 "android.view.RenderNode#nSetRotation", 230 "android.view.RenderNode#nGetRotation", 231 "android.view.RenderNode#nSetLeft", 232 "android.view.RenderNode#nSetTop", 233 "android.view.RenderNode#nSetRight", 234 "android.view.RenderNode#nSetBottom", 235 "android.view.RenderNode#nSetLeftTopRightBottom", 236 "android.view.RenderNode#nSetPivotX", 237 "android.view.RenderNode#nGetPivotX", 238 "android.view.RenderNode#nSetPivotY", 239 "android.view.RenderNode#nGetPivotY", 240 "android.view.RenderNode#nSetScaleX", 241 "android.view.RenderNode#nGetScaleX", 242 "android.view.RenderNode#nSetScaleY", 243 "android.view.RenderNode#nGetScaleY", 244 "android.view.RenderNode#nIsPivotExplicitlySet", 245 "android.view.ViewGroup#drawChild", 246 "com.android.internal.view.menu.MenuBuilder#createNewMenuItem", 247 "com.android.internal.util.XmlUtils#convertValueToInt", 248 "com.android.internal.textservice.ITextServicesManager$Stub#asInterface", 249 "dalvik.system.VMRuntime#newUnpaddedArray", 250 "libcore.io.MemoryMappedFile#mmapRO", 251 "libcore.io.MemoryMappedFile#close", 252 "libcore.io.MemoryMappedFile#bigEndianIterator", 253 "libcore.util.NativeAllocationRegistry#applyFreeFunction", 254 }; 255 256 /** 257 * The list of classes on which to delegate all native methods. 258 */ 259 public final static String[] DELEGATE_CLASS_NATIVES = new String[] { 260 "android.animation.PropertyValuesHolder", 261 "android.graphics.Bitmap", 262 "android.graphics.BitmapFactory", 263 "android.graphics.BitmapShader", 264 "android.graphics.BlurMaskFilter", 265 "android.graphics.Canvas", 266 "android.graphics.ColorFilter", 267 "android.graphics.ColorMatrixColorFilter", 268 "android.graphics.ComposePathEffect", 269 "android.graphics.ComposeShader", 270 "android.graphics.CornerPathEffect", 271 "android.graphics.DashPathEffect", 272 "android.graphics.DiscretePathEffect", 273 "android.graphics.DrawFilter", 274 "android.graphics.EmbossMaskFilter", 275 "android.graphics.FontFamily", 276 "android.graphics.LayerRasterizer", 277 "android.graphics.LightingColorFilter", 278 "android.graphics.LinearGradient", 279 "android.graphics.MaskFilter", 280 "android.graphics.Matrix", 281 "android.graphics.NinePatch", 282 "android.graphics.Paint", 283 "android.graphics.PaintFlagsDrawFilter", 284 "android.graphics.Path", 285 "android.graphics.PathDashPathEffect", 286 "android.graphics.PathEffect", 287 "android.graphics.PathMeasure", 288 "android.graphics.PorterDuffColorFilter", 289 "android.graphics.PorterDuffXfermode", 290 "android.graphics.RadialGradient", 291 "android.graphics.Rasterizer", 292 "android.graphics.Region", 293 "android.graphics.Shader", 294 "android.graphics.SumPathEffect", 295 "android.graphics.SweepGradient", 296 "android.graphics.Typeface", 297 "android.graphics.Xfermode", 298 "android.graphics.drawable.AnimatedVectorDrawable", 299 "android.graphics.drawable.VectorDrawable", 300 "android.os.SystemClock", 301 "android.os.SystemProperties", 302 "android.text.AndroidBidi", 303 "android.text.StaticLayout", 304 "android.util.PathParser", 305 "android.view.Display", 306 "com.android.internal.util.VirtualRefBasePtr", 307 "com.android.internal.view.animation.NativeInterpolatorFactoryHelper", 308 "libcore.icu.ICU", 309 }; 310 311 /** 312 * The list of methods to stub out. Each entry must be in the form 313 * "package.package.OuterClass$InnerClass#MethodName". 314 * This usage is deprecated. Please use method 'delegates' instead. 315 */ 316 private final static String[] OVERRIDDEN_METHODS = new String[] { 317 }; 318 319 /** 320 * The list of classes to rename, must be an even list: the binary FQCN 321 * of class to replace followed by the new FQCN. 322 */ 323 private final static String[] RENAMED_CLASSES = 324 new String[] { 325 "android.os.ServiceManager", "android.os._Original_ServiceManager", 326 "android.util.LruCache", "android.util._Original_LruCache", 327 "android.view.SurfaceView", "android.view._Original_SurfaceView", 328 "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager", 329 "android.webkit.WebView", "android.webkit._Original_WebView", 330 }; 331 332 /** 333 * The list of class references to update, must be an even list: the binary 334 * FQCN of class to replace followed by the new FQCN. The classes to 335 * replace are to be excluded from the output. 336 */ 337 private final static String[] JAVA_PKG_CLASSES = 338 new String[] { 339 "java.nio.charset.Charsets", "java.nio.charset.StandardCharsets", 340 "java.lang.IntegralToString", "com.android.tools.layoutlib.java.IntegralToString", 341 "java.lang.UnsafeByteSequence", "com.android.tools.layoutlib.java.UnsafeByteSequence", 342 // Use android.icu.text versions of DateFormat and SimpleDateFormat since the 343 // original ones do not match the Android implementation 344 "java.text.DateFormat", "android.icu.text.DateFormat", 345 "java.text.SimpleDateFormat", "android.icu.text.SimpleDateFormat", 346 }; 347 348 private final static String[] EXCLUDED_CLASSES = 349 new String[] { 350 "android.preference.PreferenceActivity", 351 "org.kxml2.io.KXmlParser" 352 }; 353 354 /** 355 * List of fields for which we will update the visibility to be public. This is sometimes 356 * needed when access from the delegate classes is needed. 357 */ 358 private final static String[] PROMOTED_FIELDS = new String[] { 359 "android.graphics.drawable.VectorDrawable#mVectorState", 360 "android.view.Choreographer#mLastFrameTimeNanos" 361 }; 362 363 /** 364 * List of classes for which the methods returning them should be deleted. 365 * The array contains a list of null terminated section starting with the name of the class 366 * to rename in which the methods are deleted, followed by a list of return types identifying 367 * the methods to delete. 368 */ 369 private final static String[] DELETE_RETURNS = 370 new String[] { 371 null }; // separator, for next class/methods list. 372 373 private final static Map<String, InjectMethodRunnable> INJECTED_METHODS = 374 new HashMap<String, InjectMethodRunnable>(1) {{ 375 put("android.content.Context", 376 InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); 377 }}; 378 } 379