summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2010-11-11 12:25:01 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-11-11 12:25:01 -0800
commitf917f9accf924447b3afb27d09382851003c190f (patch)
treeef1e135d130e03fc2f54a11693da204d5c991ef3 /tools
parent9232f2e5a97383f266b615841cc8560b11919cb0 (diff)
parentc2e9651bf386a1f7bf7fc706cf5424950570470c (diff)
downloadframeworks_base-f917f9accf924447b3afb27d09382851003c190f.zip
frameworks_base-f917f9accf924447b3afb27d09382851003c190f.tar.gz
frameworks_base-f917f9accf924447b3afb27d09382851003c190f.tar.bz2
Merge "Layoutlib: New bridge implementation using the new API 5."
Diffstat (limited to 'tools')
-rw-r--r--tools/layoutlib/bridge/.classpath6
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java4
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/view/SurfaceView.java2
-rw-r--r--tools/layoutlib/bridge/src/android/webkit/WebView.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java1032
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java80
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java126
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java)8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java)97
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java (renamed from tools/layoutlib/bridge/src/android/view/BridgeInflater.java)8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java)22
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java)7
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java92
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java163
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java)4
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java)4
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java)2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java689
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java)8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java (renamed from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java)26
-rw-r--r--tools/layoutlib/bridge/src/com/google/android/maps/MapView.java2
-rw-r--r--tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java (renamed from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java)4
40 files changed, 1326 insertions, 1098 deletions
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index aeeffa6..7204ace 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -4,9 +4,9 @@
<classpathentry kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/>
- <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_SRC/development/tools/ninepatch/src"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_PLAT_SRC/development/tools/ninepatch/src"/>
<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="output" path="bin"/>
</classpath>
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index e97b1e6..392462f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -17,7 +17,7 @@
package android.graphics;
import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Bitmap.Config;
import android.os.Parcel;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index ce8e960..374bbb4 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -17,7 +17,7 @@
package android.graphics;
import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Paint_Delegate.FontInfo;
import android.text.TextUtils;
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
index 59b6a91..7ee72d8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.graphics.DashPathEffect
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index 405e537..7573dc1 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Shader.TileMode;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index 0966f39..77de32d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -17,7 +17,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Matrix.ScaleToFit;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 6e90bdd..d83a33b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.FontMetricsInt;
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
index 6827ae7..ce7eef0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.graphics.PathEffect
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
index c242e80..a5885ea 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.graphics.PorterDuffXfermode
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index c4e764c..c36ce53 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Shader.TileMode;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 4dcf144..646ac80 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.graphics.Shader
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 0492e4f..358c3c7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import java.awt.Paint;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 7e90e7d..0b54a0e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -16,8 +16,8 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
-import com.android.layoutlib.bridge.FontLoader;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
import android.content.res.AssetManager;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
index d4408cf..0c1170d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
@@ -16,7 +16,7 @@
package android.graphics;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.graphics.Xfermode
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
index ed24e16..9ca1338 100644
--- a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
@@ -16,7 +16,7 @@
package android.util;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
/**
* Delegate implementing the native methods of android.util.FloatMath
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
index ce32da9..f7db98a 100644
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
@@ -16,7 +16,7 @@
package android.view;
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
index 3b66188..a20a9d1 100644
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ b/tools/layoutlib/bridge/src/android/webkit/WebView.java
@@ -16,7 +16,7 @@
package android.webkit;
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
import android.content.Context;
import android.graphics.Bitmap;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 996a942..d2092d1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,63 +16,26 @@
package com.android.layoutlib.bridge;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.ILayoutBridge;
import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.ILayoutResult;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
-import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
-import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo;
+import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.SceneParams;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.bridge.android.BridgeAssetManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
+import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
import com.android.ninepatch.NinePatch;
import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;
-import android.app.Fragment_Delegate;
-import android.content.ClipData;
-import android.content.res.Configuration;
import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Canvas_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.Typeface_Delegate;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.DragEvent;
-import android.view.IWindow;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.AttachInfo;
-import android.view.View.MeasureSpec;
-import android.view.WindowManager.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
-import java.awt.image.BufferedImage;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -81,10 +44,7 @@ import java.util.Map;
* <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
* {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
*/
-public final class Bridge implements ILayoutBridge {
-
- private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
- private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+public final class Bridge extends LayoutBridge {
public static class StaticMethodNotImplementedException extends RuntimeException {
private static final long serialVersionUID = 1L;
@@ -143,34 +103,28 @@ public final class Bridge implements ILayoutBridge {
}
};
- /**
- * Logger defined during a compute layout operation.
- * <p/>
- * This logger is generally set to {@link #sDefaultLogger} except during rendering
- * operations when it might be set to a specific provided logger.
- * <p/>
- * To change this value, use a block synchronized on {@link #sDefaultLogger}.
- */
- private static ILayoutLog sLogger = sDefaultLogger;
-
- /*
- * (non-Javadoc)
- * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
- */
+ @Override
public int getApiLevel() {
- return API_CURRENT;
+ return LayoutBridge.API_CURRENT;
}
/*
* (non-Javadoc)
* @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
*/
- public boolean init(
- String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+ @Override
+ public boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+ BridgeAssetManager.initSystem();
return sinit(fontOsLocation, enumValueMap);
}
+ @Override
+ public boolean dispose() {
+ BridgeAssetManager.clearSystem();
+ return true;
+ }
+
private static synchronized boolean sinit(String fontOsLocation,
Map<String, Map<String, Integer>> enumValueMap) {
@@ -189,12 +143,8 @@ public final class Bridge implements ILayoutBridge {
OverrideMethod.setDefaultListener(new MethodAdapter() {
@Override
public void onInvokeV(String signature, boolean isNative, Object caller) {
- if (sLogger != null) {
- synchronized (sDefaultLogger) {
- sLogger.error("Missing Stub: " + signature +
- (isNative ? " (native)" : ""));
- }
- }
+ sDefaultLogger.error("Missing Stub: " + signature +
+ (isNative ? " (native)" : ""));
if (debug.equalsIgnoreCase("throw")) {
// Throwing this exception doesn't seem that useful. It breaks
@@ -278,236 +228,82 @@ public final class Bridge implements ILayoutBridge {
return true;
}
- /*
- * For compatilibty purposes, we implement the old deprecated version of computeLayout.
- * (non-Javadoc)
- * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+ /**
+ * Sets a 9 patch in a project cache or in the framework cache.
+ * @param value the path of the 9 patch
+ * @param ninePatch the 9 patch object
+ * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
- @Deprecated
- public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
- Object projectKey,
- int screenWidth, int screenHeight, String themeName,
- Map<String, Map<String, IResourceValue>> projectResources,
- Map<String, Map<String, IResourceValue>> frameworkResources,
- IProjectCallback customViewLoader, ILayoutLog logger) {
- boolean isProjectTheme = false;
- if (themeName.charAt(0) == '*') {
- themeName = themeName.substring(1);
- isProjectTheme = true;
- }
-
- return computeLayout(layoutDescription, projectKey,
- screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
- DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
- themeName, isProjectTheme,
- projectResources, frameworkResources, customViewLoader, logger);
- }
+ public static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
+ if (projectKey != null) {
+ Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
- /*
- * For compatilibty purposes, we implement the old deprecated version of computeLayout.
- * (non-Javadoc)
- * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
- */
- @Deprecated
- public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
- int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
- Map<String, Map<String, IResourceValue>> projectResources,
- Map<String, Map<String, IResourceValue>> frameworkResources,
- IProjectCallback customViewLoader, ILayoutLog logger) {
- return computeLayout(layoutDescription, projectKey,
- screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
- DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
- themeName, isProjectTheme,
- projectResources, frameworkResources, customViewLoader, logger);
- }
+ if (map == null) {
+ map = new HashMap<String, SoftReference<NinePatch>>();
+ sProject9PatchCache.put(projectKey, map);
+ }
- /*
- * For compatilibty purposes, we implement the old deprecated version of computeLayout.
- * (non-Javadoc)
- * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
- */
- public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
- int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
- String themeName, boolean isProjectTheme,
- Map<String, Map<String, IResourceValue>> projectResources,
- Map<String, Map<String, IResourceValue>> frameworkResources,
- IProjectCallback customViewLoader, ILayoutLog logger) {
- return computeLayout(layoutDescription, projectKey,
- screenWidth, screenHeight, false /* renderFullSize */,
- density, xdpi, ydpi, themeName, isProjectTheme,
- projectResources, frameworkResources, customViewLoader, logger);
+ map.put(value, new SoftReference<NinePatch>(ninePatch));
+ } else {
+ sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
+ }
}
- /*
- * (non-Javadoc)
- * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+ /**
+ * Starts a layout session by inflating and rendering it. The method returns a
+ * {@link ILayoutScene} on which further actions can be taken.
+ *
+ * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the
+ * layout file.
+ * @param projectKey An Object identifying the project. This is used for the cache mechanism.
+ * @param screenWidth the screen width
+ * @param screenHeight the screen height
+ * @param renderFullSize if true, the rendering will render the full size needed by the
+ * layout. This size is never smaller than <var>screenWidth</var> x <var>screenHeight</var>.
+ * @param density the density factor for the screen.
+ * @param xdpi the screen actual dpi in X
+ * @param ydpi the screen actual dpi in Y
+ * @param themeName The name of the theme to use.
+ * @param isProjectTheme true if the theme is a project theme, false if it is a framework theme.
+ * @param projectResources the resources of the project. The map contains (String, map) pairs
+ * where the string is the type of the resource reference used in the layout file, and the
+ * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
+ * and the value is the resource value.
+ * @param frameworkResources the framework resources. The map contains (String, map) pairs
+ * where the string is the type of the resource reference used in the layout file, and the map
+ * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
+ * value is the resource value.
+ * @param projectCallback The {@link IProjectCallback} object to get information from
+ * the project.
+ * @param logger the object responsible for displaying warning/errors to the user.
+ * @return a new {@link ILayoutScene} object that contains the result of the layout.
+ * @since 5
*/
- public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
- int screenWidth, int screenHeight, boolean renderFullSize,
- int density, float xdpi, float ydpi,
- String themeName, boolean isProjectTheme,
- Map<String, Map<String, IResourceValue>> projectResources,
- Map<String, Map<String, IResourceValue>> frameworkResources,
- IProjectCallback customViewLoader, ILayoutLog logger) {
- if (logger == null) {
- logger = sDefaultLogger;
- }
-
- synchronized (sDefaultLogger) {
- sLogger = logger;
- }
-
- // find the current theme and compute the style inheritance map
- Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
- new HashMap<IStyleResourceValue, IStyleResourceValue>();
-
- IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme,
- projectResources.get(BridgeConstants.RES_STYLE),
- frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap);
-
- BridgeContext context = null;
+ @Override
+ public BridgeLayoutScene createScene(SceneParams params) {
try {
- // we need to make sure the Looper has been initialized for this thread.
- // this is required for View that creates Handler objects.
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
-
- // setup the display Metrics.
- DisplayMetrics metrics = new DisplayMetrics();
- metrics.densityDpi = density;
- metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT;
- metrics.scaledDensity = metrics.density;
- metrics.widthPixels = screenWidth;
- metrics.heightPixels = screenHeight;
- metrics.xdpi = xdpi;
- metrics.ydpi = ydpi;
-
- context = new BridgeContext(projectKey, metrics, currentTheme, projectResources,
- frameworkResources, styleParentMap, customViewLoader, logger);
- BridgeInflater inflater = new BridgeInflater(context, customViewLoader);
- context.setBridgeInflater(inflater);
- inflater.setFactory2(context);
-
- IResourceValue windowBackground = null;
- int screenOffset = 0;
- if (currentTheme != null) {
- windowBackground = context.findItemInStyle(currentTheme, "windowBackground");
- windowBackground = context.resolveResValue(windowBackground);
-
- screenOffset = getScreenOffset(frameworkResources, currentTheme, context);
- }
-
- BridgeXmlBlockParser parser = new BridgeXmlBlockParser(layoutDescription,
- context, false /* platformResourceFlag */);
-
- ViewGroup root = new FrameLayout(context);
-
- // Sets the project callback (custom view loader) to the fragment delegate so that
- // it can instantiate the custom Fragment.
- Fragment_Delegate.setProjectCallback(customViewLoader);
-
- View view = inflater.inflate(parser, root);
-
- // post-inflate process. For now this supports TabHost/TabWidget
- postInflateProcess(view, customViewLoader);
-
- Fragment_Delegate.setProjectCallback(null);
-
- // set the AttachInfo on the root view.
- AttachInfo info = new AttachInfo(new WindowSession(), new Window(),
- new Handler(), null);
- info.mHasWindowFocus = true;
- info.mWindowVisibility = View.VISIBLE;
- info.mInTouchMode = false; // this is so that we can display selections.
- root.dispatchAttachedToWindow(info, 0);
-
- // get the background drawable
- if (windowBackground != null) {
- Drawable d = ResourceHelper.getDrawable(windowBackground,
- context, true /* isFramework */);
- root.setBackgroundDrawable(d);
- }
-
- // measure the views
- int w_spec, h_spec;
-
- if (renderFullSize) {
- // measure the full size needed by the layout.
- w_spec = MeasureSpec.makeMeasureSpec(screenWidth,
- MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
- h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
- MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
- root.measure(w_spec, h_spec);
-
- int neededWidth = root.getChildAt(0).getMeasuredWidth();
- if (neededWidth > screenWidth) {
- screenWidth = neededWidth;
- }
-
- int neededHeight = root.getChildAt(0).getMeasuredHeight();
- if (neededHeight > screenHeight - screenOffset) {
- screenHeight = neededHeight + screenOffset;
+ SceneResult lastResult = SceneResult.SUCCESS;
+ LayoutSceneImpl scene = null;
+ synchronized (this) {
+ try {
+ scene = new LayoutSceneImpl(params);
+
+ scene.prepare();
+ lastResult = scene.inflate();
+ if (lastResult == SceneResult.SUCCESS) {
+ lastResult = scene.render();
+ }
+ } finally {
+ if (scene != null) {
+ scene.cleanup();
+ }
}
}
- // remeasure with only the size we need
- // This must always be done before the call to layout
- w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
- h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
- MeasureSpec.EXACTLY);
- root.measure(w_spec, h_spec);
-
- // now do the layout.
- root.layout(0, screenOffset, screenWidth, screenHeight);
-
- // draw the views
- // create the BufferedImage into which the layout will be rendered.
- BufferedImage image = new BufferedImage(screenWidth, screenHeight - screenOffset,
- BufferedImage.TYPE_INT_ARGB);
-
- // create an Android bitmap around the BufferedImage
- Bitmap bitmap = Bitmap_Delegate.createBitmap(image, Density.getEnum(density));
-
- // create a Canvas around the Android bitmap
- Canvas canvas = new Canvas(bitmap);
-
- // to set the logger, get the native delegate
- Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
- canvasDelegate.setLogger(logger);
-
- root.draw(canvas);
- canvasDelegate.dispose();
-
- return new LayoutResult(
- visit(((ViewGroup)view).getChildAt(0), context),
- image);
-
- } catch (PostInflateException e) {
- return new LayoutResult(ILayoutResult.ERROR, "Error during post inflation process:\n"
- + e.getMessage());
- } catch (Throwable e) {
- // get the real cause of the exception.
- Throwable t = e;
- while (t.getCause() != null) {
- t = t.getCause();
- }
-
- // log it
- logger.error(t);
-
- // then return with an ERROR status and the message from the real exception
- return new LayoutResult(ILayoutResult.ERROR,
- t.getClass().getSimpleName() + ": " + t.getMessage());
- } finally {
- // Make sure to remove static references, otherwise we could not unload the lib
- BridgeResources.clearSystem();
- BridgeAssetManager.clearSystem();
-
- // Remove the global logger
- synchronized (sDefaultLogger) {
- sLogger = sDefaultLogger;
- }
+ return new BridgeLayoutScene(this, scene, lastResult);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return new BridgeLayoutScene(this, null, new SceneResult("error!", t));
}
}
@@ -515,6 +311,7 @@ public final class Bridge implements ILayoutBridge {
* (non-Javadoc)
* @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
*/
+ @Override
public void clearCaches(Object projectKey) {
if (projectKey != null) {
sProjectBitmapCache.remove(projectKey);
@@ -556,367 +353,25 @@ public final class Bridge implements ILayoutBridge {
return null;
}
- static Map<String, Integer> getEnumValues(String attributeName) {
- if (sEnumValueMap != null) {
- return sEnumValueMap.get(attributeName);
- }
-
- return null;
- }
-
- /**
- * Visits a View and its children and generate a {@link ILayoutViewInfo} containing the
- * bounds of all the views.
- * @param view the root View
- * @param context the context.
- */
- private ILayoutViewInfo visit(View view, BridgeContext context) {
- if (view == null) {
- return null;
- }
-
- LayoutViewInfo result = new LayoutViewInfo(view.getClass().getName(),
- context.getViewKey(view),
- view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
-
- if (view instanceof ViewGroup) {
- ViewGroup group = ((ViewGroup) view);
- int n = group.getChildCount();
- ILayoutViewInfo[] children = new ILayoutViewInfo[n];
- for (int i = 0; i < group.getChildCount(); i++) {
- children[i] = visit(group.getChildAt(i), context);
- }
- result.setChildren(children);
- }
-
- return result;
- }
-
- /**
- * Compute style information from the given list of style for the project and framework.
- * @param themeName the name of the current theme. In order to differentiate project and
- * platform themes sharing the same name, all project themes must be prepended with
- * a '*' character.
- * @param isProjectTheme Is this a project theme
- * @param inProjectStyleMap the project style map
- * @param inFrameworkStyleMap the framework style map
- * @param outInheritanceMap the map of style inheritance. This is filled by the method
- * @return the {@link IStyleResourceValue} matching <var>themeName</var>
- */
- private IStyleResourceValue computeStyleMaps(
- String themeName, boolean isProjectTheme, Map<String,
- IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
- Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
-
- if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
- // first, get the theme
- IResourceValue theme = null;
-
- // project theme names have been prepended with a *
- if (isProjectTheme) {
- theme = inProjectStyleMap.get(themeName);
- } else {
- theme = inFrameworkStyleMap.get(themeName);
- }
-
- if (theme instanceof IStyleResourceValue) {
- // compute the inheritance map for both the project and framework styles
- computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
- inFrameworkStyleMap, outInheritanceMap);
-
- // Compute the style inheritance for the framework styles/themes.
- // Since, for those, the style parent values do not contain 'android:'
- // we want to force looking in the framework style only to avoid using
- // similarly named styles from the project.
- // To do this, we pass null in lieu of the project style map.
- computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
- inFrameworkStyleMap, outInheritanceMap);
-
- return (IStyleResourceValue)theme;
- }
- }
-
- return null;
- }
-
- /**
- * Compute the parent style for all the styles in a given list.
- * @param styles the styles for which we compute the parent.
- * @param inProjectStyleMap the map of project styles.
- * @param inFrameworkStyleMap the map of framework styles.
- * @param outInheritanceMap the map of style inheritance. This is filled by the method.
- */
- private void computeStyleInheritance(Collection<IResourceValue> styles,
- Map<String, IResourceValue> inProjectStyleMap,
- Map<String, IResourceValue> inFrameworkStyleMap,
- Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
- for (IResourceValue value : styles) {
- if (value instanceof IStyleResourceValue) {
- IStyleResourceValue style = (IStyleResourceValue)value;
- IStyleResourceValue parentStyle = null;
-
- // first look for a specified parent.
- String parentName = style.getParentStyle();
-
- // no specified parent? try to infer it from the name of the style.
- if (parentName == null) {
- parentName = getParentName(value.getName());
- }
-
- if (parentName != null) {
- parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
-
- if (parentStyle != null) {
- outInheritanceMap.put(style, parentStyle);
- }
- }
- }
- }
- }
-
/**
- * Searches for and returns the {@link IStyleResourceValue} from a given name.
- * <p/>The format of the name can be:
- * <ul>
- * <li>[android:]&lt;name&gt;</li>
- * <li>[android:]style/&lt;name&gt;</li>
- * <li>@[android:]style/&lt;name&gt;</li>
- * </ul>
- * @param parentName the name of the style.
- * @param inProjectStyleMap the project style map. Can be <code>null</code>
- * @param inFrameworkStyleMap the framework style map.
- * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
+ * Returns the list of possible enums for a given attribute name.
*/
- private IStyleResourceValue getStyle(String parentName,
- Map<String, IResourceValue> inProjectStyleMap,
- Map<String, IResourceValue> inFrameworkStyleMap) {
- boolean frameworkOnly = false;
-
- String name = parentName;
-
- // remove the useless @ if it's there
- if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
- name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
- }
-
- // check for framework identifier.
- if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
- frameworkOnly = true;
- name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
- }
-
- // at this point we could have the format <type>/<name>. we want only the name as long as
- // the type is style.
- if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
- name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
- } else if (name.indexOf('/') != -1) {
- return null;
- }
-
- IResourceValue parent = null;
-
- // if allowed, search in the project resources.
- if (frameworkOnly == false && inProjectStyleMap != null) {
- parent = inProjectStyleMap.get(name);
- }
-
- // if not found, then look in the framework resources.
- if (parent == null) {
- parent = inFrameworkStyleMap.get(name);
- }
-
- // make sure the result is the proper class type and return it.
- if (parent instanceof IStyleResourceValue) {
- return (IStyleResourceValue)parent;
- }
-
- sLogger.error(String.format("Unable to resolve parent style name: %s", parentName));
-
- return null;
- }
-
- /**
- * Computes the name of the parent style, or <code>null</code> if the style is a root style.
- */
- private String getParentName(String styleName) {
- int index = styleName.lastIndexOf('.');
- if (index != -1) {
- return styleName.substring(0, index);
+ public static Map<String, Integer> getEnumValues(String attributeName) {
+ if (sEnumValueMap != null) {
+ return sEnumValueMap.get(attributeName);
}
return null;
}
/**
- * Returns the top screen offset. This depends on whether the current theme defines the user
- * of the title and status bars.
- * @param frameworkResources The framework resources
- * @param currentTheme The current theme
- * @param context The context
- * @return the pixel height offset
- */
- private int getScreenOffset(Map<String, Map<String, IResourceValue>> frameworkResources,
- IStyleResourceValue currentTheme, BridgeContext context) {
- int offset = 0;
-
- // get the title bar flag from the current theme.
- IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
-
- // because it may reference something else, we resolve it.
- value = context.resolveResValue(value);
-
- // if there's a value and it's true (default is false)
- if (value == null || value.getValue() == null ||
- XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
- // default size of the window title bar
- int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT;
-
- // get value from the theme.
- value = context.findItemInStyle(currentTheme, "windowTitleSize");
-
- // resolve it
- value = context.resolveResValue(value);
-
- if (value != null) {
- // get the numerical value, if available
- TypedValue typedValue = ResourceHelper.getValue(value.getValue());
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
- }
- }
-
- offset += defaultOffset;
- }
-
- // get the fullscreen flag from the current theme.
- value = context.findItemInStyle(currentTheme, "windowFullscreen");
-
- // because it may reference something else, we resolve it.
- value = context.resolveResValue(value);
-
- if (value == null || value.getValue() == null ||
- XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
-
- // default value
- int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT;
-
- // get the real value, first the list of Dimensions from the framework map
- Map<String, IResourceValue> dimens = frameworkResources.get(BridgeConstants.RES_DIMEN);
-
- // now get the value
- value = dimens.get("status_bar_height");
- if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue(value.getValue());
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
- }
- }
-
- // add the computed offset.
- offset += defaultOffset;
- }
-
- return offset;
- }
-
- /**
- * Post process on a view hierachy that was just inflated.
- * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
- * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
- * based on the content of the {@link FrameLayout}.
- * @param view the root view to process.
- * @param projectCallback callback to the project.
- */
- private void postInflateProcess(View view, IProjectCallback projectCallback)
- throws PostInflateException {
- if (view instanceof TabHost) {
- setupTabHost((TabHost)view, projectCallback);
- } else if (view instanceof ViewGroup) {
- ViewGroup group = (ViewGroup)view;
- final int count = group.getChildCount();
- for (int c = 0 ; c < count ; c++) {
- View child = group.getChildAt(c);
- postInflateProcess(child, projectCallback);
- }
- }
- }
-
- /**
- * Sets up a {@link TabHost} object.
- * @param tabHost the TabHost to setup.
- * @param projectCallback The project callback object to access the project R class.
- * @throws PostInflateException
- */
- private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
- throws PostInflateException {
- // look for the TabWidget, and the FrameLayout. They have their own specific names
- View v = tabHost.findViewById(android.R.id.tabs);
-
- if (v == null) {
- throw new PostInflateException(
- "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
- }
-
- if ((v instanceof TabWidget) == false) {
- throw new PostInflateException(String.format(
- "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
- "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
- }
-
- v = tabHost.findViewById(android.R.id.tabcontent);
-
- if (v == null) {
- // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
- throw new PostInflateException(
- "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
- }
-
- if ((v instanceof FrameLayout) == false) {
- throw new PostInflateException(String.format(
- "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
- "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
- }
-
- FrameLayout content = (FrameLayout)v;
-
- // now process the content of the framelayout and dynamically create tabs for it.
- final int count = content.getChildCount();
-
- if (count == 0) {
- throw new PostInflateException(
- "The FrameLayout for the TabHost has no content. Rendering failed.\n");
- }
-
- // this must be called before addTab() so that the TabHost searches its TabWidget
- // and FrameLayout.
- tabHost.setup();
-
- // for each child of the framelayout, add a new TabSpec
- for (int i = 0 ; i < count ; i++) {
- View child = content.getChildAt(i);
- String tabSpec = String.format("tab_spec%d", i+1);
- int id = child.getId();
- String[] resource = projectCallback.resolveResourceValue(id);
- String name;
- if (resource != null) {
- name = resource[0]; // 0 is resource name, 1 is resource type.
- } else {
- name = String.format("Tab %d", i+1); // default name if id is unresolved.
- }
- tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
- }
- }
-
- /**
* Returns the bitmap for a specific path, from a specific project cache, or from the
* framework cache.
* @param value the path of the bitmap
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached Bitmap or null if not found.
*/
- static Bitmap getCachedBitmap(String value, Object projectKey) {
+ public static Bitmap getCachedBitmap(String value, Object projectKey) {
if (projectKey != null) {
Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
if (map != null) {
@@ -941,7 +396,7 @@ public final class Bridge implements ILayoutBridge {
* @param bmp the Bitmap object
* @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
- static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
+ public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
if (projectKey != null) {
Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
@@ -963,7 +418,7 @@ public final class Bridge implements ILayoutBridge {
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached 9 patch or null if not found.
*/
- static NinePatch getCached9Patch(String value, Object projectKey) {
+ public static NinePatch getCached9Patch(String value, Object projectKey) {
if (projectKey != null) {
Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
@@ -983,262 +438,69 @@ public final class Bridge implements ILayoutBridge {
return null;
}
- /**
- * Sets a 9 patch in a project cache or in the framework cache.
- * @param value the path of the 9 patch
- * @param ninePatch the 9 patch object
- * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
- */
- static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
- if (projectKey != null) {
- Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
- if (map == null) {
- map = new HashMap<String, SoftReference<NinePatch>>();
- sProject9PatchCache.put(projectKey, map);
- }
+ // ---------- OBSOLETE API METHODS ----------
- map.put(value, new SoftReference<NinePatch>(ninePatch));
- } else {
- sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
- }
+ /*
+ * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+ */
+ @Deprecated
+ public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, String themeName,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback customViewLoader, ILayoutLog logger) {
+ throw new UnsupportedOperationException();
}
- private static final class PostInflateException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public PostInflateException(String message) {
- super(message);
- }
+ /*
+ * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+ */
+ @Deprecated
+ public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback customViewLoader, ILayoutLog logger) {
+ throw new UnsupportedOperationException();
}
- /**
- * Implementation of {@link IWindowSession} so that mSession is not null in
- * the {@link SurfaceView}.
+ /*
+ * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
*/
- private static final class WindowSession implements IWindowSession {
-
- @SuppressWarnings("unused")
- public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
- InputChannel outInputchannel)
- throws RemoteException {
- // pass for now.
- return 0;
- }
-
- @SuppressWarnings("unused")
- public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
- throws RemoteException {
- // pass for now.
- return 0;
- }
-
- @SuppressWarnings("unused")
- public void finishDrawing(IWindow arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void finishKey(IWindow arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public boolean getInTouchMode() throws RemoteException {
- // pass for now.
- return false;
- }
-
- @SuppressWarnings("unused")
- public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
- // pass for now.
- return false;
- }
-
- @SuppressWarnings("unused")
- public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
- // pass for now.
- return null;
- }
-
- @SuppressWarnings("unused")
- public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
- // pass for now.
- return null;
- }
-
- @SuppressWarnings("unused")
- public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
- boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
- throws RemoteException {
- // pass for now.
- return 0;
- }
-
- public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void remove(IWindow arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void setInTouchMode(boolean arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void setInsets(IWindow window, int touchable, Rect contentInsets,
- Rect visibleInsets) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public IBinder prepareDrag(IWindow window, boolean localOnly,
- int thumbnailWidth, int thumbnailHeight, Surface outSurface)
- throws RemoteException {
- // pass for now
- return null;
- }
-
- @SuppressWarnings("unused")
- public boolean performDrag(IWindow window, IBinder dragToken,
- float touchX, float touchY, float thumbCenterX, float thumbCenterY,
- ClipData data)
- throws RemoteException {
- // pass for now
- return false;
- }
-
- @SuppressWarnings("unused")
- public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
- // pass for now
- }
-
- @SuppressWarnings("unused")
- public void dragRecipientEntered(IWindow window) throws RemoteException {
- // pass for now
- }
-
- @SuppressWarnings("unused")
- public void dragRecipientExited(IWindow window) throws RemoteException {
- // pass for now
- }
-
- @SuppressWarnings("unused")
- public void setWallpaperPosition(IBinder window, float x, float y,
- float xStep, float yStep) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void wallpaperOffsetsComplete(IBinder window) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
- int z, Bundle extras, boolean sync) {
- // pass for now.
- return null;
- }
-
- @SuppressWarnings("unused")
- public void wallpaperCommandComplete(IBinder window, Bundle result) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void closeSystemDialogs(String reason) {
- // pass for now.
- }
-
- public IBinder asBinder() {
- // pass for now.
- return null;
- }
+ @Deprecated
+ public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
+ String themeName, boolean isProjectTheme,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback customViewLoader, ILayoutLog logger) {
+ throw new UnsupportedOperationException();
}
- /**
- * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+ /*
+ * (non-Javadoc)
+ * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
*/
- private static final class Window implements IWindow {
-
- @SuppressWarnings("unused")
- public void dispatchAppVisibility(boolean arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchGetNewSurface() throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchKey(KeyEvent arg0) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
- throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
- throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
- boolean sync) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchWallpaperCommand(String action, int x, int y,
- int z, Bundle extras, boolean sync) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void closeSystemDialogs(String reason) {
- // pass for now.
- }
-
- @SuppressWarnings("unused")
- public void dispatchDragEvent(DragEvent event) {
- // pass for now.
- }
-
- public IBinder asBinder() {
- // pass for now.
- return null;
- }
+ @Deprecated
+ public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+ Object projectKey,
+ int screenWidth, int screenHeight, boolean renderFullSize,
+ int density, float xdpi, float ydpi,
+ String themeName, boolean isProjectTheme,
+ Map<String, Map<String, IResourceValue>> projectResources,
+ Map<String, Map<String, IResourceValue>> frameworkResources,
+ IProjectCallback customViewLoader, ILayoutLog logger) {
+ throw new UnsupportedOperationException();
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
new file mode 100644
index 0000000..5fcb9ff
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge;
+
+import com.android.layoutlib.api.LayoutScene;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * An implementation of {@link LayoutScene}.
+ *
+ * This is a pretty basic class that does almost nothing. All of the work is done in
+ * {@link LayoutSceneImpl}.
+ *
+ */
+public class BridgeLayoutScene extends LayoutScene {
+
+ private final Bridge mBridge;
+ private final LayoutSceneImpl mScene;
+ private SceneResult mLastResult;
+
+ @Override
+ public SceneResult getResult() {
+ return mLastResult;
+ }
+
+ @Override
+ public BufferedImage getImage() {
+ return mScene.getImage();
+ }
+
+ @Override
+ public ViewInfo getRootView() {
+ return mScene.getViewInfo();
+ }
+
+ @Override
+ public SceneResult render() {
+
+ synchronized (mBridge) {
+ try {
+ mScene.prepare();
+ mLastResult = mScene.render();
+ } finally {
+ mScene.cleanup();
+ }
+ }
+
+ return mLastResult;
+ }
+
+ @Override
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*package*/ BridgeLayoutScene(Bridge bridge, LayoutSceneImpl scene, SceneResult lastResult) {
+ mBridge = bridge;
+ mScene = scene;
+ mLastResult = lastResult;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
deleted file mode 100644
index c4c5225..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.layoutlib.api.ILayoutResult;
-
-import java.awt.image.BufferedImage;
-
-/**
- * Implementation of {@link ILayoutResult}
- */
-public final class LayoutResult implements ILayoutResult {
-
- private final ILayoutViewInfo mRootView;
- private final BufferedImage mImage;
- private final int mSuccess;
- private final String mErrorMessage;
-
- /**
- * Creates a {@link #SUCCESS} {@link ILayoutResult} with the specified params
- * @param rootView
- * @param image
- */
- public LayoutResult(ILayoutViewInfo rootView, BufferedImage image) {
- mSuccess = SUCCESS;
- mErrorMessage = null;
- mRootView = rootView;
- mImage = image;
- }
-
- /**
- * Creates a LayoutResult with a specific success code and associated message
- * @param code
- * @param message
- */
- public LayoutResult(int code, String message) {
- mSuccess = code;
- mErrorMessage = message;
- mRootView = null;
- mImage = null;
- }
-
- public int getSuccess() {
- return mSuccess;
- }
-
- public String getErrorMessage() {
- return mErrorMessage;
- }
-
- public BufferedImage getImage() {
- return mImage;
- }
-
- public ILayoutViewInfo getRootView() {
- return mRootView;
- }
-
- /**
- * Implementation of {@link ILayoutResult.ILayoutViewInfo}
- */
- public static final class LayoutViewInfo implements ILayoutViewInfo {
- private final Object mKey;
- private final String mName;
- private final int mLeft;
- private final int mRight;
- private final int mTop;
- private final int mBottom;
- private ILayoutViewInfo[] mChildren;
-
- public LayoutViewInfo(String name, Object key, int left, int top, int right, int bottom) {
- mName = name;
- mKey = key;
- mLeft = left;
- mRight = right;
- mTop = top;
- mBottom = bottom;
- }
-
- public void setChildren(ILayoutViewInfo[] children) {
- mChildren = children;
- }
-
- public ILayoutViewInfo[] getChildren() {
- return mChildren;
- }
-
- public Object getViewKey() {
- return mKey;
- }
-
- public String getName() {
- return mName;
- }
-
- public int getLeft() {
- return mLeft;
- }
-
- public int getTop() {
- return mTop;
- }
-
- public int getRight() {
- return mRight;
- }
-
- public int getBottom() {
- return mBottom;
- }
- }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
index 71803fc..a825060 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.Bridge;
import android.content.res.AssetManager;
@@ -28,7 +30,7 @@ public class BridgeAssetManager extends AssetManager {
* <p/>
* {@link Bridge} calls this method after setting up a new bridge.
*/
- /*package*/ static AssetManager initSystem() {
+ /*package*/ public static AssetManager initSystem() {
if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
// Note that AssetManager() creates a system AssetManager and we override it
// with our BridgeAssetManager.
@@ -42,7 +44,7 @@ public class BridgeAssetManager extends AssetManager {
* Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
* around that would prevent us from unloading the library.
*/
- /*package*/ static void clearSystem() {
+ public static void clearSystem() {
AssetManager.sSystem = null;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 9d6dd27..3835378 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
index e15cb69..0257686 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import android.content.ContentResolver;
import android.content.Context;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index b9899b2..2fa97a3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -14,12 +14,15 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.layoutlib.api.ILayoutLog;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.TempResourceValue;
import android.app.Activity;
import android.app.Fragment;
@@ -50,7 +53,6 @@ import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.view.BridgeInflater;
import android.view.LayoutInflater;
import android.view.View;
@@ -66,15 +68,16 @@ import java.util.TreeMap;
import java.util.Map.Entry;
/**
- * Custom implementation of Context to handle non compiled resources.
+ * Custom implementation of Context/Activity to handle non compiled resources.
*/
public final class BridgeContext extends Activity {
- private final Resources mResources;
- private final Theme mTheme;
+ private Resources mResources;
+ private Theme mTheme;
private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
private final IStyleResourceValue mThemeValues;
private final Object mProjectKey;
+ private final DisplayMetrics mMetrics;
private final Map<String, Map<String, IResourceValue>> mProjectResources;
private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
@@ -105,28 +108,18 @@ public final class BridgeContext extends Activity {
* contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
* value is the resource value.
* @param styleInheritanceMap
- * @param customViewLoader
+ * @param projectCallback
*/
public BridgeContext(Object projectKey, DisplayMetrics metrics,
IStyleResourceValue currentTheme,
Map<String, Map<String, IResourceValue>> projectResources,
Map<String, Map<String, IResourceValue>> frameworkResources,
Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap,
- IProjectCallback customViewLoader, ILayoutLog logger) {
+ IProjectCallback projectCallback, ILayoutLog logger) {
mProjectKey = projectKey;
- mProjectCallback = customViewLoader;
+ mMetrics = metrics;
+ mProjectCallback = projectCallback;
mLogger = logger;
- Configuration config = new Configuration();
-
- AssetManager assetManager = BridgeAssetManager.initSystem();
- mResources = BridgeResources.initSystem(
- this,
- assetManager,
- metrics,
- config,
- customViewLoader);
-
- mTheme = mResources.newTheme();
mThemeValues = currentTheme;
mProjectResources = projectResources;
@@ -137,6 +130,32 @@ public final class BridgeContext extends Activity {
mFragments.mActivity = this;
}
+ /**
+ * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
+ * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
+ *
+ * @see #disposeResources()
+ */
+ public void initResources() {
+ AssetManager assetManager = AssetManager.getSystem();
+ Configuration config = new Configuration();
+
+ mResources = BridgeResources.initSystem(
+ this,
+ assetManager,
+ mMetrics,
+ config,
+ mProjectCallback);
+ mTheme = mResources.newTheme();
+ }
+
+ /**
+ * Disposes the {@link Resources} singleton.
+ */
+ public void disposeResources() {
+ BridgeResources.disposeSystem();
+ }
+
public void setBridgeInflater(BridgeInflater inflater) {
mInflater = inflater;
}
@@ -266,6 +285,15 @@ public final class BridgeContext extends Activity {
return null;
}
+ Object key = null;
+ if (parser != null) {
+ key = parser.getViewKey();
+ }
+ if (key != null) {
+ String attrs_name = Bridge.resolveResourceValue(attrs);
+ System.out.println("KEY: " + key.toString() + "(" + attrs_name + ")");
+ }
+
boolean[] frameworkAttributes = new boolean[1];
TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
@@ -281,6 +309,9 @@ public final class BridgeContext extends Activity {
customStyle = parser.getAttributeValue(null /* namespace*/, "style");
}
if (customStyle != null) {
+ if (key != null) {
+ print("style", customStyle, false);
+ }
IResourceValue item = findResValue(customStyle, false /*forceFrameworkOnly*/);
if (item instanceof IStyleResourceValue) {
@@ -292,6 +323,10 @@ public final class BridgeContext extends Activity {
// get the name from the int.
String defStyleName = searchAttr(defStyleAttr);
+ if (key != null) {
+ print("style", defStyleName, true);
+ }
+
// look for the style in the current theme, and its parent:
if (mThemeValues != null) {
IResourceValue item = findItemInStyle(mThemeValues, defStyleName);
@@ -350,11 +385,20 @@ public final class BridgeContext extends Activity {
// if we found a value, we make sure this doesn't reference another value.
// So we resolve it.
if (resValue != null) {
+ if (key != null) {
+ print(name, resValue.getValue(), true);
+ }
+
resValue = resolveResValue(resValue);
+ } else if (key != null) {
+ print(name, "<unknown>", true);
}
ta.bridgeSetValue(index, name, resValue);
} else {
+ if (key != null) {
+ print(name, value, false);
+ }
// there is a value in the XML, but we need to resolve it in case it's
// referencing another resource or a theme value.
ta.bridgeSetValue(index, name, resolveValue(null, name, value));
@@ -367,6 +411,15 @@ public final class BridgeContext extends Activity {
return ta;
}
+ private void print(String name, String value, boolean isDefault) {
+ System.out.print("\t" + name + " : " + value);
+ if (isDefault) {
+ System.out.println(" (default)");
+ } else {
+ System.out.println("");
+ }
+ }
+
@Override
public Looper getMainLooper() {
return Looper.myLooper();
@@ -433,7 +486,7 @@ public final class BridgeContext extends Activity {
// if resValue is null, but value is not null, this means it was not a reference.
// we return the name/value wrapper in a IResourceValue
if (resValue == null) {
- return new ResourceValue(type, name, value);
+ return new TempResourceValue(type, name, value);
}
// we resolved a first reference, but we need to make sure this isn't a reference also.
@@ -453,7 +506,7 @@ public final class BridgeContext extends Activity {
* @param value the value containing the reference to resolve.
* @return a {@link IResourceValue} object or <code>null</code>
*/
- IResourceValue resolveResValue(IResourceValue value) {
+ public IResourceValue resolveResValue(IResourceValue value) {
if (value == null) {
return null;
}
@@ -661,7 +714,7 @@ public final class BridgeContext extends Activity {
* @param itemName the name of the item to search for.
* @return the {@link IResourceValue} object or <code>null</code>
*/
- IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
+ public IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
IResourceValue item = style.findItem(itemName);
// if we didn't find it, we look in the parent style (if applicable)
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index 4bc8855..b4a28a6 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -14,20 +14,22 @@
* limitations under the License.
*/
-package android.view;
+package com.android.layoutlib.bridge.android;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.BridgeContext;
-import com.android.layoutlib.bridge.BridgeXmlBlockParser;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import java.io.File;
import java.io.FileReader;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index 6358abb..46eb776 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -14,10 +14,13 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
@@ -64,21 +67,18 @@ public final class BridgeResources extends Resources {
DisplayMetrics metrics,
Configuration config,
IProjectCallback projectCallback) {
- if (!(Resources.mSystem instanceof BridgeResources)) {
- Resources.mSystem = new BridgeResources(context,
- assets,
- metrics,
- config,
- projectCallback);
- }
- return Resources.mSystem;
+ return Resources.mSystem = new BridgeResources(context,
+ assets,
+ metrics,
+ config,
+ projectCallback);
}
/**
- * Clears the static {@link Resources#mSystem} to make sure we don't leave objects
+ * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
* around that would prevent us from unloading the library.
*/
- /*package*/ static void clearSystem() {
+ /*package*/ static void disposeSystem() {
if (Resources.mSystem instanceof BridgeResources) {
((BridgeResources)(Resources.mSystem)).mContext = null;
((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 70c5bd7..c3ab461 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -14,11 +14,14 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
@@ -36,7 +39,7 @@ import java.io.FileReader;
import java.util.Map;
/**
- * TODO: describe.
+ * Custom implementation of TypedArray to handle non compiled resources.
*/
public final class BridgeTypedArray extends TypedArray {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
new file mode 100644
index 0000000..c04c9e8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.view.DragEvent;
+import android.view.IWindow;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View.AttachInfo;
+
+/**
+ * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+ */
+public final class BridgeWindow implements IWindow {
+
+ public void dispatchAppVisibility(boolean arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public void dispatchGetNewSurface() throws RemoteException {
+ // pass for now.
+ }
+
+ public void dispatchKey(KeyEvent arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+ // pass for now.
+ }
+
+ public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+ // pass for now.
+ }
+
+ public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
+ throws RemoteException {
+ // pass for now.
+ }
+
+ public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
+ throws RemoteException {
+ // pass for now.
+ }
+
+ public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
+ // pass for now.
+ }
+
+ public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
+ boolean sync) {
+ // pass for now.
+ }
+
+ public void dispatchWallpaperCommand(String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ // pass for now.
+ }
+
+ public void closeSystemDialogs(String reason) {
+ // pass for now.
+ }
+
+ public void dispatchDragEvent(DragEvent event) {
+ // pass for now.
+ }
+
+ public IBinder asBinder() {
+ // pass for now.
+ return null;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
new file mode 100644
index 0000000..74e5a65
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.ClipData;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.WindowManager.LayoutParams;
+
+/**
+ * Implementation of {@link IWindowSession} so that mSession is not null in
+ * the {@link SurfaceView}.
+ */
+public final class BridgeWindowSession implements IWindowSession {
+
+ public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+ InputChannel outInputchannel)
+ throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+ throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ public void finishDrawing(IWindow arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public void finishKey(IWindow arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public boolean getInTouchMode() throws RemoteException {
+ // pass for now.
+ return false;
+ }
+
+ public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
+ // pass for now.
+ return false;
+ }
+
+ public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
+ // pass for now.
+ return null;
+ }
+
+ public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
+ // pass for now.
+ return null;
+ }
+
+ public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
+ boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
+ throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+ // pass for now.
+ }
+
+ public void remove(IWindow arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public void setInTouchMode(boolean arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
+ // pass for now.
+ }
+
+ public void setInsets(IWindow window, int touchable, Rect contentInsets,
+ Rect visibleInsets) {
+ // pass for now.
+ }
+
+ public IBinder prepareDrag(IWindow window, boolean localOnly,
+ int thumbnailWidth, int thumbnailHeight, Surface outSurface)
+ throws RemoteException {
+ // pass for now
+ return null;
+ }
+
+ public boolean performDrag(IWindow window, IBinder dragToken,
+ float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+ ClipData data)
+ throws RemoteException {
+ // pass for now
+ return false;
+ }
+
+ public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
+ // pass for now
+ }
+
+ public void dragRecipientEntered(IWindow window) throws RemoteException {
+ // pass for now
+ }
+
+ public void dragRecipientExited(IWindow window) throws RemoteException {
+ // pass for now
+ }
+
+ public void setWallpaperPosition(IBinder window, float x, float y,
+ float xStep, float yStep) {
+ // pass for now.
+ }
+
+ public void wallpaperOffsetsComplete(IBinder window) {
+ // pass for now.
+ }
+
+ public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ // pass for now.
+ return null;
+ }
+
+ public void wallpaperCommandComplete(IBinder window, Bundle result) {
+ // pass for now.
+ }
+
+ public void closeSystemDialogs(String reason) {
+ // pass for now.
+ }
+
+ public IBinder asBinder() {
+ // pass for now.
+ return null;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index d842a66..24f61c8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.layoutlib.api.IXmlPullParser;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
index d145ff6..c99b70b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
import org.xmlpull.v1.XmlPullParser;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java
index 1ca3182..e5bddcb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
index 2c92567..4efa631 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
import com.android.ninepatch.NinePatch;
@@ -28,7 +28,7 @@ public class NinePatchDrawable extends Drawable {
private NinePatch m9Patch;
- NinePatchDrawable(NinePatch ninePatch) {
+ public NinePatchDrawable(NinePatch ninePatch) {
m9Patch = ninePatch;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 3d9f960..169d751 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
import android.util.SparseArray;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index de89a81..5d56370 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
new file mode 100644
index 0000000..2012229
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import com.android.internal.util.XmlUtils;
+import com.android.layoutlib.api.IProjectCallback;
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.SceneParams;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeInflater;
+import com.android.layoutlib.bridge.android.BridgeWindow;
+import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+
+import android.app.Fragment_Delegate;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.Canvas_Delegate;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.AttachInfo;
+import android.view.View.MeasureSpec;
+import android.widget.FrameLayout;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class managing a layout "scene".
+ *
+ * A scene is a stateful representation of a layout file. It is initialized with data coming through
+ * the {@link LayoutBridge} API to inflate the layout. Further actions and rendering can then
+ * be done on the layout.
+ *
+ */
+public class LayoutSceneImpl {
+
+ private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
+ private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+
+ private final SceneParams mParams;
+
+ // scene state
+ private BridgeContext mContext;
+ private BridgeXmlBlockParser mBlockParser;
+ private BridgeInflater mInflater;
+ private IStyleResourceValue mCurrentTheme;
+ private int mScreenOffset;
+ private IResourceValue mWindowBackground;
+ private FrameLayout mViewRoot;
+
+ // information being returned through the API
+ private BufferedImage mImage;
+ private ViewInfo mViewInfo;
+
+ private static final class PostInflateException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public PostInflateException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Creates a layout scene with all the information coming from the layout bridge API.
+ *
+ * This also calls {@link LayoutSceneImpl#prepare()}.
+ * <p>
+ * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+ *
+ * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
+ */
+ public LayoutSceneImpl(SceneParams params) {
+ // we need to make sure the Looper has been initialized for this thread.
+ // this is required for View that creates Handler objects.
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ // copy the params.
+ mParams = new SceneParams(params);
+
+ // setup the display Metrics.
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.densityDpi = mParams.getDensity();
+ metrics.density = mParams.getDensity() / (float) DisplayMetrics.DENSITY_DEFAULT;
+ metrics.scaledDensity = metrics.density;
+ metrics.widthPixels = mParams.getScreenWidth();
+ metrics.heightPixels = mParams.getScreenHeight();
+ metrics.xdpi = mParams.getXdpi();
+ metrics.ydpi = mParams.getYdpi();
+
+ // find the current theme and compute the style inheritance map
+ Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
+ new HashMap<IStyleResourceValue, IStyleResourceValue>();
+
+ mCurrentTheme = computeStyleMaps(mParams.getThemeName(), mParams.getIsProjectTheme(),
+ mParams.getProjectResources().get(BridgeConstants.RES_STYLE),
+ mParams.getFrameworkResources().get(BridgeConstants.RES_STYLE), styleParentMap);
+
+ // build the context
+ mContext = new BridgeContext(mParams.getProjectKey(), metrics, mCurrentTheme,
+ mParams.getProjectResources(), mParams.getFrameworkResources(),
+ styleParentMap, mParams.getProjectCallback(), mParams.getLogger());
+
+ // make sure the Resources object references the context (and other objects) for this
+ // scene
+ mContext.initResources();
+
+ // get the screen offset and window-background resource
+ mWindowBackground = null;
+ mScreenOffset = 0;
+ if (mCurrentTheme != null && mParams.isCustomBackgroundEnabled() == false) {
+ mWindowBackground = mContext.findItemInStyle(mCurrentTheme, "windowBackground");
+ mWindowBackground = mContext.resolveResValue(mWindowBackground);
+
+ mScreenOffset = getScreenOffset(mParams.getFrameworkResources(), mCurrentTheme, mContext);
+ }
+
+ // build the inflater and parser.
+ mInflater = new BridgeInflater(mContext, mParams.getProjectCallback());
+ mContext.setBridgeInflater(mInflater);
+ mInflater.setFactory2(mContext);
+
+ mBlockParser = new BridgeXmlBlockParser(mParams.getLayoutDescription(),
+ mContext, false /* platformResourceFlag */);
+ }
+
+ /**
+ * Prepares the scene for action.
+ * <p>
+ * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+ */
+ public void prepare() {
+ // we need to make sure the Looper has been initialized for this thread.
+ // this is required for View that creates Handler objects.
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ // make sure the Resources object references the context (and other objects) for this
+ // scene
+ mContext.initResources();
+ }
+
+ /**
+ * Cleans up the scene after an action.
+ * <p>
+ * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+ */
+ public void cleanup() {
+ // clean up the looper
+ Looper.sThreadLocal.remove();
+
+ // Make sure to remove static references, otherwise we could not unload the lib
+ mContext.disposeResources();
+ }
+
+ /**
+ * Inflates the layout.
+ * <p>
+ * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+ */
+ public SceneResult inflate() {
+ try {
+
+ mViewRoot = new FrameLayout(mContext);
+
+ // Sets the project callback (custom view loader) to the fragment delegate so that
+ // it can instantiate the custom Fragment.
+ Fragment_Delegate.setProjectCallback(mParams.getProjectCallback());
+
+ View view = mInflater.inflate(mBlockParser, mViewRoot);
+
+ // post-inflate process. For now this supports TabHost/TabWidget
+ postInflateProcess(view, mParams.getProjectCallback());
+
+ Fragment_Delegate.setProjectCallback(null);
+
+ // set the AttachInfo on the root view.
+ AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
+ new Handler(), null);
+ info.mHasWindowFocus = true;
+ info.mWindowVisibility = View.VISIBLE;
+ info.mInTouchMode = false; // this is so that we can display selections.
+ mViewRoot.dispatchAttachedToWindow(info, 0);
+
+ // get the background drawable
+ if (mWindowBackground != null) {
+ Drawable d = ResourceHelper.getDrawable(mWindowBackground,
+ mContext, true /* isFramework */);
+ mViewRoot.setBackgroundDrawable(d);
+ }
+
+ return SceneResult.SUCCESS;
+ } catch (PostInflateException e) {
+ return new SceneResult("Error during post inflation process:\n" + e.getMessage());
+ } catch (Throwable e) {
+ // get the real cause of the exception.
+ Throwable t = e;
+ while (t.getCause() != null) {
+ t = t.getCause();
+ }
+
+ // log it
+ mParams.getLogger().error(t);
+
+ return new SceneResult("Unknown error during inflation.", t);
+ }
+ }
+
+ /**
+ * Renders the scene.
+ * <p>
+ * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+ */
+ public SceneResult render() {
+ try {
+ if (mViewRoot == null) {
+ return new SceneResult("Layout has not been inflated!");
+ }
+ // measure the views
+ int w_spec, h_spec;
+
+ int renderScreenWidth = mParams.getScreenWidth();
+ int renderScreenHeight = mParams.getScreenHeight();
+
+ if (mParams.getRenderFullSize()) {
+ // measure the full size needed by the layout.
+ w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth,
+ MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
+ h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset,
+ MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
+ mViewRoot.measure(w_spec, h_spec);
+
+ int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth();
+ if (neededWidth > renderScreenWidth) {
+ renderScreenWidth = neededWidth;
+ }
+
+ int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight();
+ if (neededHeight > renderScreenHeight - mScreenOffset) {
+ renderScreenHeight = neededHeight + mScreenOffset;
+ }
+ }
+
+ // remeasure with the size we need
+ // This must always be done before the call to layout
+ w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, MeasureSpec.EXACTLY);
+ h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset,
+ MeasureSpec.EXACTLY);
+ mViewRoot.measure(w_spec, h_spec);
+
+ // now do the layout.
+ mViewRoot.layout(0, mScreenOffset, renderScreenWidth, renderScreenHeight);
+
+ // draw the views
+ // create the BufferedImage into which the layout will be rendered.
+ mImage = new BufferedImage(renderScreenWidth, renderScreenHeight - mScreenOffset,
+ BufferedImage.TYPE_INT_ARGB);
+
+ if (mParams.isCustomBackgroundEnabled()) {
+ Graphics2D gc = mImage.createGraphics();
+ gc.setColor(new Color(mParams.getCustomBackgroundColor()));
+ gc.fillRect(0, 0, renderScreenWidth, renderScreenHeight - mScreenOffset);
+ gc.dispose();
+ }
+
+ // create an Android bitmap around the BufferedImage
+ Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+ Density.getEnum(mParams.getDensity()));
+
+ // create a Canvas around the Android bitmap
+ Canvas canvas = new Canvas(bitmap);
+
+ // to set the logger, get the native delegate
+ Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
+ canvasDelegate.setLogger(mParams.getLogger());
+
+ mViewRoot.draw(canvas);
+ canvasDelegate.dispose();
+
+ mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext);
+
+ // success!
+ return SceneResult.SUCCESS;
+ } catch (Throwable e) {
+ // get the real cause of the exception.
+ Throwable t = e;
+ while (t.getCause() != null) {
+ t = t.getCause();
+ }
+
+ // log it
+ mParams.getLogger().error(t);
+
+ return new SceneResult("Unknown error during inflation.", t);
+ }
+ }
+
+ /**
+ * Compute style information from the given list of style for the project and framework.
+ * @param themeName the name of the current theme. In order to differentiate project and
+ * platform themes sharing the same name, all project themes must be prepended with
+ * a '*' character.
+ * @param isProjectTheme Is this a project theme
+ * @param inProjectStyleMap the project style map
+ * @param inFrameworkStyleMap the framework style map
+ * @param outInheritanceMap the map of style inheritance. This is filled by the method
+ * @return the {@link IStyleResourceValue} matching <var>themeName</var>
+ */
+ private IStyleResourceValue computeStyleMaps(
+ String themeName, boolean isProjectTheme, Map<String,
+ IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
+ Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
+
+ if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
+ // first, get the theme
+ IResourceValue theme = null;
+
+ // project theme names have been prepended with a *
+ if (isProjectTheme) {
+ theme = inProjectStyleMap.get(themeName);
+ } else {
+ theme = inFrameworkStyleMap.get(themeName);
+ }
+
+ if (theme instanceof IStyleResourceValue) {
+ // compute the inheritance map for both the project and framework styles
+ computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
+ inFrameworkStyleMap, outInheritanceMap);
+
+ // Compute the style inheritance for the framework styles/themes.
+ // Since, for those, the style parent values do not contain 'android:'
+ // we want to force looking in the framework style only to avoid using
+ // similarly named styles from the project.
+ // To do this, we pass null in lieu of the project style map.
+ computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
+ inFrameworkStyleMap, outInheritanceMap);
+
+ return (IStyleResourceValue)theme;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Compute the parent style for all the styles in a given list.
+ * @param styles the styles for which we compute the parent.
+ * @param inProjectStyleMap the map of project styles.
+ * @param inFrameworkStyleMap the map of framework styles.
+ * @param outInheritanceMap the map of style inheritance. This is filled by the method.
+ */
+ private void computeStyleInheritance(Collection<IResourceValue> styles,
+ Map<String, IResourceValue> inProjectStyleMap,
+ Map<String, IResourceValue> inFrameworkStyleMap,
+ Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
+ for (IResourceValue value : styles) {
+ if (value instanceof IStyleResourceValue) {
+ IStyleResourceValue style = (IStyleResourceValue)value;
+ IStyleResourceValue parentStyle = null;
+
+ // first look for a specified parent.
+ String parentName = style.getParentStyle();
+
+ // no specified parent? try to infer it from the name of the style.
+ if (parentName == null) {
+ parentName = getParentName(value.getName());
+ }
+
+ if (parentName != null) {
+ parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
+
+ if (parentStyle != null) {
+ outInheritanceMap.put(style, parentStyle);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Searches for and returns the {@link IStyleResourceValue} from a given name.
+ * <p/>The format of the name can be:
+ * <ul>
+ * <li>[android:]&lt;name&gt;</li>
+ * <li>[android:]style/&lt;name&gt;</li>
+ * <li>@[android:]style/&lt;name&gt;</li>
+ * </ul>
+ * @param parentName the name of the style.
+ * @param inProjectStyleMap the project style map. Can be <code>null</code>
+ * @param inFrameworkStyleMap the framework style map.
+ * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
+ */
+ private IStyleResourceValue getStyle(String parentName,
+ Map<String, IResourceValue> inProjectStyleMap,
+ Map<String, IResourceValue> inFrameworkStyleMap) {
+ boolean frameworkOnly = false;
+
+ String name = parentName;
+
+ // remove the useless @ if it's there
+ if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
+ name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
+ }
+
+ // check for framework identifier.
+ if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
+ frameworkOnly = true;
+ name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
+ }
+
+ // at this point we could have the format <type>/<name>. we want only the name as long as
+ // the type is style.
+ if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
+ name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
+ } else if (name.indexOf('/') != -1) {
+ return null;
+ }
+
+ IResourceValue parent = null;
+
+ // if allowed, search in the project resources.
+ if (frameworkOnly == false && inProjectStyleMap != null) {
+ parent = inProjectStyleMap.get(name);
+ }
+
+ // if not found, then look in the framework resources.
+ if (parent == null) {
+ parent = inFrameworkStyleMap.get(name);
+ }
+
+ // make sure the result is the proper class type and return it.
+ if (parent instanceof IStyleResourceValue) {
+ return (IStyleResourceValue)parent;
+ }
+
+ mParams.getLogger().error(
+ String.format("Unable to resolve parent style name: %s", parentName));
+
+ return null;
+ }
+
+ /**
+ * Computes the name of the parent style, or <code>null</code> if the style is a root style.
+ */
+ private String getParentName(String styleName) {
+ int index = styleName.lastIndexOf('.');
+ if (index != -1) {
+ return styleName.substring(0, index);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the top screen offset. This depends on whether the current theme defines the user
+ * of the title and status bars.
+ * @param frameworkResources The framework resources
+ * @param currentTheme The current theme
+ * @param context The context
+ * @return the pixel height offset
+ */
+ private int getScreenOffset(Map<String, Map<String, IResourceValue>> frameworkResources,
+ IStyleResourceValue currentTheme, BridgeContext context) {
+ int offset = 0;
+
+ // get the title bar flag from the current theme.
+ IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
+
+ // because it may reference something else, we resolve it.
+ value = context.resolveResValue(value);
+
+ // if there's a value and it's true (default is false)
+ if (value == null || value.getValue() == null ||
+ XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
+ // default size of the window title bar
+ int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT;
+
+ // get value from the theme.
+ value = context.findItemInStyle(currentTheme, "windowTitleSize");
+
+ // resolve it
+ value = context.resolveResValue(value);
+
+ if (value != null) {
+ // get the numerical value, if available
+ TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+ if (typedValue != null) {
+ // compute the pixel value based on the display metrics
+ defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
+ }
+ }
+
+ offset += defaultOffset;
+ }
+
+ // get the fullscreen flag from the current theme.
+ value = context.findItemInStyle(currentTheme, "windowFullscreen");
+
+ // because it may reference something else, we resolve it.
+ value = context.resolveResValue(value);
+
+ if (value == null || value.getValue() == null ||
+ XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
+
+ // default value
+ int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT;
+
+ // get the real value, first the list of Dimensions from the framework map
+ Map<String, IResourceValue> dimens = frameworkResources.get(BridgeConstants.RES_DIMEN);
+
+ // now get the value
+ value = dimens.get("status_bar_height");
+ if (value != null) {
+ TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+ if (typedValue != null) {
+ // compute the pixel value based on the display metrics
+ defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
+ }
+ }
+
+ // add the computed offset.
+ offset += defaultOffset;
+ }
+
+ return offset;
+
+ }
+
+ /**
+ * Post process on a view hierachy that was just inflated.
+ * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
+ * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
+ * based on the content of the {@link FrameLayout}.
+ * @param view the root view to process.
+ * @param projectCallback callback to the project.
+ */
+ private void postInflateProcess(View view, IProjectCallback projectCallback)
+ throws PostInflateException {
+ if (view instanceof TabHost) {
+ setupTabHost((TabHost)view, projectCallback);
+ } else if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup)view;
+ final int count = group.getChildCount();
+ for (int c = 0 ; c < count ; c++) {
+ View child = group.getChildAt(c);
+ postInflateProcess(child, projectCallback);
+ }
+ }
+ }
+
+ /**
+ * Sets up a {@link TabHost} object.
+ * @param tabHost the TabHost to setup.
+ * @param projectCallback The project callback object to access the project R class.
+ * @throws PostInflateException
+ */
+ private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
+ throws PostInflateException {
+ // look for the TabWidget, and the FrameLayout. They have their own specific names
+ View v = tabHost.findViewById(android.R.id.tabs);
+
+ if (v == null) {
+ throw new PostInflateException(
+ "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
+ }
+
+ if ((v instanceof TabWidget) == false) {
+ throw new PostInflateException(String.format(
+ "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
+ "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
+ }
+
+ v = tabHost.findViewById(android.R.id.tabcontent);
+
+ if (v == null) {
+ // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
+ throw new PostInflateException(
+ "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
+ }
+
+ if ((v instanceof FrameLayout) == false) {
+ throw new PostInflateException(String.format(
+ "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
+ "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
+ }
+
+ FrameLayout content = (FrameLayout)v;
+
+ // now process the content of the framelayout and dynamically create tabs for it.
+ final int count = content.getChildCount();
+
+ if (count == 0) {
+ throw new PostInflateException(
+ "The FrameLayout for the TabHost has no content. Rendering failed.\n");
+ }
+
+ // this must be called before addTab() so that the TabHost searches its TabWidget
+ // and FrameLayout.
+ tabHost.setup();
+
+ // for each child of the framelayout, add a new TabSpec
+ for (int i = 0 ; i < count ; i++) {
+ View child = content.getChildAt(i);
+ String tabSpec = String.format("tab_spec%d", i+1);
+ int id = child.getId();
+ String[] resource = projectCallback.resolveResourceValue(id);
+ String name;
+ if (resource != null) {
+ name = resource[0]; // 0 is resource name, 1 is resource type.
+ } else {
+ name = String.format("Tab %d", i+1); // default name if id is unresolved.
+ }
+ tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
+ }
+ }
+
+
+ /**
+ * Visits a View and its children and generate a {@link ViewInfo} containing the
+ * bounds of all the views.
+ * @param view the root View
+ * @param context the context.
+ */
+ private ViewInfo visit(View view, BridgeContext context) {
+ if (view == null) {
+ return null;
+ }
+
+ ViewInfo result = new ViewInfo(view.getClass().getName(),
+ context.getViewKey(view),
+ view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+
+ if (view instanceof ViewGroup) {
+ ViewGroup group = ((ViewGroup) view);
+ List<ViewInfo> children = new ArrayList<ViewInfo>();
+ for (int i = 0; i < group.getChildCount(); i++) {
+ children.add(visit(group.getChildAt(i), context));
+ }
+ result.setChildren(children);
+ }
+
+ return result;
+ }
+
+ public BufferedImage getImage() {
+ return mImage;
+ }
+
+ public ViewInfo getViewInfo() {
+ return mViewInfo;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index f13ecdc..3e506b8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -14,11 +14,15 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
import com.android.layoutlib.api.IDensityBasedResourceValue;
import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.android.NinePatchDrawable;
import com.android.ninepatch.NinePatch;
import org.kxml2.io.KXmlParser;
@@ -56,7 +60,7 @@ public final class ResourceHelper {
* @return the color as an int
* @throw NumberFormatException if the conversion failed.
*/
- static int getColor(String value) {
+ public static int getColor(String value) {
if (value != null) {
if (value.startsWith("#") == false) {
throw new NumberFormatException();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java
index 01a4871..4ab98ce 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java
@@ -14,24 +14,24 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
+import com.android.layoutlib.api.ILayoutBridge;
import com.android.layoutlib.api.IResourceValue;
/**
- * Basic implementation of IResourceValue.
+ * Basic implementation of IResourceValue for when it is needed to dynamically make a new
+ * {@link IResourceValue} object.
+ *
+ * Most of the time, implementations of IResourceValue come through the {@link ILayoutBridge}
+ * API.
*/
-class ResourceValue implements IResourceValue {
+public class TempResourceValue implements IResourceValue {
private final String mType;
private final String mName;
private String mValue = null;
-
- ResourceValue(String name) {
- mType = null;
- mName = name;
- }
- public ResourceValue(String type, String name, String value) {
+ public TempResourceValue(String type, String name, String value) {
mType = type;
mName = name;
mValue = value;
@@ -44,16 +44,16 @@ class ResourceValue implements IResourceValue {
public final String getName() {
return mName;
}
-
+
public final String getValue() {
return mValue;
}
-
+
public final void setValue(String value) {
mValue = value;
}
-
- public void replaceWith(ResourceValue value) {
+
+ public void replaceWith(TempResourceValue value) {
mValue = value.mValue;
}
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
index 6d013bb..1ec6262 100644
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
@@ -16,7 +16,7 @@
package com.google.android.maps;
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
import android.content.Context;
import android.os.Bundle;
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index db1262f..3252fb4 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import org.kxml2.io.KXmlParser;
import org.w3c.dom.Node;