summaryrefslogtreecommitdiffstats
path: root/tools/layoutlib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/layoutlib')
-rw-r--r--tools/layoutlib/bridge/.classpath4
-rw-r--r--tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java50
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java5
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/BridgeResources.java6
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java25
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java37
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java4
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java64
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java6
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java6
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java183
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java38
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java29
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java7
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java1
-rw-r--r--tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java (renamed from tools/layoutlib/bridge/src/android/os/Build_Delegate.java)23
-rw-r--r--tools/layoutlib/bridge/src/android/view/BridgeInflater.java5
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java43
-rw-r--r--tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java22
-rw-r--r--tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilderAccessor.java12
-rw-r--r--tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java17
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java16
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java9
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java9
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java10
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java7
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java64
-rw-r--r--tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java6
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java16
-rw-r--r--tools/layoutlib/create/.classpath2
-rw-r--r--tools/layoutlib/create/README.txt266
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java11
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java3
-rw-r--r--tools/layoutlib/rename_font/README9
-rw-r--r--tools/layoutlib/rename_font/Roboto-Regular.ttfbin0 -> 114976 bytes
-rwxr-xr-xtools/layoutlib/rename_font/build_font.py121
-rwxr-xr-xtools/layoutlib/rename_font/test.py44
43 files changed, 678 insertions, 510 deletions
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 2e4274d..aef3efa 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
+ <classpathentry kind="src" path="tests/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <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/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
<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/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="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
index 224eac6..4603b63 100644
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
@@ -48,6 +48,20 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
}
@LayoutlibDelegate
+ /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName,
+ int numParams) {
+ // TODO: return the right thing.
+ return 0;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName,
+ int numParams) {
+ // TODO: return the right thing.
+ return 0;
+ }
+
+ @LayoutlibDelegate
/*package*/ static void nCallIntMethod(Object target, long methodID, int arg) {
// do nothing
}
@@ -56,4 +70,40 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
/*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) {
// do nothing
}
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1,
+ int arg2) {
+ // do nothing
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1,
+ int arg2, int arg3, int arg4) {
+ // do nothing
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallMultipleIntMethod(Object target, long methodID,
+ int[] args) {
+ // do nothing
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1,
+ float arg2) {
+ // do nothing
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1,
+ float arg2, float arg3, float arg4) {
+ // do nothing
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID,
+ float[] args) {
+ // do nothing
+ }
}
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
index 5c2b793..914a359 100644
--- a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
@@ -40,9 +40,6 @@ public class AssetManager_Delegate {
@LayoutlibDelegate
/*package*/ static void applyThemeStyle(long theme, int styleRes, boolean force) {
- Resources_Theme_Delegate delegate = Resources_Theme_Delegate.getDelegateManager()
- .getDelegate(theme);
- delegate.mThemeResId = styleRes;
- delegate.force = force;
+ Resources_Theme_Delegate.getDelegateManager().getDelegate(theme).force = force;
}
}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 8794452..dd573be 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -51,6 +51,7 @@ public final class BridgeResources extends Resources {
private BridgeContext mContext;
private IProjectCallback mProjectCallback;
private boolean[] mPlatformResourceFlag = new boolean[1];
+ private TypedValue mTmpValue = new TypedValue();
/**
* Simpler wrapper around FileInputStream. This is used when the input stream represent
@@ -154,6 +155,11 @@ public final class BridgeResources extends Resources {
@Override
public Drawable getDrawable(int id) throws NotFoundException {
+ return getDrawable(id, null);
+ }
+
+ @Override
+ public Drawable getDrawable(int id, Theme theme) {
Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 446d139..cc621c4 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -52,13 +52,13 @@ public final class BridgeTypedArray extends TypedArray {
private final BridgeContext mContext;
private final boolean mPlatformFile;
- private ResourceValue[] mResourceData;
- private String[] mNames;
- private boolean[] mIsFramework;
+ private final ResourceValue[] mResourceData;
+ private final String[] mNames;
+ private final boolean[] mIsFramework;
public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
boolean platformFile) {
- super(null, null, null, 0);
+ super(resources, null, null, 0);
mBridgeResources = resources;
mContext = context;
mPlatformFile = platformFile;
@@ -81,8 +81,8 @@ public final class BridgeTypedArray extends TypedArray {
}
/**
- * Seals the array after all calls to {@link #bridgeSetValue(int, String, ResourceValue)} have
- * been done.
+ * Seals the array after all calls to
+ * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done.
* <p/>This allows to compute the list of non default values, permitting
* {@link #getIndexCount()} to return the proper value.
*/
@@ -252,7 +252,7 @@ public final class BridgeTypedArray extends TypedArray {
for (String keyword : keywords) {
Integer i = map.get(keyword.trim());
if (i != null) {
- result |= i.intValue();
+ result |= i;
} else {
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
String.format(
@@ -731,7 +731,7 @@ public final class BridgeTypedArray extends TypedArray {
}
// not a direct id valid reference? resolve it
- Integer idValue = null;
+ Integer idValue;
if (resValue.isFramework()) {
idValue = Bridge.getResourceId(resValue.getResourceType(),
@@ -742,7 +742,7 @@ public final class BridgeTypedArray extends TypedArray {
}
if (idValue != null) {
- return idValue.intValue();
+ return idValue;
}
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
@@ -753,6 +753,12 @@ public final class BridgeTypedArray extends TypedArray {
return defValue;
}
+ @Override
+ public int getThemeAttributeId(int index, int defValue) {
+ // TODO: Get the right Theme Attribute ID to enable caching of the drawables.
+ return defValue;
+ }
+
/**
* Retrieve the Drawable for the attribute at <var>index</var>. This
* gets the resource ID of the selected attribute, and uses
@@ -854,6 +860,7 @@ public final class BridgeTypedArray extends TypedArray {
*/
@Override
public boolean hasValue(int index) {
+ //noinspection SimplifiableIfStatement
if (index < 0 || index >= mResourceData.length) {
return false;
}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
new file mode 100644
index 0000000..112250d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import java.util.Locale;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Resources}
+ *
+ * Through the layoutlib_create tool, the original methods of Resources have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Resources_Delegate {
+
+ @LayoutlibDelegate
+ /*package*/ static String localeToLanguageTag(Resources res, Locale locale) {
+ return ULocale.forLocale(locale).toLanguageTag();
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
index b89d15f..31d1594 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
@@ -39,8 +39,6 @@ import android.util.TypedValue;
*/
public class Resources_Theme_Delegate {
- // Resource identifier for the theme.
- int mThemeResId;
// Whether to use the Theme.mThemeResId as primary theme.
boolean force;
@@ -103,7 +101,7 @@ public class Resources_Theme_Delegate {
private static boolean setupResources(Theme thisTheme) {
Resources_Theme_Delegate themeDelegate = sManager.getDelegate(thisTheme.getNativeTheme());
- StyleResourceValue style = resolveStyle(themeDelegate.mThemeResId);
+ StyleResourceValue style = resolveStyle(thisTheme.getAppliedStyleResId());
if (style != null) {
RenderSessionImpl.getCurrentContext().getRenderResources()
.applyStyle(style, themeDelegate.force);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 73d274c..56c0de9 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -71,7 +71,7 @@ public final class Canvas_Delegate {
* Returns the native delegate associated to a given {@link Canvas} object.
*/
public static Canvas_Delegate getDelegate(Canvas canvas) {
- return sManager.getDelegate(canvas.mNativeCanvas);
+ return sManager.getDelegate(canvas.getNativeCanvas());
}
/**
@@ -102,7 +102,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static boolean isOpaque(Canvas thisCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return false;
}
@@ -113,7 +113,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static int getWidth(Canvas thisCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return 0;
}
@@ -124,7 +124,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static int getHeight(Canvas thisCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return 0;
}
@@ -135,7 +135,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void translate(Canvas thisCanvas, float dx, float dy) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -146,7 +146,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void rotate(Canvas thisCanvas, float degrees) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -157,7 +157,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void scale(Canvas thisCanvas, float sx, float sy) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -168,7 +168,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void skew(Canvas thisCanvas, float kx, float ky) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -204,7 +204,7 @@ public final class Canvas_Delegate {
/*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
float bottom) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return false;
}
@@ -227,7 +227,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static int save(Canvas thisCanvas, int saveFlags) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return 0;
}
@@ -238,7 +238,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void restore(Canvas thisCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -249,7 +249,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static int getSaveCount(Canvas thisCanvas) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return 0;
}
@@ -260,7 +260,7 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void restoreToCount(Canvas thisCanvas, int saveCount) {
// get the delegate from the native int.
- Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+ Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.getNativeCanvas());
if (canvasDelegate == null) {
return;
}
@@ -287,7 +287,7 @@ public final class Canvas_Delegate {
/*package*/ static void drawLines(Canvas thisCanvas,
final float[] pts, final int offset, final int count,
Paint paint) {
- draw(thisCanvas.mNativeCanvas, paint.mNativePaint, false /*compositeOnly*/,
+ draw(thisCanvas.getNativeCanvas(), paint.mNativePaint, false /*compositeOnly*/,
false /*forceSrcMode*/, new GcSnapshot.Drawable() {
@Override
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
@@ -344,7 +344,7 @@ public final class Canvas_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_saveLayer(long nativeCanvas, RectF bounds,
+ /*package*/ static int native_saveLayer(long nativeCanvas, RectF bounds,
long paint, int layerFlags) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -361,7 +361,7 @@ public final class Canvas_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_saveLayer(long nativeCanvas, float l,
+ /*package*/ static int native_saveLayer(long nativeCanvas, float l,
float t, float r, float b,
long paint, int layerFlags) {
// get the delegate from the native int.
@@ -380,7 +380,7 @@ public final class Canvas_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_saveLayerAlpha(long nativeCanvas,
+ /*package*/ static int native_saveLayerAlpha(long nativeCanvas,
RectF bounds, int alpha,
int layerFlags) {
// get the delegate from the native int.
@@ -393,7 +393,7 @@ public final class Canvas_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_saveLayerAlpha(long nativeCanvas, float l,
+ /*package*/ static int native_saveLayerAlpha(long nativeCanvas, float l,
float t, float r, float b,
int alpha, int layerFlags) {
// get the delegate from the native int.
@@ -757,7 +757,8 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void native_drawRoundRect(long nativeCanvas,
- final RectF rect, final float rx, final float ry, long paint) {
+ final float left, final float top, final float right, final float bottom,
+ final float rx, final float ry, long paint) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
@@ -769,16 +770,16 @@ public final class Canvas_Delegate {
if (style == Paint.Style.FILL.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
graphics.fillRoundRect(
- (int)rect.left, (int)rect.top,
- (int)rect.width(), (int)rect.height(),
+ (int)left, (int)top,
+ (int)(right - left), (int)(bottom - top),
(int)rx, (int)ry);
}
if (style == Paint.Style.STROKE.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
graphics.drawRoundRect(
- (int)rect.left, (int)rect.top,
- (int)rect.width(), (int)rect.height(),
+ (int)left, (int)top,
+ (int)(right - left), (int)(bottom - top),
(int)rx, (int)ry);
}
}
@@ -975,8 +976,10 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void native_drawText(long nativeCanvas,
final char[] text, final int index, final int count,
- final float startX, final float startY, final int flags, long paint) {
+ final float startX, final float startY, final int flags, long paint,
+ long typeface) {
+ // TODO: use typeface.
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
@Override
@@ -1006,30 +1009,31 @@ public final class Canvas_Delegate {
@LayoutlibDelegate
/*package*/ static void native_drawText(long nativeCanvas, String text,
- int start, int end, float x, float y, final int flags, long paint) {
+ int start, int end, float x, float y, final int flags, long paint,
+ long typeface) {
int count = end - start;
char[] buffer = TemporaryBuffer.obtain(count);
TextUtils.getChars(text, start, end, buffer, 0);
- native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
+ native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
}
@LayoutlibDelegate
/*package*/ static void native_drawTextRun(long nativeCanvas, String text,
int start, int end, int contextStart, int contextEnd,
- float x, float y, int flags, long paint) {
+ float x, float y, int flags, long paint, long typeface) {
int count = end - start;
char[] buffer = TemporaryBuffer.obtain(count);
TextUtils.getChars(text, start, end, buffer, 0);
- native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
+ native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
}
@LayoutlibDelegate
/*package*/ static void native_drawTextRun(long nativeCanvas, char[] text,
int start, int count, int contextStart, int contextCount,
- float x, float y, int flags, long paint) {
- native_drawText(nativeCanvas, text, start, count, x, y, flags, paint);
+ float x, float y, int flags, long paint, long typeface) {
+ native_drawText(nativeCanvas, text, start, count, x, y, flags, paint, typeface);
}
@LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
index d6b3da1..bf03a5e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
@@ -56,7 +56,7 @@ public abstract class ColorFilter_Delegate {
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static void finalizer(long native_instance, long nativeColorFilter) {
+ /*package*/ static void destroyFilter(long native_instance) {
sManager.removeJavaReferenceFor(native_instance);
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
index ca8f450..9aac2bd 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
@@ -60,11 +60,5 @@ public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
return sManager.addNewDelegate(newDelegate);
}
- @LayoutlibDelegate
- /*package*/ static long nColorMatrixFilter(long nativeFilter, float[] array) {
- // pass
- return 0;
- }
-
// ---- Private delegate/helper methods ----
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
index defaac3..501d55c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
@@ -60,11 +60,5 @@ public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
return sManager.addNewDelegate(newDelegate);
}
- @LayoutlibDelegate
- /*package*/ static int nCreateLightingFilter(long nativeFilter, int mul, int add) {
- // pass
- return 0;
- }
-
// ---- Private delegate/helper methods ----
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index ebfe9bc..8862f5b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -355,227 +355,162 @@ public final class Matrix_Delegate {
}
@LayoutlibDelegate
- /*package*/ static boolean native_setConcat(long native_object, long a, long b) {
+ /*package*/ static void native_setConcat(long native_object, long a, long b) {
if (a == native_object) {
- return native_preConcat(native_object, b);
+ native_preConcat(native_object, b);
+ return;
} else if (b == native_object) {
- return native_postConcat(native_object, a);
+ native_postConcat(native_object, a);
+ return;
}
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
- }
-
Matrix_Delegate a_mtx = sManager.getDelegate(a);
- if (a_mtx == null) {
- return false;
- }
-
Matrix_Delegate b_mtx = sManager.getDelegate(b);
- if (b_mtx == null) {
- return false;
+ if (d != null && a_mtx != null && b_mtx != null) {
+ multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
}
-
- multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
-
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preTranslate(long native_object, float dx, float dy) {
+ /*package*/ static void native_preTranslate(long native_object, float dx, float dy) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getTranslate(dx, dy));
}
-
- d.preTransform(getTranslate(dx, dy));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preScale(long native_object, float sx, float sy,
+ /*package*/ static void native_preScale(long native_object, float sx, float sy,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getScale(sx, sy, px, py));
}
-
- d.preTransform(getScale(sx, sy, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preScale(long native_object, float sx, float sy) {
+ /*package*/ static void native_preScale(long native_object, float sx, float sy) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getScale(sx, sy));
}
-
- d.preTransform(getScale(sx, sy));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preRotate(long native_object, float degrees,
+ /*package*/ static void native_preRotate(long native_object, float degrees,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getRotate(degrees, px, py));
}
-
- d.preTransform(getRotate(degrees, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preRotate(long native_object, float degrees) {
+ /*package*/ static void native_preRotate(long native_object, float degrees) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
- }
+ if (d != null) {
- double rad = Math.toRadians(degrees);
- float sin = (float)Math.sin(rad);
- float cos = (float)Math.cos(rad);
+ double rad = Math.toRadians(degrees);
+ float sin = (float) Math.sin(rad);
+ float cos = (float) Math.cos(rad);
- d.preTransform(getRotate(sin, cos));
- return true;
+ d.preTransform(getRotate(sin, cos));
+ }
}
@LayoutlibDelegate
- /*package*/ static boolean native_preSkew(long native_object, float kx, float ky,
+ /*package*/ static void native_preSkew(long native_object, float kx, float ky,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getSkew(kx, ky, px, py));
}
-
- d.preTransform(getSkew(kx, ky, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preSkew(long native_object, float kx, float ky) {
+ /*package*/ static void native_preSkew(long native_object, float kx, float ky) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.preTransform(getSkew(kx, ky));
}
-
- d.preTransform(getSkew(kx, ky));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_preConcat(long native_object, long other_matrix) {
+ /*package*/ static void native_preConcat(long native_object, long other_matrix) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
- }
-
Matrix_Delegate other = sManager.getDelegate(other_matrix);
- if (other == null) {
- return false;
+ if (d != null && other != null) {
+ d.preTransform(other.mValues);
}
-
- d.preTransform(other.mValues);
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postTranslate(long native_object, float dx, float dy) {
+ /*package*/ static void native_postTranslate(long native_object, float dx, float dy) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getTranslate(dx, dy));
}
-
- d.postTransform(getTranslate(dx, dy));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postScale(long native_object, float sx, float sy,
+ /*package*/ static void native_postScale(long native_object, float sx, float sy,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getScale(sx, sy, px, py));
}
-
- d.postTransform(getScale(sx, sy, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postScale(long native_object, float sx, float sy) {
+ /*package*/ static void native_postScale(long native_object, float sx, float sy) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getScale(sx, sy));
}
-
- d.postTransform(getScale(sx, sy));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postRotate(long native_object, float degrees,
+ /*package*/ static void native_postRotate(long native_object, float degrees,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getRotate(degrees, px, py));
}
-
- d.postTransform(getRotate(degrees, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postRotate(long native_object, float degrees) {
+ /*package*/ static void native_postRotate(long native_object, float degrees) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getRotate(degrees));
}
-
- d.postTransform(getRotate(degrees));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postSkew(long native_object, float kx, float ky,
+ /*package*/ static void native_postSkew(long native_object, float kx, float ky,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getSkew(kx, ky, px, py));
}
-
- d.postTransform(getSkew(kx, ky, px, py));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postSkew(long native_object, float kx, float ky) {
+ /*package*/ static void native_postSkew(long native_object, float kx, float ky) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
+ if (d != null) {
+ d.postTransform(getSkew(kx, ky));
}
-
- d.postTransform(getSkew(kx, ky));
- return true;
}
@LayoutlibDelegate
- /*package*/ static boolean native_postConcat(long native_object, long other_matrix) {
+ /*package*/ static void native_postConcat(long native_object, long other_matrix) {
Matrix_Delegate d = sManager.getDelegate(native_object);
- if (d == null) {
- return false;
- }
-
Matrix_Delegate other = sManager.getDelegate(other_matrix);
- if (other == null) {
- return false;
+ if (d != null && other != null) {
+ d.postTransform(other.mValues);
}
-
- d.postTransform(other.mValues);
- return true;
}
@LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 7007b71..83df745 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -420,7 +420,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static void nSetShadowLayer(Paint thisPaint, float radius, float dx, float dy,
+ /*package*/ static void native_setShadowLayer(long paint, float radius, float dx, float dy,
int color) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -428,6 +428,24 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
+ /*package*/ static boolean native_hasShadowLayer(long paint) {
+ // FIXME
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Paint.hasShadowLayer is not supported.", null, null /*data*/);
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void setElegantTextHeight(Paint thisPaint, boolean elegant) {
+ // TODO
+ }
+
+ @LayoutlibDelegate
/*package*/ static float getTextSize(Paint thisPaint) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
@@ -688,7 +706,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getStyle(long native_object) {
+ /*package*/ static int native_getStyle(long native_object) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
@@ -710,7 +728,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getStrokeCap(long native_object) {
+ /*package*/ static int native_getStrokeCap(long native_object) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
@@ -732,7 +750,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getStrokeJoin(long native_object) {
+ /*package*/ static int native_getStrokeJoin(long native_object) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
@@ -889,7 +907,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getTextAlign(long native_object) {
+ /*package*/ static int native_getTextAlign(long native_object) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
if (delegate == null) {
@@ -922,7 +940,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getTextWidths(long native_object, char[] text, int index,
+ /*package*/ static int native_getTextWidths(long native_object, char[] text, int index,
int count, int bidiFlags, float[] widths) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(native_object);
@@ -964,14 +982,14 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getTextWidths(long native_object, String text, int start,
+ /*package*/ static int native_getTextWidths(long native_object, String text, int start,
int end, int bidiFlags, float[] widths) {
return native_getTextWidths(native_object, text.toCharArray(), start, end - start,
bidiFlags, widths);
}
@LayoutlibDelegate
- /* package */static long native_getTextGlyphs(long native_object, String text, int start,
+ /* package */static int native_getTextGlyphs(long native_object, String text, int start,
int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
// FIXME
return 0;
@@ -1012,7 +1030,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
+ /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -1021,7 +1039,7 @@ public class Paint_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, String text,
+ /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text,
int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 6f6ef20..0ec7115 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -142,7 +142,14 @@ public final class Path_Delegate {
}
@LayoutlibDelegate
- /*package*/ static long native_getFillType(long nPath) {
+ /*package*/ static boolean native_isConvex(long nPath) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Path.isConvex is not supported.", null, null);
+ return true;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static int native_getFillType(long nPath) {
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return 0;
@@ -311,16 +318,6 @@ public final class Path_Delegate {
}
@LayoutlibDelegate
- /*package*/ static void native_addRect(long nPath, RectF rect, int dir) {
- Path_Delegate pathDelegate = sManager.getDelegate(nPath);
- if (pathDelegate == null) {
- return;
- }
-
- pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
- }
-
- @LayoutlibDelegate
/*package*/ static void native_addRect(long nPath,
float left, float top, float right, float bottom, int dir) {
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
@@ -332,14 +329,15 @@ public final class Path_Delegate {
}
@LayoutlibDelegate
- /*package*/ static void native_addOval(long nPath, RectF oval, int dir) {
+ /*package*/ static void native_addOval(long nPath, float left, float top, float right,
+ float bottom, int dir) {
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mPath.append(new Ellipse2D.Float(
- oval.left, oval.top, oval.width(), oval.height()), false);
+ left, top, right - left, bottom - top), false);
}
@LayoutlibDelegate
@@ -484,6 +482,11 @@ public final class Path_Delegate {
sManager.removeJavaReferenceFor(nPath);
}
+ @LayoutlibDelegate
+ /*package*/ static float[] native_approximate(long nPath, float error) {
+ Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null);
+ return new float[0];
+ }
// ---- Private helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
index 6049919..1bc3033 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
@@ -60,12 +60,5 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
return sManager.addNewDelegate(newDelegate);
}
- @LayoutlibDelegate
- /*package*/ static long nCreatePorterDuffFilter(long nativeFilter, int srcColor,
- int porterDuffMode) {
- // pass
- return 0;
- }
-
// ---- Private delegate/helper methods ----
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
index d2aae92..edb7025 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
@@ -289,7 +289,6 @@ public class Region_Delegate {
dstRegion.mArea.reset();
dstRegion.mArea.add(srcRegion.mArea);
- return;
}
@LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/os/Build_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
index ff82a5e..1e7564e 100644
--- a/tools/layoutlib/bridge/src/android/os/Build_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,26 +23,29 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import java.util.Map;
/**
- * Delegate implementing the native methods of android.os.Build
+ * Delegate implementing the native methods of android.os.SystemProperties
*
- * Through the layoutlib_create tool, the original native methods of Build have been replaced
- * by calls to methods of the same name in this delegate class.
+ * Through the layoutlib_create tool, the original native methods of SystemProperties have been
+ * replaced by calls to methods of the same name in this delegate class.
*
* Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
* around to map int to instance of the delegate.
- *
*/
-public class Build_Delegate {
+public class SystemProperties_Delegate {
@LayoutlibDelegate
- /*package*/ static String getString(String property) {
+ /*package*/ static String native_get(String key) {
+ return native_get(key, "");
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static String native_get(String key, String def) {
Map<String, String> properties = Bridge.getPlatformProperties();
- String value = properties.get(property);
+ String value = properties.get(key);
if (value != null) {
return value;
}
- return Build.UNKNOWN;
+ return def;
}
-
}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index a2e93a7..af22f44 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -121,10 +121,11 @@ public final class BridgeInflater extends LayoutInflater {
}
@Override
- public View createViewFromTag(View parent, String name, AttributeSet attrs) {
+ public View createViewFromTag(View parent, String name, AttributeSet attrs,
+ boolean inheritContext) {
View view = null;
try {
- view = super.createViewFromTag(parent, name, attrs);
+ view = super.createViewFromTag(parent, name, attrs, inheritContext);
} catch (InflateException e) {
// try to load the class from using the custom view loader
try {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index dd2cbc1..757cdd2 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -23,22 +23,13 @@ import com.android.internal.view.IInputMethodClient;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
-import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.IApplicationToken;
-import android.view.IInputFilter;
-import android.view.IOnKeyguardExitResult;
-import android.view.IRotationWatcher;
-import android.view.IWindowManager;
-import android.view.IWindowSession;
-import java.util.List;
+import java.lang.Override;
/**
* Basic implementation of {@link IWindowManager} so that {@link Display} (and
@@ -458,44 +449,26 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public IBinder getFocusedWindowToken() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void setInputFilter(IInputFilter filter) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void getWindowFrame(IBinder token, Rect outFrame) {
+ public boolean isRotationFrozen() throws RemoteException {
// TODO Auto-generated method stub
+ return false;
}
@Override
- public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
+ public void enableScreenIfNeeded() throws RemoteException {
// TODO Auto-generated method stub
}
@Override
- public void setMagnificationSpec(MagnificationSpec spec) {
+ public boolean clearWindowContentFrameStats(IBinder token) throws RemoteException {
// TODO Auto-generated method stub
+ return false;
}
@Override
- public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
+ public WindowContentFrameStats getWindowContentFrameStats(IBinder token)
+ throws RemoteException {
// TODO Auto-generated method stub
return null;
}
-
- @Override
- public boolean isRotationFrozen() throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void setTouchExplorationEnabled(boolean enabled) {
- }
}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 3db3a1b..7a73fae 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -48,9 +48,9 @@ public class LayoutInflater_Delegate {
* This implementation just records the merge status before calling the default implementation.
*/
@LayoutlibDelegate
- /*package*/ static void rInflate(LayoutInflater thisInflater,
- XmlPullParser parser, View parent, final AttributeSet attrs,
- boolean finishInflate) throws XmlPullParserException, IOException {
+ /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
+ View parent, final AttributeSet attrs, boolean finishInflate, boolean inheritContext)
+ throws XmlPullParserException, IOException {
if (finishInflate == false) {
// this is a merge rInflate!
@@ -61,7 +61,7 @@ public class LayoutInflater_Delegate {
// ---- START DEFAULT IMPLEMENTATION.
- thisInflater.rInflate_Original(parser, parent, attrs, finishInflate);
+ thisInflater.rInflate_Original(parser, parent, attrs, finishInflate, inheritContext);
// ---- END DEFAULT IMPLEMENTATION.
@@ -74,10 +74,8 @@ public class LayoutInflater_Delegate {
}
@LayoutlibDelegate
- public static void parseInclude(
- LayoutInflater thisInflater,
- XmlPullParser parser, View parent, AttributeSet attrs)
- throws XmlPullParserException, IOException {
+ public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser, View parent,
+ AttributeSet attrs, boolean inheritContext) throws XmlPullParserException, IOException {
int type;
@@ -113,9 +111,11 @@ public class LayoutInflater_Delegate {
if (TAG_MERGE.equals(childName)) {
// Inflate all children.
- thisInflater.rInflate(childParser, parent, childAttrs, false);
+ thisInflater.rInflate(childParser, parent, childAttrs, false,
+ inheritContext);
} else {
- final View view = thisInflater.createViewFromTag(parent, childName, childAttrs);
+ final View view = thisInflater.createViewFromTag(parent, childName,
+ childAttrs, inheritContext);
final ViewGroup group = (ViewGroup) parent;
// We try to load the layout params set in the <include /> tag. If
@@ -151,7 +151,7 @@ public class LayoutInflater_Delegate {
}
// Inflate all children.
- thisInflater.rInflate(childParser, view, childAttrs, true);
+ thisInflater.rInflate(childParser, view, childAttrs, true, true);
// Attempt to override the included layout's android:id with the
// one set on the <include /> tag itself.
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
index e34ad38..0dddf3d 100644
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
@@ -23,7 +23,6 @@ import com.android.internal.view.menu.BridgeMenuItemImpl;
import com.android.internal.view.menu.MenuView;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.util.AttributeSet;
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilderAccessor.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilderAccessor.java
deleted file mode 100644
index f0798cb..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilderAccessor.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.android.internal.view.menu;
-
-import java.util.ArrayList;
-
-/**
- * To access non public members of {@link MenuBuilder}
- */
-public class MenuBuilderAccessor {
- public static ArrayList<MenuItemImpl> getNonActionItems(MenuBuilder builder) {
- return builder.getNonActionItems();
- }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java b/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
index 47a3679..40b6220 100644
--- a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
+++ b/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
@@ -16,7 +16,7 @@
package com.android.internal.widget;
-import com.android.internal.view.menu.ActionMenuPresenter;
+import android.widget.ActionMenuPresenter;
/**
* To access non public members of AbsActionBarView
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 01740b1..89288bf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -135,6 +135,7 @@ public final class BridgeContentProvider implements IContentProvider {
return null;
}
+
@Override
public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 6595ce1..d31239b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -58,6 +58,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -101,6 +102,7 @@ public final class BridgeContext extends Context {
private final ApplicationInfo mApplicationInfo;
private final IProjectCallback mProjectCallback;
private final WindowManager mWindowManager;
+ private final DisplayManager mDisplayManager;
private Resources.Theme mTheme;
@@ -149,6 +151,7 @@ public final class BridgeContext extends Context {
}
mWindowManager = new WindowManagerImpl(mMetrics);
+ mDisplayManager = new DisplayManager(this);
}
/**
@@ -455,6 +458,10 @@ public final class BridgeContext extends Context {
return new PowerManager(this, new BridgePowerManager(), new Handler());
}
+ if (DISPLAY_SERVICE.equals(service)) {
+ return mDisplayManager;
+ }
+
throw new UnsupportedOperationException("Unsupported Service: " + service);
}
@@ -560,7 +567,7 @@ public final class BridgeContext extends Context {
StyleResourceValue customStyleValues = null;
if (customStyle != null) {
ResourceValue item = mRenderResources.findResValue(customStyle,
- false /*forceFrameworkOnly*/);
+ isPlatformFile /*forceFrameworkOnly*/);
// resolve it in case it links to something else
item = mRenderResources.resolveResValue(item);
@@ -1277,6 +1284,14 @@ public final class BridgeContext extends Context {
}
@Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+ Handler scheduler,
+ int initialCode, String initialData, Bundle initialExtras) {
+ // pass
+ }
+
+ @Override
public void sendStickyBroadcast(Intent arg0) {
// pass
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index 3cf5ed5..0bb7fc2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -209,6 +209,17 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
}
@Override
+ public int getInputMethodWindowVisibleHeight() throws RemoteException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void notifyTextCommitted() throws RemoteException {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
// TODO Auto-generated method stub
@@ -227,4 +238,9 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public void setCursorAnchorMonitorMode(IBinder arg0, int arg1) {
+ // TODO Auto-generated method stub
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 95221fb..00c0f93 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -39,7 +39,7 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
- public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3)
+ public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
throws RemoteException {
// pass for now.
}
@@ -51,6 +51,11 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
+ public void powerHint(int hintId, int data) {
+ // pass for now.
+ }
+
+ @Override
public void crash(String arg0) throws RemoteException {
// pass for now.
}
@@ -111,7 +116,7 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
- public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1) throws RemoteException {
+ public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1, String arg2) throws RemoteException {
// pass for now.
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index 0e39a57..936ab4f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -25,11 +25,9 @@ import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SystemViewCookie;
import com.android.internal.R;
-import com.android.internal.app.ActionBarImpl;
+import com.android.internal.app.WindowDecorActionBar;
import com.android.internal.util.Predicate;
-import com.android.internal.view.menu.ActionMenuView;
import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuBuilderAccessor;
import com.android.internal.view.menu.MenuItemImpl;
import com.android.internal.widget.ActionBarAccessor;
import com.android.internal.widget.ActionBarContainer;
@@ -52,6 +50,7 @@ import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ActionMenuView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
@@ -101,7 +100,7 @@ public class ActionBarLayout extends LinearLayout {
// Inflate action bar layout.
LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this,
true /*attachToRoot*/);
- mActionBar = new ActionBarImpl(this);
+ mActionBar = new WindowDecorActionBar(this);
// Set contexts.
mBridgeContext = context;
@@ -323,7 +322,7 @@ public class ActionBarLayout extends LinearLayout {
return false;
}
// Copied from android.widget.ActionMenuPresenter.updateMenuView()
- ArrayList<MenuItemImpl> menus = MenuBuilderAccessor.getNonActionItems(mMenuBuilder);
+ ArrayList<MenuItemImpl> menus = mMenuBuilder.getNonActionItems();
if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() &&
menus != null) {
final int count = menus.size();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index bcd08eb4..86797e5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -87,7 +87,7 @@ abstract class CustomBar extends LinearLayout {
}
}
- private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction,
+ private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction,
String[] pathOut, boolean tryOtherDensities) {
// current density
Density density = densityInOut[0];
@@ -111,10 +111,10 @@ abstract class CustomBar extends LinearLayout {
return stream;
}
}
- }
- // couldn't find resource with direction qualifier. try without.
- if (direction != null) {
- return getIcon(iconName, densityInOut, null, pathOut, true);
+ // couldn't find resource with direction qualifier. try without.
+ if (direction != null) {
+ return getIcon(iconName, densityInOut, null, pathOut, true);
+ }
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index 84e676e..112c267 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -17,7 +17,6 @@
package com.android.layoutlib.bridge.bars;
import com.android.resources.Density;
-import com.android.layoutlib.bridge.Bridge;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
index 79e231c..778305d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
@@ -17,7 +17,6 @@
package com.android.layoutlib.bridge.bars;
import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuBuilderAccessor;
import com.android.internal.view.menu.MenuItemImpl;
import com.android.internal.view.menu.MenuView;
@@ -47,7 +46,7 @@ public class OverflowMenuAdapter extends BaseAdapter {
@Override
public int getCount() {
- ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
+ ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
if (mExpandedIndex < 0) {
return items.size();
}
@@ -56,7 +55,7 @@ public class OverflowMenuAdapter extends BaseAdapter {
@Override
public MenuItemImpl getItem(int position) {
- ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
+ ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
position++;
}
@@ -86,7 +85,7 @@ public class OverflowMenuAdapter extends BaseAdapter {
private void findExpandedIndex() {
final MenuItemImpl expandedItem = mMenu.getExpandedItem();
if (expandedItem != null) {
- final ArrayList<MenuItemImpl> items = MenuBuilderAccessor.getNonActionItems(mMenu);
+ final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
final int count = items.size();
for (int i = 0; i < count; i++) {
final MenuItemImpl item = items.get(i);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 3692d96..1498044 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -33,7 +33,6 @@ public class StatusBar extends CustomBar {
public StatusBar(Context context, Density density, int direction, boolean RtlEnabled)
throws XmlPullParserException {
// FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-
super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
// FIXME: use FILL_H?
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
index 53e1640..a2a8aa9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
@@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import android.util.SparseArray;
@@ -59,10 +60,8 @@ public class SparseWeakArray<E> {
* number of mappings.
*/
public SparseWeakArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
- mKeys = new long[initialCapacity];
- mValues = new WeakReference[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
+ mValues = new WeakReference[mKeys.length];
mSize = 0;
}
@@ -142,18 +141,6 @@ public class SparseWeakArray<E> {
mGarbage = false;
mSize = o;
-
- int newSize = ArrayUtils.idealLongArraySize(mSize);
- if (newSize < mKeys.length) {
- long[] nkeys = new long[newSize];
- WeakReference<?>[] nvalues = new WeakReference[newSize];
-
- System.arraycopy(mKeys, 0, nkeys, 0, newSize);
- System.arraycopy(mValues, 0, nvalues, 0, newSize);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
}
/**
@@ -182,28 +169,8 @@ public class SparseWeakArray<E> {
i = ~binarySearch(mKeys, 0, mSize, key);
}
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(mSize + 1);
-
- long[] nkeys = new long[n];
- WeakReference<?>[] nvalues = new WeakReference[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = new WeakReference(value);
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value));
mSize++;
}
}
@@ -321,24 +288,9 @@ public class SparseWeakArray<E> {
gc();
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(pos + 1);
-
- long[] nkeys = new long[n];
- WeakReference<?>[] nvalues = new WeakReference[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = new WeakReference(value);
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value));
+ mSize++;
}
private boolean hasReclaimedRefs() {
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index 0f66fd7..19d249b 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -18,6 +18,7 @@ package libcore.icu;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.ibm.icu.text.DateTimePatternGenerator;
+import com.ibm.icu.util.Currency;
import com.ibm.icu.util.ULocale;
import java.util.Locale;
@@ -117,6 +118,11 @@ public class ICU_Delegate {
}
@LayoutlibDelegate
+ /*package*/ static int getCurrencyNumericCode(String currencyCode) {
+ return Currency.getInstance(currencyCode).getNumericCode();
+ }
+
+ @LayoutlibDelegate
/*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
return "";
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
index 7c0bc84..274516c 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
@@ -121,14 +121,6 @@ public class TestDelegates extends TestCase {
Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
parameters);
- // check that the method has the annotation
- assertNotNull(
- String.format(
- "Delegate method %1$s for class %2$s does not have the @LayoutlibDelegate annotation",
- delegateMethod.getName(),
- originalClass.getName()),
- delegateMethod.getAnnotation(LayoutlibDelegate.class));
-
// check the return type of the methods match.
assertTrue(
String.format("Delegate method %1$s.%2$s does not match the corresponding " +
@@ -138,6 +130,14 @@ public class TestDelegates extends TestCase {
originalMethod.getReturnType().getName()),
delegateMethod.getReturnType() == originalMethod.getReturnType());
+ // check that the method has the annotation
+ assertNotNull(
+ String.format(
+ "Delegate method %1$s for class %2$s does not have the @LayoutlibDelegate annotation",
+ delegateMethod.getName(),
+ originalClass.getName()),
+ delegateMethod.getAnnotation(LayoutlibDelegate.class));
+
// check that the method is static
assertTrue(
String.format(
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
index cd8bb0d..25c3b3e 100644
--- a/tools/layoutlib/create/.classpath
+++ b/tools/layoutlib/create/.classpath
@@ -4,6 +4,6 @@
<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/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_PLAT/prebuilts/tools/common/asm-tools/src-4.0.zip"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/asm/asm-4.0.jar" sourcepath="/ANDROID_PLAT_SRC/prebuilts/misc/common/asm/src.zip"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
index ef2b185..6e0a300 100644
--- a/tools/layoutlib/create/README.txt
+++ b/tools/layoutlib/create/README.txt
@@ -4,46 +4,45 @@
- Description -
---------------
-Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor
-to perform layout.
+Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor to perform
+layout.
- Usage -
---------
- ./layoutlib_create path/to/android.jar destination.jar
+ ./layoutlib_create destination.jar path/to/android1.jar path/to/android2.jar
- Design Overview -
-------------------
-Layoutlib_create uses the "android.jar" containing all the Java code used by Android
-as generated by the Android build, right before the classes are converted to a DEX format.
+Layoutlib_create uses a few jars from the framework containing the Java code used by Android as
+generated by the Android build, right before the classes are converted to a DEX format.
-The Android JAR can't be used directly in Eclipse:
-- it contains references to native code (which we want to avoid in Eclipse),
-- some classes need to be overridden, for example all the drawing code that is
- replaced by Java 2D calls in Eclipse.
-- some of the classes that need to be changed are final and/or we need access
- to their private internal state.
+These jars can't be used directly in Eclipse as:
+- they contains references to native code (which we want to avoid in Eclipse),
+- some classes need to be overridden, for example all the drawing code that is replaced by Java 2D
+ calls in Eclipse.
+- some of the classes that need to be changed are final and/or we need access to their private
+ internal state.
Consequently this tool:
- parses the input JAR,
- modifies some of the classes directly using some bytecode manipulation,
- filters some packages and removes those we don't want in the output JAR,
- injects some new classes,
-- generates a modified JAR file that is suitable for the Android plugin
- for Eclipse to perform rendering.
+- generates a modified JAR file that is suitable for the Android plugin for Eclipse to perform
+ rendering.
The ASM library is used to do the bytecode modification using its visitor pattern API.
-The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the
-configuration is done in the main() method and the CreateInfo structure is expected to
-change with the Android platform as new classes are added, changed or removed.
+The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the configuration
+is done in the main() method and the CreateInfo structure is expected to change with the Android
+platform as new classes are added, changed or removed.
-The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the
-platform, that provides all the necessary missing implementation for rendering graphics
-in Eclipse.
+The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the platform, that
+provides all the necessary missing implementation for rendering graphics in Eclipse.
@@ -58,97 +57,96 @@ The tool works in two phases:
- Analyzer
----------
-The goal of the analyzer is to create a graph of all the classes from the input JAR
-with their dependencies and then only keep the ones we want.
+The goal of the analyzer is to create a graph of all the classes from the input JAR with their
+dependencies and then only keep the ones we want.
-To do that, the analyzer is created with a list of base classes to keep -- everything
-that derives from these is kept. Currently the one such class is android.view.View:
-since we want to render layouts, anything that is sort of a view needs to be kept.
+To do that, the analyzer is created with a list of base classes to keep -- everything that derives
+from these is kept. Currently the one such class is android.view.View: since we want to render
+layouts, anything that is sort of a view needs to be kept.
-The analyzer is also given a list of class names to keep in the output.
-This is done using shell-like glob patterns that filter on the fully-qualified
-class names, for example "android.*.R**" ("*" does not matches dots whilst "**" does,
-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 class names to keep in the output. This is done using
+shell-like glob patterns that filter on the fully-qualified class names, for example "android.*.R**"
+("*" does not matches dots whilst "**" does, 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.
+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.
-The analysis then finds all the dependencies of the classes that are to be kept
-using an ASM visitor on the class, the field types, the method types and annotations types.
-Classes that belong to the current JRE are excluded.
+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 whose name match the glob pattern
+are kept. The analysis then finds all the dependencies of the classes that are to be kept using an
+ASM visitor on the class, the field types, the method types and annotations types. Classes that
+belong to the current JRE are excluded.
-The output of the analyzer is a set of ASM ClassReader instances which are then
-fed to the generator.
+The output of the analyzer is a set of ASM ClassReader instances which are then fed to the
+generator.
- Generator
-----------
-The generator is constructed from a CreateInfo struct that acts as a config file
-and lists:
-- the classes to inject in the output JAR -- these classes are directly implemented
- in layoutlib_create and will be used to interface with the renderer in Eclipse.
+The generator is constructed from a CreateInfo struct that acts as a config file and lists:
+- the classes to inject in the output JAR -- these classes are directly implemented in
+ layoutlib_create and will be used to interface with the renderer in Eclipse.
- specific methods to override (see method stubs details below).
- 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.
+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.
-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 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 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.
-All classes are made non-final.
-Interfaces are left as-is.
+The TransformClassAdapter is then used to process the potentially renamed class. All protected or
+private classes are market as public. All classes are made non-final. Interfaces are left as-is.
-If a method has a return type that must be erased, the whole method is skipped.
-Methods are also changed from protected/private to public.
-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.
+If a method has a return type that must be erased, the whole method is skipped. Methods are also
+changed from protected/private to public. 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.
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:
+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.
+
+RenameClassAdapter and RefactorClassAdapter both inherit from AbstractClassAdapter which changes the
+class version (version of the JDK used to compile the class) to 50 (corresponding to Java 6), if the
+class was originally compiled with Java 7 (version 51). This is because we don't currently generate
+the StackMapTable correctly and Java 7 VM enforces that classes with version greater than 51 have
+valid StackMapTable. As a side benefit of this, we can continue to support Java 6 because Java 7 on
+Mac has horrible font rendering support.
+
+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
--------------
-As indicated above, all native and overridden methods are replaced by a stub.
-We don't have the code to replace with in layoutlib_create.
-Instead the StubMethodAdapter replaces the code of the method by a call to
-OverrideMethod.invokeX(). When using the final JAR, the bridge can register
+As indicated above, all native and overridden methods are replaced by a stub. We don't have the
+code to replace with in layoutlib_create. Instead the StubMethodAdapter replaces the code of the
+method by a call to OverrideMethod.invokeX(). When using the final JAR, the bridge can register
listeners from these overridden method calls based on the method signatures.
-The listeners are currently pretty basic: we only pass the signature of the
-method being called, its caller object and a flag indicating whether the
-method was native. We do not currently provide the parameters. The listener
-can however specify the return value of the overridden method.
+The listeners are currently pretty basic: we only pass the signature of the method being called, its
+caller object and a flag indicating whether the method was native. We do not currently provide the
+parameters. The listener can however specify the return value of the overridden method.
This strategy is now obsolete and replaced by the method delegates.
@@ -156,97 +154,89 @@ This strategy is now obsolete and replaced by the method delegates.
- Strategies
------------
-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.
+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 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).
+- 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
-As explained earlier, the creator doesn't have any replacement code for
-methods to override. Instead it removes the original code and replaces it
-by a call to a specific OveriddeMethod.invokeX(). The bridge then registers
-a listener on the method signature and can provide an implementation.
+As explained earlier, the creator doesn't have any replacement code for methods to override. Instead
+it removes the original code and replaces it by a call to a specific OveriddeMethod.invokeX(). The
+bridge then registers a listener on the method signature and can provide an implementation.
-This strategy is now obsolete and replaced by the method delegates.
-See strategy 5 below.
+This strategy is now obsolete and replaced by the method delegates (See strategy 6- Method
+Delegates).
3- Renaming classes
-This simply changes the name of a class in its definition, as well as all its
-references in internal inner classes and methods.
-Calls from other classes are not modified -- they keep referencing the original
-class name. This allows the bridge to literally replace an implementation.
+This simply changes the name of a class in its definition, as well as all its references in internal
+inner classes and methods. Calls from other classes are not modified -- they keep referencing the
+original class name. This allows the bridge to literally replace an implementation.
-An example will make this easier: android.graphics.Paint is the main drawing
-class that we need to replace. To do so, the generator renames Paint to _original_Paint.
-Later the bridge provides its own replacement version of Paint which will be used
-by the rest of the Android stack. The replacement version of Paint can still use
-(either by inheritance or delegation) all the original non-native code of _original_Paint
-if it so desires.
+An example will make this easier: android.graphics.Paint is the main drawing class that we need to
+replace. To do so, the generator renames Paint to _original_Paint. Later the bridge provides its own
+replacement version of Paint which will be used by the rest of the Android stack. The replacement
+version of Paint can still use (either by inheritance or delegation) all the original non-native
+code of _original_Paint if it so desires.
-Some of the Android classes are basically wrappers over native objects and since
-we don't have the native code in Eclipse, we need to provide a full alternate
-implementation. Sub-classing doesn't work as some native methods are static and
-we don't control object creation.
+Some of the Android classes are basically wrappers over native objects and since we don't have the
+native code in Eclipse, we need to provide a full alternate implementation. Sub-classing doesn't
+work as some native methods are static and we don't control object creation.
This won't rename/replace the inner static methods of a given class.
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.
+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
-attributes (e.g. FontMetrics, or the Style enum) and all the original implementation
-is native.
+This is mostly an implementation detail of the bridge: in the Paint class mentioned above, some
+inner static classes are used to pass around attributes (e.g. FontMetrics, or the Style enum) and
+all the original implementation is native.
-In this case we have a strategy that tells the generator that anything returning, for
-example, the inner class Paint$Style in the Paint class should be discarded and the
-bridge will provide its own implementation.
+In this case we have a strategy that tells the generator that anything returning, for example, the
+inner class Paint$Style in the Paint class should be discarded and the bridge will provide its own
+implementation.
6- Method Delegates
-This strategy is used to override method implementations.
-Given a method SomeClass.MethodName(), 1 or 2 methods are generated:
-a- A copy of the original method named SomeClass.MethodName_Original().
- The content is the original method as-is from the reader.
- This step is omitted if the method is native, since it has no Java implementation.
-b- A brand new implementation of SomeClass.MethodName() which calls to a
- non-existing static method named SomeClass_Delegate.MethodName().
- The implementation of this 'delegate' method is done in layoutlib_brigde.
-
-The delegate method is a static method.
-If the original method is non-static, the delegate method receives the original 'this'
-as its first argument. If the original method is an inner non-static method, it also
-receives the inner 'this' as the second argument.
+This strategy is used to override method implementations. Given a method SomeClass.MethodName(), 1
+or 2 methods are generated:
+a- A copy of the original method named SomeClass.MethodName_Original(). The content is the original
+method as-is from the reader. This step is omitted if the method is native, since it has no Java
+implementation.
+b- A brand new implementation of SomeClass.MethodName() which calls to a non-existing static method
+named SomeClass_Delegate.MethodName(). The implementation of this 'delegate' method is done in
+layoutlib_brigde.
+
+The delegate method is a static method. If the original method is non-static, the delegate method
+receives the original 'this' as its first argument. If the original method is an inner non-static
+method, it also receives the inner 'this' as the second argument.
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
index b2caa25..323a791 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
@@ -177,6 +177,17 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
}
}
+ /* Java 7 verifies the StackMapTable of a class if its version number is greater than 50.0.
+ * However, the check is disabled if the class version number is 50.0 or less. Generation
+ * of the StackMapTable requires a rewrite using the tree API of ASM. As a workaround,
+ * we rewrite the version number of the class to be 50.0
+ *
+ * http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6693236
+ */
+ if (version > 50) {
+ version = 50;
+ }
+
super.visit(version, access, name, signature, superName, interfaces);
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 911df7d..bb72a1e 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -125,6 +125,7 @@ public final class CreateInfo implements ICreateInfo {
"android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
"android.content.res.Resources$Theme#obtainStyledAttributes",
"android.content.res.Resources$Theme#resolveAttribute",
+ "android.content.res.Resources#localeToLanguageTag",
"android.content.res.AssetManager#newTheme",
"android.content.res.AssetManager#deleteTheme",
"android.content.res.AssetManager#applyThemeStyle",
@@ -132,7 +133,6 @@ public final class CreateInfo implements ICreateInfo {
"android.graphics.BitmapFactory#finishDecode",
"android.os.Handler#sendMessageAtTime",
"android.os.HandlerThread#run",
- "android.os.Build#getString",
"android.text.format.DateFormat#is24HourFormat",
"android.view.Choreographer#getRefreshRate",
"android.view.Display#updateDisplayInfoLocked",
@@ -147,6 +147,7 @@ public final class CreateInfo implements ICreateInfo {
"com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
+ "android.os.SystemProperties#native_get",
};
/**
diff --git a/tools/layoutlib/rename_font/README b/tools/layoutlib/rename_font/README
new file mode 100644
index 0000000..600b756
--- /dev/null
+++ b/tools/layoutlib/rename_font/README
@@ -0,0 +1,9 @@
+This tool is used to rename the PS name encoded inside the ttf font that we ship
+with the SDK. There is bug in Java that returns incorrect results for
+java.awt.Font#layoutGlyphVector() if two fonts with same name but differnt
+versions are loaded. As a workaround, we rename all the fonts that we ship with
+the SDK by appending the font version to its name.
+
+
+The build_font.py copies all files from input_dir to output_dir while renaming
+the font files (*.ttf) in the process.
diff --git a/tools/layoutlib/rename_font/Roboto-Regular.ttf b/tools/layoutlib/rename_font/Roboto-Regular.ttf
new file mode 100644
index 0000000..7469063
--- /dev/null
+++ b/tools/layoutlib/rename_font/Roboto-Regular.ttf
Binary files differ
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
new file mode 100755
index 0000000..ea3dccc
--- /dev/null
+++ b/tools/layoutlib/rename_font/build_font.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Rename the PS name of all fonts in the input directory and copy them to the
+output directory.
+
+Usage: build_font.py /path/to/input_fonts/ /path/to/output_fonts/
+
+"""
+
+import sys
+# fontTools is available at platform/external/fonttools
+from fontTools import ttx
+import re
+import os
+from lxml import etree
+import shutil
+import glob
+
+def main(argv):
+ if len(argv) != 2:
+ print "Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/"
+ sys.exit(1)
+ if not os.path.isdir(argv[0]):
+ print argv[0] + "is not a valid directory"
+ sys.exit(1)
+ if not os.path.isdir(argv[1]):
+ print argv[1] + "is not a valid directory"
+ sys.exit(1)
+ cwd = os.getcwd()
+ os.chdir(argv[1])
+ files = glob.glob('*')
+ for filename in files:
+ os.remove(filename)
+ os.chdir(cwd)
+ for filename in os.listdir(argv[0]):
+ if not os.path.splitext(filename)[1].lower() == ".ttf":
+ shutil.copy(os.path.join(argv[0], filename), argv[1])
+ continue
+ print os.path.join(argv[0], filename)
+ old_ttf_path = os.path.join(argv[0], filename)
+ # run ttx to generate an xml file in the output folder which represents all
+ # its info
+ ttx_args = ["-d", argv[1], old_ttf_path]
+ ttx.main(ttx_args)
+ # the path to the output file. The file name is the fontfilename.ttx
+ ttx_path = os.path.join(argv[1], filename)
+ ttx_path = ttx_path[:-1] + "x"
+ # now parse the xml file to change its PS name.
+ tree = etree.parse(ttx_path)
+ encoding = tree.docinfo.encoding
+ root = tree.getroot()
+ for name in root.iter('name'):
+ [old_ps_name, version] = get_font_info(name)
+ new_ps_name = old_ps_name + version
+ update_name(name, new_ps_name)
+ tree.write(ttx_path, xml_declaration=True, encoding=encoding )
+ # generate the udpated font now.
+ ttx_args = ["-d", argv[1], ttx_path]
+ ttx.main(ttx_args)
+ # delete the temp ttx file.
+ os.remove(ttx_path)
+
+def get_font_info(tag):
+ ps_name = None
+ ps_version = None
+ for namerecord in tag.iter('namerecord'):
+ if 'nameID' in namerecord.attrib:
+ # if the tag has nameID=6, it is the postscript name of the font.
+ # see: http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
+ if namerecord.attrib['nameID'] == '6':
+ if ps_name is not None:
+ if not sanitize(namerecord.text) == ps_name:
+ sys.exit('found multiple possibilities of the font name')
+ else:
+ ps_name = sanitize(namerecord.text)
+ # nameID=5 means the font version
+ if namerecord.attrib['nameID'] == '5':
+ if ps_version is not None:
+ if not ps_version == get_version(namerecord.text):
+ sys.exit('found multiple possibilities of the font version')
+ else:
+ ps_version = get_version(namerecord.text)
+ if ps_name is not None and ps_version is not None:
+ return [ps_name, ps_version]
+ sys.exit('didn\'t find the font name or version')
+
+
+def update_name(tag, name):
+ for namerecord in tag.iter('namerecord'):
+ if 'nameID' in namerecord.attrib:
+ if namerecord.attrib['nameID'] == '6':
+ namerecord.text = name
+
+def sanitize(string):
+ return re.sub(r'[^\w-]+', '', string)
+
+def get_version(string):
+ # The string must begin with "Version n.nn "
+ # to extract n.nn, we return the second entry in the split strings.
+ string = string.strip()
+ if not string.startswith("Version "):
+ sys.exit('mal-formed font version')
+ return sanitize(string.split()[1])
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
new file mode 100755
index 0000000..d4c86cb
--- /dev/null
+++ b/tools/layoutlib/rename_font/test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+"""Tests build_font.py by renaming a font.
+
+The test copies Roboto-Regular.ttf to a tmp directory and ask build_font.py to rename it and put in another dir.
+We then use ttx to dump the new font to its xml and check if rename was successful
+
+To test locally, use:
+PYTHONPATH="$PYTHONPATH:/path/to/android/checkout/external/fonttools/Lib" ./test.py
+"""
+
+import unittest
+import build_font
+
+from fontTools import ttx
+import os
+from lxml import etree
+import shutil
+import tempfile
+
+class MyTest(unittest.TestCase):
+ def test(self):
+ font_name = "Roboto-Regular.ttf"
+ srcdir = tempfile.mkdtemp()
+ print "srcdir: " + srcdir
+ shutil.copy(font_name, srcdir)
+ destdir = tempfile.mkdtemp()
+ print "destdir: " + destdir
+ self.assertTrue(build_font.main([srcdir, destdir]) is None)
+ out_path = os.path.join(destdir, font_name)
+ ttx.main([out_path])
+ ttx_path = out_path[:-1] + "x"
+ tree = etree.parse(ttx_path)
+ root = tree.getroot()
+ name_tag = root.find('name')
+ [f_name, f_version] = build_font.get_font_info(name_tag)
+ shutil.rmtree(srcdir)
+ shutil.rmtree(destdir)
+ self.assertEqual(f_name, "Roboto-Regular1200310")
+
+
+
+if __name__ == '__main__':
+ unittest.main()