Skip to content

Instantly share code, notes, and snippets.

@sfrdmn
Created March 14, 2014 07:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sfrdmn/9543481 to your computer and use it in GitHub Desktop.
Save sfrdmn/9543481 to your computer and use it in GitHub Desktop.
diff -ru layoutlib_4-0-3-r1/Android.mk layoutlib_4-4-2-r1/Android.mk
--- layoutlib_4-0-3-r1/Android.mk 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/Android.mk 2014-03-13 18:28:01.000000000 -0700
@@ -25,12 +25,15 @@
# We need to process the framework classes.jar file, but we can't
# depend directly on it (private vars won't be inherited correctly).
# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework)
-built_framework_classes := $(call java-lib-files,framework)
+built_framework_dep := $(call java-lib-deps,framework-base)
+built_framework_classes := $(call java-lib-files,framework-base)
built_core_dep := $(call java-lib-deps,core)
built_core_classes := $(call java-lib-files,core)
+built_ext_dep := $(call java-lib-deps,ext)
+built_ext_classes := $(call java-lib-files,ext)
+
built_layoutlib_create_jar := $(call intermediates-dir-for, \
JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
@@ -47,6 +50,7 @@
$(LOCAL_BUILT_MODULE): $(built_core_dep) \
$(built_framework_dep) \
+ $(built_ext_dep) \
$(built_layoutlib_create_jar)
$(hide) echo "host layoutlib_create: $@"
$(hide) mkdir -p $(dir $@)
@@ -55,7 +59,8 @@
$(hide) java -jar $(built_layoutlib_create_jar) \
$@ \
$(built_core_classes) \
- $(built_framework_classes)
+ $(built_framework_classes) \
+ $(built_ext_classes)
$(hide) ls -l $(built_framework_classes)
diff -ru layoutlib_4-0-3-r1/bridge/.classpath layoutlib_4-4-2-r1/bridge/.classpath
--- layoutlib_4-0-3-r1/bridge/.classpath 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/.classpath 2014-03-13 18:28:01.000000000 -0700
@@ -2,10 +2,11 @@
<classpath>
<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Only in layoutlib_4-4-2-r1/bridge: .settings
diff -ru layoutlib_4-0-3-r1/bridge/Android.mk layoutlib_4-4-2-r1/bridge/Android.mk
--- layoutlib_4-0-3-r1/bridge/Android.mk 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/Android.mk 2014-03-13 18:28:01.000000000 -0700
@@ -22,6 +22,7 @@
LOCAL_JAVA_LIBRARIES := \
kxml2-2.3.0 \
+ icu4j \
layoutlib_api-prebuilt \
tools-common-prebuilt
diff -ru layoutlib_4-0-3-r1/bridge/resources/bars/action_bar.xml layoutlib_4-4-2-r1/bridge/resources/bars/action_bar.xml
--- layoutlib_4-0-3-r1/bridge/resources/bars/action_bar.xml 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/resources/bars/action_bar.xml 2014-03-13 18:28:01.000000000 -0700
@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ <include layout="@android:layout/action_bar_home" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
</merge>
Only in layoutlib_4-4-2-r1/bridge/resources/bars/hdpi: ic_sysbar_back.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/hdpi: ic_sysbar_back_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/hdpi: ic_sysbar_home.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/hdpi: ic_sysbar_home_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/hdpi: ic_sysbar_recent.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/hdpi: ic_sysbar_recent_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/hdpi: stat_sys_battery_charge_anim100.png
Binary files layoutlib_4-0-3-r1/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png and layoutlib_4-4-2-r1/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png differ
Only in layoutlib_4-4-2-r1/bridge/resources/bars: ldrtl-hdpi
Only in layoutlib_4-4-2-r1/bridge/resources/bars: ldrtl-mdpi
Only in layoutlib_4-4-2-r1/bridge/resources/bars: ldrtl-xhdpi
Only in layoutlib_4-4-2-r1/bridge/resources/bars/mdpi: ic_sysbar_back.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/mdpi: ic_sysbar_back_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/mdpi: ic_sysbar_home.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/mdpi: ic_sysbar_home_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/mdpi: ic_sysbar_recent.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/mdpi: ic_sysbar_recent_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/mdpi: stat_sys_battery_charge_anim100.png
Binary files layoutlib_4-0-3-r1/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png and layoutlib_4-4-2-r1/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png differ
Only in layoutlib_4-4-2-r1/bridge/resources/bars: navigation_bar.xml
Only in layoutlib_4-0-3-r1/bridge/resources/bars: phone_system_bar.xml
Only in layoutlib_4-4-2-r1/bridge/resources/bars: status_bar.xml
Only in layoutlib_4-0-3-r1/bridge/resources/bars: tablet_system_bar.xml
Only in layoutlib_4-4-2-r1/bridge/resources/bars/xhdpi: ic_sysbar_back.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/xhdpi: ic_sysbar_back_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/xhdpi: ic_sysbar_home.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/xhdpi: ic_sysbar_home_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/xhdpi: ic_sysbar_recent.png
Only in layoutlib_4-0-3-r1/bridge/resources/bars/xhdpi: ic_sysbar_recent_default.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/xhdpi: stat_sys_battery_charge_anim100.png
Only in layoutlib_4-4-2-r1/bridge/resources/bars/xhdpi: stat_sys_wifi_signal_4_fully.png
diff -ru layoutlib_4-0-3-r1/bridge/src/android/animation/AnimationThread.java layoutlib_4-4-2-r1/bridge/src/android/animation/AnimationThread.java
--- layoutlib_4-0-3-r1/bridge/src/android/animation/AnimationThread.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/animation/AnimationThread.java 2014-03-13 18:28:01.000000000 -0700
@@ -23,11 +23,10 @@
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import android.animation.ValueAnimator;
import android.os.Handler;
import android.os.Handler_Delegate;
-import android.os.Message;
import android.os.Handler_Delegate.IHandlerCallback;
+import android.os.Message;
import java.util.PriorityQueue;
import java.util.Queue;
@@ -57,6 +56,7 @@
mUptimeMillis = uptimeMillis;
}
+ @Override
public int compareTo(MessageBundle bundle) {
if (mUptimeMillis < bundle.mUptimeMillis) {
return -1;
@@ -84,7 +84,12 @@
public void run() {
Bridge.prepareThread();
try {
+ /* FIXME: The ANIMATION_FRAME message no longer exists. Instead, the
+ * animation timing loop is completely based on a Choreographer objects
+ * that schedules animation and drawing frames. The animation handler is
+ * no longer even a handler; it is just a Runnable enqueued on the Choreographer.
Handler_Delegate.setCallback(new IHandlerCallback() {
+ @Override
public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
if (msg.what == ValueAnimator.ANIMATION_START ||
msg.what == ValueAnimator.ANIMATION_FRAME) {
@@ -94,6 +99,7 @@
}
}
});
+ */
// call out to the pre-animation work, which should start an animation or more.
Result result = preAnimation();
diff -ru layoutlib_4-0-3-r1/bridge/src/android/content/res/BridgeResources.java layoutlib_4-4-2-r1/bridge/src/android/content/res/BridgeResources.java
--- layoutlib_4-0-3-r1/bridge/src/android/content/res/BridgeResources.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/content/res/BridgeResources.java 2014-03-13 18:28:01.000000000 -0700
@@ -120,10 +120,8 @@
mProjectCallback = projectCallback;
}
- public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile,
- boolean platformStyleable, String styleableName) {
- return new BridgeTypedArray(this, mContext, numEntries, platformFile,
- platformStyleable, styleableName);
+ public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
+ return new BridgeTypedArray(this, mContext, numEntries, platformFile);
}
private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) {
diff -ru layoutlib_4-0-3-r1/bridge/src/android/content/res/BridgeTypedArray.java layoutlib_4-4-2-r1/bridge/src/android/content/res/BridgeTypedArray.java
--- layoutlib_4-0-3-r1/bridge/src/android/content/res/BridgeTypedArray.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/content/res/BridgeTypedArray.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,7 +16,7 @@
package android.content.res;
-import com.android.ide.common.rendering.api.DeclareStyleableResourceValue;
+import com.android.ide.common.rendering.api.AttrResourceValue;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
@@ -51,28 +51,33 @@
private final BridgeResources mBridgeResources;
private final BridgeContext mContext;
private final boolean mPlatformFile;
- private final boolean mPlatformStyleable;
- private final String mStyleableName;
private ResourceValue[] mResourceData;
private String[] mNames;
+ private boolean[] mIsFramework;
public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
- boolean platformFile, boolean platformStyleable, String styleableName) {
+ boolean platformFile) {
super(null, null, null, 0);
mBridgeResources = resources;
mContext = context;
mPlatformFile = platformFile;
- mPlatformStyleable = platformStyleable;
- mStyleableName = styleableName;
mResourceData = new ResourceValue[len];
mNames = new String[len];
+ mIsFramework = new boolean[len];
}
- /** A bridge-specific method that sets a value in the type array */
- public void bridgeSetValue(int index, String name, ResourceValue value) {
+ /**
+ * A bridge-specific method that sets a value in the type array
+ * @param index the index of the value in the TypedArray
+ * @param name the name of the attribute
+ * @param isFramework whether the attribute is in the android namespace.
+ * @param value the value of the attribute
+ */
+ public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) {
mResourceData[index] = value;
mNames[index] = name;
+ mIsFramework[index] = isFramework;
}
/**
@@ -213,8 +218,12 @@
return defValue;
}
+ if (s == null || s.length() == 0) {
+ return defValue;
+ }
+
try {
- return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue);
+ return XmlUtils.convertValueToInt(s, defValue);
} catch (NumberFormatException e) {
// pass
}
@@ -223,15 +232,14 @@
// Check for possible constants and try to find them.
// Get the map of attribute-constant -> IntegerValue
Map<String, Integer> map = null;
- if (mPlatformStyleable) {
+ if (mIsFramework[index]) {
map = Bridge.getEnumValues(mNames[index]);
- } else if (mStyleableName != null) {
+ } else {
// get the styleable matching the resolved name
RenderResources res = mContext.getRenderResources();
- ResourceValue styleable = res.getProjectResource(ResourceType.DECLARE_STYLEABLE,
- mStyleableName);
- if (styleable instanceof DeclareStyleableResourceValue) {
- map = ((DeclareStyleableResourceValue) styleable).getAttributeValues(mNames[index]);
+ ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
+ if (attr instanceof AttrResourceValue) {
+ map = ((AttrResourceValue) attr).getAttributeValues();
}
}
@@ -886,7 +894,7 @@
}
/**
- * Give back a previously retrieved StyledAttributes, for later re-use.
+ * Give back a previously retrieved TypedArray, for later re-use.
*/
@Override
public void recycle() {
Only in layoutlib_4-4-2-r1/bridge/src/android/graphics: BidiRenderer.java
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/BitmapFactory_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/BitmapFactory_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/BitmapFactory_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/BitmapFactory_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,10 +24,13 @@
import android.content.res.BridgeResources.NinePatchInputStream;
import android.graphics.BitmapFactory.Options;
+import android.graphics.Bitmap_Delegate.BitmapCreateFlags;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
+import java.util.EnumSet;
+import java.util.Set;
/**
* Delegate implementing the native methods of android.graphics.BitmapFactory
@@ -85,18 +88,25 @@
// ------ Native Delegates ------
@LayoutlibDelegate
- /*package*/ static void nativeSetDefaultConfig(int nativeConfig) {
- // pass
+ /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+ Rect padding, Options opts) {
+ return nativeDecodeStream(is, storage, padding, opts, false, 1.f);
}
@LayoutlibDelegate
- /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
- Rect padding, Options opts) {
+ /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+ Rect padding, Options opts, boolean applyScale, float scale) {
Bitmap bm = null;
+ //TODO support rescaling
+
Density density = Density.MEDIUM;
+ Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
if (opts != null) {
density = Density.getEnum(opts.inDensity);
+ if (opts.inPremultiplied) {
+ bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
+ }
}
try {
@@ -109,7 +119,7 @@
npis, true /*is9Patch*/, false /*convert*/);
// get the bitmap and chunk objects.
- bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), true /*isMutable*/,
+ bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
density);
NinePatchChunk chunk = ninePatch.getChunk();
@@ -124,7 +134,7 @@
padding.bottom = paddingarray[3];
} else {
// load the bitmap directly.
- bm = Bitmap_Delegate.createBitmap(is, true, density);
+ bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
}
} catch (IOException e) {
Bridge.getLog().error(null,"Failed to load image" , e, null);
@@ -147,6 +157,13 @@
}
@LayoutlibDelegate
+ /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
+ boolean applyScale, float scale) {
+ opts.inBitmap = null;
+ return null;
+ }
+
+ @LayoutlibDelegate
/*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts) {
opts.inBitmap = null;
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/BitmapShader_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/BitmapShader_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/BitmapShader_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/BitmapShader_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -105,6 +105,7 @@
mTileModeY = tileModeY;
}
+ @Override
public java.awt.PaintContext createContext(
java.awt.image.ColorModel colorModel,
java.awt.Rectangle deviceBounds,
@@ -148,13 +149,16 @@
mColorModel = colorModel;
}
+ @Override
public void dispose() {
}
+ @Override
public java.awt.image.ColorModel getColorModel() {
return mColorModel;
}
+ @Override
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
java.awt.image.BufferedImage.TYPE_INT_ARGB);
@@ -240,6 +244,7 @@
}
+ @Override
public int getTransparency() {
return java.awt.Paint.TRANSLUCENT;
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Bitmap_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Bitmap_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Bitmap_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Bitmap_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -33,6 +33,8 @@
import java.io.OutputStream;
import java.nio.Buffer;
import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Set;
import javax.imageio.ImageIO;
@@ -51,6 +53,10 @@
*/
public final class Bitmap_Delegate {
+ public enum BitmapCreateFlags {
+ PREMULTIPLIED, MUTABLE
+ }
+
// ---- delegate manager ----
private static final DelegateManager<Bitmap_Delegate> sManager =
new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
@@ -61,6 +67,7 @@
private final Config mConfig;
private BufferedImage mImage;
private boolean mHasAlpha = true;
+ private boolean mHasMipMap = false; // TODO: check the default.
private int mGenerationId = 0;
@@ -92,10 +99,25 @@
*/
public static Bitmap createBitmap(File input, boolean isMutable, Density density)
throws IOException {
+ return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
+ }
+
+ /**
+ * Creates and returns a {@link Bitmap} initialized with the given file content.
+ *
+ * @param input the file from which to read the bitmap content
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isPremultiplied()
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
+ */
+ public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
+ Density density) throws IOException {
// create a delegate with the content of the file.
Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
- return createBitmap(delegate, isMutable, density.getDpiValue());
+ return createBitmap(delegate, createFlags, density.getDpiValue());
}
/**
@@ -110,10 +132,26 @@
*/
public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
throws IOException {
+ return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
+ }
+
+ /**
+ * Creates and returns a {@link Bitmap} initialized with the given stream content.
+ *
+ * @param input the stream from which to read the bitmap content
+ * @param createFlags
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isPremultiplied()
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
+ */
+ public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
+ Density density) throws IOException {
// create a delegate with the content of the stream.
Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
- return createBitmap(delegate, isMutable, density.getDpiValue());
+ return createBitmap(delegate, createFlags, density.getDpiValue());
}
/**
@@ -128,10 +166,26 @@
*/
public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
Density density) throws IOException {
+ return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
+ }
+
+ /**
+ * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
+ *
+ * @param image the bitmap content
+ * @param createFlags
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isPremultiplied()
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
+ */
+ public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
+ Density density) throws IOException {
// create a delegate with the given image.
Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
- return createBitmap(delegate, isMutable, density.getDpiValue());
+ return createBitmap(delegate, createFlags, density.getDpiValue());
}
/**
@@ -185,6 +239,10 @@
return mHasAlpha && mConfig != Config.RGB_565;
}
+ public boolean hasMipMap() {
+ // TODO: check if more checks are required as in hasAlpha.
+ return mHasMipMap;
+ }
/**
* Update the generationId.
*
@@ -198,7 +256,7 @@
@LayoutlibDelegate
/*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
- int height, int nativeConfig, boolean mutable) {
+ int height, int nativeConfig, boolean isMutable) {
int imageType = getBufferedImageType(nativeConfig);
// create the image
@@ -211,7 +269,8 @@
// create a delegate with the content of the stream.
Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
- return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
+ return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
+ Bitmap.getDefaultDensity());
}
@LayoutlibDelegate
@@ -239,7 +298,8 @@
// create a delegate with the content of the stream.
Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
- return createBitmap(delegate, isMutable, Bitmap.getDefaultDensity());
+ return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
+ Bitmap.getDefaultDensity());
}
@LayoutlibDelegate
@@ -248,8 +308,9 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeRecycle(int nativeBitmap) {
+ /*package*/ static boolean nativeRecycle(int nativeBitmap) {
sManager.removeJavaReferenceFor(nativeBitmap);
+ return true;
}
@LayoutlibDelegate
@@ -336,6 +397,17 @@
}
@LayoutlibDelegate
+ /*package*/ static boolean nativeHasMipMap(int nativeBitmap) {
+ // get the delegate from the native int.
+ Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+ if (delegate == null) {
+ return true;
+ }
+
+ return delegate.mHasMipMap;
+ }
+
+ @LayoutlibDelegate
/*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) {
// get the delegate from the native int.
Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
@@ -448,7 +520,7 @@
Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
// the density doesn't matter, it's set by the Java method.
- return createBitmap(delegate, false /*isMutable*/,
+ return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
Density.DEFAULT_DENSITY /*density*/);
}
@@ -469,6 +541,17 @@
}
@LayoutlibDelegate
+ /*package*/ static void nativeSetHasMipMap(int nativeBitmap, boolean hasMipMap) {
+ // get the delegate from the native int.
+ Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+ if (delegate == null) {
+ return;
+ }
+
+ delegate.mHasMipMap = hasMipMap;
+ }
+
+ @LayoutlibDelegate
/*package*/ static boolean nativeSameAs(int nb0, int nb1) {
Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
if (delegate1 == null) {
@@ -519,12 +602,27 @@
mConfig = config;
}
- private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
+ private static Bitmap createBitmap(Bitmap_Delegate delegate,
+ Set<BitmapCreateFlags> createFlags, int density) {
// get its native_int
int nativeInt = sManager.addNewDelegate(delegate);
+ int width = delegate.mImage.getWidth();
+ int height = delegate.mImage.getHeight();
+ boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
+ boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
+
// and create/return a new Bitmap with it
- return new Bitmap(nativeInt, null /* buffer */, isMutable, null /*ninePatchChunk*/, density);
+ return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
+ isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
+ }
+
+ private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
+ Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
+ if (isMutable) {
+ createFlags.add(BitmapCreateFlags.MUTABLE);
+ }
+ return createFlags;
}
/**
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Canvas_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Canvas_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Canvas_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Canvas_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -23,7 +23,6 @@
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.graphics.Bitmap.Config;
-import android.graphics.Paint_Delegate.FontInfo;
import android.text.TextUtils;
import java.awt.Color;
@@ -35,7 +34,6 @@
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.image.BufferedImage;
-import java.util.List;
/**
@@ -291,6 +289,7 @@
Paint paint) {
draw(thisCanvas.mNativeCanvas, paint.mNativePaint, false /*compositeOnly*/,
false /*forceSrcMode*/, new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
for (int i = 0 ; i < count ; i += 4) {
graphics.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
@@ -306,6 +305,11 @@
}
@LayoutlibDelegate
+ /*package*/ static void freeTextLayoutCaches() {
+ // nothing to be done here yet.
+ }
+
+ @LayoutlibDelegate
/*package*/ static int initRaster(int nativeBitmapOrZero) {
if (nativeBitmapOrZero > 0) {
// get the Bitmap from the int
@@ -324,20 +328,19 @@
}
@LayoutlibDelegate
- /*package*/ static void native_setBitmap(int nativeCanvas, int bitmap) {
+ /*package*/ static void copyNativeCanvasState(int srcCanvas, int dstCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
- if (canvasDelegate == null) {
+ Canvas_Delegate srcCanvasDelegate = sManager.getDelegate(srcCanvas);
+ if (srcCanvasDelegate == null) {
return;
}
// get the delegate from the native int.
- Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
- if (bitmapDelegate == null) {
+ Canvas_Delegate dstCanvasDelegate = sManager.getDelegate(dstCanvas);
+ if (dstCanvasDelegate == null) {
return;
}
-
- canvasDelegate.setBitmap(bitmapDelegate);
+ // TODO: actually copy the canvas state.
}
@LayoutlibDelegate
@@ -566,16 +569,14 @@
@LayoutlibDelegate
/*package*/ static boolean native_quickReject(int nativeCanvas,
- RectF rect,
- int native_edgeType) {
+ RectF rect) {
// FIXME properly implement quickReject
return false;
}
@LayoutlibDelegate
/*package*/ static boolean native_quickReject(int nativeCanvas,
- int path,
- int native_edgeType) {
+ int path) {
// FIXME properly implement quickReject
return false;
}
@@ -583,8 +584,7 @@
@LayoutlibDelegate
/*package*/ static boolean native_quickReject(int nativeCanvas,
float left, float top,
- float right, float bottom,
- int native_edgeType) {
+ float right, float bottom) {
// FIXME properly implement quickReject
return false;
}
@@ -619,6 +619,7 @@
final int h = canvasDelegate.mBitmap.getImage().getHeight();
draw(nativeCanvas, new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paint) {
// reset its transform just in case
graphics.setTransform(new AffineTransform());
@@ -651,6 +652,7 @@
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
}
@@ -669,6 +671,7 @@
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
int style = paintDelegate.getStyle();
@@ -693,6 +696,7 @@
if (oval.right > oval.left && oval.bottom > oval.top) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
int style = paintDelegate.getStyle();
@@ -717,7 +721,7 @@
/*package*/ static void native_drawCircle(int nativeCanvas,
float cx, float cy, float radius, int paint) {
native_drawOval(nativeCanvas,
- new RectF(cx - radius, cy - radius, radius, radius),
+ new RectF(cx - radius, cy - radius, cx + radius, cy + radius),
paint);
}
@@ -728,6 +732,7 @@
if (oval.right > oval.left && oval.bottom > oval.top) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
int style = paintDelegate.getStyle();
@@ -757,6 +762,7 @@
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
int style = paintDelegate.getStyle();
@@ -789,6 +795,7 @@
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
Shape shape = pathDelegate.getJavaShape();
int style = paintDelegate.getStyle();
@@ -892,6 +899,7 @@
draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paint) {
if (paint != null && paint.isFilterBitmap()) {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
@@ -931,6 +939,7 @@
final AffineTransform mtx = matrixDelegate.getAffineTransform();
canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paint) {
if (paint != null && paint.isFilterBitmap()) {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
@@ -967,18 +976,21 @@
@LayoutlibDelegate
/*package*/ static void native_drawText(int nativeCanvas,
final char[] text, final int index, final int count,
- final float startX, final float startY, int flags, int paint) {
+ final float startX, final float startY, final int flags, int paint) {
+
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
// WARNING: the logic in this method is similar to Paint_Delegate.measureText.
// Any change to this method should be reflected in Paint.measureText
// Paint.TextAlign indicates how the text is positioned relative to X.
// LEFT is the default and there's nothing to do.
float x = startX;
- float y = startY;
+ int limit = index + count;
+ boolean isRtl = flags == Canvas.DIRECTION_RTL;
if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
- float m = paintDelegate.measureText(text, index, count);
+ float m = paintDelegate.measureText(text, index, count, isRtl);
if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
x -= m / 2;
} else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
@@ -986,87 +998,15 @@
}
}
- List<FontInfo> fonts = paintDelegate.getFonts();
-
- if (fonts.size() > 0) {
- FontInfo mainFont = fonts.get(0);
- int i = index;
- int lastIndex = index + count;
- while (i < lastIndex) {
- // always start with the main font.
- int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
- if (upTo == -1) {
- // draw all the rest and exit.
- graphics.setFont(mainFont.mFont);
- graphics.drawChars(text, i, lastIndex - i, (int)x, (int)y);
- return;
- } else if (upTo > 0) {
- // draw what's possible
- graphics.setFont(mainFont.mFont);
- graphics.drawChars(text, i, upTo - i, (int)x, (int)y);
-
- // compute the width that was drawn to increase x
- x += mainFont.mMetrics.charsWidth(text, i, upTo - i);
-
- // move index to the first non displayed char.
- i = upTo;
-
- // don't call continue at this point. Since it is certain the main font
- // cannot display the font a index upTo (now ==i), we move on to the
- // fallback fonts directly.
- }
-
- // no char supported, attempt to read the next char(s) with the
- // fallback font. In this case we only test the first character
- // and then go back to test with the main font.
- // Special test for 2-char characters.
- boolean foundFont = false;
- for (int f = 1 ; f < fonts.size() ; f++) {
- FontInfo fontInfo = fonts.get(f);
-
- // need to check that the font can display the character. We test
- // differently if the char is a high surrogate.
- int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
- upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
- if (upTo == -1) {
- // draw that char
- graphics.setFont(fontInfo.mFont);
- graphics.drawChars(text, i, charCount, (int)x, (int)y);
-
- // update x
- x += fontInfo.mMetrics.charsWidth(text, i, charCount);
-
- // update the index in the text, and move on
- i += charCount;
- foundFont = true;
- break;
-
- }
- }
-
- // in case no font can display the char, display it with the main font.
- // (it'll put a square probably)
- if (foundFont == false) {
- int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
-
- graphics.setFont(mainFont.mFont);
- graphics.drawChars(text, i, charCount, (int)x, (int)y);
-
- // measure it to advance x
- x += mainFont.mMetrics.charsWidth(text, i, charCount);
-
- // and move to the next chars.
- i += charCount;
- }
- }
- }
+ new BidiRenderer(graphics, paintDelegate, text).renderText(
+ index, limit, isRtl, null, 0, true, x, startY);
}
});
}
@LayoutlibDelegate
/*package*/ static void native_drawText(int nativeCanvas, String text,
- int start, int end, float x, float y, int flags, int paint) {
+ int start, int end, float x, float y, final int flags, int paint) {
int count = end - start;
char[] buffer = TemporaryBuffer.obtain(count);
TextUtils.getChars(text, start, end, buffer, 0);
@@ -1135,14 +1075,6 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawPicture(int nativeCanvas,
- int nativePicture) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Canvas.drawPicture is not supported.", null, null /*data*/);
- }
-
- @LayoutlibDelegate
/*package*/ static void finalizer(int nativeCanvas) {
// get the delegate from the native int so that it can be disposed.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -1279,6 +1211,7 @@
draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paint) {
if (paint != null && paint.isFilterBitmap()) {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Gradient_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Gradient_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Gradient_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Gradient_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -87,6 +87,7 @@
mTileMode = tileMode;
}
+ @Override
public int getTransparency() {
return java.awt.Paint.TRANSLUCENT;
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/LinearGradient_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/LinearGradient_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/LinearGradient_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/LinearGradient_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -132,6 +132,7 @@
mDSize2 = mDx * mDx + mDy * mDy;
}
+ @Override
public java.awt.PaintContext createContext(
java.awt.image.ColorModel colorModel,
java.awt.Rectangle deviceBounds,
@@ -176,13 +177,16 @@
mColorModel = colorModel;
}
+ @Override
public void dispose() {
}
+ @Override
public java.awt.image.ColorModel getColorModel() {
return mColorModel;
}
+ @Override
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
java.awt.image.BufferedImage.TYPE_INT_ARGB);
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Matrix_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Matrix_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Matrix_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Matrix_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -474,7 +474,7 @@
}
Matrix_Delegate other = sManager.getDelegate(other_matrix);
- if (d == null) {
+ if (other == null) {
return false;
}
@@ -570,7 +570,7 @@
}
Matrix_Delegate other = sManager.getDelegate(other_matrix);
- if (d == null) {
+ if (other == null) {
return false;
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/NinePatch_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/NinePatch_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/NinePatch_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/NinePatch_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -48,6 +48,11 @@
*/
public final class NinePatch_Delegate {
+ // ---- delegate manager ----
+ private static final DelegateManager<NinePatch_Delegate> sManager =
+ new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class);
+
+ // ---- delegate helper data ----
/**
* Cache map for {@link NinePatchChunk}.
* When the chunks are created they are serialized into a byte[], and both are put
@@ -60,6 +65,10 @@
private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
new HashMap<byte[], SoftReference<NinePatchChunk>>();
+ // ---- delegate data ----
+ private byte[] chunk;
+
+
// ---- Public Helper methods ----
/**
@@ -149,32 +158,39 @@
}
@LayoutlibDelegate
- /*package*/ static void validateNinePatchChunk(int bitmap, byte[] chunk) {
+ /*package*/ static int validateNinePatchChunk(int bitmap, byte[] chunk) {
// the default JNI implementation only checks that the byte[] has the same
// size as the C struct it represent. Since we cannot do the same check (serialization
// will return different size depending on content), we do nothing.
+ NinePatch_Delegate newDelegate = new NinePatch_Delegate();
+ newDelegate.chunk = chunk;
+ return sManager.addNewDelegate(newDelegate);
+ }
+
+ /*package*/ static void nativeFinalize(int chunk) {
+ sManager.removeJavaReferenceFor(chunk);
}
@LayoutlibDelegate
/*package*/ static void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
- byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+ int chunk, int paint_instance_or_null, int destDensity, int srcDensity) {
draw(canvas_instance,
(int) loc.left, (int) loc.top, (int) loc.width(), (int) loc.height(),
- bitmap_instance, c, paint_instance_or_null,
+ bitmap_instance, chunk, paint_instance_or_null,
destDensity, srcDensity);
}
@LayoutlibDelegate
/*package*/ static void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
- byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+ int chunk, int paint_instance_or_null, int destDensity, int srcDensity) {
draw(canvas_instance,
loc.left, loc.top, loc.width(), loc.height(),
- bitmap_instance, c, paint_instance_or_null,
+ bitmap_instance, chunk, paint_instance_or_null,
destDensity, srcDensity);
}
@LayoutlibDelegate
- /*package*/ static int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location) {
+ /*package*/ static int nativeGetTransparentRegion(int bitmap, int chunk, Rect location) {
return 0;
}
@@ -182,7 +198,7 @@
private static void draw(int canvas_instance,
final int left, final int top, final int right, final int bottom,
- int bitmap_instance, byte[] c, int paint_instance_or_null,
+ int bitmap_instance, int chunk, int paint_instance_or_null,
final int destDensity, final int srcDensity) {
// get the delegate from the native int.
final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
@@ -190,6 +206,11 @@
return;
}
+ byte[] c = null;
+ NinePatch_Delegate delegate = sManager.getDelegate(chunk);
+ if (delegate != null) {
+ c = delegate.chunk;
+ }
if (c == null) {
// not a 9-patch?
BufferedImage image = bitmap_delegate.getImage();
@@ -215,6 +236,7 @@
Paint_Delegate paint_delegate = Paint_Delegate.getDelegate(paint_instance_or_null);
canvas_delegate.getSnapshot().draw(new GcSnapshot.Drawable() {
+ @Override
public void draw(Graphics2D graphics, Paint_Delegate paint) {
chunkObject.draw(bitmap_delegate.getImage(), graphics,
left, top, right - left, bottom - top, destDensity, srcDensity);
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Paint_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Paint_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Paint_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Paint_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -32,10 +32,10 @@
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* Delegate implementing the native methods of android.graphics.Paint
@@ -91,6 +91,8 @@
private MaskFilter_Delegate mMaskFilter;
private Rasterizer_Delegate mRasterizer;
+ private Locale mLocale = Locale.getDefault();
+
// ---- Public Helper methods ----
@@ -254,6 +256,8 @@
return delegate.mFlags;
}
+
+
@LayoutlibDelegate
/*package*/ static void setFlags(Paint thisPaint, int flags) {
// get the delegate from the native int.
@@ -564,29 +568,30 @@
@LayoutlibDelegate
/*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
- int count) {
+ int count, int bidiFlags) {
// get the delegate
Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
if (delegate == null) {
return 0;
}
- return delegate.measureText(text, index, count);
+ return delegate.measureText(text, index, count, isRtl(bidiFlags));
}
@LayoutlibDelegate
- /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end) {
- return native_measureText(thisPaint, text.toCharArray(), start, end - start);
+ /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end,
+ int bidiFlags) {
+ return native_measureText(thisPaint, text.toCharArray(), start, end - start, bidiFlags);
}
@LayoutlibDelegate
- /*package*/ static float native_measureText(Paint thisPaint, String text) {
- return native_measureText(thisPaint, text.toCharArray(), 0, text.length());
+ /*package*/ static float native_measureText(Paint thisPaint, String text, int bidiFlags) {
+ return native_measureText(thisPaint, text.toCharArray(), 0, text.length(), bidiFlags);
}
@LayoutlibDelegate
/*package*/ static int native_breakText(Paint thisPaint, char[] text, int index, int count,
- float maxWidth, float[] measuredWidth) {
+ float maxWidth, int bidiFlags, float[] measuredWidth) {
// get the delegate
Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
@@ -609,7 +614,7 @@
}
// measure from start to end
- float res = delegate.measureText(text, start, end - start + 1);
+ float res = delegate.measureText(text, start, end - start + 1, isRtl(bidiFlags));
if (measuredWidth != null) {
measuredWidth[measureIndex] = res;
@@ -629,9 +634,9 @@
@LayoutlibDelegate
/*package*/ static int native_breakText(Paint thisPaint, String text, boolean measureForwards,
- float maxWidth, float[] measuredWidth) {
+ float maxWidth, int bidiFlags, float[] measuredWidth) {
return native_breakText(thisPaint, text.toCharArray(), 0, text.length(), maxWidth,
- measuredWidth);
+ bidiFlags, measuredWidth);
}
@LayoutlibDelegate
@@ -904,19 +909,19 @@
}
@LayoutlibDelegate
- /*package*/ static float native_getFontMetrics(int native_paint, FontMetrics metrics) {
+ /*package*/ static void native_setTextLocale(int native_object, String locale) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(native_paint);
+ Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
- return 0.f;
+ return;
}
- return delegate.getFontMetrics(metrics);
+ delegate.setTextLocale(locale);
}
@LayoutlibDelegate
/*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
- int count, float[] widths) {
+ int count, int bidiFlags, float[] widths) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
@@ -958,8 +963,9 @@
@LayoutlibDelegate
/*package*/ static int native_getTextWidths(int native_object, String text, int start,
- int end, float[] widths) {
- return native_getTextWidths(native_object, text.toCharArray(), start, end - start, widths);
+ int end, int bidiFlags, float[] widths) {
+ return native_getTextWidths(native_object, text.toCharArray(), start, end - start,
+ bidiFlags, widths);
}
@LayoutlibDelegate
@@ -972,58 +978,34 @@
@LayoutlibDelegate
/*package*/ static float native_getTextRunAdvances(int native_object,
char[] text, int index, int count, int contextIndex, int contextCount,
- int flags, float[] advances, int advancesIndex, int reserved) {
+ int flags, float[] advances, int advancesIndex) {
+
+ if (advances != null)
+ for (int i = advancesIndex; i< advancesIndex+count; i++)
+ advances[i]=0;
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
- if (delegate == null) {
+ if (delegate == null || delegate.mFonts == null || delegate.mFonts.size() == 0) {
return 0.f;
}
+ boolean isRtl = isRtl(flags);
- if (delegate.mFonts.size() > 0) {
- // FIXME: handle multi-char characters (see measureText)
- float totalAdvance = 0;
- for (int i = 0; i < count; i++) {
- char c = text[i + index];
- boolean found = false;
- for (FontInfo info : delegate.mFonts) {
- if (info.mFont.canDisplay(c)) {
- float adv = info.mMetrics.charWidth(c);
- totalAdvance += adv;
- if (advances != null) {
- advances[i] = adv;
- }
-
- found = true;
- break;
- }
- }
-
- if (found == false) {
- // no advance for this char.
- if (advances != null) {
- advances[i] = 0.f;
- }
- }
- }
-
- return totalAdvance;
- }
-
- return 0;
-
+ int limit = index + count;
+ return new BidiRenderer(null, delegate, text).renderText(
+ index, limit, isRtl, advances, advancesIndex, false, 0, 0);
}
@LayoutlibDelegate
/*package*/ static float native_getTextRunAdvances(int native_object,
String text, int start, int end, int contextStart, int contextEnd,
- int flags, float[] advances, int advancesIndex, int reserved) {
- // FIXME: support contextStart, contextEnd and direction flag
+ int flags, float[] advances, int advancesIndex) {
+ // FIXME: support contextStart and contextEnd
int count = end - start;
char[] buffer = TemporaryBuffer.obtain(count);
TextUtils.getChars(text, start, end, buffer, 0);
return native_getTextRunAdvances(native_object, buffer, 0, count, contextStart,
- contextEnd - contextStart, flags, advances, advancesIndex, reserved);
+ contextEnd - contextStart, flags, advances, advancesIndex);
}
@LayoutlibDelegate
@@ -1062,29 +1044,23 @@
@LayoutlibDelegate
/*package*/ static void nativeGetStringBounds(int nativePaint, String text, int start,
- int end, Rect bounds) {
- nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bounds);
+ int end, int bidiFlags, Rect bounds) {
+ nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bidiFlags,
+ bounds);
}
@LayoutlibDelegate
/*package*/ static void nativeGetCharArrayBounds(int nativePaint, char[] text, int index,
- int count, Rect bounds) {
+ int count, int bidiFlags, Rect bounds) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(nativePaint);
- if (delegate == null) {
+ if (delegate == null || delegate.mFonts == null || delegate.mFonts.size() == 0) {
return;
}
-
- // FIXME should test if the main font can display all those characters.
- // See MeasureText
- if (delegate.mFonts.size() > 0) {
- FontInfo mainInfo = delegate.mFonts.get(0);
-
- Rectangle2D rect = mainInfo.mFont.getStringBounds(text, index, index + count,
- delegate.mFontContext);
- bounds.set(0, 0, (int) rect.getWidth(), (int) rect.getHeight());
- }
+ int w = (int) delegate.measureText(text, index, count, isRtl(bidiFlags));
+ int h= delegate.getFonts().get(0).mMetrics.getHeight();
+ bounds.set(0, 0, w, h);
}
@LayoutlibDelegate
@@ -1168,6 +1144,7 @@
info.mFont = info.mFont.deriveFont(new AffineTransform(
mTextScaleX, mTextSkewX, 0, 1, 0, 0));
}
+ // The metrics here don't have anti-aliasing set.
info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
infoList.add(info);
@@ -1177,63 +1154,9 @@
}
}
- /*package*/ float measureText(char[] text, int index, int count) {
-
- // WARNING: the logic in this method is similar to Canvas_Delegate.native_drawText
- // Any change to this method should be reflected there as well
-
- if (mFonts.size() > 0) {
- FontInfo mainFont = mFonts.get(0);
- int i = index;
- int lastIndex = index + count;
- float total = 0f;
- while (i < lastIndex) {
- // always start with the main font.
- int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
- if (upTo == -1) {
- // shortcut to exit
- return total + mainFont.mMetrics.charsWidth(text, i, lastIndex - i);
- } else if (upTo > 0) {
- total += mainFont.mMetrics.charsWidth(text, i, upTo - i);
- i = upTo;
- // don't call continue at this point. Since it is certain the main font
- // cannot display the font a index upTo (now ==i), we move on to the
- // fallback fonts directly.
- }
-
- // no char supported, attempt to read the next char(s) with the
- // fallback font. In this case we only test the first character
- // and then go back to test with the main font.
- // Special test for 2-char characters.
- boolean foundFont = false;
- for (int f = 1 ; f < mFonts.size() ; f++) {
- FontInfo fontInfo = mFonts.get(f);
-
- // need to check that the font can display the character. We test
- // differently if the char is a high surrogate.
- int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
- upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
- if (upTo == -1) {
- total += fontInfo.mMetrics.charsWidth(text, i, charCount);
- i += charCount;
- foundFont = true;
- break;
-
- }
- }
-
- // in case no font can display the char, measure it with the main font.
- if (foundFont == false) {
- int size = Character.isHighSurrogate(text[i]) ? 2 : 1;
- total += mainFont.mMetrics.charsWidth(text, i, size);
- i += size;
- }
- }
-
- return total;
- }
-
- return 0;
+ /*package*/ float measureText(char[] text, int index, int count, boolean isRtl) {
+ return new BidiRenderer(null, this, text).renderText(
+ index, index + count, isRtl, null, 0, false, 0, 0);
}
private float getFontMetrics(FontMetrics metrics) {
@@ -1254,7 +1177,9 @@
return 0;
}
-
+ private void setTextLocale(String locale) {
+ mLocale = new Locale(locale);
+ }
private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
// get the delegate from the native int.
@@ -1269,4 +1194,15 @@
delegate.mFlags &= ~flagMask;
}
}
+
+ private static boolean isRtl(int flag) {
+ switch(flag) {
+ case Paint.BIDI_RTL:
+ case Paint.BIDI_FORCE_RTL:
+ case Paint.BIDI_DEFAULT_RTL:
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/RadialGradient_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/RadialGradient_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/RadialGradient_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/RadialGradient_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -118,6 +118,7 @@
mRadius = radius;
}
+ @Override
public java.awt.PaintContext createContext(
java.awt.image.ColorModel colorModel,
java.awt.Rectangle deviceBounds,
@@ -162,13 +163,16 @@
mColorModel = colorModel;
}
+ @Override
public void dispose() {
}
+ @Override
public java.awt.image.ColorModel getColorModel() {
return mColorModel;
}
+ @Override
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
java.awt.image.BufferedImage.TYPE_INT_ARGB);
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/SweepGradient_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/SweepGradient_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/SweepGradient_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/SweepGradient_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -110,6 +110,7 @@
mCy = cy;
}
+ @Override
public java.awt.PaintContext createContext(
java.awt.image.ColorModel colorModel,
java.awt.Rectangle deviceBounds,
@@ -154,13 +155,16 @@
mColorModel = colorModel;
}
+ @Override
public void dispose() {
}
+ @Override
public java.awt.image.ColorModel getColorModel() {
return mColorModel;
}
+ @Override
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
java.awt.image.BufferedImage.TYPE_INT_ARGB);
diff -ru layoutlib_4-0-3-r1/bridge/src/android/graphics/Typeface_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/graphics/Typeface_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/graphics/Typeface_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/graphics/Typeface_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -188,11 +188,6 @@
return delegate.mStyle;
}
- @LayoutlibDelegate
- /*package*/ static void setGammaForText(float blackGamma, float whiteGamma) {
- // This is for device testing only: pass
- }
-
// ---- Private delegate/helper methods ----
private Typeface_Delegate(String family, int style) {
diff -ru layoutlib_4-0-3-r1/bridge/src/android/os/Looper_Accessor.java layoutlib_4-4-2-r1/bridge/src/android/os/Looper_Accessor.java
--- layoutlib_4-0-3-r1/bridge/src/android/os/Looper_Accessor.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/os/Looper_Accessor.java 2014-03-13 18:28:01.000000000 -0700
@@ -15,6 +15,8 @@
*/
package android.os;
+import java.lang.reflect.Field;
+
/**
* Class allowing access to package-protected methods/fields.
*/
@@ -23,5 +25,23 @@
public static void cleanupThread() {
// clean up the looper
Looper.sThreadLocal.remove();
+ try {
+ Field sMainLooper = Looper.class.getDeclaredField("sMainLooper");
+ sMainLooper.setAccessible(true);
+ sMainLooper.set(null, null);
+ } catch (SecurityException e) {
+ catchReflectionException();
+ } catch (IllegalArgumentException e) {
+ catchReflectionException();
+ } catch (NoSuchFieldException e) {
+ catchReflectionException();
+ } catch (IllegalAccessException e) {
+ catchReflectionException();
+ }
+
+ }
+
+ private static void catchReflectionException() {
+ assert(false);
}
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/os/SystemClock_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/os/SystemClock_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/os/SystemClock_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/os/SystemClock_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -31,6 +31,7 @@
*/
public class SystemClock_Delegate {
private static long sBootTime = System.currentTimeMillis();
+ private static long sBootTimeNano = System.nanoTime();
@LayoutlibDelegate
/*package*/ static boolean setCurrentTimeMillis(long millis) {
@@ -60,6 +61,16 @@
}
/**
+ * Returns nanoseconds since boot, including time spent in sleep.
+ *
+ * @return elapsed nanoseconds since boot.
+ */
+ @LayoutlibDelegate
+ /*package*/ static long elapsedRealtimeNanos() {
+ return System.nanoTime() - sBootTimeNano;
+ }
+
+ /**
* Returns milliseconds running in the current thread.
*
* @return elapsed milliseconds in the thread
diff -ru layoutlib_4-0-3-r1/bridge/src/android/text/AndroidBidi_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/text/AndroidBidi_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/text/AndroidBidi_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/text/AndroidBidi_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,7 +16,10 @@
package android.text;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.ibm.icu.text.Bidi;
/**
@@ -29,9 +32,29 @@
public class AndroidBidi_Delegate {
@LayoutlibDelegate
- /*package*/ static int runBidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo) {
- // return the equivalent of Layout.DIR_LEFT_TO_RIGHT
- // TODO: actually figure the direction.
- return 0;
+ /*package*/ static int runBidi(int dir, char[] chars, byte[] charInfo, int count,
+ boolean haveInfo) {
+
+ switch (dir) {
+ case 0: // Layout.DIR_REQUEST_LTR
+ case 1: // Layout.DIR_REQUEST_RTL
+ break; // No change.
+ case -1:
+ dir = Bidi.LEVEL_DEFAULT_LTR;
+ break;
+ case -2:
+ dir = Bidi.LEVEL_DEFAULT_RTL;
+ break;
+ default:
+ // Invalid code. Log error, assume LEVEL_DEFAULT_LTR and continue.
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Invalid direction flag", null);
+ dir = Bidi.LEVEL_DEFAULT_LTR;
+ }
+ Bidi bidi = new Bidi(chars, 0, null, 0, count, dir);
+ if (charInfo != null) {
+ for (int i = 0; i < count; ++i)
+ charInfo[i] = bidi.getLevelAt(i);
+ }
+ return bidi.getParaLevel();
}
}
Only in layoutlib_4-4-2-r1/bridge/src/android/text: format
diff -ru layoutlib_4-0-3-r1/bridge/src/android/util/BridgeXmlPullAttributes.java layoutlib_4-4-2-r1/bridge/src/android/util/BridgeXmlPullAttributes.java
--- layoutlib_4-0-3-r1/bridge/src/android/util/BridgeXmlPullAttributes.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/util/BridgeXmlPullAttributes.java 2014-03-13 18:28:01.000000000 -0700
@@ -18,6 +18,7 @@
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
@@ -25,9 +26,6 @@
import org.xmlpull.v1.XmlPullParser;
-import android.util.AttributeSet;
-import android.util.XmlPullAttributes;
-
/**
* A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
*/
@@ -80,21 +78,40 @@
return 0;
}
- /*
- * (non-Javadoc)
- * @see android.util.XmlPullAttributes#getAttributeResourceValue(int, int)
- */
@Override
- public int getAttributeResourceValue(int index, int defaultValue) {
- String value = getAttributeValue(index);
+ public int getAttributeListValue(String namespace, String attribute,
+ String[] options, int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
- return resolveResourceValue(value, defaultValue);
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToList(value, options, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public boolean getAttributeBooleanValue(String namespace, String attribute,
+ boolean defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToBoolean(value, defaultValue);
+ }
+
+ return defaultValue;
}
- /*
- * (non-Javadoc)
- * @see android.util.XmlPullAttributes#getAttributeResourceValue(java.lang.String, java.lang.String, int)
- */
@Override
public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
String value = getAttributeValue(namespace, attribute);
@@ -102,12 +119,151 @@
return resolveResourceValue(value, defaultValue);
}
- private int resolveResourceValue(String value, int defaultValue) {
+ @Override
+ public int getAttributeIntValue(String namespace, String attribute,
+ int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeUnsignedIntValue(String namespace, String attribute,
+ int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public float getAttributeFloatValue(String namespace, String attribute,
+ float defaultValue) {
+ String s = getAttributeValue(namespace, attribute);
+ if (s != null) {
+ ResourceValue r = getResourceValue(s);
+
+ if (r != null) {
+ s = r.getValue();
+ }
+
+ return Float.parseFloat(s);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeListValue(int index,
+ String[] options, int defaultValue) {
+ return XmlUtils.convertValueToList(
+ getAttributeValue(index), options, defaultValue);
+ }
+
+ @Override
+ public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToBoolean(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeResourceValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+
+ return resolveResourceValue(value, defaultValue);
+ }
+
+ @Override
+ public int getAttributeIntValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeUnsignedIntValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public float getAttributeFloatValue(int index, float defaultValue) {
+ String s = getAttributeValue(index);
+ if (s != null) {
+ ResourceValue r = getResourceValue(s);
+
+ if (r != null) {
+ s = r.getValue();
+ }
+
+ return Float.parseFloat(s);
+ }
+
+ return defaultValue;
+ }
+
+ // -- private helper methods
+
+ /**
+ * Returns a resolved {@link ResourceValue} from a given value.
+ */
+ private ResourceValue getResourceValue(String value) {
// now look for this particular value
RenderResources resources = mContext.getRenderResources();
- ResourceValue resource = resources.resolveResValue(
- resources.findResValue(value, mPlatformFile));
+ return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
+ }
+ /**
+ * Resolves and return a value to its associated integer.
+ */
+ private int resolveResourceValue(String value, int defaultValue) {
+ ResourceValue resource = getResourceValue(value);
if (resource != null) {
Integer id = null;
if (mPlatformFile || resource.isFramework()) {
@@ -124,5 +280,4 @@
return defaultValue;
}
-
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/util/FloatMath_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/util/FloatMath_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/util/FloatMath_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/util/FloatMath_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -91,4 +91,42 @@
/*package*/ static float sqrt(float value) {
return (float)Math.sqrt(value);
}
+
+ /**
+ * Returns the closest float approximation of the raising "e" to the power
+ * of the argument.
+ *
+ * @param value to compute the exponential of
+ * @return the exponential of value
+ */
+ @LayoutlibDelegate
+ /*package*/ static float exp(float value) {
+ return (float)Math.exp(value);
+ }
+
+ /**
+ * Returns the closest float approximation of the result of raising {@code
+ * x} to the power of {@code y}.
+ *
+ * @param x the base of the operation.
+ * @param y the exponent of the operation.
+ * @return {@code x} to the power of {@code y}.
+ */
+ @LayoutlibDelegate
+ /*package*/ static float pow(float x, float y) {
+ return (float)Math.pow(x, y);
+ }
+
+ /**
+ * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
+ * {@code y}</i><sup>{@code 2}</sup>{@code )}.
+ *
+ * @param x a float number
+ * @param y a float number
+ * @return the hypotenuse
+ */
+ @LayoutlibDelegate
+ /*package*/ static float hypot(float x, float y) {
+ return (float)Math.sqrt(x*x + y*y);
+ }
}
Only in layoutlib_4-4-2-r1/bridge/src/android/util: LruCache.java
diff -ru layoutlib_4-0-3-r1/bridge/src/android/view/AttachInfo_Accessor.java layoutlib_4-4-2-r1/bridge/src/android/view/AttachInfo_Accessor.java
--- layoutlib_4-0-3-r1/bridge/src/android/view/AttachInfo_Accessor.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/view/AttachInfo_Accessor.java 2014-03-13 18:28:01.000000000 -0700
@@ -19,6 +19,7 @@
import com.android.layoutlib.bridge.android.BridgeWindow;
import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import android.content.Context;
import android.os.Handler;
import android.view.View.AttachInfo;
@@ -28,8 +29,12 @@
public class AttachInfo_Accessor {
public static void setAttachInfo(View view) {
+ Context context = view.getContext();
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ ViewRootImpl root = new ViewRootImpl(context, display);
AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
- new Handler(), null);
+ display, root, new Handler(), null);
info.mHasWindowFocus = true;
info.mWindowVisibility = View.VISIBLE;
info.mInTouchMode = false; // this is so that we can display selections.
Only in layoutlib_4-4-2-r1/bridge/src/android/view: Choreographer_Delegate.java
diff -ru layoutlib_4-0-3-r1/bridge/src/android/view/Display_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/view/Display_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/view/Display_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/view/Display_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,11 +16,8 @@
package android.view;
-import com.android.layoutlib.bridge.android.BridgeWindowManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import android.os.RemoteException;
/**
* Delegate used to provide new implementation of a select few methods of {@link Display}
@@ -31,57 +28,9 @@
*/
public class Display_Delegate {
- // ---- Overridden methods ----
-
- @LayoutlibDelegate
- public static IWindowManager getWindowManager() {
- return RenderAction.getCurrentContext().getIWindowManager();
- }
-
- // ---- Native methods ----
-
- @LayoutlibDelegate
- /*package*/ static int getDisplayCount() {
- return 1;
- }
-
- @LayoutlibDelegate
- /** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawWidthNative(Display theDisplay) {
- // same as real since we're not faking compatibility mode.
- return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels;
- }
-
- @LayoutlibDelegate
- /** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawHeightNative(Display theDisplay) {
- // same as real since we're not faking compatibility mode.
- return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels;
- }
-
- @LayoutlibDelegate
- /*package*/ static int getOrientation(Display theDisplay) {
- try {
- // always dynamically query for the current window manager
- return getWindowManager().getRotation();
- } catch (RemoteException e) {
- // this will never been thrown since this is not a true RPC.
- }
-
- return Surface.ROTATION_0;
- }
-
@LayoutlibDelegate
- /*package*/ static void nativeClassInit() {
- // not needed for now.
+ static void updateDisplayInfoLocked(Display theDisplay) {
+ // do nothing
}
- @LayoutlibDelegate
- /*package*/ static void init(Display theDisplay, int display) {
- // always dynamically query for the current window manager
- BridgeWindowManager wm = RenderAction.getCurrentContext().getIWindowManager();
- theDisplay.mDensity = wm.getMetrics().density;
- theDisplay.mDpiX = wm.getMetrics().xdpi;
- theDisplay.mDpiY = wm.getMetrics().ydpi;
- }
}
Only in layoutlib_4-4-2-r1/bridge/src/android/view: IWindowManagerImpl.java
diff -ru layoutlib_4-0-3-r1/bridge/src/android/view/SurfaceView.java layoutlib_4-4-2-r1/bridge/src/android/view/SurfaceView.java
--- layoutlib_4-0-3-r1/bridge/src/android/view/SurfaceView.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/view/SurfaceView.java 2014-03-13 18:28:01.000000000 -0700
@@ -27,7 +27,7 @@
* Mock version of the SurfaceView.
* Only non override public methods from the real SurfaceView have been added in there.
* Methods that take an unknown class as parameter or as return object, have been removed for now.
- *
+ *
* TODO: generate automatically.
*
*/
@@ -36,7 +36,7 @@
public SurfaceView(Context context) {
this(context, null);
}
-
+
public SurfaceView(Context context, AttributeSet attrs) {
this(context, attrs , 0);
}
@@ -44,53 +44,66 @@
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
-
+
public SurfaceHolder getHolder() {
return mSurfaceHolder;
}
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-
+
+ @Override
public boolean isCreating() {
return false;
}
+ @Override
public void addCallback(Callback callback) {
}
+ @Override
public void removeCallback(Callback callback) {
}
-
+
+ @Override
public void setFixedSize(int width, int height) {
}
+ @Override
public void setSizeFromLayout() {
}
+ @Override
public void setFormat(int format) {
}
+ @Override
public void setType(int type) {
}
+ @Override
public void setKeepScreenOn(boolean screenOn) {
}
-
+
+ @Override
public Canvas lockCanvas() {
return null;
}
+ @Override
public Canvas lockCanvas(Rect dirty) {
return null;
}
+ @Override
public void unlockCanvasAndPost(Canvas canvas) {
}
+ @Override
public Surface getSurface() {
return null;
}
+ @Override
public Rect getSurfaceFrame() {
return null;
}
Only in layoutlib_4-4-2-r1/bridge/src/android/view: ViewRootImpl_Delegate.java
Only in layoutlib_4-4-2-r1/bridge/src/android/view: WindowManagerGlobal_Delegate.java
diff -ru layoutlib_4-0-3-r1/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java layoutlib_4-4-2-r1/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
--- layoutlib_4-0-3-r1/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java 2014-03-13 18:28:01.000000000 -0700
@@ -22,6 +22,6 @@
public class InputMethodManager_Accessor {
public static void resetInstance() {
- InputMethodManager.mInstance = null;
+ InputMethodManager.sInstance = null;
}
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java layoutlib_4-4-2-r1/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -35,28 +35,15 @@
// ---- Overridden methods ----
@LayoutlibDelegate
- /*package*/ static InputMethodManager getInstance(Looper mainLooper) {
- synchronized (InputMethodManager.mInstanceSync) {
- if (InputMethodManager.mInstance != null) {
- return InputMethodManager.mInstance;
+ /*package*/ static InputMethodManager getInstance() {
+ synchronized (InputMethodManager.class) {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm == null) {
+ imm = new InputMethodManager(
+ new BridgeIInputMethodManager(), Looper.getMainLooper());
+ InputMethodManager.sInstance = imm;
}
-
- InputMethodManager.mInstance = new InputMethodManager(new BridgeIInputMethodManager(),
- mainLooper);
- }
- return InputMethodManager.mInstance;
- }
-
- @LayoutlibDelegate
- /*package*/ static InputMethodManager getInstance(Context context) {
- synchronized (InputMethodManager.mInstanceSync) {
- if (InputMethodManager.mInstance != null) {
- return InputMethodManager.mInstance;
- }
-
- InputMethodManager.mInstance = new InputMethodManager(new BridgeIInputMethodManager(),
- Looper.myLooper());
+ return imm;
}
- return InputMethodManager.mInstance;
}
}
diff -ru layoutlib_4-0-3-r1/bridge/src/android/webkit/WebView.java layoutlib_4-4-2-r1/bridge/src/android/webkit/WebView.java
--- layoutlib_4-0-3-r1/bridge/src/android/webkit/WebView.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/android/webkit/WebView.java 2014-03-13 18:28:01.000000000 -0700
@@ -99,14 +99,6 @@
public static void disablePlatformNotifications() {
}
- public WebBackForwardList saveState(Bundle outState) {
- return null;
- }
-
- public WebBackForwardList restoreState(Bundle inState) {
- return null;
- }
-
public void loadUrl(String url) {
}
@@ -213,10 +205,6 @@
public void clearSslPreferences() {
}
- public WebBackForwardList copyBackForwardList() {
- return null;
- }
-
public static String findAddress(String addr) {
return null;
}
@@ -236,10 +224,6 @@
public void addJavascriptInterface(Object obj, String interfaceName) {
}
- public WebSettings getSettings() {
- return null;
- }
-
public View getZoomControls() {
return null;
}
Only in layoutlib_4-4-2-r1/bridge/src/com/android/internal: policy
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java layoutlib_4-4-2-r1/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/internal/textservice/ITextServicesManager_Stub_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -43,28 +43,33 @@
private static class FakeTextServicesManager implements ITextServicesManager {
+ @Override
public void finishSpellCheckerService(ISpellCheckerSessionListener arg0)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public SpellCheckerInfo getCurrentSpellChecker(String arg0) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String arg0, boolean arg1)
throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public SpellCheckerInfo[] getEnabledSpellCheckers() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public void getSpellCheckerService(String arg0, String arg1,
ITextServicesSessionListener arg2, ISpellCheckerSessionListener arg3, Bundle arg4)
throws RemoteException {
@@ -72,26 +77,31 @@
}
+ @Override
public boolean isSpellCheckerEnabled() throws RemoteException {
// TODO Auto-generated method stub
return false;
}
+ @Override
public void setCurrentSpellChecker(String arg0, String arg1) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void setCurrentSpellCheckerSubtype(String arg0, int arg1) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void setSpellCheckerEnabled(boolean arg0) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public IBinder asBinder() {
// TODO Auto-generated method stub
return null;
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/Bridge.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/Bridge.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/Bridge.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/Bridge.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,16 +24,18 @@
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.Result.Status;
+import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.RenderDrawable;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+import com.android.layoutlib.bridge.util.DynamicIdMap;
import com.android.ninepatch.NinePatchChunk;
import com.android.resources.ResourceType;
import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;
import com.android.util.Pair;
+import com.ibm.icu.util.ULocale;
import android.content.res.BridgeAssetManager;
import android.graphics.Bitmap;
@@ -63,6 +65,8 @@
*/
public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
+ private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
+
public static class StaticMethodNotImplementedException extends RuntimeException {
private static final long serialVersionUID = 1L;
@@ -78,7 +82,7 @@
private final static ReentrantLock sLock = new ReentrantLock();
/**
- * Maps from id to resource type/name. This is for android.R only.
+ * Maps from id to resource type/name. This is for com.android.internal.R
*/
private final static Map<Integer, Pair<ResourceType, String>> sRMap =
new HashMap<Integer, Pair<ResourceType, String>>();
@@ -89,11 +93,17 @@
private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>();
/**
* Reverse map compared to sRMap, resource type -> (resource name -> id).
- * This is for android.R only.
+ * This is for com.android.internal.R.
*/
- private final static Map<ResourceType, Map<String, Integer>> sRFullMap =
+ private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
+ // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
+ // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
+ // collision which should be fine.
+ private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
+ private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
+
private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
@@ -203,7 +213,9 @@
Capability.PLAY_ANIMATION,
Capability.ANIMATED_VIEW_MANIPULATION,
Capability.ADAPTER_BINDING,
- Capability.EXTENDED_VIEWINFO);
+ Capability.EXTENDED_VIEWINFO,
+ Capability.FIXED_SCALABLE_NINE_PATCH,
+ Capability.RTL);
BridgeAssetManager.initSystem();
@@ -242,6 +254,8 @@
if (fontLoader != null) {
Typeface_Delegate.init(fontLoader);
} else {
+ log.error(LayoutLog.TAG_BROKEN,
+ "Failed create FontLoader in layout lib.", null);
return false;
}
@@ -255,7 +269,7 @@
ResourceType resType = ResourceType.getEnum(resTypeName);
if (resType != null) {
Map<String, Integer> fullMap = new HashMap<String, Integer>();
- sRFullMap.put(resType, fullMap);
+ sRevRMap.put(resType, fullMap);
for (Field f : inner.getDeclaredFields()) {
// only process static final fields. Since the final attribute may have
@@ -401,6 +415,20 @@
throw new IllegalArgumentException("viewObject is not a View");
}
+ @Override
+ public boolean isRtl(String locale) {
+ return isLocaleRtl(locale);
+ }
+
+ public static boolean isLocaleRtl(String locale) {
+ if (locale == null) {
+ locale = "";
+ }
+ ULocale uLocale = new ULocale(locale);
+ return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL) ?
+ true : false;
+ }
+
/**
* Returns the lock for the bridge
*/
@@ -418,7 +446,7 @@
// we need to make sure the Looper has been initialized for this thread.
// this is required for View that creates Handler objects.
if (Looper.myLooper() == null) {
- Looper.prepare();
+ Looper.prepareMainLooper();
}
}
@@ -457,7 +485,14 @@
* does not match any resource.
*/
public static Pair<ResourceType, String> resolveResourceId(int value) {
- return sRMap.get(value);
+ Pair<ResourceType, String> pair = sRMap.get(value);
+ if (pair == null) {
+ pair = sDynamicIds.resolveId(value);
+ if (pair == null) {
+ //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
+ }
+ }
+ return pair;
}
/**
@@ -476,12 +511,17 @@
* @return an {@link Integer} containing the resource id, or null if no resource were found.
*/
public static Integer getResourceId(ResourceType type, String name) {
- Map<String, Integer> map = sRFullMap.get(type);
+ Map<String, Integer> map = sRevRMap.get(type);
+ Integer value = null;
if (map != null) {
- return map.get(name);
+ value = map.get(name);
}
- return null;
+ if (value == null) {
+ value = sDynamicIds.getId(type, name);
+ }
+
+ return value;
}
/**
@@ -596,6 +636,4 @@
sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
}
}
-
-
}
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java 2014-03-13 18:28:01.000000000 -0700
@@ -39,6 +39,9 @@
/** Namespace for the resource XML */
public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
+ /** App auto namespace */
+ public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
+
public final static String R = "com.android.internal.R";
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java 2014-03-13 18:28:01.000000000 -0700
@@ -70,13 +70,13 @@
@Override
public Result getProperty(Object objectView, String propertyName) {
- // TODO Auto-generated method stub
+ // pass
return super.getProperty(objectView, propertyName);
}
@Override
public Result setProperty(Object objectView, String propertyName, String propertyValue) {
- // TODO Auto-generated method stub
+ // pass
return super.setProperty(objectView, propertyName, propertyValue);
}
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java 2014-03-13 18:28:01.000000000 -0700
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -39,26 +40,30 @@
*/
public final class BridgeContentProvider implements IContentProvider {
@Override
- public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
+ public ContentProviderResult[] applyBatch(String callingPackage,
+ ArrayList<ContentProviderOperation> arg0)
throws RemoteException, OperationApplicationException {
// TODO Auto-generated method stub
return null;
}
@Override
- public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
+ public int bulkInsert(String callingPackage, Uri arg0, ContentValues[] arg1)
+ throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
@Override
- public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
+ public Bundle call(String callingPackage, String arg0, String arg1, Bundle arg2)
+ throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@Override
- public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
+ public int delete(String callingPackage, Uri arg0, String arg1, String[] arg2)
+ throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
@@ -70,35 +75,37 @@
}
@Override
- public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
+ public Uri insert(String callingPackage, Uri arg0, ContentValues arg1) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@Override
- public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
- FileNotFoundException {
+ public AssetFileDescriptor openAssetFile(
+ String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
+ throws RemoteException, FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
@Override
- public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
- FileNotFoundException {
+ public ParcelFileDescriptor openFile(
+ String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
+ throws RemoteException, FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
@Override
- public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
- throws RemoteException {
+ public Cursor query(String callingPackage, Uri arg0, String[] arg1, String arg2, String[] arg3,
+ String arg4, ICancellationSignal arg5) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@Override
- public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
- throws RemoteException {
+ public int update(String callingPackage, Uri arg0, ContentValues arg1, String arg2,
+ String[] arg3) throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
@@ -116,10 +123,25 @@
}
@Override
- public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2)
- throws RemoteException, FileNotFoundException {
+ public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
+ Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ICancellationSignal createCancellationSignal() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
+ public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
+ return null;
+ }
+
+ @Override
+ public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
+ return null;
+ }
}
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java 2014-03-13 18:28:01.000000000 -0700
@@ -62,6 +62,21 @@
return false;
}
+ @Override
+ protected IContentProvider acquireUnstableProvider(Context c, String name) {
+ return acquireProvider(c, name);
+ }
+
+ @Override
+ public boolean releaseUnstableProvider(IContentProvider icp) {
+ return releaseProvider(icp);
+ }
+
+ /** @hide */
+ @Override
+ public void unstableProviderDied(IContentProvider icp) {
+ }
+
/**
* Stub for the layoutlib bridge content resolver.
*/
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java 2014-03-13 18:28:01.000000000 -0700
@@ -25,6 +25,7 @@
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
@@ -49,8 +50,8 @@
import android.content.res.BridgeTypedArray;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -60,13 +61,17 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.os.PowerManager;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.BridgeInflater;
-import android.view.Surface;
+import android.view.Display;
+import android.view.DisplayAdjustments;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.textservice.TextServicesManager;
import java.io.File;
@@ -75,13 +80,11 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
/**
* Custom implementation of Context/Activity to handle non compiled resources.
@@ -96,7 +99,7 @@
private final Configuration mConfig;
private final ApplicationInfo mApplicationInfo;
private final IProjectCallback mProjectCallback;
- private final BridgeWindowManager mIWindowManager;
+ private final WindowManager mWindowManager;
private Resources.Theme mTheme;
@@ -129,7 +132,8 @@
RenderResources renderResources,
IProjectCallback projectCallback,
Configuration config,
- int targetSdkVersion) {
+ int targetSdkVersion,
+ boolean hasRtlSupport) {
mProjectKey = projectKey;
mMetrics = metrics;
mProjectCallback = projectCallback;
@@ -137,10 +141,13 @@
mRenderResources = renderResources;
mConfig = config;
- mIWindowManager = new BridgeWindowManager(mConfig, metrics, Surface.ROTATION_0);
-
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.targetSdkVersion = targetSdkVersion;
+ if (hasRtlSupport) {
+ mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
+ }
+
+ mWindowManager = new WindowManagerImpl(mMetrics);
}
/**
@@ -196,14 +203,14 @@
return mRenderResources;
}
- public BridgeWindowManager getIWindowManager() {
- return mIWindowManager;
- }
-
public Map<String, String> getDefaultPropMap(Object key) {
return mDefaultPropMaps.get(key);
}
+ public Configuration getConfiguration() {
+ return mConfig;
+ }
+
/**
* Adds a parser to the stack.
* @param parser the parser to add.
@@ -246,15 +253,18 @@
public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
+ boolean isFrameworkRes = true;
if (resourceInfo == null) {
resourceInfo = mProjectCallback.resolveResourceId(resid);
+ isFrameworkRes = false;
}
if (resourceInfo == null) {
return false;
}
- ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond());
+ ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
+ isFrameworkRes);
if (resolveRefs) {
value = mRenderResources.resolveResValue(value);
}
@@ -314,12 +324,7 @@
if (isPlatformLayout == false && skipCallbackParser == false) {
// check if the project callback can provide us with a custom parser.
- ILayoutPullParser parser;
- if (resource instanceof ResourceValue) {
- parser = mProjectCallback.getParser((ResourceValue) resource);
- } else {
- parser = mProjectCallback.getParser(resource.getName());
- }
+ ILayoutPullParser parser = getParser(resource);
if (parser != null) {
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
@@ -392,6 +397,17 @@
return Pair.of(null, false);
}
+ @SuppressWarnings("deprecation")
+ private ILayoutPullParser getParser(ResourceReference resource) {
+ ILayoutPullParser parser;
+ if (resource instanceof ResourceValue) {
+ parser = mProjectCallback.getParser((ResourceValue) resource);
+ } else {
+ parser = mProjectCallback.getParser(resource.getName());
+ }
+ return parser;
+ }
+
// ------------ Context methods
@Override
@@ -420,10 +436,8 @@
return TextServicesManager.getInstance();
}
- // AutoCompleteTextView and MultiAutoCompleteTextView want a window
- // service. We don't have any but it's not worth an exception.
if (WINDOW_SERVICE.equals(service)) {
- return null;
+ return mWindowManager;
}
// needed by SearchView
@@ -431,6 +445,10 @@
return null;
}
+ if (POWER_SERVICE.equals(service)) {
+ return new PowerManager(this, new BridgePowerManager(), new Handler());
+ }
+
throw new UnsupportedOperationException("Unsupported Service: " + service);
}
@@ -519,12 +537,10 @@
return null;
}
- AtomicBoolean frameworkAttributes = new AtomicBoolean();
- AtomicReference<String> attrName = new AtomicReference<String>();
- TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes, attrName);
+ List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
- isPlatformFile, frameworkAttributes.get(), attrName.get());
+ isPlatformFile);
// look for a custom style.
String customStyle = null;
@@ -550,14 +566,19 @@
if (defStyleAttr != 0) {
// get the name from the int.
- String defStyleName = searchAttr(defStyleAttr);
+ Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
if (defaultPropMap != null) {
+ String defStyleName = defStyleAttribute.getFirst();
+ if (defStyleAttribute.getSecond()) {
+ defStyleName = "android:" + defStyleName;
+ }
defaultPropMap.put("style", defStyleName);
}
// look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
+ ResourceValue item = mRenderResources.findItemInTheme(defStyleAttribute.getFirst(),
+ defStyleAttribute.getSecond());
if (item != null) {
// item is a reference to a style entry. Search for it.
@@ -568,21 +589,25 @@
defStyleValues = (StyleResourceValue)item;
}
} else {
- Bridge.getLog().error(null,
+ Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
String.format(
- "Failed to find style '%s' in current theme", defStyleName),
+ "Failed to find style '%s' in current theme",
+ defStyleAttribute.getFirst()),
null /*data*/);
}
} else if (defStyleRes != 0) {
+ boolean isFrameworkRes = true;
Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
if (value == null) {
value = mProjectCallback.resolveResourceId(defStyleRes);
+ isFrameworkRes = false;
}
if (value != null) {
if (value.getFirst() == ResourceType.STYLE) {
// look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
+ ResourceValue item = mRenderResources.findItemInTheme(value.getSecond(),
+ isFrameworkRes);
if (item != null) {
if (item instanceof StyleResourceValue) {
if (defaultPropMap != null) {
@@ -614,20 +639,29 @@
}
}
- String namespace = BridgeConstants.NS_RESOURCES;
- if (frameworkAttributes.get() == false) {
- // need to use the application namespace
- namespace = mProjectCallback.getNamespace();
- }
+ String appNamespace = mProjectCallback.getNamespace();
- if (styleNameMap != null) {
- for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
- int index = styleAttribute.getKey().intValue();
+ if (attributeList != null) {
+ for (int index = 0 ; index < attributeList.size() ; index++) {
+ Pair<String, Boolean> attribute = attributeList.get(index);
- String name = styleAttribute.getValue();
+ if (attribute == null) {
+ continue;
+ }
+
+ String attrName = attribute.getFirst();
+ boolean frameworkAttr = attribute.getSecond().booleanValue();
String value = null;
if (set != null) {
- value = set.getAttributeValue(namespace, name);
+ value = set.getAttributeValue(
+ frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
+ attrName);
+
+ // if this is an app attribute, and the first get fails, try with the
+ // new res-auto namespace as well
+ if (frameworkAttr == false && value == null) {
+ value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
+ }
}
// if there's no direct value for this attribute in the XML, we look for default
@@ -637,18 +671,20 @@
// look for the value in the custom style first (and its parent if needed)
if (customStyleValues != null) {
- resValue = mRenderResources.findItemInStyle(customStyleValues, name);
+ resValue = mRenderResources.findItemInStyle(customStyleValues,
+ attrName, frameworkAttr);
}
// then look for the value in the default Style (and its parent if needed)
if (resValue == null && defStyleValues != null) {
- resValue = mRenderResources.findItemInStyle(defStyleValues, name);
+ resValue = mRenderResources.findItemInStyle(defStyleValues,
+ attrName, frameworkAttr);
}
// if the item is not present in the defStyle, we look in the main theme (and
// its parent themes)
if (resValue == null) {
- resValue = mRenderResources.findItemInTheme(name);
+ resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
}
// if we found a value, we make sure this doesn't reference another value.
@@ -656,18 +692,18 @@
if (resValue != null) {
// put the first default value, before the resolution.
if (defaultPropMap != null) {
- defaultPropMap.put(name, resValue.getValue());
+ defaultPropMap.put(attrName, resValue.getValue());
}
resValue = mRenderResources.resolveResValue(resValue);
}
- ta.bridgeSetValue(index, name, resValue);
+ ta.bridgeSetValue(index, attrName, frameworkAttr, resValue);
} else {
// there is a value in the XML, but we need to resolve it in case it's
// referencing another resource or a theme value.
- ta.bridgeSetValue(index, name,
- mRenderResources.resolveValue(null, name, value, isPlatformFile));
+ ta.bridgeSetValue(index, attrName, frameworkAttr,
+ mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
}
}
}
@@ -693,22 +729,24 @@
private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
throws Resources.NotFoundException {
+ List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
+
BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
- false, true, null);
+ false);
// for each attribute, get its name so that we can search it in the style
for (int i = 0 ; i < attrs.length ; i++) {
- Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
- if (resolvedResource != null) {
- String attrName = resolvedResource.getSecond();
+ Pair<String, Boolean> attribute = attributes.get(i);
+
+ if (attribute != null) {
// look for the value in the given style
- ResourceValue resValue = mRenderResources.findItemInStyle(style, attrName);
+ ResourceValue resValue = mRenderResources.findItemInStyle(style,
+ attribute.getFirst(), attribute.getSecond());
if (resValue != null) {
// resolve it to make sure there are no references left.
- ta.bridgeSetValue(i, attrName, mRenderResources.resolveResValue(resValue));
-
- resValue = mRenderResources.resolveResValue(resValue);
+ ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(),
+ mRenderResources.resolveResValue(resValue));
}
}
}
@@ -720,91 +758,52 @@
/**
- * The input int[] attrs is one of com.android.internal.R.styleable fields where the name
- * of the field is the style being referenced and the array contains one index per attribute.
+ * The input int[] attrs is a list of attributes. The returns a list of information about
+ * each attributes. The information is (name, isFramework)
* <p/>
- * searchAttrs() finds all the names of the attributes referenced so for example if
- * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where
- * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index
- * that is used to reference the attribute later in the TypedArray.
*
* @param attrs An attribute array reference given to obtainStyledAttributes.
- * @param outFrameworkFlag out value indicating if the attr array is a framework value
- * @param outAttrName out value for the resolved attr name.
- * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the
- * attribute array. Returns null if nothing is found.
+ * @return List of attribute information.
*/
- private TreeMap<Integer,String> searchAttrs(int[] attrs, AtomicBoolean outFrameworkFlag,
- AtomicReference<String> outAttrName) {
- // get the name of the array from the framework resources
- String arrayName = Bridge.resolveResourceId(attrs);
- if (arrayName != null) {
- // if we found it, get the name of each of the int in the array.
- TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
- for (int i = 0 ; i < attrs.length ; i++) {
- Pair<ResourceType, String> info = Bridge.resolveResourceId(attrs[i]);
- if (info != null) {
- attributes.put(i, info.getSecond());
- } else {
- // FIXME Not sure what we should be doing here...
- attributes.put(i, null);
- }
- }
+ private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
+ List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
- if (outFrameworkFlag != null) {
- outFrameworkFlag.set(true);
- }
- if (outAttrName != null) {
- outAttrName.set(arrayName);
- }
-
- return attributes;
- }
-
- // if the name was not found in the framework resources, look in the project
- // resources
- arrayName = mProjectCallback.resolveResourceId(attrs);
- if (arrayName != null) {
- TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
- for (int i = 0 ; i < attrs.length ; i++) {
- Pair<ResourceType, String> info = mProjectCallback.resolveResourceId(attrs[i]);
- if (info != null) {
- attributes.put(i, info.getSecond());
- } else {
- // FIXME Not sure what we should be doing here...
- attributes.put(i, null);
- }
+ // for each attribute, get its name so that we can search it in the style
+ for (int i = 0 ; i < attrs.length ; i++) {
+ Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
+ boolean isFramework = false;
+ if (resolvedResource != null) {
+ isFramework = true;
+ } else {
+ resolvedResource = mProjectCallback.resolveResourceId(attrs[i]);
}
- if (outFrameworkFlag != null) {
- outFrameworkFlag.set(false);
- }
- if (outAttrName != null) {
- outAttrName.set(arrayName);
+ if (resolvedResource != null) {
+ results.add(Pair.of(resolvedResource.getSecond(), isFramework));
+ } else {
+ results.add(null);
}
-
- return attributes;
}
- return null;
+ return results;
}
/**
* Searches for the attribute referenced by its internal id.
*
* @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
- * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null
+ * @return A (name, isFramework) pair describing the attribute if found. Returns null
* if nothing is found.
*/
- public String searchAttr(int attr) {
+ public Pair<String, Boolean> searchAttr(int attr) {
Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
if (info != null) {
- return info.getSecond();
+ return Pair.of(info.getSecond(), Boolean.TRUE);
}
info = mProjectCallback.resolveResourceId(attr);
if (info != null) {
- return info.getSecond();
+ return Pair.of(info.getSecond(), Boolean.FALSE);
}
return null;
@@ -864,149 +863,167 @@
@Override
public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
- // TODO Auto-generated method stub
+ // pass
return false;
}
@Override
public int checkCallingOrSelfPermission(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkCallingPermission(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkCallingUriPermission(Uri arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkPermission(String arg0, int arg1, int arg2) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
int arg4, int arg5) {
- // TODO Auto-generated method stub
+ // pass
return 0;
}
@Override
public void clearWallpaper() {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public Context createPackageContext(String arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
+ return null;
+ }
+
+ @Override
+ public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
+ // pass
+ return null;
+ }
+
+ @Override
+ public Context createConfigurationContext(Configuration overrideConfiguration) {
+ // pass
+ return null;
+ }
+
+ @Override
+ public Context createDisplayContext(Display display) {
+ // pass
return null;
}
@Override
public String[] databaseList() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public boolean deleteDatabase(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return false;
}
@Override
public boolean deleteFile(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return false;
}
@Override
public void enforceCallingOrSelfPermission(String arg0, String arg1) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
String arg2) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforceCallingPermission(String arg0, String arg1) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
String arg4) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void enforceUriPermission(Uri arg0, String arg1, String arg2,
int arg3, int arg4, int arg5, String arg6) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public String[] fileList() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public AssetManager getAssets() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getCacheDir() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getExternalCacheDir() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@@ -1020,49 +1037,61 @@
@Override
public File getDatabasePath(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getDir(String arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getFileStreamPath(String arg0) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getFilesDir() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getExternalFilesDir(String type) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public String getPackageCodePath() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public PackageManager getPackageManager() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public String getPackageName() {
- // TODO Auto-generated method stub
+ // pass
+ return null;
+ }
+
+ @Override
+ public String getBasePackageName() {
+ // pass
+ return null;
+ }
+
+ @Override
+ public String getOpPackageName() {
+ // pass
return null;
}
@@ -1073,25 +1102,25 @@
@Override
public String getPackageResourcePath() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public File getSharedPrefsFile(String name) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public SharedPreferences getSharedPreferences(String arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public Drawable getWallpaper() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@@ -1107,81 +1136,93 @@
@Override
public void grantUriPermission(String arg0, Uri arg1, int arg2) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
CursorFactory arg2, DatabaseErrorHandler arg3) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public Drawable peekWallpaper() {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
String arg2, Handler arg3) {
- // TODO Auto-generated method stub
+ // pass
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
+ IntentFilter arg1, String arg2, Handler arg3) {
+ // pass
return null;
}
@Override
public void removeStickyBroadcast(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void revokeUriPermission(Uri arg0, int arg1) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void sendBroadcast(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void sendBroadcast(Intent arg0, String arg1) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
+ public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
+ // pass
+ }
+
+ @Override
public void sendOrderedBroadcast(Intent arg0, String arg1) {
- // TODO Auto-generated method stub
+ // pass
}
@@ -1189,13 +1230,38 @@
public void sendOrderedBroadcast(Intent arg0, String arg1,
BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
Bundle arg6) {
- // TODO Auto-generated method stub
+ // pass
+
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ // pass
+ }
+
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+ // pass
+ }
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission) {
+ // pass
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
+ int initialCode, String initialData, Bundle initialExtras) {
+ // pass
}
@Override
public void sendStickyBroadcast(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@@ -1203,68 +1269,109 @@
public void sendStickyOrderedBroadcast(Intent intent,
BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
Bundle initialExtras) {
- // TODO Auto-generated method stub
+ // pass
+ }
+
+ @Override
+ public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ // pass
+ }
+
+ @Override
+ public void sendStickyOrderedBroadcastAsUser(Intent intent,
+ UserHandle user, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ // pass
+ }
+
+ @Override
+ public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ // pass
}
@Override
public void setTheme(int arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void setWallpaper(Bitmap arg0) throws IOException {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void setWallpaper(InputStream arg0) throws IOException {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void startActivity(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
+ }
+ @Override
+ public void startActivity(Intent arg0, Bundle arg1) {
+ // pass
}
@Override
public void startIntentSender(IntentSender intent,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
throws IntentSender.SendIntentException {
- // TODO Auto-generated method stub
+ // pass
+ }
+
+ @Override
+ public void startIntentSender(IntentSender intent,
+ Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+ Bundle options) throws IntentSender.SendIntentException {
+ // pass
}
@Override
public boolean startInstrumentation(ComponentName arg0, String arg1,
Bundle arg2) {
- // TODO Auto-generated method stub
+ // pass
return false;
}
@Override
public ComponentName startService(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
return null;
}
@Override
public boolean stopService(Intent arg0) {
- // TODO Auto-generated method stub
+ // pass
+ return false;
+ }
+
+ @Override
+ public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
+ // pass
+ return null;
+ }
+
+ @Override
+ public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
+ // pass
return false;
}
@Override
public void unbindService(ServiceConnection arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@Override
public void unregisterReceiver(BroadcastReceiver arg0) {
- // TODO Auto-generated method stub
+ // pass
}
@@ -1275,7 +1382,13 @@
@Override
public void startActivities(Intent[] arg0) {
- // TODO Auto-generated method stub
+ // pass
+
+ }
+
+ @Override
+ public void startActivities(Intent[] arg0, Bundle arg1) {
+ // pass
}
@@ -1289,4 +1402,36 @@
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
return null;
}
+
+ @Override
+ public DisplayAdjustments getDisplayAdjustments(int displayId) {
+ // pass
+ return null;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public int getUserId() {
+ return 0; // not used
+ }
+
+ @Override
+ public File[] getExternalFilesDirs(String type) {
+ // pass
+ return new File[0];
+ }
+
+ @Override
+ public File[] getObbDirs() {
+ // pass
+ return new File[0];
+ }
+
+ @Override
+ public File[] getExternalCacheDirs() {
+ // pass
+ return new File[0];
+ }
}
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java 2014-03-13 18:28:01.000000000 -0700
@@ -37,151 +37,192 @@
*/
public class BridgeIInputMethodManager implements IInputMethodManager {
+ @Override
public void addClient(IInputMethodClient arg0, IInputContext arg1, int arg2, int arg3)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void finishInput(IInputMethodClient arg0) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public InputMethodSubtype getCurrentInputMethodSubtype() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public List<InputMethodInfo> getEnabledInputMethodList() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
- public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo arg0,
+ @Override
+ public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public List<InputMethodInfo> getInputMethodList() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public InputMethodSubtype getLastInputMethodSubtype() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public List getShortcutInputMethodsAndSubtypes() throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public void hideMySoftInput(IBinder arg0, int arg1) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public boolean hideSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
throws RemoteException {
// TODO Auto-generated method stub
return false;
}
+ @Override
public boolean notifySuggestionPicked(SuggestionSpan arg0, String arg1, int arg2)
throws RemoteException {
// TODO Auto-generated method stub
return false;
}
+ @Override
public void registerSuggestionSpansForNotification(SuggestionSpan[] arg0)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void removeClient(IInputMethodClient arg0) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
+ @Override
public void setImeWindowStatus(IBinder arg0, int arg1, int arg2) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void setInputMethod(IBinder arg0, String arg1) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void setInputMethodAndSubtype(IBinder arg0, String arg1, InputMethodSubtype arg2)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public boolean setInputMethodEnabled(String arg0, boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
+ @Override
public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient arg0, String arg1)
throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void showInputMethodPickerFromClient(IInputMethodClient arg0) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public void showMySoftInput(IBinder arg0, int arg1) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
public boolean showSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
throws RemoteException {
// TODO Auto-generated method stub
return false;
}
- public InputBindResult startInput(IInputMethodClient arg0, IInputContext arg1, EditorInfo arg2,
- boolean arg3, boolean arg4) throws RemoteException {
+ @Override
+ public InputBindResult startInput(IInputMethodClient client, IInputContext inputContext,
+ EditorInfo attribute, int controlFlags) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public boolean switchToLastInputMethod(IBinder arg0) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
- public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
+ @Override
+ public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
+ return false;
+ }
+ @Override
+ public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
+ // TODO Auto-generated method stub
+ return false;
}
- public void windowGainedFocus(IInputMethodClient arg0, IBinder arg1, boolean arg2,
- boolean arg3, int arg4, boolean arg5, int arg6) throws RemoteException {
+ @Override
+ public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
// TODO Auto-generated method stub
}
+ @Override
+ public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
+ int controlFlags, int softInputMode, int windowFlags, EditorInfo attribute,
+ IInputContext inputContext) throws RemoteException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
public IBinder asBinder() {
// TODO Auto-generated method stub
return null;
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java 2014-03-13 18:28:01.000000000 -0700
@@ -37,6 +37,7 @@
mAttributes = attributes;
}
+ @Override
public String getAttributeValue(String namespace, String name) {
if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
return mAttributes.get(name);
@@ -49,93 +50,114 @@
// BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
// Should they ever be called, we'll just implement them on a need basis.
+ @Override
public int getAttributeCount() {
throw new UnsupportedOperationException();
}
+ @Override
public String getAttributeName(int index) {
throw new UnsupportedOperationException();
}
+ @Override
public String getAttributeValue(int index) {
throw new UnsupportedOperationException();
}
+ @Override
public String getPositionDescription() {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeNameResource(int index) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeListValue(String namespace, String attribute,
String[] options, int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean getAttributeBooleanValue(String namespace, String attribute,
boolean defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeResourceValue(String namespace, String attribute,
int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeIntValue(String namespace, String attribute,
int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeUnsignedIntValue(String namespace, String attribute,
int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public float getAttributeFloatValue(String namespace, String attribute,
float defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeListValue(int index,
String[] options, int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeResourceValue(int index, int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeIntValue(int index, int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getAttributeUnsignedIntValue(int index, int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public float getAttributeFloatValue(int index, float defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public String getIdAttribute() {
throw new UnsupportedOperationException();
}
+ @Override
public String getClassAttribute() {
throw new UnsupportedOperationException();
}
+ @Override
public int getIdAttributeResourceValue(int defaultValue) {
throw new UnsupportedOperationException();
}
+ @Override
public int getStyleAttribute() {
throw new UnsupportedOperationException();
}
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android: BridgePowerManager.java
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,72 +24,82 @@
import android.os.RemoteException;
import android.view.DragEvent;
import android.view.IWindow;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
/**
* Implementation of {@link IWindow} to pass to the AttachInfo.
*/
public final class BridgeWindow implements IWindow {
+ @Override
public void dispatchAppVisibility(boolean arg0) throws RemoteException {
// pass for now.
}
+ @Override
public void dispatchGetNewSurface() throws RemoteException {
// pass for now.
}
- public void dispatchKey(KeyEvent arg0) throws RemoteException {
- // pass for now.
- }
-
- public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+ @Override
+ public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
+ throws RemoteException {
// pass for now.
}
- public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2)
- throws RemoteException {
+ @Override
+ public void resized(Rect arg1, Rect arg1p5, Rect arg2, Rect arg3,
+ boolean arg4, Configuration arg5) throws RemoteException {
// pass for now.
}
- public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
- throws RemoteException {
+ @Override
+ public void moved(int arg0, int arg1) throws RemoteException {
// pass for now.
}
- public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
- throws RemoteException {
+ @Override
+ public void dispatchScreenState(boolean on) throws RemoteException {
// pass for now.
}
+ @Override
public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
// pass for now.
}
+ @Override
public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
boolean sync) {
// pass for now.
}
+ @Override
public void dispatchWallpaperCommand(String action, int x, int y,
int z, Bundle extras, boolean sync) {
// pass for now.
}
+ @Override
public void closeSystemDialogs(String reason) {
// pass for now.
}
+ @Override
public void dispatchDragEvent(DragEvent event) {
// pass for now.
}
+ @Override
public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
int localValue, int localChanges) {
// pass for now.
}
+ @Override
+ public void doneAnimating() {
+ }
+
+ @Override
public IBinder asBinder() {
// pass for now.
return null;
Only in layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android: BridgeWindowManager.java
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,9 +24,9 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.view.IWindow;
+import android.view.IWindowId;
import android.view.IWindowSession;
import android.view.InputChannel;
-import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.WindowManager.LayoutParams;
@@ -37,6 +37,7 @@
*/
public final class BridgeWindowSession implements IWindowSession {
+ @Override
public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3,
InputChannel outInputchannel)
throws RemoteException {
@@ -44,76 +45,91 @@
return 0;
}
- public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3)
+ @Override
+ public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
+ Rect arg3, InputChannel outInputchannel)
throws RemoteException {
// pass for now.
return 0;
}
- public void finishDrawing(IWindow arg0) throws RemoteException {
+ @Override
+ public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
+ Rect arg3)
+ throws RemoteException {
// pass for now.
+ return 0;
}
- public void finishKey(IWindow arg0) throws RemoteException {
+ @Override
+ public int addToDisplayWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
+ int displayId, Rect arg3)
+ throws RemoteException {
// pass for now.
+ return 0;
}
- public boolean getInTouchMode() throws RemoteException {
+ @Override
+ public void finishDrawing(IWindow arg0) throws RemoteException {
// pass for now.
- return false;
}
- public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
+ @Override
+ public boolean getInTouchMode() throws RemoteException {
// pass for now.
return false;
}
- public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
- // pass for now.
- return null;
- }
-
- public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
+ @Override
+ public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
// pass for now.
- return null;
+ return false;
}
-
+ @Override
public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
- int arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
- throws RemoteException {
+ int arg4_5, Rect arg5Z, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b,
+ Surface arg8) throws RemoteException {
// pass for now.
return 0;
}
+ @Override
public void performDeferredDestroy(IWindow window) {
// pass for now.
}
+ @Override
public boolean outOfMemory(IWindow window) throws RemoteException {
return false;
}
+ @Override
public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
// pass for now.
}
+ @Override
public void remove(IWindow arg0) throws RemoteException {
// pass for now.
}
+ @Override
public void setInTouchMode(boolean arg0) throws RemoteException {
// pass for now.
}
+ @Override
public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
// pass for now.
}
+ @Override
public void setInsets(IWindow window, int touchable, Rect contentInsets,
Rect visibleInsets, Region touchableRegion) {
// pass for now.
}
+ @Override
public IBinder prepareDrag(IWindow window, int flags,
int thumbnailWidth, int thumbnailHeight, Surface outSurface)
throws RemoteException {
@@ -121,6 +137,7 @@
return null;
}
+ @Override
public boolean performDrag(IWindow window, IBinder dragToken,
float touchX, float touchY, float thumbCenterX, float thumbCenterY,
ClipData data)
@@ -129,49 +146,64 @@
return false;
}
+ @Override
public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
// pass for now
}
+ @Override
public void dragRecipientEntered(IWindow window) throws RemoteException {
// pass for now
}
+ @Override
public void dragRecipientExited(IWindow window) throws RemoteException {
// pass for now
}
+ @Override
public void setWallpaperPosition(IBinder window, float x, float y,
float xStep, float yStep) {
// pass for now.
}
+ @Override
public void wallpaperOffsetsComplete(IBinder window) {
// pass for now.
}
+ @Override
public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
int z, Bundle extras, boolean sync) {
// pass for now.
return null;
}
+ @Override
public void wallpaperCommandComplete(IBinder window, Bundle result) {
// pass for now.
}
- public void closeSystemDialogs(String reason) {
+ @Override
+ public void setUniverseTransform(IBinder window, float alpha, float offx, float offy,
+ float dsdx, float dtdx, float dsdy, float dtdy) {
// pass for now.
}
+ @Override
public IBinder asBinder() {
// pass for now.
return null;
}
- public IBinder prepareDrag(IWindow arg0, boolean arg1, int arg2, int arg3, Surface arg4)
- throws RemoteException {
- // TODO Auto-generated method stub
+ @Override
+ public void onRectangleOnScreenRequested(IBinder window, Rect rectangle, boolean immediate) {
+ // pass for now.
+ }
+
+ @Override
+ public IWindowId getWindowId(IBinder window) throws RemoteException {
+ // pass for now.
return null;
}
}
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java 2014-03-13 18:28:01.000000000 -0700
@@ -95,6 +95,7 @@
// ------- XmlResourceParser implementation
+ @Override
public void setFeature(String name, boolean state)
throws XmlPullParserException {
if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
@@ -106,6 +107,7 @@
throw new XmlPullParserException("Unsupported feature: " + name);
}
+ @Override
public boolean getFeature(String name) {
if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
return true;
@@ -116,82 +118,101 @@
return false;
}
+ @Override
public void setProperty(String name, Object value) throws XmlPullParserException {
throw new XmlPullParserException("setProperty() not supported");
}
+ @Override
public Object getProperty(String name) {
return null;
}
+ @Override
public void setInput(Reader in) throws XmlPullParserException {
mParser.setInput(in);
}
+ @Override
public void setInput(InputStream inputStream, String inputEncoding)
throws XmlPullParserException {
mParser.setInput(inputStream, inputEncoding);
}
+ @Override
public void defineEntityReplacementText(String entityName,
String replacementText) throws XmlPullParserException {
throw new XmlPullParserException(
"defineEntityReplacementText() not supported");
}
+ @Override
public String getNamespacePrefix(int pos) throws XmlPullParserException {
throw new XmlPullParserException("getNamespacePrefix() not supported");
}
+ @Override
public String getInputEncoding() {
return null;
}
+ @Override
public String getNamespace(String prefix) {
throw new RuntimeException("getNamespace() not supported");
}
+ @Override
public int getNamespaceCount(int depth) throws XmlPullParserException {
throw new XmlPullParserException("getNamespaceCount() not supported");
}
+ @Override
public String getPositionDescription() {
return "Binary XML file line #" + getLineNumber();
}
+ @Override
public String getNamespaceUri(int pos) throws XmlPullParserException {
throw new XmlPullParserException("getNamespaceUri() not supported");
}
+ @Override
public int getColumnNumber() {
return -1;
}
+ @Override
public int getDepth() {
return mParser.getDepth();
}
+ @Override
public String getText() {
return mParser.getText();
}
+ @Override
public int getLineNumber() {
return mParser.getLineNumber();
}
+ @Override
public int getEventType() {
return mEventType;
}
+ @Override
public boolean isWhitespace() throws XmlPullParserException {
// Original comment: whitespace was stripped by aapt.
return mParser.isWhitespace();
}
+ @Override
public String getPrefix() {
throw new RuntimeException("getPrefix not supported");
}
+ @Override
public char[] getTextCharacters(int[] holderForStartAndLength) {
String txt = getText();
char[] chars = null;
@@ -204,55 +225,68 @@
return chars;
}
+ @Override
public String getNamespace() {
return mParser.getNamespace();
}
+ @Override
public String getName() {
return mParser.getName();
}
+ @Override
public String getAttributeNamespace(int index) {
return mParser.getAttributeNamespace(index);
}
+ @Override
public String getAttributeName(int index) {
return mParser.getAttributeName(index);
}
+ @Override
public String getAttributePrefix(int index) {
throw new RuntimeException("getAttributePrefix not supported");
}
+ @Override
public boolean isEmptyElementTag() {
// XXX Need to detect this.
return false;
}
+ @Override
public int getAttributeCount() {
return mParser.getAttributeCount();
}
+ @Override
public String getAttributeValue(int index) {
return mParser.getAttributeValue(index);
}
+ @Override
public String getAttributeType(int index) {
return "CDATA";
}
+ @Override
public boolean isAttributeDefault(int index) {
return false;
}
+ @Override
public int nextToken() throws XmlPullParserException, IOException {
return next();
}
+ @Override
public String getAttributeValue(String namespace, String name) {
return mParser.getAttributeValue(namespace, name);
}
+ @Override
public int next() throws XmlPullParserException, IOException {
if (!mStarted) {
mStarted = true;
@@ -313,6 +347,7 @@
return "????";
}
+ @Override
public void require(int type, String namespace, String name)
throws XmlPullParserException {
if (type != getEventType()
@@ -322,6 +357,7 @@
+ getPositionDescription());
}
+ @Override
public String nextText() throws XmlPullParserException, IOException {
if (getEventType() != START_TAG) {
throw new XmlPullParserException(getPositionDescription()
@@ -348,6 +384,7 @@
}
}
+ @Override
public int nextTag() throws XmlPullParserException, IOException {
int eventType = next();
if (eventType == TEXT && isWhitespace()) { // skip whitespace
@@ -363,76 +400,94 @@
// AttributeSet implementation
+ @Override
public void close() {
// pass
}
+ @Override
public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
return mAttrib.getAttributeBooleanValue(index, defaultValue);
}
+ @Override
public boolean getAttributeBooleanValue(String namespace, String attribute,
boolean defaultValue) {
return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
}
+ @Override
public float getAttributeFloatValue(int index, float defaultValue) {
return mAttrib.getAttributeFloatValue(index, defaultValue);
}
+ @Override
public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
}
+ @Override
public int getAttributeIntValue(int index, int defaultValue) {
return mAttrib.getAttributeIntValue(index, defaultValue);
}
+ @Override
public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
}
+ @Override
public int getAttributeListValue(int index, String[] options, int defaultValue) {
return mAttrib.getAttributeListValue(index, options, defaultValue);
}
+ @Override
public int getAttributeListValue(String namespace, String attribute,
String[] options, int defaultValue) {
return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
}
+ @Override
public int getAttributeNameResource(int index) {
return mAttrib.getAttributeNameResource(index);
}
+ @Override
public int getAttributeResourceValue(int index, int defaultValue) {
return mAttrib.getAttributeResourceValue(index, defaultValue);
}
+ @Override
public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
}
+ @Override
public int getAttributeUnsignedIntValue(int index, int defaultValue) {
return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
}
+ @Override
public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
}
+ @Override
public String getClassAttribute() {
return mAttrib.getClassAttribute();
}
+ @Override
public String getIdAttribute() {
return mAttrib.getIdAttribute();
}
+ @Override
public int getIdAttributeResourceValue(int defaultValue) {
return mAttrib.getIdAttributeResourceValue(defaultValue);
}
+ @Override
public int getStyleAttribute() {
return mAttrib.getStyleAttribute();
}
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/android: view
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java 2014-03-13 18:28:01.000000000 -0700
@@ -25,6 +25,7 @@
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.Density;
+import com.android.resources.LayoutDirection;
import com.android.resources.ResourceType;
import org.xmlpull.v1.XmlPullParser;
@@ -60,11 +61,15 @@
protected abstract TextView getStyleableTextView();
- protected CustomBar(Context context, Density density, String layoutPath, String name)
- throws XmlPullParserException {
+ protected CustomBar(Context context, Density density, int orientation, String layoutPath,
+ String name) throws XmlPullParserException {
super(context);
- setOrientation(LinearLayout.HORIZONTAL);
- setGravity(Gravity.CENTER_VERTICAL);
+ setOrientation(orientation);
+ if (orientation == LinearLayout.HORIZONTAL) {
+ setGravity(Gravity.CENTER_VERTICAL);
+ } else {
+ setGravity(Gravity.CENTER_HORIZONTAL);
+ }
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
@@ -82,38 +87,53 @@
}
}
- private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut,
- boolean tryOtherDensities) {
+ private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction,
+ String[] pathOut, boolean tryOtherDensities) {
// current density
Density density = densityInOut[0];
// bitmap url relative to this class
- pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
+ if (direction != null) {
+ pathOut[0] = "/bars/" + direction.getResourceValue() + "-" + density.getResourceValue()
+ + "/" + iconName;
+ } else {
+ pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
+ }
InputStream stream = getClass().getResourceAsStream(pathOut[0]);
if (stream == null && tryOtherDensities) {
for (Density d : Density.values()) {
if (d != density) {
densityInOut[0] = d;
- stream = getIcon(iconName, densityInOut, pathOut, false /*tryOtherDensities*/);
+ stream = getIcon(iconName, densityInOut, direction, pathOut,
+ false /*tryOtherDensities*/);
if (stream != null) {
return stream;
}
}
}
+ // couldn't find resource with direction qualifier. try without.
+ if (direction != null) {
+ return getIcon(iconName, densityInOut, null, pathOut, true);
+ }
}
return stream;
}
protected void loadIcon(int index, String iconName, Density density) {
+ loadIcon(index, iconName, density, false);
+ }
+
+ protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
View child = getChildAt(index);
if (child instanceof ImageView) {
ImageView imageView = (ImageView) child;
String[] pathOut = new String[1];
Density[] densityInOut = new Density[] { density };
- InputStream stream = getIcon(iconName, densityInOut, pathOut,
+ LayoutDirection dir = isRtl ? LayoutDirection.RTL : LayoutDirection.LTR;
+ InputStream stream = getIcon(iconName, densityInOut, dir, pathOut,
true /*tryOtherDensities*/);
density = densityInOut[0];
@@ -132,7 +152,7 @@
if (bitmap != null) {
BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
bitmap);
- imageView.setBackgroundDrawable(drawable);
+ imageView.setImageDrawable(drawable);
}
}
}
@@ -145,6 +165,14 @@
}
}
+ protected void loadIconById(int id, String iconReference) {
+ ResourceValue value = getResourceValue(iconReference);
+ if (value != null) {
+ loadIconById(id, value);
+ }
+ }
+
+
protected Drawable loadIcon(int index, ResourceType type, String name) {
BridgeContext bridgeContext = (BridgeContext) mContext;
RenderResources res = bridgeContext.getRenderResources();
@@ -162,40 +190,70 @@
if (child instanceof ImageView) {
ImageView imageView = (ImageView) child;
- Drawable drawable = ResourceHelper.getDrawable(
- value, (BridgeContext) mContext);
- if (drawable != null) {
- imageView.setBackgroundDrawable(drawable);
- }
+ return loadIcon(imageView, value);
+ }
+
+ return null;
+ }
+
+ private Drawable loadIconById(int id, ResourceValue value) {
+ View child = findViewById(id);
+ if (child instanceof ImageView) {
+ ImageView imageView = (ImageView) child;
- return drawable;
+ return loadIcon(imageView, value);
}
return null;
}
+
+ private Drawable loadIcon(ImageView imageView, ResourceValue value) {
+ Drawable drawable = ResourceHelper.getDrawable(value, (BridgeContext) mContext);
+ if (drawable != null) {
+ imageView.setImageDrawable(drawable);
+ }
+
+ return drawable;
+ }
+
protected TextView setText(int index, String stringReference) {
View child = getChildAt(index);
if (child instanceof TextView) {
TextView textView = (TextView) child;
- ResourceValue value = getResourceValue(stringReference);
- if (value != null) {
- textView.setText(value.getValue());
- } else {
- textView.setText(stringReference);
- }
+ setText(textView, stringReference);
+ return textView;
+ }
+
+ return null;
+ }
+
+ protected TextView setTextById(int id, String stringReference) {
+ View child = findViewById(id);
+ if (child instanceof TextView) {
+ TextView textView = (TextView) child;
+ setText(textView, stringReference);
return textView;
}
return null;
}
+ private void setText(TextView textView, String stringReference) {
+ ResourceValue value = getResourceValue(stringReference);
+ if (value != null) {
+ textView.setText(value.getValue());
+ } else {
+ textView.setText(stringReference);
+ }
+ }
+
protected void setStyle(String themeEntryName) {
BridgeContext bridgeContext = (BridgeContext) mContext;
RenderResources res = bridgeContext.getRenderResources();
- ResourceValue value = res.findItemInTheme(themeEntryName);
+ ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/);
value = res.resolveResValue(value);
if (value instanceof StyleResourceValue == false) {
@@ -205,37 +263,41 @@
StyleResourceValue style = (StyleResourceValue) value;
// get the background
- ResourceValue backgroundValue = res.findItemInStyle(style, "background");
+ ResourceValue backgroundValue = res.findItemInStyle(style, "background",
+ true /*isFrameworkAttr*/);
backgroundValue = res.resolveResValue(backgroundValue);
if (backgroundValue != null) {
Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
if (d != null) {
- setBackgroundDrawable(d);
+ setBackground(d);
}
}
TextView textView = getStyleableTextView();
if (textView != null) {
// get the text style
- ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle");
+ ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle",
+ true /*isFrameworkAttr*/);
textStyleValue = res.resolveResValue(textStyleValue);
if (textStyleValue instanceof StyleResourceValue) {
StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
- ResourceValue textSize = res.findItemInStyle(textStyle, "textSize");
+ ResourceValue textSize = res.findItemInStyle(textStyle, "textSize",
+ true /*isFrameworkAttr*/);
textSize = res.resolveResValue(textSize);
if (textSize != null) {
TypedValue out = new TypedValue();
if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
true /*requireUnit*/)) {
- textView.setTextSize(
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
}
}
- ResourceValue textColor = res.findItemInStyle(textStyle, "textColor");
+ ResourceValue textColor = res.findItemInStyle(textStyle, "textColor",
+ true /*isFrameworkAttr*/);
textColor = res.resolveResValue(textColor);
if (textColor != null) {
ColorStateList stateList = ResourceHelper.getColorStateList(
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java 2014-03-13 18:28:01.000000000 -0700
@@ -21,6 +21,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.widget.LinearLayout;
import android.widget.TextView;
public class FakeActionBar extends CustomBar {
@@ -29,12 +30,12 @@
public FakeActionBar(Context context, Density density, String label, String icon)
throws XmlPullParserException {
- super(context, density, "/bars/action_bar.xml", "action_bar.xml");
+ super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml");
// Cannot access the inside items through id because no R.id values have been
// created for them.
// We do know the order though.
- loadIcon(0, icon);
+ loadIconById(android.R.id.home, icon);
mTextView = setText(1, label);
setStyle("actionBarStyle");
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars: NavigationBar.java
Only in layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars: PhoneSystemBar.java
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars: StatusBar.java
Only in layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars: TabletSystemBar.java
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java 2014-03-13 18:28:01.000000000 -0700
@@ -21,6 +21,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.widget.LinearLayout;
import android.widget.TextView;
public class TitleBar extends CustomBar {
@@ -29,7 +30,7 @@
public TitleBar(Context context, Density density, String label)
throws XmlPullParserException {
- super(context, density, "/bars/title_bar.xml", "title_bar.xml");
+ super(context, density, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml");
// Cannot access the inside items through id because no R.id values have been
// created for them.
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java 2014-03-13 18:28:01.000000000 -0700
@@ -52,6 +52,8 @@
private static final String NODE_NAME = "name";
private static final String NODE_FILE = "file";
+ private static final String ATTRIBUTE_VARIANT = "variant";
+ private static final String ATTRIBUTE_VALUE_ELEGANT = "elegant";
private static final String FONT_SUFFIX_NONE = ".ttf";
private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf";
private static final String FONT_SUFFIX_BOLD = "-Bold.ttf";
@@ -189,6 +191,7 @@
private FontInfo mFontInfo = null;
private final StringBuilder mBuilder = new StringBuilder();
private List<FontInfo> mFontList = new ArrayList<FontInfo>();
+ private boolean isCompactFont = true;
private FontHandler(String osFontsLocation) {
super();
@@ -209,8 +212,21 @@
mFontList = new ArrayList<FontInfo>();
} else if (NODE_FAMILY.equals(localName)) {
if (mFontList != null) {
+ mFontInfo = null;
+ }
+ } else if (NODE_NAME.equals(localName)) {
+ if (mFontList != null && mFontInfo == null) {
+ mFontInfo = new FontInfo();
+ }
+ } else if (NODE_FILE.equals(localName)) {
+ if (mFontList != null && mFontInfo == null) {
mFontInfo = new FontInfo();
}
+ if (ATTRIBUTE_VALUE_ELEGANT.equals(attributes.getValue(ATTRIBUTE_VARIANT))) {
+ isCompactFont = false;
+ } else {
+ isCompactFont = true;
+ }
}
mBuilder.setLength(0);
@@ -223,7 +239,9 @@
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
- mBuilder.append(ch, start, length);
+ if (isCompactFont) {
+ mBuilder.append(ch, start, length);
+ }
}
/* (non-Javadoc)
@@ -259,7 +277,7 @@
}
} else if (NODE_FILE.equals(localName)) {
// handle a new file for an existing Font Info
- if (mFontInfo != null) {
+ if (isCompactFont && mFontInfo != null) {
String fileName = trimXmlWhitespaces(mBuilder.toString());
Font font = getFont(fileName);
if (font != null) {
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java 2014-03-13 18:28:01.000000000 -0700
@@ -21,9 +21,12 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
/**
@@ -38,14 +41,21 @@
public static XmlPullParser create(File f)
throws XmlPullParserException, FileNotFoundException {
- KXmlParser parser = instantiateParser(f.getName());
- parser.setInput(new FileInputStream(f), ENCODING);
- return parser;
+ InputStream stream = new FileInputStream(f);
+ return create(stream, f.getName(), f.length());
}
public static XmlPullParser create(InputStream stream, String name)
+ throws XmlPullParserException {
+ return create(stream, name, -1);
+ }
+
+ private static XmlPullParser create(InputStream stream, String name, long size)
throws XmlPullParserException {
KXmlParser parser = instantiateParser(name);
+
+ stream = readAndClose(stream, name, size);
+
parser.setInput(stream, ENCODING);
return parser;
}
@@ -61,6 +71,61 @@
return parser;
}
+ private static InputStream readAndClose(InputStream stream, String name, long size)
+ throws XmlPullParserException {
+ // just a sanity check. It's doubtful we'll have such big files!
+ if (size > Integer.MAX_VALUE) {
+ throw new XmlPullParserException("File " + name + " is too big to be parsed");
+ }
+ int intSize = (int) size;
+
+ // create a buffered reader to facilitate reading.
+ BufferedInputStream bufferedStream = new BufferedInputStream(stream);
+ try {
+ int avail;
+ if (intSize != -1) {
+ avail = intSize;
+ } else {
+ // get the size to read.
+ avail = bufferedStream.available();
+ }
+
+ // create the initial buffer and read it.
+ byte[] buffer = new byte[avail];
+ int read = stream.read(buffer);
+
+ // this is the easy case.
+ if (read == intSize) {
+ return new ByteArrayInputStream(buffer);
+ }
+
+ // check if there is more to read (read() does not necessarily read all that
+ // available() returned!)
+ while ((avail = bufferedStream.available()) > 0) {
+ if (read + avail > buffer.length) {
+ // just allocate what is needed. We're mostly reading small files
+ // so it shouldn't be too problematic.
+ byte[] moreBuffer = new byte[read + avail];
+ System.arraycopy(buffer, 0, moreBuffer, 0, read);
+ buffer = moreBuffer;
+ }
+
+ read += stream.read(buffer, read, avail);
+ }
+
+ // return a new stream encapsulating this buffer.
+ return new ByteArrayInputStream(buffer);
+
+ } catch (IOException e) {
+ throw new XmlPullParserException("Failed to read " + name, null, e);
+ } finally {
+ try {
+ bufferedStream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
private static class CustomParser extends KXmlParser {
private final String mName;
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java 2014-03-13 18:28:01.000000000 -0700
@@ -20,15 +20,17 @@
import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderParams;
import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
+import com.android.ide.common.rendering.api.Result;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.Density;
import com.android.resources.ResourceType;
+import com.android.resources.ScreenOrientation;
import com.android.resources.ScreenSize;
import android.content.res.Configuration;
@@ -98,25 +100,29 @@
return result;
}
+ HardwareConfig hardwareConfig = mParams.getHardwareConfig();
+
// setup the display Metrics.
DisplayMetrics metrics = new DisplayMetrics();
- metrics.densityDpi = mParams.getDensity().getDpiValue();
+ metrics.densityDpi = metrics.noncompatDensityDpi =
+ hardwareConfig.getDensity().getDpiValue();
metrics.density = metrics.noncompatDensity =
metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
- metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth();
- metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight();
- metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi();
- metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi();
+ metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
+ metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
+ metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
+ metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
RenderResources resources = mParams.getResources();
// build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
- mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion());
+ mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion(),
+ mParams.isRtlSupported());
setUp();
@@ -228,7 +234,7 @@
sCurrentContext = mContext;
// create an InputMethodManager
- InputMethodManager.getInstance(Looper.myLooper());
+ InputMethodManager.getInstance();
LayoutLog currentLog = mParams.getLog();
Bridge.setLog(currentLog);
@@ -242,11 +248,16 @@
* The counterpart is {@link #setUp()}.
*/
private void tearDown() {
- // Make sure to remove static references, otherwise we could not unload the lib
- mContext.disposeResources();
+ // The context may be null, if there was an error during init().
+ if (mContext != null) {
+ // Make sure to remove static references, otherwise we could not unload the lib
+ mContext.disposeResources();
+ }
- // quit HandlerThread created during this session.
- HandlerThread_Delegate.cleanUp(sCurrentContext);
+ if (sCurrentContext != null) {
+ // quit HandlerThread created during this session.
+ HandlerThread_Delegate.cleanUp(sCurrentContext);
+ }
// clear the stored ViewConfiguration since the map is per density and not per context.
ViewConfiguration_Accessor.clearConfigurations();
@@ -257,8 +268,11 @@
sCurrentContext = null;
Bridge.setLog(null);
- mContext.getRenderResources().setFrameworkResourceIdProvider(null);
- mContext.getRenderResources().setLogger(null);
+ if (mContext != null) {
+ mContext.getRenderResources().setFrameworkResourceIdProvider(null);
+ mContext.getRenderResources().setLogger(null);
+ }
+
}
public static BridgeContext getCurrentContext() {
@@ -305,7 +319,9 @@
private Configuration getConfiguration() {
Configuration config = new Configuration();
- ScreenSize screenSize = mParams.getConfigScreenSize();
+ HardwareConfig hardwareConfig = mParams.getHardwareConfig();
+
+ ScreenSize screenSize = hardwareConfig.getScreenSize();
if (screenSize != null) {
switch (screenSize) {
case SMALL:
@@ -323,23 +339,41 @@
}
}
- Density density = mParams.getDensity();
+ Density density = hardwareConfig.getDensity();
if (density == null) {
density = Density.MEDIUM;
}
- config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue();
- config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue();
+ config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
+ config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
if (config.screenHeightDp < config.screenWidthDp) {
config.smallestScreenWidthDp = config.screenHeightDp;
} else {
config.smallestScreenWidthDp = config.screenWidthDp;
}
+ config.densityDpi = density.getDpiValue();
// never run in compat mode:
config.compatScreenWidthDp = config.screenWidthDp;
config.compatScreenHeightDp = config.screenHeightDp;
+ ScreenOrientation orientation = hardwareConfig.getOrientation();
+ if (orientation != null) {
+ switch (orientation) {
+ case PORTRAIT:
+ config.orientation = Configuration.ORIENTATION_PORTRAIT;
+ break;
+ case LANDSCAPE:
+ config.orientation = Configuration.ORIENTATION_LANDSCAPE;
+ break;
+ case SQUARE:
+ config.orientation = Configuration.ORIENTATION_SQUARE;
+ break;
+ }
+ } else {
+ config.orientation = Configuration.ORIENTATION_UNDEFINED;
+ }
+
// TODO: fill in more config info.
return config;
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java 2014-03-13 18:28:01.000000000 -0700
@@ -19,6 +19,7 @@
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result.Status;
@@ -59,6 +60,7 @@
try {
// get the drawable resource value
DrawableParams params = getParams();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
ResourceValue drawableResource = params.getDrawable();
// resolve it
@@ -75,15 +77,15 @@
// get the actual Drawable object to draw
Drawable d = ResourceHelper.getDrawable(drawableResource, context);
- content.setBackgroundDrawable(d);
+ content.setBackground(d);
// set the AttachInfo on the root view.
AttachInfo_Accessor.setAttachInfo(content);
// measure
- int w = params.getScreenWidth();
- int h = params.getScreenHeight();
+ int w = hardwareConfig.getScreenWidth();
+ int h = hardwareConfig.getScreenHeight();
int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
content.measure(w_spec, h_spec);
@@ -99,11 +101,11 @@
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
- true /*isMutable*/, params.getDensity());
+ true /*isMutable*/, hardwareConfig.getDensity());
// create a Canvas around the Android bitmap
Canvas canvas = new Canvas(bitmap);
- canvas.setDensity(params.getDensity().getDpiValue());
+ canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
// and draw
content.draw(canvas);
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,6 +24,7 @@
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
import com.android.ide.common.rendering.api.AdapterBinding;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
@@ -33,23 +34,23 @@
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.Result.Status;
+import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
+import com.android.ide.common.rendering.api.ViewInfo;
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.bars.FakeActionBar;
-import com.android.layoutlib.bridge.bars.PhoneSystemBar;
-import com.android.layoutlib.bridge.bars.TabletSystemBar;
+import com.android.layoutlib.bridge.bars.NavigationBar;
+import com.android.layoutlib.bridge.bars.StatusBar;
import com.android.layoutlib.bridge.bars.TitleBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.resources.ResourceType;
-import com.android.resources.ScreenSize;
+import com.android.resources.ScreenOrientation;
import com.android.util.Pair;
import org.xmlpull.v1.XmlPullParserException;
@@ -68,11 +69,15 @@
import android.util.TypedValue;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
+import android.view.IWindowManager;
+import android.view.IWindowManagerImpl;
+import android.view.Surface;
import android.view.View;
-import android.view.ViewGroup;
import android.view.View.MeasureSpec;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
+import android.view.WindowManagerGlobal_Delegate;
import android.widget.AbsListView;
import android.widget.AbsSpinner;
import android.widget.AdapterView;
@@ -82,8 +87,8 @@
import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TabHost;
-import android.widget.TabWidget;
import android.widget.TabHost.TabSpec;
+import android.widget.TabWidget;
import java.awt.AlphaComposite;
import java.awt.Color;
@@ -120,7 +125,8 @@
private boolean mWindowIsFloating;
private int mStatusBarSize;
- private int mSystemBarSize;
+ private int mNavigationBarSize;
+ private int mNavigationBarOrientation = LinearLayout.HORIZONTAL;
private int mTitleBarSize;
private int mActionBarSize;
@@ -183,7 +189,14 @@
findBackground(resources);
findStatusBar(resources, metrics);
findActionBar(resources, metrics);
- findSystemBar(resources, metrics);
+ findNavigationBar(resources, metrics);
+
+ // FIXME: find those out, and possibly add them to the render params
+ boolean hasNavigationBar = true;
+ IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
+ metrics, Surface.ROTATION_0,
+ hasNavigationBar);
+ WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser.
mInflater = new BridgeInflater(context, params.getProjectCallback());
@@ -209,19 +222,61 @@
try {
SessionParams params = getParams();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
BridgeContext context = getContext();
+ boolean isRtl = Bridge.isLocaleRtl(params.getLocale());
+ int direction = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
// the view group that receives the window background.
ViewGroup backgroundView = null;
if (mWindowIsFloating || params.isForceNoDecor()) {
backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
+ mViewRoot.setLayoutDirection(direction);
} else {
+ if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
+ /*
+ * This is a special case where the navigation bar is on the right.
+ +-------------------------------------------------+---+
+ | Status bar (always) | |
+ +-------------------------------------------------+ |
+ | (Layout with background drawable) | |
+ | +---------------------------------------------+ | |
+ | | Title/Action bar (optional) | | |
+ | +---------------------------------------------+ | |
+ | | Content, vertical extending | | |
+ | | | | |
+ | +---------------------------------------------+ | |
+ +-------------------------------------------------+---+
+
+ So we create a horizontal layout, with the nav bar on the right,
+ and the left part is the normal layout below without the nav bar at
+ the bottom
+ */
+ LinearLayout topLayout = new LinearLayout(context);
+ topLayout.setLayoutDirection(direction);
+ mViewRoot = topLayout;
+ topLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ try {
+ NavigationBar navigationBar = new NavigationBar(context,
+ hardwareConfig.getDensity(), LinearLayout.VERTICAL, isRtl,
+ params.isRtlSupported());
+ navigationBar.setLayoutParams(
+ new LinearLayout.LayoutParams(
+ mNavigationBarSize,
+ LayoutParams.MATCH_PARENT));
+ topLayout.addView(navigationBar);
+ } catch (XmlPullParserException e) {
+
+ }
+ }
+
/*
* we're creating the following layout
*
+-------------------------------------------------+
- | System bar (only in phone UI) |
+ | Status bar (always) |
+-------------------------------------------------+
| (Layout with background drawable) |
| +---------------------------------------------+ |
@@ -231,20 +286,41 @@
| | | |
| +---------------------------------------------+ |
+-------------------------------------------------+
- | System bar (only in tablet UI) |
+ | Navigation bar for soft buttons, maybe see above|
+-------------------------------------------------+
*/
LinearLayout topLayout = new LinearLayout(context);
- mViewRoot = topLayout;
topLayout.setOrientation(LinearLayout.VERTICAL);
+ topLayout.setLayoutDirection(direction);
+ // if we don't already have a view root this is it
+ if (mViewRoot == null) {
+ mViewRoot = topLayout;
+ } else {
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
+ layoutParams.weight = 1;
+ topLayout.setLayoutParams(layoutParams);
+
+ // this is the case of soft buttons + vertical bar.
+ // this top layout is the first layout in the horizontal layout. see above)
+ if (isRtl && params.isRtlSupported()) {
+ // If RTL is enabled, layoutlib will mirror the layouts. So, add the
+ // topLayout to the right of Navigation Bar and layoutlib will draw it
+ // to the left.
+ mViewRoot.addView(topLayout);
+ } else {
+ // Add the top layout to the left of the Navigation Bar.
+ mViewRoot.addView(topLayout, 0);
+ }
+ }
if (mStatusBarSize > 0) {
// system bar
try {
- PhoneSystemBar systemBar = new PhoneSystemBar(context,
- params.getDensity());
+ StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity(),
+ direction, params.isRtlSupported());
systemBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mStatusBarSize));
@@ -268,7 +344,7 @@
if (mActionBarSize > 0) {
try {
FakeActionBar actionBar = new FakeActionBar(context,
- params.getDensity(),
+ hardwareConfig.getDensity(),
params.getAppLabel(), params.getAppIcon());
actionBar.setLayoutParams(
new LinearLayout.LayoutParams(
@@ -280,7 +356,7 @@
} else if (mTitleBarSize > 0) {
try {
TitleBar titleBar = new TitleBar(context,
- params.getDensity(), params.getAppLabel());
+ hardwareConfig.getDensity(), params.getAppLabel());
titleBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mTitleBarSize));
@@ -298,15 +374,17 @@
mContentRoot.setLayoutParams(layoutParams);
backgroundLayout.addView(mContentRoot);
- if (mSystemBarSize > 0) {
+ if (mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
+ mNavigationBarSize > 0) {
// system bar
try {
- TabletSystemBar systemBar = new TabletSystemBar(context,
- params.getDensity());
- systemBar.setLayoutParams(
+ NavigationBar navigationBar = new NavigationBar(context,
+ hardwareConfig.getDensity(), LinearLayout.HORIZONTAL, isRtl,
+ params.isRtlSupported());
+ navigationBar.setLayoutParams(
new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, mSystemBarSize));
- topLayout.addView(systemBar);
+ LayoutParams.MATCH_PARENT, mNavigationBarSize));
+ topLayout.addView(navigationBar);
} catch (XmlPullParserException e) {
}
@@ -334,7 +412,7 @@
// get the background drawable
if (mWindowBackground != null && backgroundView != null) {
Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
- backgroundView.setBackgroundDrawable(d);
+ backgroundView.setBackground(d);
}
return SUCCESS.createResult();
@@ -377,13 +455,14 @@
}
RenderingMode renderingMode = params.getRenderingMode();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
// only do the screen measure when needed.
boolean newRenderSize = false;
if (mMeasuredScreenWidth == -1) {
newRenderSize = true;
- mMeasuredScreenWidth = params.getScreenWidth();
- mMeasuredScreenHeight = params.getScreenHeight();
+ mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
+ mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
if (renderingMode != RenderingMode.NORMAL) {
int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
@@ -483,11 +562,11 @@
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
- true /*isMutable*/, params.getDensity());
+ true /*isMutable*/, hardwareConfig.getDensity());
// create a Canvas around the Android bitmap
mCanvas = new Canvas(bitmap);
- mCanvas.setDensity(params.getDensity().getDpiValue());
+ mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
}
if (freshRender && newImage == false) {
@@ -835,6 +914,7 @@
previousTransition.addTransitionListener(new TransitionListener() {
private int mChangeDisappearingCount = 0;
+ @Override
public void startTransition(LayoutTransition transition, ViewGroup container,
View view, int transitionType) {
if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
@@ -842,6 +922,7 @@
}
}
+ @Override
public void endTransition(LayoutTransition transition, ViewGroup container,
View view, int transitionType) {
if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
@@ -950,37 +1031,36 @@
private void findBackground(RenderResources resources) {
if (getParams().isBgColorOverridden() == false) {
- mWindowBackground = resources.findItemInTheme("windowBackground");
+ mWindowBackground = resources.findItemInTheme("windowBackground",
+ true /*isFrameworkAttr*/);
if (mWindowBackground != null) {
mWindowBackground = resources.resolveResValue(mWindowBackground);
}
}
}
- private boolean isTabletUi() {
- return getParams().getConfigScreenSize() == ScreenSize.XLARGE;
+ private boolean hasSoftwareButtons() {
+ return getParams().getHardwareConfig().hasSoftwareButtons();
}
private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
- if (isTabletUi() == false) {
- boolean windowFullscreen = getBooleanThemeValue(resources,
- "windowFullscreen", false /*defaultValue*/);
-
- if (windowFullscreen == false && mWindowIsFloating == false) {
- // default value
- mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
-
- // get the real value
- ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- "status_bar_height");
+ boolean windowFullscreen = getBooleanThemeValue(resources,
+ "windowFullscreen", false /*defaultValue*/);
- if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
- value.getValue(), true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mStatusBarSize = (int)typedValue.getDimension(metrics);
- }
+ if (windowFullscreen == false && mWindowIsFloating == false) {
+ // default value
+ mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
+
+ // get the real value
+ ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
+ "status_bar_height");
+
+ if (value != null) {
+ TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+ value.getValue(), true /*requireUnit*/);
+ if (typedValue != null) {
+ // compute the pixel value based on the display metrics
+ mStatusBarSize = (int)typedValue.getDimension(metrics);
}
}
}
@@ -1001,7 +1081,8 @@
mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT;
// get value from the theme.
- ResourceValue value = resources.findItemInTheme("actionBarSize");
+ ResourceValue value = resources.findItemInTheme("actionBarSize",
+ true /*isFrameworkAttr*/);
// resolve it
value = resources.resolveResValue(value);
@@ -1026,7 +1107,8 @@
mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
// get value from the theme.
- ResourceValue value = resources.findItemInTheme("windowTitleSize");
+ ResourceValue value = resources.findItemInTheme("windowTitleSize",
+ true /*isFrameworkAttr*/);
// resolve it
value = resources.resolveResValue(value);
@@ -1045,32 +1127,67 @@
}
}
- private void findSystemBar(RenderResources resources, DisplayMetrics metrics) {
- if (isTabletUi() && mWindowIsFloating == false) {
+ private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) {
+ if (hasSoftwareButtons() && mWindowIsFloating == false) {
// default value
- mSystemBarSize = 48; // ??
+ mNavigationBarSize = 48; // ??
+
+ HardwareConfig hardwareConfig = getParams().getHardwareConfig();
+
+ boolean barOnBottom = true;
+
+ if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
+ // compute the dp of the screen.
+ int shortSize = hardwareConfig.getScreenHeight();
+
+ // compute in dp
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue();
+
+ if (shortSizeDp < 600) {
+ // 0-599dp: "phone" UI with bar on the side
+ barOnBottom = false;
+ } else {
+ // 600+dp: "tablet" UI with bar on the bottom
+ barOnBottom = true;
+ }
+ }
+
+ if (barOnBottom) {
+ mNavigationBarOrientation = LinearLayout.HORIZONTAL;
+ } else {
+ mNavigationBarOrientation = LinearLayout.VERTICAL;
+ }
// get the real value
ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- "status_bar_height");
+ barOnBottom ? "navigation_bar_height" : "navigation_bar_width");
if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+ TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height",
value.getValue(), true /*requireUnit*/);
if (typedValue != null) {
// compute the pixel value based on the display metrics
- mSystemBarSize = (int)typedValue.getDimension(metrics);
+ mNavigationBarSize = (int)typedValue.getDimension(metrics);
}
}
}
}
+ /**
+ * Looks for a attribute in the current theme. The attribute is in the android
+ * namespace.
+ *
+ * @param resources the render resources
+ * @param name the name of the attribute
+ * @param defaultValue the default value.
+ * @return the value of the attribute or the default one if not found.
+ */
private boolean getBooleanThemeValue(RenderResources resources,
String name, boolean defaultValue) {
// get the title bar flag from the current theme.
- ResourceValue value = resources.findItemInTheme(name);
+ ResourceValue value = resources.findItemInTheme(name, true /*isFrameworkAttr*/);
// because it may reference something else, we resolve it.
value = resources.resolveResValue(value);
@@ -1227,6 +1344,7 @@
TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
.setContent(new TabHost.TabContentFactory() {
+ @Override
public View createTabContent(String tag) {
return new LinearLayout(getContext());
}
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding: AdapterHelper.java
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding: AdapterItem.java
Only in layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/binding: BaseAdapter.java
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -20,10 +20,12 @@
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
@@ -35,17 +37,23 @@
* and {@link SpinnerAdapter}.
*
*/
-public class FakeAdapter extends BaseAdapter implements ListAdapter, SpinnerAdapter {
+@SuppressWarnings("deprecation")
+public class FakeAdapter extends BaseAdapter {
// don't use a set because the order is important.
private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
+ private final IProjectCallback mCallback;
+ private final ResourceReference mAdapterRef;
+ private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
+ private boolean mSkipCallbackParser = false;
public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
IProjectCallback callback) {
- super(adapterRef, binding, callback);
+ mAdapterRef = adapterRef;
+ mCallback = callback;
- final int repeatCount = getBinding().getRepeatCount();
- final int itemCount = getBinding().getItemCount();
+ final int repeatCount = binding.getRepeatCount();
+ final int itemCount = binding.getItemCount();
// Need an array to count for each type.
// This is likely too big, but is the max it can be.
@@ -54,7 +62,7 @@
// We put several repeating sets.
for (int r = 0 ; r < repeatCount ; r++) {
// loop on the type of list items, and add however many for each type.
- for (DataBindingItem dataBindingItem : getBinding()) {
+ for (DataBindingItem dataBindingItem : binding) {
ResourceReference viewRef = dataBindingItem.getViewReference();
int typeIndex = mTypes.indexOf(viewRef);
if (typeIndex == -1) {
@@ -74,38 +82,50 @@
}
}
+ @Override
public boolean isEnabled(int position) {
return true;
}
+ @Override
public int getCount() {
return mItems.size();
}
+ @Override
public Object getItem(int position) {
return mItems.get(position);
}
+ @Override
public long getItemId(int position) {
return position;
}
+ @Override
public int getItemViewType(int position) {
return mItems.get(position).getType();
}
+ @Override
public View getView(int position, View convertView, ViewGroup parent) {
// we don't care about recycling here because we never scroll.
AdapterItem item = mItems.get(position);
- return getView(item, null /*parentGroup*/, convertView, parent);
+ Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
+ mCallback, mAdapterRef, mSkipCallbackParser);
+ mSkipCallbackParser = pair.getSecond();
+ return pair.getFirst();
+
}
+ @Override
public int getViewTypeCount() {
return mTypes.size();
}
// ---- SpinnerAdapter
+ @Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// pass
return null;
diff -ru layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
--- layoutlib_4-0-3-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -20,7 +20,9 @@
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.util.Pair;
+import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
@@ -29,8 +31,14 @@
import java.util.ArrayList;
import java.util.List;
-public class FakeExpandableAdapter extends BaseAdapter implements ExpandableListAdapter,
- HeterogeneousExpandableList {
+@SuppressWarnings("deprecation")
+public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
+
+ private final IProjectCallback mCallback;
+ private final ResourceReference mAdapterRef;
+ private boolean mSkipCallbackParser = false;
+
+ protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
// don't use a set because the order is important.
private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
@@ -38,7 +46,8 @@
public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
IProjectCallback callback) {
- super(adapterRef, binding, callback);
+ mAdapterRef = adapterRef;
+ mCallback = callback;
createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
}
@@ -99,80 +108,128 @@
// ---- ExpandableListAdapter
+ @Override
public int getGroupCount() {
return mItems.size();
}
+ @Override
public int getChildrenCount(int groupPosition) {
AdapterItem item = mItems.get(groupPosition);
return item.getChildren().size();
}
+ @Override
public Object getGroup(int groupPosition) {
return mItems.get(groupPosition);
}
+ @Override
public Object getChild(int groupPosition, int childPosition) {
return getChildItem(groupPosition, childPosition);
}
+ @Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
// we don't care about recycling here because we never scroll.
AdapterItem item = mItems.get(groupPosition);
- return getView(item, null /*parentItem*/, convertView, parent);
+ Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
+ mCallback, mAdapterRef, mSkipCallbackParser);
+ mSkipCallbackParser = pair.getSecond();
+ return pair.getFirst();
}
+ @Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
// we don't care about recycling here because we never scroll.
AdapterItem parentItem = mItems.get(groupPosition);
AdapterItem item = getChildItem(groupPosition, childPosition);
- return getView(item, parentItem, convertView, parent);
+ Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
+ mAdapterRef, mSkipCallbackParser);
+ mSkipCallbackParser = pair.getSecond();
+ return pair.getFirst();
}
+ @Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
+ @Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
+ @Override
public long getCombinedGroupId(long groupId) {
return groupId << 16 | 0x0000FFFF;
}
+ @Override
public long getCombinedChildId(long groupId, long childId) {
return groupId << 16 | childId;
}
+ @Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
+ @Override
public void onGroupCollapsed(int groupPosition) {
// pass
}
+ @Override
public void onGroupExpanded(int groupPosition) {
// pass
}
+ @Override
+ public void registerDataSetObserver(DataSetObserver observer) {
+ // pass
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ // pass
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return mItems.isEmpty();
+ }
+
// ---- HeterogeneousExpandableList
+ @Override
public int getChildType(int groupPosition, int childPosition) {
return getChildItem(groupPosition, childPosition).getType();
}
+ @Override
public int getChildTypeCount() {
return mChildrenTypes.size();
}
+ @Override
public int getGroupType(int groupPosition) {
return mItems.get(groupPosition).getType();
}
+ @Override
public int getGroupTypeCount() {
return mGroupTypes.size();
}
Only in layoutlib_4-4-2-r1/bridge/src/com/android/layoutlib/bridge/util: DynamicIdMap.java
Only in layoutlib_4-4-2-r1/bridge/src/libcore/icu: DateIntervalFormat_Delegate.java
diff -ru layoutlib_4-0-3-r1/bridge/src/libcore/icu/ICU_Delegate.java layoutlib_4-4-2-r1/bridge/src/libcore/icu/ICU_Delegate.java
--- layoutlib_4-0-3-r1/bridge/src/libcore/icu/ICU_Delegate.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/src/libcore/icu/ICU_Delegate.java 2014-03-13 18:28:01.000000000 -0700
@@ -17,6 +17,8 @@
package libcore.icu;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.ibm.icu.text.DateTimePatternGenerator;
+import com.ibm.icu.util.ULocale;
import java.util.Locale;
@@ -44,6 +46,17 @@
// --- Native methods accessing ICU's database.
@LayoutlibDelegate
+ /*package*/ static String getBestDateTimePattern(String skeleton, String localeName) {
+ return DateTimePatternGenerator.getInstance(new ULocale(localeName))
+ .getBestPattern(skeleton);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static String getCldrVersion() {
+ return "22.1.1"; // TODO: check what the right value should be.
+ }
+
+ @LayoutlibDelegate
/*package*/ static String getIcuVersion() {
return "unknown_layoutlib";
}
@@ -171,12 +184,18 @@
result.longStandAloneMonthNames = result.longMonthNames;
result.shortStandAloneMonthNames = result.shortMonthNames;
+ // The platform code expects this to begin at index 1, rather than 0. It maps it directly to
+ // the constants from java.util.Calendar.<weekday>
result.longWeekdayNames = new String[] {
- "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
+ "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
result.shortWeekdayNames = new String[] {
- "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+ "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" };
+ result.tinyWeekdayNames = new String[] {
+ "", "S", "M", "T", "W", "T", "F", "S" };
+
result.longStandAloneWeekdayNames = result.longWeekdayNames;
result.shortStandAloneWeekdayNames = result.shortWeekdayNames;
+ result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames;
result.fullTimeFormat = "";
result.longTimeFormat = "";
diff -ru layoutlib_4-0-3-r1/bridge/tests/.classpath layoutlib_4-4-2-r1/bridge/tests/.classpath
--- layoutlib_4-0-3-r1/bridge/tests/.classpath 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/bridge/tests/.classpath 2014-03-13 18:28:01.000000000 -0700
@@ -4,7 +4,7 @@
<classpathentry kind="src" path="res"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="output" path="bin"/>
diff -ru layoutlib_4-0-3-r1/create/.classpath layoutlib_4-4-2-r1/create/.classpath
--- layoutlib_4-0-3-r1/create/.classpath 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/.classpath 2014-03-13 18:28:01.000000000 -0700
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
- <classpathentry excluding="mock_android/" kind="src" path="tests"/>
+ <classpathentry excluding="mock_data/" kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_PLAT/prebuilts/tools/common/asm-tools/src-4.0.zip"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Only in layoutlib_4-4-2-r1/create: .settings
diff -ru layoutlib_4-0-3-r1/create/Android.mk layoutlib_4-4-2-r1/create/Android.mk
--- layoutlib_4-0-3-r1/create/Android.mk 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/Android.mk 2014-03-13 18:28:01.000000000 -0700
@@ -20,7 +20,7 @@
LOCAL_JAR_MANIFEST := manifest.txt
LOCAL_STATIC_JAVA_LIBRARIES := \
- asm-3.1
+ asm-4.0
LOCAL_MODULE := layoutlib_create
diff -ru layoutlib_4-0-3-r1/create/README.txt layoutlib_4-4-2-r1/create/README.txt
--- layoutlib_4-0-3-r1/create/README.txt 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/README.txt 2014-03-13 18:28:01.000000000 -0700
@@ -71,6 +71,9 @@
and "." and "$" are interpreted as-is).
In practice we almost but not quite request the inclusion of full packages.
+The analyzer is also given a list of classes to exclude. A fake implementation of these
+classes is injected by the Generator.
+
With this information, the analyzer parses the input zip to find all the classes.
All classes deriving from the requested bases classes are kept.
All classes which name matched the glob pattern are kept.
@@ -93,6 +96,7 @@
- specific methods for which to delegate calls.
- specific methods to remove based on their return type.
- specific classes to rename.
+- specific classes to refactor.
Each of these are specific strategies we use to be able to modify the Android code
to fit within the Eclipse renderer. These strategies are explained beow.
@@ -100,10 +104,7 @@
The core method of the generator is transform(): it takes an input ASM ClassReader
and modifies it to produce a byte array suitable for the final JAR file.
-The first step of the transformation is changing the name of the class in case
-we requested the class to be renamed. This uses the RenameClassAdapter to also rename
-all inner classes and references in methods and types. Note that other classes are
-not transformed and keep referencing the original name.
+The first step of the transformation is to implement the method delegates.
The TransformClassAdapter is then used to process the potentially renamed class.
All protected or private classes are market as public.
@@ -115,11 +116,25 @@
The code of the methods is then kept as-is, except for native methods which are
replaced by a stub. Methods that are to be overridden are also replaced by a stub.
-The transformed class is then fed through the DelegateClassAdapter to implement
-method delegates.
-
Finally fields are also visited and changed from protected/private to public.
+The next step of the transformation is changing the name of the class in case
+we requested the class to be renamed. This uses the RenameClassAdapter to also rename
+all inner classes and references in methods and types. Note that other classes are
+not transformed and keep referencing the original name.
+
+The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but
+updates the references in all classes. This is used to update the references of classes
+in the java package that were added in the Dalvik VM but are not a part of the standard
+JVM. The existing classes are modified to update all references to these non-standard
+classes. An alternate implementation of these (com.android.tools.layoutlib.java.*) is
+injected.
+
+The ClassAdapters are chained together to achieve the desired output. (Look at section
+2.2.7 Transformation chains in the asm user guide, link in the References.) The order of
+execution of these is:
+ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
+RefactorClassAdapter -> ClassWriter
- Method stubs
--------------
@@ -141,19 +156,27 @@
- Strategies
------------
-We currently have 4 strategies to deal with overriding the rendering code
+We currently have 6 strategies to deal with overriding the rendering code
and make it run in Eclipse. Most of these strategies are implemented hand-in-hand
by the bridge (which runs in Eclipse) and the generator.
1- Class Injection
-This is the easiest: we currently inject 4 classes, namely:
+This is the easiest: we currently inject the following classes:
- OverrideMethod and its associated MethodListener and MethodAdapter are used
to intercept calls to some specific methods that are stubbed out and change
their return value.
- CreateInfo class, which configured the generator. Not used yet, but could
in theory help us track what the generator changed.
+- AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new
+ classes are injected. The implementation for these classes has been taken from
+ Android's libcore (platform/libcore/luni/src/main/java/java/...).
+- Charsets, IntegralToString and UnsafeByteSequence are not part of the standard JAVA VM.
+ They are added to the Dalvik VM for performance reasons. An implementation that is very
+ close to the original (which is at platform/libcore/luni/src/main/java/...) is injected.
+ Since these classees were in part of the java package, where we can't inject classes,
+ all references to these have been updated (See strategy 4- Refactoring Classes).
2- Overriding methods
@@ -189,7 +212,15 @@
This won't rename/replace the inner static methods of a given class.
-4- Method erasure based on return type
+4- Refactoring classes
+
+This is very similar to the Renaming classes except that it also updates the reference in
+all classes. This is done for classes which are added to the Dalvik VM for performance
+reasons but are not present in the Standard Java VM. An implementation for these classes
+is also injected.
+
+
+5- Method erasure based on return type
This is mostly an implementation detail of the bridge: in the Paint class
mentioned above, some inner static classes are used to pass around
@@ -201,7 +232,7 @@
bridge will provide its own implementation.
-5- Method Delegates
+6- Method Delegates
This strategy is used to override method implementations.
Given a method SomeClass.MethodName(), 1 or 2 methods are generated:
@@ -233,7 +264,7 @@
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
ASM user guide:
- http://download.forge.objectweb.org/asm/asm-guide.pdf
+ http://download.forge.objectweb.org/asm/asm4-guide.pdf
--
Only in layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create: AbstractClassAdapter.java
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java 2014-03-13 18:28:01.000000000 -0700
@@ -23,6 +23,7 @@
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor;
@@ -32,8 +33,9 @@
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -45,7 +47,7 @@
public class AsmAnalyzer {
// Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
+
/** Output logger. */
private final Log mLog;
/** The input source JAR to parse. */
@@ -56,24 +58,27 @@
private final String[] mDeriveFrom;
/** Glob patterns of classes to keep, e.g. "com.foo.*" */
private final String[] mIncludeGlobs;
+ /** The set of classes to exclude.*/
+ private final Set<String> mExcludedClasses;
/**
* Creates a new analyzer.
- *
+ *
* @param log The log output.
* @param osJarPath The input source JARs to parse.
* @param gen The generator to fill with the class list and dependency list.
- * @param deriveFrom Keep all classes that derive from these one (these included).
+ * @param deriveFrom Keep all classes that derive from these one (these included).
* @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
* ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
*/
public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
- String[] deriveFrom, String[] includeGlobs) {
+ String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses) {
mLog = log;
mGen = gen;
mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
+ mExcludedClasses = excludeClasses;
}
/**
@@ -81,16 +86,13 @@
* Fills the generator with classes & dependencies found.
*/
public void analyze() throws IOException, LogAbortException {
-
- AsmAnalyzer visitor = this;
-
Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar);
mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
mOsSourceJar.size() > 1 ? "s" : "");
-
+
Map<String, ClassReader> found = findIncludes(zipClasses);
Map<String, ClassReader> deps = findDeps(zipClasses, found);
-
+
if (mGen != null) {
mGen.setKeep(found);
mGen.setDeps(deps);
@@ -117,10 +119,10 @@
}
}
}
-
+
return classes;
}
-
+
/**
* Utility that returns the fully qualified binary class name for a ClassReader.
* E.g. it returns something like android.view.View.
@@ -132,7 +134,7 @@
return classReader.getClassName().replace('/', '.');
}
}
-
+
/**
* Utility that returns the fully qualified binary class name from a path-like FQCN.
* E.g. it returns android.view.View from android/view/View.
@@ -144,7 +146,7 @@
return className.replace('/', '.');
}
}
-
+
/**
* Process the "includes" arrays.
* <p/>
@@ -162,11 +164,11 @@
for (String s : mDeriveFrom) {
findClassesDerivingFrom(s, zipClasses, found);
}
-
+
return found;
}
-
+
/**
* Uses ASM to find the class reader for the given FQCN class name.
* If found, insert it in the in_out_found map.
@@ -215,7 +217,7 @@
globPattern += "$";
Pattern regexp = Pattern.compile(globPattern);
-
+
for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
String class_name = entry.getKey();
if (regexp.matcher(class_name).matches()) {
@@ -231,7 +233,7 @@
*/
void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
Map<String, ClassReader> inOutFound) throws LogAbortException {
- ClassReader super_clazz = findClass(super_name, zipClasses, inOutFound);
+ findClass(super_name, zipClasses, inOutFound);
for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
String className = entry.getKey();
@@ -284,7 +286,7 @@
for (ClassReader cr : inOutKeepClasses.values()) {
cr.accept(visitor, 0 /* flags */);
}
-
+
while (new_deps.size() > 0 || new_keep.size() > 0) {
deps.putAll(new_deps);
inOutKeepClasses.putAll(new_keep);
@@ -308,15 +310,14 @@
return deps;
}
-
+
// ----------------------------------
-
+
/**
- * Visitor to collect all the type dependencies from a class.
+ * Visitor to collect all the type dependencies from a class.
*/
- public class DependencyVisitor
- implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor {
+ public class DependencyVisitor extends ClassVisitor {
/** All classes found in the source JAR. */
private final Map<String, ClassReader> mZipClasses;
@@ -333,7 +334,7 @@
* Creates a new visitor that will find all the dependencies for the visited class.
* Types which are already in the zipClasses, keepClasses or inDeps are not marked.
* New dependencies are marked in outDeps.
- *
+ *
* @param zipClasses All classes found in the source JAR.
* @param inKeep Classes from which dependencies are to be found.
* @param inDeps Dependencies already known.
@@ -344,13 +345,14 @@
Map<String, ClassReader> outKeep,
Map<String,ClassReader> inDeps,
Map<String,ClassReader> outDeps) {
+ super(Opcodes.ASM4);
mZipClasses = zipClasses;
mInKeep = inKeep;
mOutKeep = outKeep;
mInDeps = inDeps;
mOutDeps = outDeps;
}
-
+
/**
* Considers the given class name as a dependency.
* If it does, add to the mOutDeps map.
@@ -361,12 +363,13 @@
}
className = internalToBinaryClassName(className);
-
- // exclude classes that have already been found
+
+ // exclude classes that have already been found or are marked to be excluded
if (mInKeep.containsKey(className) ||
mOutKeep.containsKey(className) ||
mInDeps.containsKey(className) ||
- mOutDeps.containsKey(className)) {
+ mOutDeps.containsKey(className) ||
+ mExcludedClasses.contains(getBaseName(className))) {
return;
}
@@ -384,7 +387,7 @@
} catch (ClassNotFoundException e) {
// ignore
}
-
+
// accept this class:
// - android classes are added to dependencies
// - non-android classes are added to the list of classes to keep as-is (they don't need
@@ -395,7 +398,7 @@
mOutKeep.put(className, cr);
}
}
-
+
/**
* Considers this array of names using considerName().
*/
@@ -416,7 +419,7 @@
SignatureReader sr = new SignatureReader(signature);
// SignatureReader.accept will call accessType so we don't really have
// to differentiate where the signature comes from.
- sr.accept(this);
+ sr.accept(new MySignatureVisitor());
}
}
@@ -450,17 +453,25 @@
}
}
-
+ private String getBaseName(String className) {
+ int pos = className.indexOf('$');
+ if (pos > 0) {
+ return className.substring(0, pos);
+ }
+ return className;
+ }
+
// ---------------------------------------------------
// --- ClassVisitor, FieldVisitor
// ---------------------------------------------------
// Visits a class header
+ @Override
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) {
// signature is the signature of this class. May be null if the class is not a generic
// one, and does not extend or implement generic classes or interfaces.
-
+
if (signature != null) {
considerSignature(signature);
}
@@ -468,27 +479,57 @@
// superName is the internal of name of the super class (see getInternalName).
// For interfaces, the super class is Object. May be null but only for the Object class.
considerName(superName);
-
+
// interfaces is the internal names of the class's interfaces (see getInternalName).
// May be null.
considerNames(interfaces);
}
+
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
// desc is the class descriptor of the annotation class.
considerDesc(desc);
- return this; // return this to visit annotion values
+ return new MyAnnotationVisitor();
}
+ @Override
public void visitAttribute(Attribute attr) {
// pass
}
// Visits the end of a class
+ @Override
public void visitEnd() {
// pass
}
+ private class MyFieldVisitor extends FieldVisitor {
+
+ public MyFieldVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ // desc is the class descriptor of the annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitAttribute(Attribute attr) {
+ // pass
+ }
+
+ // Visits the end of a class
+ @Override
+ public void visitEnd() {
+ // pass
+ }
+ }
+
+ @Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
// desc is the field's descriptor (see Type).
@@ -498,14 +539,16 @@
// generic types.
considerSignature(signature);
- return this; // a visitor to visit field annotations and attributes
+ return new MyFieldVisitor();
}
+ @Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
// name is the internal name of an inner class (see getInternalName).
considerName(name);
}
+ @Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
// desc is the method's descriptor (see Type).
@@ -513,239 +556,299 @@
// signature is the method's signature. May be null if the method parameters, return
// type and exceptions do not use generic types.
considerSignature(signature);
-
- return this; // returns this to visit the method
+
+ return new MyMethodVisitor();
}
+ @Override
public void visitOuterClass(String owner, String name, String desc) {
// pass
}
+ @Override
public void visitSource(String source, String debug) {
// pass
}
-
+
// ---------------------------------------------------
// --- MethodVisitor
// ---------------------------------------------------
- public AnnotationVisitor visitAnnotationDefault() {
- return this; // returns this to visit the default value
- }
+ private class MyMethodVisitor extends MethodVisitor {
+ public MyMethodVisitor() {
+ super(Opcodes.ASM4);
+ }
- public void visitCode() {
- // pass
- }
- // field instruction
- public void visitFieldInsn(int opcode, String owner, String name, String desc) {
- // name is the field's name.
- considerName(name);
- // desc is the field's descriptor (see Type).
- considerDesc(desc);
- }
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new MyAnnotationVisitor();
+ }
- public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
- // pass
- }
+ @Override
+ public void visitCode() {
+ // pass
+ }
- public void visitIincInsn(int var, int increment) {
- // pass -- an IINC instruction
- }
+ // field instruction
+ @Override
+ public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+ // name is the field's name.
+ considerName(name);
+ // desc is the field's descriptor (see Type).
+ considerDesc(desc);
+ }
- public void visitInsn(int opcode) {
- // pass -- a zero operand instruction
- }
+ @Override
+ public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
+ // pass
+ }
- public void visitIntInsn(int opcode, int operand) {
- // pass -- a single int operand instruction
- }
+ @Override
+ public void visitIincInsn(int var, int increment) {
+ // pass -- an IINC instruction
+ }
- public void visitJumpInsn(int opcode, Label label) {
- // pass -- a jump instruction
- }
+ @Override
+ public void visitInsn(int opcode) {
+ // pass -- a zero operand instruction
+ }
- public void visitLabel(Label label) {
- // pass -- a label target
- }
+ @Override
+ public void visitIntInsn(int opcode, int operand) {
+ // pass -- a single int operand instruction
+ }
- // instruction to load a constant from the stack
- public void visitLdcInsn(Object cst) {
- if (cst instanceof Type) {
- considerType((Type) cst);
+ @Override
+ public void visitJumpInsn(int opcode, Label label) {
+ // pass -- a jump instruction
}
- }
- public void visitLineNumber(int line, Label start) {
- // pass
- }
+ @Override
+ public void visitLabel(Label label) {
+ // pass -- a label target
+ }
- public void visitLocalVariable(String name, String desc,
- String signature, Label start, Label end, int index) {
- // desc is the type descriptor of this local variable.
- considerDesc(desc);
- // signature is the type signature of this local variable. May be null if the local
- // variable type does not use generic types.
- considerSignature(signature);
- }
+ // instruction to load a constant from the stack
+ @Override
+ public void visitLdcInsn(Object cst) {
+ if (cst instanceof Type) {
+ considerType((Type) cst);
+ }
+ }
- public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
- // pass -- a lookup switch instruction
- }
+ @Override
+ public void visitLineNumber(int line, Label start) {
+ // pass
+ }
- public void visitMaxs(int maxStack, int maxLocals) {
- // pass
- }
+ @Override
+ public void visitLocalVariable(String name, String desc,
+ String signature, Label start, Label end, int index) {
+ // desc is the type descriptor of this local variable.
+ considerDesc(desc);
+ // signature is the type signature of this local variable. May be null if the local
+ // variable type does not use generic types.
+ considerSignature(signature);
+ }
- // instruction that invokes a method
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-
- // owner is the internal name of the method's owner class
- considerName(owner);
- // desc is the method's descriptor (see Type).
- considerDesc(desc);
- }
+ @Override
+ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+ // pass -- a lookup switch instruction
+ }
- // instruction multianewarray, whatever that is
- public void visitMultiANewArrayInsn(String desc, int dims) {
-
- // desc an array type descriptor.
- considerDesc(desc);
- }
+ @Override
+ public void visitMaxs(int maxStack, int maxLocals) {
+ // pass
+ }
- public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
- boolean visible) {
- // desc is the class descriptor of the annotation class.
- considerDesc(desc);
- return this; // return this to visit annotation values
- }
+ // instruction that invokes a method
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
- public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
- // pass -- table switch instruction
-
- }
+ // owner is the internal name of the method's owner class
+ considerName(owner);
+ // desc is the method's descriptor (see Type).
+ considerDesc(desc);
+ }
- public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
- // type is the internal name of the type of exceptions handled by the handler,
- // or null to catch any exceptions (for "finally" blocks).
- considerName(type);
- }
+ // instruction multianewarray, whatever that is
+ @Override
+ public void visitMultiANewArrayInsn(String desc, int dims) {
- // type instruction
- public void visitTypeInsn(int opcode, String type) {
- // type is the operand of the instruction to be visited. This operand must be the
- // internal name of an object or array class.
- considerName(type);
- }
+ // desc an array type descriptor.
+ considerDesc(desc);
+ }
- public void visitVarInsn(int opcode, int var) {
- // pass -- local variable instruction
- }
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+ boolean visible) {
+ // desc is the class descriptor of the annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
-
- // ---------------------------------------------------
- // --- SignatureVisitor
- // ---------------------------------------------------
+ @Override
+ public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+ // pass -- table switch instruction
- private String mCurrentSignatureClass = null;
+ }
- // Starts the visit of a signature corresponding to a class or interface type
- public void visitClassType(String name) {
- mCurrentSignatureClass = name;
- considerName(name);
- }
+ @Override
+ public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+ // type is the internal name of the type of exceptions handled by the handler,
+ // or null to catch any exceptions (for "finally" blocks).
+ considerName(type);
+ }
- // Visits an inner class
- public void visitInnerClassType(String name) {
- if (mCurrentSignatureClass != null) {
- mCurrentSignatureClass += "$" + name;
- considerName(mCurrentSignatureClass);
+ // type instruction
+ @Override
+ public void visitTypeInsn(int opcode, String type) {
+ // type is the operand of the instruction to be visited. This operand must be the
+ // internal name of an object or array class.
+ considerName(type);
}
- }
- public SignatureVisitor visitArrayType() {
- return this; // returns this to visit the signature of the array element type
+ @Override
+ public void visitVarInsn(int opcode, int var) {
+ // pass -- local variable instruction
+ }
}
- public void visitBaseType(char descriptor) {
- // pass -- a primitive type, ignored
- }
+ private class MySignatureVisitor extends SignatureVisitor {
- public SignatureVisitor visitClassBound() {
- return this; // returns this to visit the signature of the class bound
- }
+ public MySignatureVisitor() {
+ super(Opcodes.ASM4);
+ }
- public SignatureVisitor visitExceptionType() {
- return this; // return this to visit the signature of the exception type.
- }
+ // ---------------------------------------------------
+ // --- SignatureVisitor
+ // ---------------------------------------------------
- public void visitFormalTypeParameter(String name) {
- // pass
- }
+ private String mCurrentSignatureClass = null;
- public SignatureVisitor visitInterface() {
- return this; // returns this to visit the signature of the interface type
- }
+ // Starts the visit of a signature corresponding to a class or interface type
+ @Override
+ public void visitClassType(String name) {
+ mCurrentSignatureClass = name;
+ considerName(name);
+ }
- public SignatureVisitor visitInterfaceBound() {
- return this; // returns this to visit the signature of the interface bound
- }
+ // Visits an inner class
+ @Override
+ public void visitInnerClassType(String name) {
+ if (mCurrentSignatureClass != null) {
+ mCurrentSignatureClass += "$" + name;
+ considerName(mCurrentSignatureClass);
+ }
+ }
- public SignatureVisitor visitParameterType() {
- return this; // returns this to visit the signature of the parameter type
- }
+ @Override
+ public SignatureVisitor visitArrayType() {
+ return new MySignatureVisitor();
+ }
- public SignatureVisitor visitReturnType() {
- return this; // returns this to visit the signature of the return type
- }
+ @Override
+ public void visitBaseType(char descriptor) {
+ // pass -- a primitive type, ignored
+ }
- public SignatureVisitor visitSuperclass() {
- return this; // returns this to visit the signature of the super class type
- }
+ @Override
+ public SignatureVisitor visitClassBound() {
+ return new MySignatureVisitor();
+ }
- public SignatureVisitor visitTypeArgument(char wildcard) {
- return this; // returns this to visit the signature of the type argument
- }
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ return new MySignatureVisitor();
+ }
- public void visitTypeVariable(String name) {
- // pass
- }
+ @Override
+ public void visitFormalTypeParameter(String name) {
+ // pass
+ }
- public void visitTypeArgument() {
- // pass
+ @Override
+ public SignatureVisitor visitInterface() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public void visitTypeVariable(String name) {
+ // pass
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ // pass
+ }
}
-
-
+
+
// ---------------------------------------------------
// --- AnnotationVisitor
// ---------------------------------------------------
+ private class MyAnnotationVisitor extends AnnotationVisitor {
- // Visits a primitive value of an annotation
- public void visit(String name, Object value) {
- // value is the actual value, whose type must be Byte, Boolean, Character, Short,
- // Integer, Long, Float, Double, String or Type
- if (value instanceof Type) {
- considerType((Type) value);
+ public MyAnnotationVisitor() {
+ super(Opcodes.ASM4);
}
- }
- public AnnotationVisitor visitAnnotation(String name, String desc) {
- // desc is the class descriptor of the nested annotation class.
- considerDesc(desc);
- return this; // returns this to visit the actual nested annotation value
- }
-
- public AnnotationVisitor visitArray(String name) {
- return this; // returns this to visit the actual array value elements
- }
+ // Visits a primitive value of an annotation
+ @Override
+ public void visit(String name, Object value) {
+ // value is the actual value, whose type must be Byte, Boolean, Character, Short,
+ // Integer, Long, Float, Double, String or Type
+ if (value instanceof Type) {
+ considerType((Type) value);
+ }
+ }
- public void visitEnum(String name, String desc, String value) {
- // desc is the class descriptor of the enumeration class.
- considerDesc(desc);
+ @Override
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ // desc is the class descriptor of the nested annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(String name) {
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitEnum(String name, String desc, String value) {
+ // desc is the class descriptor of the enumeration class.
+ considerDesc(desc);
+ }
}
-
}
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/AsmGenerator.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/AsmGenerator.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/AsmGenerator.java 2014-03-13 18:28:01.000000000 -0700
@@ -65,6 +65,9 @@
/** A map { FQCN => set { method names } } of methods to rewrite as delegates.
* The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
private final HashMap<String, Set<String>> mDelegateMethods;
+ /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
+ * map old-FQCN => new-FQCN */
+ private final HashMap<String, String> mRefactorClasses;
/**
* Creates a new generator that can generate the output JAR with the stubbed classes.
@@ -119,6 +122,17 @@
mClassesNotRenamed.add(oldFqcn);
}
+ // Create a map of classes to be refactored.
+ mRefactorClasses = new HashMap<String, String>();
+ String[] refactorClasses = createInfo.getJavaPkgClasses();
+ n = refactorClasses.length;
+ for (int i = 0; i < n; i += 2) {
+ assert i + 1 < n;
+ String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
+ String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
+ mRefactorClasses.put(oldFqcn, newFqcn);;
+ }
+
// create the map of renamed class -> return type of method to delete.
mDeleteReturns = new HashMap<String, Set<String>>();
String[] deleteReturns = createInfo.getDeleteReturns();
@@ -308,14 +322,14 @@
// original class reader.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- ClassVisitor rv = cw;
+ ClassVisitor cv = new RefactorClassAdapter(cw, mRefactorClasses);
if (newName != className) {
- rv = new RenameClassAdapter(cw, className, newName);
+ cv = new RenameClassAdapter(cv, className, newName);
}
- ClassVisitor cv = new TransformClassAdapter(mLog, mStubMethods,
+ cv = new TransformClassAdapter(mLog, mStubMethods,
mDeleteReturns.get(className),
- newName, rv,
+ newName, cv,
stubNativesOnly, stubNativesOnly || hasNativeMethods);
Set<String> delegateMethods = mDelegateMethods.get(className);
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java 2014-03-13 18:28:01.000000000 -0700
@@ -29,7 +29,10 @@
/**
* Indicates if a class contains any native methods.
*/
-public class ClassHasNativeVisitor implements ClassVisitor {
+public class ClassHasNativeVisitor extends ClassVisitor {
+ public ClassHasNativeVisitor() {
+ super(Opcodes.ASM4);
+ }
private boolean mHasNativeMethods = false;
@@ -42,35 +45,42 @@
mHasNativeMethods = hasNativeMethods;
}
+ @Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
// pass
}
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
// pass
return null;
}
+ @Override
public void visitAttribute(Attribute attr) {
// pass
}
+ @Override
public void visitEnd() {
// pass
}
+ @Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
// pass
return null;
}
+ @Override
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
// pass
}
+ @Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
if ((access & Opcodes.ACC_NATIVE) != 0) {
@@ -79,10 +89,12 @@
return null;
}
+ @Override
public void visitOuterClass(String owner, String name, String desc) {
// pass
}
+ @Override
public void visitSource(String source, String debug) {
// pass
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/CreateInfo.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/CreateInfo.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/CreateInfo.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/CreateInfo.java 2014-03-13 18:28:01.000000000 -0700
@@ -17,6 +17,11 @@
package com.android.tools.layoutlib.create;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.android.tools.layoutlib.java.AutoCloseable;
+import com.android.tools.layoutlib.java.Charsets;
+import com.android.tools.layoutlib.java.IntegralToString;
+import com.android.tools.layoutlib.java.Objects;
+import com.android.tools.layoutlib.java.UnsafeByteSequence;
/**
* Describes the work to be done by {@link AsmGenerator}.
@@ -27,6 +32,7 @@
* Returns the list of class from layoutlib_create to inject in layoutlib.
* The list can be empty but must not be null.
*/
+ @Override
public Class<?>[] getInjectedClasses() {
return INJECTED_CLASSES;
}
@@ -35,6 +41,7 @@
* Returns the list of methods to rewrite as delegates.
* The list can be empty but must not be null.
*/
+ @Override
public String[] getDelegateMethods() {
return DELEGATE_METHODS;
}
@@ -43,6 +50,7 @@
* Returns the list of classes on which to delegate all native methods.
* The list can be empty but must not be null.
*/
+ @Override
public String[] getDelegateClassNatives() {
return DELEGATE_CLASS_NATIVES;
}
@@ -54,6 +62,7 @@
* <p/>
* This usage is deprecated. Please use method 'delegates' instead.
*/
+ @Override
public String[] getOverriddenMethods() {
return OVERRIDDEN_METHODS;
}
@@ -63,6 +72,7 @@
* of class to replace followed by the new FQCN.
* The list can be empty but must not be null.
*/
+ @Override
public String[] getRenamedClasses() {
return RENAMED_CLASSES;
}
@@ -74,10 +84,20 @@
* the methods to delete.
* The list can be empty but must not be null.
*/
+ @Override
public String[] getDeleteReturns() {
return DELETE_RETURNS;
}
+ /**
+ * Returns the list of classes to refactor, must be an even list: the binary FQCN of class to
+ * replace followed by the new FQCN. All references to the old class should be updated to the
+ * new class. The list can be empty but must not be null.
+ */
+ @Override
+ public String[] getJavaPkgClasses() {
+ return JAVA_PKG_CLASSES;
+ }
//-----
/**
@@ -89,7 +109,13 @@
MethodAdapter.class,
ICreateInfo.class,
CreateInfo.class,
- LayoutlibDelegate.class
+ LayoutlibDelegate.class,
+ /* Java package classes */
+ AutoCloseable.class,
+ Objects.class,
+ IntegralToString.class,
+ UnsafeByteSequence.class,
+ Charsets.class,
};
/**
@@ -104,12 +130,16 @@
"android.os.Handler#sendMessageAtTime",
"android.os.HandlerThread#run",
"android.os.Build#getString",
- "android.view.Display#getWindowManager",
+ "android.text.format.DateFormat#is24HourFormat",
+ "android.text.format.Time#format1",
+ "android.view.Choreographer#getRefreshRate",
+ "android.view.Display#updateDisplayInfoLocked",
"android.view.LayoutInflater#rInflate",
"android.view.LayoutInflater#parseInclude",
"android.view.View#isInEditMode",
+ "android.view.ViewRootImpl#isInTouchMode",
+ "android.view.WindowManagerGlobal#getWindowManagerService",
"android.view.inputmethod.InputMethodManager#getInstance",
- "android.util.Log#println_native",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
};
@@ -160,6 +190,7 @@
"android.text.AndroidBidi",
"android.util.FloatMath",
"android.view.Display",
+ "libcore.icu.DateIntervalFormat",
"libcore.icu.ICU",
};
@@ -177,10 +208,26 @@
*/
private final static String[] RENAMED_CLASSES =
new String[] {
- "android.os.ServiceManager", "android.os._Original_ServiceManager",
- "android.view.SurfaceView", "android.view._Original_SurfaceView",
+ "android.os.ServiceManager", "android.os._Original_ServiceManager",
+ "android.util.LruCache", "android.util._Original_LruCache",
+ "android.view.SurfaceView", "android.view._Original_SurfaceView",
"android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
- "android.webkit.WebView", "android.webkit._Original_WebView",
+ "android.webkit.WebView", "android.webkit._Original_WebView",
+ "com.android.internal.policy.PolicyManager", "com.android.internal.policy._Original_PolicyManager",
+ };
+
+ /**
+ * 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[] {
+ "java.lang.AutoCloseable", "com.android.tools.layoutlib.java.AutoCloseable",
+ "java.util.Objects", "com.android.tools.layoutlib.java.Objects",
+ "java.nio.charset.Charsets", "com.android.tools.layoutlib.java.Charsets",
+ "java.lang.IntegralToString", "com.android.tools.layoutlib.java.IntegralToString",
+ "java.lang.UnsafeByteSequence", "com.android.tools.layoutlib.java.UnsafeByteSequence",
};
/**
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,7 +16,6 @@
package com.android.tools.layoutlib.create;
-import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -29,7 +28,7 @@
* <p/>
* This is used to override specific methods and or all native methods in classes.
*/
-public class DelegateClassAdapter extends ClassAdapter {
+public class DelegateClassAdapter extends ClassVisitor {
/** Suffix added to original methods. */
private static final String ORIGINAL_SUFFIX = "_Original";
@@ -59,7 +58,7 @@
ClassVisitor cv,
String className,
Set<String> delegateMethods) {
- super(cv);
+ super(Opcodes.ASM4, cv);
mLog = log;
mClassName = className;
mDelegateMethods = delegateMethods;
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java 2014-03-13 18:28:01.000000000 -0700
@@ -71,7 +71,7 @@
* Instances of this class are not re-usable.
* The class adapter creates a new instance for each method.
*/
-class DelegateMethodAdapter2 implements MethodVisitor {
+class DelegateMethodAdapter2 extends MethodVisitor {
/** Suffix added to delegate classes. */
public static final String DELEGATE_SUFFIX = "_Delegate";
@@ -121,6 +121,7 @@
String methodName,
String desc,
boolean isStatic) {
+ super(Opcodes.ASM4);
mLog = log;
mOrgWriter = mvOriginal;
mDelWriter = mvDelegate;
@@ -265,6 +266,7 @@
}
/* Pass down to visitor writer. In this implementation, either do nothing. */
+ @Override
public void visitCode() {
if (mOrgWriter != null) {
mOrgWriter.visitCode();
@@ -274,6 +276,7 @@
/*
* visitMaxs is called just before visitEnd if there was any code to rewrite.
*/
+ @Override
public void visitMaxs(int maxStack, int maxLocals) {
if (mOrgWriter != null) {
mOrgWriter.visitMaxs(maxStack, maxLocals);
@@ -281,6 +284,7 @@
}
/** End of visiting. Generate the delegating code. */
+ @Override
public void visitEnd() {
if (mOrgWriter != null) {
mOrgWriter.visitEnd();
@@ -289,6 +293,7 @@
}
/* Writes all annotation from the original method. */
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (mOrgWriter != null) {
return mOrgWriter.visitAnnotation(desc, visible);
@@ -298,6 +303,7 @@
}
/* Writes all annotation default values from the original method. */
+ @Override
public AnnotationVisitor visitAnnotationDefault() {
if (mOrgWriter != null) {
return mOrgWriter.visitAnnotationDefault();
@@ -306,6 +312,7 @@
}
}
+ @Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
boolean visible) {
if (mOrgWriter != null) {
@@ -316,6 +323,7 @@
}
/* Writes all attributes from the original method. */
+ @Override
public void visitAttribute(Attribute attr) {
if (mOrgWriter != null) {
mOrgWriter.visitAttribute(attr);
@@ -326,6 +334,7 @@
* Only writes the first line number present in the original code so that source
* viewers can direct to the correct method, even if the content doesn't match.
*/
+ @Override
public void visitLineNumber(int line, Label start) {
// Capture the first line values for the new delegate method
if (mDelegateLineNumber == null) {
@@ -336,66 +345,77 @@
}
}
+ @Override
public void visitInsn(int opcode) {
if (mOrgWriter != null) {
mOrgWriter.visitInsn(opcode);
}
}
+ @Override
public void visitLabel(Label label) {
if (mOrgWriter != null) {
mOrgWriter.visitLabel(label);
}
}
+ @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
if (mOrgWriter != null) {
mOrgWriter.visitTryCatchBlock(start, end, handler, type);
}
}
+ @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
if (mOrgWriter != null) {
mOrgWriter.visitMethodInsn(opcode, owner, name, desc);
}
}
+ @Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (mOrgWriter != null) {
mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
}
}
+ @Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
if (mOrgWriter != null) {
mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
}
}
+ @Override
public void visitIincInsn(int var, int increment) {
if (mOrgWriter != null) {
mOrgWriter.visitIincInsn(var, increment);
}
}
+ @Override
public void visitIntInsn(int opcode, int operand) {
if (mOrgWriter != null) {
mOrgWriter.visitIntInsn(opcode, operand);
}
}
+ @Override
public void visitJumpInsn(int opcode, Label label) {
if (mOrgWriter != null) {
mOrgWriter.visitJumpInsn(opcode, label);
}
}
+ @Override
public void visitLdcInsn(Object cst) {
if (mOrgWriter != null) {
mOrgWriter.visitLdcInsn(cst);
}
}
+ @Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
if (mOrgWriter != null) {
@@ -403,30 +423,35 @@
}
}
+ @Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mOrgWriter != null) {
mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
}
}
+ @Override
public void visitMultiANewArrayInsn(String desc, int dims) {
if (mOrgWriter != null) {
mOrgWriter.visitMultiANewArrayInsn(desc, dims);
}
}
+ @Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
if (mOrgWriter != null) {
mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
}
}
+ @Override
public void visitTypeInsn(int opcode, String type) {
if (mOrgWriter != null) {
mOrgWriter.visitTypeInsn(opcode, type);
}
}
+ @Override
public void visitVarInsn(int opcode, int var) {
if (mOrgWriter != null) {
mOrgWriter.visitVarInsn(opcode, var);
Only in layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create: DependencyFinder.java
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/ICreateInfo.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/ICreateInfo.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/ICreateInfo.java 2014-03-13 18:28:01.000000000 -0700
@@ -62,4 +62,11 @@
*/
public abstract String[] getDeleteReturns();
+ /**
+ * Returns the list of classes to refactor, must be an even list: the
+ * binary FQCN of class to replace followed by the new FQCN. All references
+ * to the old class should be updated to the new class.
+ * The list can be empty but must not be null.
+ */
+ public abstract String[] getJavaPkgClasses();
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/Log.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/Log.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/Log.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/Log.java 2014-03-13 18:28:01.000000000 -0700
@@ -33,11 +33,19 @@
}
}
+ /** Similar to debug() but doesn't do a \n automatically. */
+ public void debugNoln(String format, Object... args) {
+ if (mVerbose) {
+ String s = String.format(format, args);
+ System.out.print(s);
+ }
+ }
+
public void info(String format, Object... args) {
String s = String.format(format, args);
outPrintln(s);
}
-
+
public void error(String format, Object... args) {
String s = String.format(format, args);
errPrintln(s);
@@ -50,15 +58,15 @@
pw.flush();
error(format + "\n" + sw.toString(), args);
}
-
+
/** for unit testing */
protected void errPrintln(String msg) {
System.err.println(msg);
}
-
+
/** for unit testing */
protected void outPrintln(String msg) {
System.out.println(msg);
}
-
+
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/Main.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/Main.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/Main.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/Main.java 2014-03-13 18:28:01.000000000 -0700
@@ -18,6 +18,9 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
@@ -47,6 +50,8 @@
public static class Options {
public boolean generatePublicAccess = true;
+ public boolean listAllDeps = false;
+ public boolean listOnlyMissingDeps = false;
}
public static final Options sOptions = new Options();
@@ -60,16 +65,31 @@
if (!processArgs(log, args, osJarPath, osDestJar)) {
log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
+ log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
System.exit(1);
}
- log.info("Output: %1$s", osDestJar[0]);
+ if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
+ System.exit(listDeps(osJarPath, log));
+
+ } else {
+ System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
+ }
+
+
+ System.exit(1);
+ }
+
+ private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
+ log.info("Output: %1$s", osDestJar);
for (String path : osJarPath) {
log.info("Input : %1$s", path);
}
try {
- AsmGenerator agen = new AsmGenerator(log, osDestJar[0], new CreateInfo());
+ CreateInfo info = new CreateInfo();
+ Set<String> excludeClasses = getExcludedClasses(info);
+ AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
new String[] { // derived from
@@ -93,7 +113,9 @@
"android.pim.*", // for datepicker
"android.os.*", // for android.os.Handler
"android.database.ContentObserver", // for Digital clock
- });
+ "com.android.i18n.phonenumbers.*", // for TextView with autolink attribute
+ },
+ excludeClasses);
aa.analyze();
agen.generate();
@@ -116,17 +138,43 @@
for (String path : osJarPath) {
log.info("- Input JAR : %1$s", path);
}
- System.exit(1);
+ return 1;
}
- System.exit(0);
+ return 0;
} catch (IOException e) {
log.exception(e, "Failed to load jar");
} catch (LogAbortException e) {
e.error(log);
}
- System.exit(1);
+ return 1;
+ }
+
+ private static Set<String> getExcludedClasses(CreateInfo info) {
+ String[] refactoredClasses = info.getJavaPkgClasses();
+ Set<String> excludedClasses = new HashSet<String>(refactoredClasses.length);
+ for (int i = 0; i < refactoredClasses.length; i+=2) {
+ excludedClasses.add(refactoredClasses[i]);
+ }
+ return excludedClasses;
+
+ }
+
+ private static int listDeps(ArrayList<String> osJarPath, Log log) {
+ DependencyFinder df = new DependencyFinder(log);
+ try {
+ List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
+ if (sOptions.listAllDeps) {
+ df.printAllDeps(result);
+ } else if (sOptions.listOnlyMissingDeps) {
+ df.printMissingDeps(result);
+ }
+ } catch (IOException e) {
+ log.exception(e, "Failed to load jar");
+ }
+
+ return 0;
}
/**
@@ -138,14 +186,21 @@
*/
private static boolean processArgs(Log log, String[] args,
ArrayList<String> osJarPath, String[] osDestJar) {
+ boolean needs_dest = true;
for (int i = 0; i < args.length; i++) {
String s = args[i];
if (s.equals("-v")) {
log.setVerbose(true);
} else if (s.equals("-p")) {
sOptions.generatePublicAccess = false;
+ } else if (s.equals("--list-deps")) {
+ sOptions.listAllDeps = true;
+ needs_dest = false;
+ } else if (s.equals("--missing-deps")) {
+ sOptions.listOnlyMissingDeps = true;
+ needs_dest = false;
} else if (!s.startsWith("-")) {
- if (osDestJar[0] == null) {
+ if (needs_dest && osDestJar[0] == null) {
osDestJar[0] = s;
} else {
osJarPath.add(s);
@@ -160,7 +215,7 @@
log.error("Missing parameter: path to input jar");
return false;
}
- if (osDestJar[0] == null) {
+ if (needs_dest && osDestJar[0] == null) {
log.error("Missing parameter: path to output jar");
return false;
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/MethodAdapter.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/MethodAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/MethodAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -28,13 +28,14 @@
* A stub method is being invoked.
* <p/>
* Known limitation: caller arguments are not available.
- *
+ *
* @param signature The signature of the method being invoked, composed of the
* binary class name followed by the method descriptor (aka argument
* types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
* @param isNative True if the method was a native method.
* @param caller The calling object. Null for static methods, "this" for instance methods.
*/
+ @Override
public void onInvokeV(String signature, boolean isNative, Object caller) {
}
@@ -43,6 +44,7 @@
* @see #onInvokeV(String, boolean, Object)
* @return an integer, or a boolean, or a short or a byte.
*/
+ @Override
public int onInvokeI(String signature, boolean isNative, Object caller) {
onInvokeV(signature, isNative, caller);
return 0;
@@ -53,6 +55,7 @@
* @see #onInvokeV(String, boolean, Object)
* @return a long.
*/
+ @Override
public long onInvokeL(String signature, boolean isNative, Object caller) {
onInvokeV(signature, isNative, caller);
return 0;
@@ -63,6 +66,7 @@
* @see #onInvokeV(String, boolean, Object)
* @return a float.
*/
+ @Override
public float onInvokeF(String signature, boolean isNative, Object caller) {
onInvokeV(signature, isNative, caller);
return 0;
@@ -73,6 +77,7 @@
* @see #onInvokeV(String, boolean, Object)
* @return a double.
*/
+ @Override
public double onInvokeD(String signature, boolean isNative, Object caller) {
onInvokeV(signature, isNative, caller);
return 0;
@@ -83,6 +88,7 @@
* @see #onInvokeV(String, boolean, Object)
* @return an object.
*/
+ @Override
public Object onInvokeA(String signature, boolean isNative, Object caller) {
onInvokeV(signature, isNative, caller);
return null;
Only in layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create: RefactorClassAdapter.java
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,29 +16,19 @@
package com.android.tools.layoutlib.create;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-import org.objectweb.asm.signature.SignatureWriter;
+import org.objectweb.asm.ClassVisitor;
/**
* This class visitor renames a class from a given old name to a given new name.
* The class visitor will also rename all inner classes and references in the methods.
* <p/>
- *
+ *
* For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same.
+ * The inner class name should remain the same.
*/
-public class RenameClassAdapter extends ClassAdapter {
+public class RenameClassAdapter extends AbstractClassAdapter {
+
-
private final String mOldName;
private final String mNewName;
private String mOldBase;
@@ -49,11 +39,11 @@
* The class visitor will also rename all inner classes and references in the methods.
* The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
*/
- public RenameClassAdapter(ClassWriter cv, String oldName, String newName) {
+ public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) {
super(cv);
mOldBase = mOldName = oldName;
mNewBase = mNewName = newName;
-
+
int pos = mOldName.indexOf('$');
if (pos > 0) {
mOldBase = mOldName.substring(0, pos);
@@ -62,73 +52,8 @@
if (pos > 0) {
mNewBase = mNewName.substring(0, pos);
}
-
- assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
- }
-
-
- /**
- * Renames a type descriptor, e.g. "Lcom.package.MyClass;"
- * If the type doesn't need to be renamed, returns the input string as-is.
- */
- String renameTypeDesc(String desc) {
- if (desc == null) {
- return null;
- }
-
- return renameType(Type.getType(desc));
- }
-
- /**
- * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
- * object element, e.g. "[Lcom.package.MyClass;"
- * If the type doesn't need to be renamed, returns the internal name of the input type.
- */
- String renameType(Type type) {
- if (type == null) {
- return null;
- }
- if (type.getSort() == Type.OBJECT) {
- String in = type.getInternalName();
- return "L" + renameInternalType(in) + ";";
- } else if (type.getSort() == Type.ARRAY) {
- StringBuilder sb = new StringBuilder();
- for (int n = type.getDimensions(); n > 0; n--) {
- sb.append('[');
- }
- sb.append(renameType(type.getElementType()));
- return sb.toString();
- }
- return type.getDescriptor();
- }
-
- /**
- * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
- * object element, e.g. "[Lcom.package.MyClass;".
- * This is like renameType() except that it returns a Type object.
- * If the type doesn't need to be renamed, returns the input type object.
- */
- Type renameTypeAsType(Type type) {
- if (type == null) {
- return null;
- }
-
- if (type.getSort() == Type.OBJECT) {
- String in = type.getInternalName();
- String newIn = renameInternalType(in);
- if (newIn != in) {
- return Type.getType("L" + newIn + ";");
- }
- } else if (type.getSort() == Type.ARRAY) {
- StringBuilder sb = new StringBuilder();
- for (int n = type.getDimensions(); n > 0; n--) {
- sb.append('[');
- }
- sb.append(renameType(type.getElementType()));
- return Type.getType(sb.toString());
- }
- return type;
+ assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
}
/**
@@ -138,7 +63,8 @@
* The internal type of some of the MethodVisitor turns out to be a type
descriptor sometimes so descriptors are renamed too.
*/
- String renameInternalType(String type) {
+ @Override
+ protected String renameInternalType(String type) {
if (type == null) {
return null;
}
@@ -150,297 +76,12 @@
if (mOldBase != mOldName && type.equals(mOldBase)) {
return mNewBase;
}
-
+
int pos = type.indexOf('$');
if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
return mNewBase + type.substring(pos);
}
-
- // The internal type of some of the MethodVisitor turns out to be a type
- // descriptor sometimes. This is the case with visitTypeInsn(type) and
- // visitMethodInsn(owner). We try to detect it and adjust it here.
- if (type.indexOf(';') > 0) {
- type = renameTypeDesc(type);
- }
-
return type;
}
- /**
- * Renames a method descriptor, i.e. applies renameType to all arguments and to the
- * return value.
- */
- String renameMethodDesc(String desc) {
- if (desc == null) {
- return null;
- }
-
- Type[] args = Type.getArgumentTypes(desc);
-
- StringBuilder sb = new StringBuilder("(");
- for (Type arg : args) {
- String name = renameType(arg);
- sb.append(name);
- }
- sb.append(')');
-
- Type ret = Type.getReturnType(desc);
- String name = renameType(ret);
- sb.append(name);
-
- return sb.toString();
- }
-
-
- /**
- * Renames the ClassSignature handled by ClassVisitor.visit
- * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
- */
- String renameTypeSignature(String sig) {
- if (sig == null) {
- return null;
- }
- SignatureReader reader = new SignatureReader(sig);
- SignatureWriter writer = new SignatureWriter();
- reader.accept(new RenameSignatureAdapter(writer));
- sig = writer.toString();
- return sig;
- }
-
-
- /**
- * Renames the FieldTypeSignature handled by ClassVisitor.visitField
- * or MethodVisitor.visitLocalVariable.
- */
- String renameFieldSignature(String sig) {
- if (sig == null) {
- return null;
- }
- SignatureReader reader = new SignatureReader(sig);
- SignatureWriter writer = new SignatureWriter();
- reader.acceptType(new RenameSignatureAdapter(writer));
- sig = writer.toString();
- return sig;
- }
-
-
- //----------------------------------
- // Methods from the ClassAdapter
-
- @Override
- public void visit(int version, int access, String name, String signature,
- String superName, String[] interfaces) {
- name = renameInternalType(name);
- superName = renameInternalType(superName);
- signature = renameTypeSignature(signature);
-
- super.visit(version, access, name, signature, superName, interfaces);
- }
-
- @Override
- public void visitInnerClass(String name, String outerName, String innerName, int access) {
- assert outerName.equals(mOldName);
- outerName = renameInternalType(outerName);
- name = outerName + "$" + innerName;
- super.visitInnerClass(name, outerName, innerName, access);
- }
-
- @Override
- public MethodVisitor visitMethod(int access, String name, String desc,
- String signature, String[] exceptions) {
- desc = renameMethodDesc(desc);
- signature = renameTypeSignature(signature);
- MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
- return new RenameMethodAdapter(mw);
- }
-
- @Override
- public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- desc = renameTypeDesc(desc);
- return super.visitAnnotation(desc, visible);
- }
-
- @Override
- public FieldVisitor visitField(int access, String name, String desc,
- String signature, Object value) {
- desc = renameTypeDesc(desc);
- signature = renameFieldSignature(signature);
- return super.visitField(access, name, desc, signature, value);
- }
-
-
- //----------------------------------
-
- /**
- * A method visitor that renames all references from an old class name to a new class name.
- */
- public class RenameMethodAdapter extends MethodAdapter {
-
- /**
- * Creates a method visitor that renames all references from a given old name to a given new
- * name. The method visitor will also rename all inner classes.
- * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
- */
- public RenameMethodAdapter(MethodVisitor mv) {
- super(mv);
- }
-
- @Override
- public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- desc = renameTypeDesc(desc);
-
- return super.visitAnnotation(desc, visible);
- }
-
- @Override
- public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
- desc = renameTypeDesc(desc);
-
- return super.visitParameterAnnotation(parameter, desc, visible);
- }
-
- @Override
- public void visitTypeInsn(int opcode, String type) {
- type = renameInternalType(type);
-
- super.visitTypeInsn(opcode, type);
- }
-
- @Override
- public void visitFieldInsn(int opcode, String owner, String name, String desc) {
- owner = renameInternalType(owner);
- desc = renameTypeDesc(desc);
-
- super.visitFieldInsn(opcode, owner, name, desc);
- }
-
- @Override
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
- owner = renameInternalType(owner);
- desc = renameMethodDesc(desc);
-
- super.visitMethodInsn(opcode, owner, name, desc);
- }
-
- @Override
- public void visitLdcInsn(Object cst) {
- // If cst is a Type, this means the code is trying to pull the .class constant
- // for this class, so it needs to be renamed too.
- if (cst instanceof Type) {
- cst = renameTypeAsType((Type) cst);
- }
- super.visitLdcInsn(cst);
- }
-
- @Override
- public void visitMultiANewArrayInsn(String desc, int dims) {
- desc = renameTypeDesc(desc);
-
- super.visitMultiANewArrayInsn(desc, dims);
- }
-
- @Override
- public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
- type = renameInternalType(type);
-
- super.visitTryCatchBlock(start, end, handler, type);
- }
-
- @Override
- public void visitLocalVariable(String name, String desc, String signature,
- Label start, Label end, int index) {
- desc = renameTypeDesc(desc);
- signature = renameFieldSignature(signature);
-
- super.visitLocalVariable(name, desc, signature, start, end, index);
- }
-
- }
-
- //----------------------------------
-
- public class RenameSignatureAdapter implements SignatureVisitor {
-
- private final SignatureVisitor mSv;
-
- public RenameSignatureAdapter(SignatureVisitor sv) {
- mSv = sv;
- }
-
- public void visitClassType(String name) {
- name = renameInternalType(name);
- mSv.visitClassType(name);
- }
-
- public void visitInnerClassType(String name) {
- name = renameInternalType(name);
- mSv.visitInnerClassType(name);
- }
-
- public SignatureVisitor visitArrayType() {
- SignatureVisitor sv = mSv.visitArrayType();
- return new RenameSignatureAdapter(sv);
- }
-
- public void visitBaseType(char descriptor) {
- mSv.visitBaseType(descriptor);
- }
-
- public SignatureVisitor visitClassBound() {
- SignatureVisitor sv = mSv.visitClassBound();
- return new RenameSignatureAdapter(sv);
- }
-
- public void visitEnd() {
- mSv.visitEnd();
- }
-
- public SignatureVisitor visitExceptionType() {
- SignatureVisitor sv = mSv.visitExceptionType();
- return new RenameSignatureAdapter(sv);
- }
-
- public void visitFormalTypeParameter(String name) {
- mSv.visitFormalTypeParameter(name);
- }
-
- public SignatureVisitor visitInterface() {
- SignatureVisitor sv = mSv.visitInterface();
- return new RenameSignatureAdapter(sv);
- }
-
- public SignatureVisitor visitInterfaceBound() {
- SignatureVisitor sv = mSv.visitInterfaceBound();
- return new RenameSignatureAdapter(sv);
- }
-
- public SignatureVisitor visitParameterType() {
- SignatureVisitor sv = mSv.visitParameterType();
- return new RenameSignatureAdapter(sv);
- }
-
- public SignatureVisitor visitReturnType() {
- SignatureVisitor sv = mSv.visitReturnType();
- return new RenameSignatureAdapter(sv);
- }
-
- public SignatureVisitor visitSuperclass() {
- SignatureVisitor sv = mSv.visitSuperclass();
- return new RenameSignatureAdapter(sv);
- }
-
- public void visitTypeArgument() {
- mSv.visitTypeArgument();
- }
-
- public SignatureVisitor visitTypeArgument(char wildcard) {
- SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
- return new RenameSignatureAdapter(sv);
- }
-
- public void visitTypeVariable(String name) {
- mSv.visitTypeVariable(name);
- }
-
- }
}
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -27,7 +27,7 @@
* This method adapter rewrites a method by discarding the original code and generating
* a stub depending on the return type. Original annotations are passed along unchanged.
*/
-class StubMethodAdapter implements MethodVisitor {
+class StubMethodAdapter extends MethodVisitor {
private static String CONSTRUCTOR = "<init>";
private static String CLASS_INIT = "<clinit>";
@@ -50,6 +50,7 @@
public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
String invokeSignature, boolean isStatic, boolean isNative) {
+ super(Opcodes.ASM4);
mParentVisitor = mv;
mReturnType = returnType;
mInvokeSignature = invokeSignature;
@@ -172,6 +173,7 @@
}
/* Pass down to visitor writer. In this implementation, either do nothing. */
+ @Override
public void visitCode() {
mParentVisitor.visitCode();
}
@@ -181,6 +183,7 @@
* For non-constructor, generate the messaging code and the return statement
* if it hasn't been done before.
*/
+ @Override
public void visitMaxs(int maxStack, int maxLocals) {
if (!mIsInitMethod && !mMessageGenerated) {
generateInvoke();
@@ -194,6 +197,7 @@
* For non-constructor, generate the messaging code and the return statement
* if it hasn't been done before.
*/
+ @Override
public void visitEnd() {
if (!mIsInitMethod && !mMessageGenerated) {
generateInvoke();
@@ -204,21 +208,25 @@
}
/* Writes all annotation from the original method. */
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return mParentVisitor.visitAnnotation(desc, visible);
}
/* Writes all annotation default values from the original method. */
+ @Override
public AnnotationVisitor visitAnnotationDefault() {
return mParentVisitor.visitAnnotationDefault();
}
+ @Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
boolean visible) {
return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
}
/* Writes all attributes from the original method. */
+ @Override
public void visitAttribute(Attribute attr) {
mParentVisitor.visitAttribute(attr);
}
@@ -227,6 +235,7 @@
* Only writes the first line number present in the original code so that source
* viewers can direct to the correct method, even if the content doesn't match.
*/
+ @Override
public void visitLineNumber(int line, Label start) {
if (mIsInitMethod || mOutputFirstLineNumber) {
mParentVisitor.visitLineNumber(line, start);
@@ -237,6 +246,7 @@
/**
* For non-constructor, rewrite existing "return" instructions to write the message.
*/
+ @Override
public void visitInsn(int opcode) {
if (mIsInitMethod) {
switch (opcode) {
@@ -257,60 +267,70 @@
}
}
+ @Override
public void visitLabel(Label label) {
if (mIsInitMethod) {
mParentVisitor.visitLabel(label);
}
}
+ @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
if (mIsInitMethod) {
mParentVisitor.visitTryCatchBlock(start, end, handler, type);
}
}
+ @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
if (mIsInitMethod) {
mParentVisitor.visitMethodInsn(opcode, owner, name, desc);
}
}
+ @Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (mIsInitMethod) {
mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
}
}
+ @Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
if (mIsInitMethod) {
mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
}
}
+ @Override
public void visitIincInsn(int var, int increment) {
if (mIsInitMethod) {
mParentVisitor.visitIincInsn(var, increment);
}
}
+ @Override
public void visitIntInsn(int opcode, int operand) {
if (mIsInitMethod) {
mParentVisitor.visitIntInsn(opcode, operand);
}
}
+ @Override
public void visitJumpInsn(int opcode, Label label) {
if (mIsInitMethod) {
mParentVisitor.visitJumpInsn(opcode, label);
}
}
+ @Override
public void visitLdcInsn(Object cst) {
if (mIsInitMethod) {
mParentVisitor.visitLdcInsn(cst);
}
}
+ @Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
if (mIsInitMethod) {
@@ -318,30 +338,35 @@
}
}
+ @Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mIsInitMethod) {
mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
}
}
+ @Override
public void visitMultiANewArrayInsn(String desc, int dims) {
if (mIsInitMethod) {
mParentVisitor.visitMultiANewArrayInsn(desc, dims);
}
}
+ @Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
if (mIsInitMethod) {
mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
}
}
+ @Override
public void visitTypeInsn(int opcode, String type) {
if (mIsInitMethod) {
mParentVisitor.visitTypeInsn(opcode, type);
}
}
+ @Override
public void visitVarInsn(int opcode, int var) {
if (mIsInitMethod) {
mParentVisitor.visitVarInsn(opcode, var);
diff -ru layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
--- layoutlib_4-0-3-r1/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java 2014-03-13 18:28:01.000000000 -0700
@@ -16,7 +16,6 @@
package com.android.tools.layoutlib.create;
-import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
@@ -28,7 +27,7 @@
/**
* Class adapter that can stub some or all of the methods of the class.
*/
-class TransformClassAdapter extends ClassAdapter {
+class TransformClassAdapter extends ClassVisitor {
/** True if all methods should be stubbed, false if only native ones must be stubbed. */
private final boolean mStubAll;
@@ -54,7 +53,7 @@
public TransformClassAdapter(Log logger, Set<String> stubMethods,
Set<String> deleteReturns, String className, ClassVisitor cv,
boolean stubNativesOnly, boolean hasNative) {
- super(cv);
+ super(Opcodes.ASM4, cv);
mLog = logger;
mStubMethods = stubMethods;
mClassName = className;
Only in layoutlib_4-4-2-r1/create/src/com/android/tools/layoutlib: java
diff -ru layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
--- layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java 2014-03-13 18:28:01.000000000 -0700
@@ -31,7 +31,9 @@
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
/**
@@ -51,8 +53,10 @@
mOsJarPath = new ArrayList<String>();
mOsJarPath.add(url.getFile());
+ Set<String> excludeClasses = new HashSet<String>(1);
+ excludeClasses.add("java.lang.JavaClass");
mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */,
- null /* deriveFrom */, null /* includeGlobs */ );
+ null /* deriveFrom */, null /* includeGlobs */, excludeClasses);
}
@After
@@ -64,6 +68,7 @@
Map<String, ClassReader> map = mAa.parseZip(mOsJarPath);
assertArrayEquals(new String[] {
+ "java.lang.JavaClass",
"mock_android.dummy.InnerTest",
"mock_android.dummy.InnerTest$DerivingClass",
"mock_android.dummy.InnerTest$MyGenerics1",
@@ -221,7 +226,11 @@
for (ClassReader cr2 : in_deps.values()) {
cr2.accept(visitor, 0 /* flags */);
}
+ keep.putAll(new_keep);
assertArrayEquals(new String[] { }, out_deps.keySet().toArray());
+ assertArrayEquals(new String[] {
+ "mock_android.widget.TableLayout",
+ }, keep.keySet().toArray());
}
}
diff -ru layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
--- layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java 2014-03-13 18:28:01.000000000 -0700
@@ -19,16 +19,29 @@
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
/**
* Unit tests for some methods of {@link AsmGenerator}.
@@ -40,6 +53,9 @@
private String mOsDestJar;
private File mTempFile;
+ // ASM internal name for the the class in java package that should be refactored.
+ private static final String JAVA_CLASS_NAME = "java/lang/JavaClass";
+
@Before
public void setUp() throws Exception {
mLog = new MockLog();
@@ -48,7 +64,7 @@
mOsJarPath = new ArrayList<String>();
mOsJarPath.add(url.getFile());
- mTempFile = File.createTempFile("mock", "jar");
+ mTempFile = File.createTempFile("mock", ".jar");
mOsDestJar = mTempFile.getAbsolutePath();
mTempFile.deleteOnExit();
}
@@ -65,24 +81,29 @@
public void testClassRenaming() throws IOException, LogAbortException {
ICreateInfo ci = new ICreateInfo() {
+ @Override
public Class<?>[] getInjectedClasses() {
// classes to inject in the final JAR
return new Class<?>[0];
}
+ @Override
public String[] getDelegateMethods() {
return new String[0];
}
+ @Override
public String[] getDelegateClassNatives() {
return new String[0];
}
+ @Override
public String[] getOverriddenMethods() {
// methods to force override
return new String[0];
}
+ @Override
public String[] getRenamedClasses() {
// classes to rename (so that we can replace them)
return new String[] {
@@ -91,6 +112,12 @@
};
}
+ @Override
+ public String[] getJavaPkgClasses() {
+ return new String[0];
+ }
+
+ @Override
public String[] getDeleteReturns() {
// methods deleted from their return type.
return new String[0];
@@ -103,11 +130,201 @@
null, // derived from
new String[] { // include classes
"**"
- });
+ },
+ new HashSet<String>(0) /* excluded classes */);
aa.analyze();
agen.generate();
Set<String> notRenamed = agen.getClassesNotRenamed();
assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
+
+ }
+
+ @Test
+ public void testClassRefactoring() throws IOException, LogAbortException {
+ ICreateInfo ci = new ICreateInfo() {
+ @Override
+ public Class<?>[] getInjectedClasses() {
+ // classes to inject in the final JAR
+ return new Class<?>[] {
+ com.android.tools.layoutlib.create.dataclass.JavaClass.class
+ };
+ }
+
+ @Override
+ public String[] getDelegateMethods() {
+ return new String[0];
+ }
+
+ @Override
+ public String[] getDelegateClassNatives() {
+ return new String[0];
+ }
+
+ @Override
+ public String[] getOverriddenMethods() {
+ // methods to force override
+ return new String[0];
+ }
+
+ @Override
+ public String[] getRenamedClasses() {
+ // classes to rename (so that we can replace them)
+ return new String[0];
+ }
+
+ @Override
+ public String[] getJavaPkgClasses() {
+ // classes to refactor (so that we can replace them)
+ return new String[] {
+ "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass",
+ };
+ }
+
+ @Override
+ public String[] getDeleteReturns() {
+ // methods deleted from their return type.
+ return new String[0];
+ }
+ };
+
+ AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
+
+ AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
+ null, // derived from
+ new String[] { // include classes
+ "**"
+ },
+ new HashSet<String>(1));
+ aa.analyze();
+ agen.generate();
+ Map<String, ClassReader> output = parseZip(mOsDestJar);
+ boolean injectedClassFound = false;
+ for (ClassReader cr: output.values()) {
+ TestClassVisitor cv = new TestClassVisitor();
+ cr.accept(cv, 0);
+ injectedClassFound |= cv.mInjectedClassFound;
+ }
+ assertTrue(injectedClassFound);
+ }
+
+ private Map<String,ClassReader> parseZip(String jarPath) throws IOException {
+ TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
+
+ ZipFile zip = new ZipFile(jarPath);
+ Enumeration<? extends ZipEntry> entries = zip.entries();
+ ZipEntry entry;
+ while (entries.hasMoreElements()) {
+ entry = entries.nextElement();
+ if (entry.getName().endsWith(".class")) {
+ ClassReader cr = new ClassReader(zip.getInputStream(entry));
+ String className = classReaderToClassName(cr);
+ classes.put(className, cr);
+ }
+ }
+
+ return classes;
+ }
+
+ private String classReaderToClassName(ClassReader classReader) {
+ if (classReader == null) {
+ return null;
+ } else {
+ return classReader.getClassName().replace('/', '.');
+ }
+ }
+
+ private class TestClassVisitor extends ClassVisitor {
+
+ boolean mInjectedClassFound = false;
+
+ TestClassVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ @Override
+ public void visit(int version, int access, String name, String signature,
+ String superName, String[] interfaces) {
+ assertTrue(!getBase(name).equals(JAVA_CLASS_NAME));
+ if (name.equals("com/android/tools/layoutlib/create/dataclass/JavaClass")) {
+ mInjectedClassFound = true;
+ }
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
+ assertTrue(testType(Type.getType(desc)));
+ return super.visitField(access, name, desc, signature, value);
+ }
+
+ @SuppressWarnings("hiding")
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
+ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+ return new MethodVisitor(Opcodes.ASM4, mv) {
+
+ @Override
+ public void visitFieldInsn(int opcode, String owner, String name,
+ String desc) {
+ assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
+ assertTrue(testType(Type.getType(desc)));
+ super.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ @Override
+ public void visitLdcInsn(Object cst) {
+ if (cst instanceof Type) {
+ assertTrue(testType((Type)cst));
+ }
+ super.visitLdcInsn(cst);
+ }
+
+ @Override
+ public void visitTypeInsn(int opcode, String type) {
+ assertTrue(!getBase(type).equals(JAVA_CLASS_NAME));
+ super.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name,
+ String desc) {
+ assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
+ assertTrue(testType(Type.getType(desc)));
+ super.visitMethodInsn(opcode, owner, name, desc);
+ }
+
+ };
+ }
+
+ private boolean testType(Type type) {
+ int sort = type.getSort();
+ if (sort == Type.OBJECT) {
+ assertTrue(!getBase(type.getInternalName()).equals(JAVA_CLASS_NAME));
+ } else if (sort == Type.ARRAY) {
+ assertTrue(!getBase(type.getElementType().getInternalName())
+ .equals(JAVA_CLASS_NAME));
+ } else if (sort == Type.METHOD) {
+ boolean r = true;
+ for (Type t : type.getArgumentTypes()) {
+ r &= testType(t);
+ }
+ return r & testType(type.getReturnType());
+ }
+ return true;
+ }
+
+ private String getBase(String className) {
+ if (className == null) {
+ return null;
+ }
+ int pos = className.indexOf('$');
+ if (pos > 0) {
+ return className.substring(0, pos);
+ }
+ return className;
+ }
}
}
diff -ru layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
--- layoutlib_4-0-3-r1/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java 2014-03-13 18:27:34.000000000 -0700
+++ layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java 2014-03-13 18:28:01.000000000 -0700
@@ -24,7 +24,7 @@
import org.junit.Test;
/**
- *
+ *
*/
public class RenameClassAdapterTest {
@@ -36,10 +36,10 @@
mOuter = new RenameClassAdapter(null, // cv
"com.pack.Old",
"org.blah.New");
-
+
mInner = new RenameClassAdapter(null, // cv
"com.pack.Old$Inner",
- "org.blah.New$Inner");
+ "org.blah.New$Inner");
}
@After
@@ -72,7 +72,7 @@
// arrays
assertEquals("[Lorg.blah.New;", mOuter.renameTypeDesc("[Lcom.pack.Old;"));
assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;"));
-
+
assertEquals("[Lorg.blah.New;", mInner.renameTypeDesc("[Lcom.pack.Old;"));
assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;"));
}
@@ -93,10 +93,6 @@
*/
@Test
public void testRenameInternalType() {
- // a descriptor is not left untouched
- assertEquals("Lorg.blah.New;", mOuter.renameInternalType("Lcom.pack.Old;"));
- assertEquals("Lorg.blah.New$Inner;", mOuter.renameInternalType("Lcom.pack.Old$Inner;"));
-
// an actual FQCN
assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old"));
assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner"));
@@ -115,6 +111,6 @@
mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;"));
}
-
+
}
Only in layoutlib_4-4-2-r1/create/tests/com/android/tools/layoutlib/create/dataclass: JavaClass.java
Binary files layoutlib_4-0-3-r1/create/tests/data/mock_android.jar and layoutlib_4-4-2-r1/create/tests/data/mock_android.jar differ
Only in layoutlib_4-0-3-r1/create/tests/data: mock_android.jardesc
Only in layoutlib_4-0-3-r1/create/tests: mock_android
Only in layoutlib_4-4-2-r1/create/tests: mock_data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment