| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.tools.layoutlib.create; |
| |
| import com.android.tools.layoutlib.annotations.LayoutlibDelegate; |
| import com.android.tools.layoutlib.java.LinkedHashMap_Delegate; |
| import com.android.tools.layoutlib.java.System_Delegate; |
| |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Describes the work to be done by {@link AsmGenerator}. |
| */ |
| public final class CreateInfo implements ICreateInfo { |
| |
| @Override |
| public Class<?>[] getInjectedClasses() { |
| return INJECTED_CLASSES; |
| } |
| |
| @Override |
| public String[] getDelegateMethods() { |
| return DELEGATE_METHODS; |
| } |
| |
| @Override |
| public String[] getDelegateClassNatives() { |
| return DELEGATE_CLASS_NATIVES; |
| } |
| |
| @Override |
| public String[] getRenamedClasses() { |
| return RENAMED_CLASSES; |
| } |
| |
| @Override |
| public String[] getDeleteReturns() { |
| return DELETE_RETURNS; |
| } |
| |
| @Override |
| public String[] getJavaPkgClasses() { |
| return JAVA_PKG_CLASSES; |
| } |
| |
| @Override |
| public String[] getRefactoredClasses() { |
| return REFACTOR_CLASSES; |
| } |
| |
| @Override |
| public String[] getExcludedClasses() { |
| String[] refactoredClasses = getJavaPkgClasses(); |
| int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length; |
| Set<String> excludedClasses = new HashSet<>(count); |
| for (int i = 0; i < refactoredClasses.length; i+=2) { |
| excludedClasses.add(refactoredClasses[i]); |
| } |
| excludedClasses.addAll(Arrays.asList(EXCLUDED_CLASSES)); |
| return excludedClasses.toArray(new String[0]); |
| } |
| |
| @Override |
| public String[] getPromotedFields() { |
| return PROMOTED_FIELDS; |
| } |
| |
| @Override |
| public String[] getPromotedClasses() { |
| return PROMOTED_CLASSES; |
| } |
| |
| @Override |
| public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { |
| return INJECTED_METHODS; |
| } |
| |
| //----- |
| |
| /** |
| * The list of class from layoutlib_create to inject in layoutlib. |
| */ |
| private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] { |
| OverrideMethod.class, |
| MethodListener.class, |
| MethodAdapter.class, |
| ICreateInfo.class, |
| CreateInfo.class, |
| LayoutlibDelegate.class, |
| InjectMethodRunnable.class, |
| InjectMethodRunnables.class, |
| /* Java package classes */ |
| System_Delegate.class, |
| LinkedHashMap_Delegate.class, |
| }; |
| |
| /** |
| * The list of methods to rewrite as delegates. |
| */ |
| public final static String[] DELEGATE_METHODS = new String[] { |
| "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;", |
| "android.content.res.Resources#getAnimation", |
| "android.content.res.Resources#getAttributeSetSourceResId", |
| "android.content.res.Resources#getBoolean", |
| "android.content.res.Resources#getColor", |
| "android.content.res.Resources#getColorStateList", |
| "android.content.res.Resources#getDimension", |
| "android.content.res.Resources#getDimensionPixelOffset", |
| "android.content.res.Resources#getDimensionPixelSize", |
| "android.content.res.Resources#getDrawable", |
| "android.content.res.Resources#getFloat", |
| "android.content.res.Resources#getFont", |
| "android.content.res.Resources#getIdentifier", |
| "android.content.res.Resources#getIntArray", |
| "android.content.res.Resources#getInteger", |
| "android.content.res.Resources#getLayout", |
| "android.content.res.Resources#getQuantityString", |
| "android.content.res.Resources#getQuantityText", |
| "android.content.res.Resources#getResourceEntryName", |
| "android.content.res.Resources#getResourceName", |
| "android.content.res.Resources#getResourcePackageName", |
| "android.content.res.Resources#getResourceTypeName", |
| "android.content.res.Resources#getString", |
| "android.content.res.Resources#getStringArray", |
| "android.content.res.Resources#getText", |
| "android.content.res.Resources#getTextArray", |
| "android.content.res.Resources#getValue", |
| "android.content.res.Resources#getValueForDensity", |
| "android.content.res.Resources#getXml", |
| "android.content.res.Resources#loadXmlResourceParser", |
| "android.content.res.Resources#obtainAttributes", |
| "android.content.res.Resources#obtainTypedArray", |
| "android.content.res.Resources#openRawResource", |
| "android.content.res.Resources#openRawResourceFd", |
| "android.content.res.Resources$Theme#obtainStyledAttributes", |
| "android.content.res.Resources$Theme#resolveAttribute", |
| "android.content.res.Resources$Theme#resolveAttributes", |
| "android.content.res.AssetManager#nativeCreate", |
| "android.content.res.AssetManager#nativeDestroy", |
| "android.content.res.AssetManager#nativeThemeCreate", |
| "android.content.res.AssetManager#nativeThemeDestroy", |
| "android.content.res.AssetManager#getAssignedPackageIdentifiers", |
| "android.content.res.AssetManager#nativeCreateIdmapsForStaticOverlaysTargetingAndroid", |
| "android.content.res.TypedArray#getValueAt", |
| "android.content.res.TypedArray#obtain", |
| "android.graphics.BitmapFactory#finishDecode", |
| "android.graphics.BitmapFactory#setDensityFromOptions", |
| "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget", |
| "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw", |
| "android.graphics.drawable.GradientDrawable#buildRing", |
| "android.graphics.drawable.AdaptiveIconDrawable#<init>", |
| "android.graphics.drawable.DrawableInflater#inflateFromClass", |
| "android.graphics.FontFamily#addFont", |
| "android.graphics.Typeface#create", |
| "android.graphics.Typeface$Builder#createAssetUid", |
| "android.graphics.fonts.Font$Builder#createBuffer", |
| "android.graphics.fonts.SystemFonts#buildSystemFallback", |
| "android.os.Binder#getNativeBBinderHolder", |
| "android.os.Binder#getNativeFinalizer", |
| "android.os.Handler#sendMessageAtTime", |
| "android.os.HandlerThread#run", |
| "android.preference.Preference#getView", |
| "android.text.format.DateFormat#is24HourFormat", |
| "android.util.Xml#newPullParser", |
| "android.view.Choreographer#getInstance", |
| "android.view.Choreographer#getRefreshRate", |
| "android.view.Choreographer#scheduleVsyncLocked", |
| "android.view.Display#updateDisplayInfoLocked", |
| "android.view.Display#getWindowManager", |
| "android.view.HandlerActionQueue#postDelayed", |
| "android.view.LayoutInflater#initPrecompiledViews", |
| "android.view.LayoutInflater#rInflate", |
| "android.view.LayoutInflater#parseInclude", |
| "android.view.View#draw", |
| "android.view.View#dispatchDetachedFromWindow", |
| "android.view.View#layout", |
| "android.view.View#measure", |
| "android.view.View#getWindowToken", |
| "android.view.View#isInEditMode", |
| "android.view.ViewRootImpl#isInTouchMode", |
| "android.view.WindowManagerGlobal#getWindowManagerService", |
| "android.view.inputmethod.InputMethodManager#isInEditMode", |
| "android.view.MenuInflater#registerMenu", |
| "android.graphics.RenderNode#getMatrix", |
| "android.graphics.RenderNode#nCreate", |
| "android.graphics.RenderNode#nGetNativeFinalizer", |
| "android.graphics.RenderNode#nSetElevation", |
| "android.graphics.RenderNode#nGetElevation", |
| "android.graphics.RenderNode#nSetTranslationX", |
| "android.graphics.RenderNode#nGetTranslationX", |
| "android.graphics.RenderNode#nSetTranslationY", |
| "android.graphics.RenderNode#nGetTranslationY", |
| "android.graphics.RenderNode#nSetTranslationZ", |
| "android.graphics.RenderNode#nGetTranslationZ", |
| "android.graphics.RenderNode#nSetRotation", |
| "android.graphics.RenderNode#nGetRotation", |
| "android.graphics.RenderNode#nSetLeft", |
| "android.graphics.RenderNode#nSetTop", |
| "android.graphics.RenderNode#nSetRight", |
| "android.graphics.RenderNode#nSetBottom", |
| "android.graphics.RenderNode#nSetLeftTopRightBottom", |
| "android.graphics.RenderNode#nSetPivotX", |
| "android.graphics.RenderNode#nGetPivotX", |
| "android.graphics.RenderNode#nSetPivotY", |
| "android.graphics.RenderNode#nGetPivotY", |
| "android.graphics.RenderNode#nSetScaleX", |
| "android.graphics.RenderNode#nGetScaleX", |
| "android.graphics.RenderNode#nSetScaleY", |
| "android.graphics.RenderNode#nGetScaleY", |
| "android.graphics.RenderNode#nIsPivotExplicitlySet", |
| "android.provider.DeviceConfig#getBoolean", |
| "android.provider.DeviceConfig#getFloat", |
| "android.provider.DeviceConfig#getInt", |
| "android.provider.DeviceConfig#getLong", |
| "android.provider.DeviceConfig#getString", |
| "android.view.PointerIcon#loadResource", |
| "android.view.PointerIcon#registerDisplayListener", |
| "android.view.SurfaceControl#nativeCreateTransaction", |
| "android.view.SurfaceControl#nativeGetNativeTransactionFinalizer", |
| "android.view.ViewGroup#drawChild", |
| "com.android.internal.view.menu.MenuBuilder#createNewMenuItem", |
| "com.android.internal.util.XmlUtils#convertValueToInt", |
| "dalvik.system.VMRuntime#getNotifyNativeInterval", |
| "dalvik.system.VMRuntime#newUnpaddedArray", |
| "libcore.io.MemoryMappedFile#mmapRO", |
| "libcore.io.MemoryMappedFile#close", |
| "libcore.io.MemoryMappedFile#bigEndianIterator", |
| "libcore.util.NativeAllocationRegistry#applyFreeFunction", |
| "libcore.util.NativeAllocationRegistry#registerNativeAllocation", |
| }; |
| |
| /** |
| * The list of classes on which to delegate all native methods. |
| */ |
| public final static String[] DELEGATE_CLASS_NATIVES = new String[] { |
| "android.animation.PropertyValuesHolder", |
| "android.graphics.BaseCanvas", |
| "android.graphics.Bitmap", |
| "android.graphics.BitmapFactory", |
| "android.graphics.BitmapShader", |
| "android.graphics.BlendModeColorFilter", |
| "android.graphics.BlurMaskFilter", |
| "android.graphics.Canvas", |
| "android.graphics.Color", |
| "android.graphics.ColorFilter", |
| "android.graphics.ColorMatrixColorFilter", |
| "android.graphics.ColorSpace$Rgb", |
| "android.graphics.ComposePathEffect", |
| "android.graphics.ComposeShader", |
| "android.graphics.CornerPathEffect", |
| "android.graphics.DashPathEffect", |
| "android.graphics.DiscretePathEffect", |
| "android.graphics.DrawFilter", |
| "android.graphics.EmbossMaskFilter", |
| "android.graphics.FontFamily", |
| "android.graphics.LightingColorFilter", |
| "android.graphics.LinearGradient", |
| "android.graphics.MaskFilter", |
| "android.graphics.Matrix", |
| "android.graphics.NinePatch", |
| "android.graphics.Paint", |
| "android.graphics.PaintFlagsDrawFilter", |
| "android.graphics.Path", |
| "android.graphics.PathDashPathEffect", |
| "android.graphics.PathEffect", |
| "android.graphics.PathMeasure", |
| "android.graphics.PorterDuffColorFilter", |
| "android.graphics.RadialGradient", |
| "android.graphics.Region", |
| "android.graphics.Shader", |
| "android.graphics.SumPathEffect", |
| "android.graphics.SweepGradient", |
| "android.graphics.Typeface", |
| "android.graphics.animation.NativeInterpolatorFactory", |
| "android.graphics.drawable.AnimatedVectorDrawable", |
| "android.graphics.drawable.VectorDrawable", |
| "android.graphics.fonts.Font$Builder", |
| "android.graphics.fonts.FontFamily$Builder", |
| "android.graphics.text.MeasuredText", |
| "android.graphics.text.MeasuredText$Builder", |
| "android.graphics.text.LineBreaker", |
| "android.os.SystemClock", |
| "android.os.SystemProperties", |
| "android.util.PathParser", |
| "android.view.Display", |
| "com.android.internal.util.VirtualRefBasePtr", |
| "libcore.icu.ICU", |
| }; |
| |
| /** |
| * The list of classes to rename, must be an even list: the binary FQCN |
| * of class to replace followed by the new FQCN. |
| */ |
| private final static String[] RENAMED_CLASSES = |
| new String[] { |
| "android.os.ServiceManager", "android.os._Original_ServiceManager", |
| "android.view.textservice.TextServicesManager", "android.view.textservice._Original_TextServicesManager", |
| "android.view.SurfaceView", "android.view._Original_SurfaceView", |
| "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager", |
| "android.view.accessibility.AccessibilityNodeIdManager", "android.view.accessibility._Original_AccessibilityNodeIdManager", |
| "android.webkit.WebView", "android.webkit._Original_WebView", |
| "android.graphics.ImageDecoder", "android.graphics._Original_ImageDecoder", |
| }; |
| |
| /** |
| * The list of class references to update, must be an even list: the binary |
| * FQCN of class to replace followed by the new FQCN. The classes to |
| * replace are to be excluded from the output. |
| */ |
| private final static String[] JAVA_PKG_CLASSES = |
| new String[] { |
| "sun.misc.Cleaner", "com.android.layoutlib.bridge.libcore.util.Cleaner", |
| }; |
| |
| /** |
| * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and |
| * {@link #getJavaPkgClasses()}. |
| * Classes included here will be renamed and then all their references in any other classes |
| * will be also modified. |
| * FQCN of class to refactor followed by its new FQCN. |
| */ |
| private final static String[] REFACTOR_CLASSES = |
| new String[] { |
| "android.os.Build", "android.os._Original_Build", |
| }; |
| |
| private final static String[] EXCLUDED_CLASSES = |
| new String[] { |
| "android.preference.PreferenceActivity", |
| "java.**", |
| "org.kxml2.io.KXmlParser", |
| "org.xmlpull.**", |
| "sun.**", |
| }; |
| |
| /** |
| * List of fields for which we will update the visibility to be public. This is sometimes |
| * needed when access from the delegate classes is needed. |
| */ |
| private final static String[] PROMOTED_FIELDS = new String[] { |
| "android.graphics.drawable.VectorDrawable#mVectorState", |
| "android.view.Choreographer#mLastFrameTimeNanos", |
| "android.graphics.FontFamily#mBuilderPtr", |
| "android.graphics.Typeface#DEFAULT_FAMILY", |
| "android.graphics.Typeface#sDynamicTypefaceCache", |
| "android.graphics.drawable.AdaptiveIconDrawable#sMask", |
| "android.graphics.drawable.DrawableInflater#mRes", |
| "android.animation.PropertyValuesHolder#sSetterPropertyMap", |
| "android.animation.PropertyValuesHolder#sGetterPropertyMap", |
| "android.animation.PropertyValuesHolder$IntPropertyValuesHolder#sJNISetterPropertyMap", |
| "android.animation.PropertyValuesHolder$FloatPropertyValuesHolder#sJNISetterPropertyMap", |
| "android.animation.PropertyValuesHolder$MultiFloatValuesHolder#sJNISetterPropertyMap", |
| "android.animation.PropertyValuesHolder$MultiIntValuesHolder#sJNISetterPropertyMap", |
| }; |
| |
| /** |
| * List of classes to be promoted to public visibility. Prefer using PROMOTED_FIELDS to this |
| * if possible. |
| */ |
| private final static String[] PROMOTED_CLASSES = new String[] { |
| }; |
| |
| /** |
| * List of classes for which the methods returning them should be deleted. |
| * The array contains a list of null terminated section starting with the name of the class |
| * to rename in which the methods are deleted, followed by a list of return types identifying |
| * the methods to delete. |
| */ |
| private final static String[] DELETE_RETURNS = |
| new String[] { |
| null }; // separator, for next class/methods list. |
| |
| private final static Map<String, InjectMethodRunnable> INJECTED_METHODS = |
| new HashMap<String, InjectMethodRunnable>(1) {{ |
| put("android.content.Context", |
| InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); |
| }}; |
| } |