aboutsummaryrefslogtreecommitdiffstats
path: root/layoutlib_utils
diff options
context:
space:
mode:
Diffstat (limited to 'layoutlib_utils')
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/BasicLayoutScene.java58
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/DensityBasedResourceValue.java (renamed from layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java)2
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutBridgeWrapper.java201
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutLibrary.java143
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/ResourceValue.java (renamed from layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java)2
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/StyleResourceValue.java (renamed from layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java)2
-rw-r--r--layoutlib_utils/src/com/android/ide/common/layoutlib/ValueResourceParser.java (renamed from layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java)2
-rw-r--r--layoutlib_utils/src/com/android/ide/common/log/ILogger.java64
-rw-r--r--layoutlib_utils/src/com/android/ide/common/sdk/LoadStatus.java24
9 files changed, 494 insertions, 4 deletions
diff --git a/layoutlib_utils/src/com/android/ide/common/layoutlib/BasicLayoutScene.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/BasicLayoutScene.java
new file mode 100644
index 0000000..dfb3992
--- /dev/null
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/BasicLayoutScene.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ide.common.layoutlib;
+
+import com.android.layoutlib.api.LayoutScene;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Basic LayoutScene returning a given {@link SceneResult}, {@link ViewInfo} and
+ * {@link BufferedImage}.
+ * <p/>
+ * All other methods are untouched from the base implementation provided by the API.
+ *
+ */
+public class BasicLayoutScene extends LayoutScene {
+
+ private final SceneResult mResult;
+ private final ViewInfo mRootViewInfo;
+ private final BufferedImage mImage;
+
+ public BasicLayoutScene(SceneResult result, ViewInfo rootViewInfo, BufferedImage image) {
+ mResult = result;
+ mRootViewInfo = rootViewInfo;
+ mImage = image;
+ }
+
+ @Override
+ public SceneResult getResult() {
+ return mResult;
+ }
+
+ @Override
+ public ViewInfo getRootView() {
+ return mRootViewInfo;
+ }
+
+ @Override
+ public BufferedImage getImage() {
+ return mImage;
+ }
+}
diff --git a/layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/DensityBasedResourceValue.java
index 59de463..e1c0caa 100644
--- a/layoutlib_utils/src/com/android/layoutlib/utils/DensityBasedResourceValue.java
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/DensityBasedResourceValue.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.utils;
+package com.android.ide.common.layoutlib;
import com.android.layoutlib.api.IDensityBasedResourceValue;
diff --git a/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutBridgeWrapper.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutBridgeWrapper.java
new file mode 100644
index 0000000..f4c99bd
--- /dev/null
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutBridgeWrapper.java
@@ -0,0 +1,201 @@
+/*
+ * 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.ide.common.layoutlib;
+
+import com.android.layoutlib.api.ILayoutBridge;
+import com.android.layoutlib.api.ILayoutResult;
+import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.LayoutScene;
+import com.android.layoutlib.api.SceneParams;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * {@link LayoutBridge} wrapper around a {@link ILayoutBridge}.
+ * <p/>
+ * The goal is to let tools only uses the latest API by providing a conversion interface
+ * between the really old API ({@link ILayoutBridge}) and the new one ({@link ILayoutBridge}).
+ *
+ */
+@SuppressWarnings("deprecation")
+class LayoutBridgeWrapper extends LayoutBridge {
+
+ private final ILayoutBridge mBridge;
+ private final ClassLoader mClassLoader;
+
+ LayoutBridgeWrapper(ILayoutBridge bridge, ClassLoader classLoader) {
+ mBridge = bridge;
+ mClassLoader = classLoader;
+ }
+
+ @Override
+ public int getApiLevel() {
+ int apiLevel = 1;
+ try {
+ apiLevel = mBridge.getApiLevel();
+ } catch (AbstractMethodError e) {
+ // the first version of the api did not have this method
+ // so this is 1
+ }
+
+ return apiLevel;
+ }
+
+ @Override
+ public boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+ return mBridge.init(fontOsLocation, enumValueMap);
+ }
+
+ @Override
+ public boolean dispose() {
+ // there's no dispose in ILayoutBridge
+ return true;
+ }
+
+
+ @Override
+ public LayoutScene createScene(SceneParams params) {
+ int apiLevel = mBridge.getApiLevel();
+
+ ILayoutResult result = null;
+
+ if (apiLevel == 4) {
+ // Final ILayoutBridge API added support for "render full height"
+ result = mBridge.computeLayout(
+ params.getLayoutDescription(), params.getProjectKey(),
+ params.getScreenWidth(), params.getScreenHeight(), params.getRenderFullSize(),
+ params.getDensity(), params.getXdpi(), params.getYdpi(),
+ params.getThemeName(), params.getIsProjectTheme(),
+ params.getProjectResources(), params.getFrameworkResources(),
+ params.getProjectCallback(), params.getLogger());
+ } else if (apiLevel == 3) {
+ // api 3 add density support.
+ result = mBridge.computeLayout(
+ params.getLayoutDescription(), params.getProjectKey(),
+ params.getScreenWidth(), params.getScreenHeight(),
+ params.getDensity(), params.getXdpi(), params.getYdpi(),
+ params.getThemeName(), params.getIsProjectTheme(),
+ params.getProjectResources(), params.getFrameworkResources(),
+ params.getProjectCallback(), params.getLogger());
+ } else if (apiLevel == 2) {
+ // api 2 added boolean for separation of project/framework theme
+ result = mBridge.computeLayout(
+ params.getLayoutDescription(), params.getProjectKey(),
+ params.getScreenWidth(), params.getScreenHeight(),
+ params.getThemeName(), params.getIsProjectTheme(),
+ params.getProjectResources(), params.getFrameworkResources(),
+ params.getProjectCallback(), params.getLogger());
+ } else {
+ // First api with no density/dpi, and project theme boolean mixed
+ // into the theme name.
+
+ // change the string if it's a custom theme to make sure we can
+ // differentiate them
+ String themeName = params.getThemeName();
+ if (params.getIsProjectTheme()) {
+ themeName = "*" + themeName; //$NON-NLS-1$
+ }
+
+ result = mBridge.computeLayout(
+ params.getLayoutDescription(), params.getProjectKey(),
+ params.getScreenWidth(), params.getScreenHeight(),
+ themeName,
+ params.getProjectResources(), params.getFrameworkResources(),
+ params.getProjectCallback(), params.getLogger());
+ }
+
+ // clean up that is not done by the ILayoutBridge itself
+ cleanUp();
+
+ return convertToScene(result);
+ }
+
+
+ @Override
+ public void clearCaches(Object projectKey) {
+ mBridge.clearCaches(projectKey);
+ }
+
+ /**
+ * Converts a {@link ILayoutResult} to a {@link LayoutScene}.
+ */
+ private LayoutScene convertToScene(ILayoutResult result) {
+
+ SceneResult sceneResult;
+ ViewInfo rootViewInfo;
+
+ if (result.getSuccess() == ILayoutResult.SUCCESS) {
+ sceneResult = SceneResult.SUCCESS;
+ rootViewInfo = convertToViewInfo(result.getRootView());
+ } else {
+ sceneResult = new SceneResult(result.getErrorMessage());
+ rootViewInfo = null;
+ }
+
+ // create a BasicLayoutScene. This will return the given values but return the default
+ // implementation for all method.
+ // ADT should gracefully handle the default implementations of LayoutScene
+ return new BasicLayoutScene(sceneResult, rootViewInfo, result.getImage());
+ }
+
+ /**
+ * Converts a {@link ILayoutViewInfo} (and its children) to a {@link ViewInfo}.
+ */
+ private ViewInfo convertToViewInfo(ILayoutViewInfo view) {
+ // create the view info.
+ ViewInfo viewInfo = new ViewInfo(view.getName(), view.getViewKey(),
+ view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+
+ // then convert the children
+ ILayoutViewInfo[] children = view.getChildren();
+ if (children != null) {
+ ArrayList<ViewInfo> convertedChildren = new ArrayList<ViewInfo>(children.length);
+ for (ILayoutViewInfo child : children) {
+ convertedChildren.add(convertToViewInfo(child));
+ }
+ viewInfo.setChildren(convertedChildren);
+ }
+
+ return viewInfo;
+ }
+
+ /**
+ * Post rendering clean-up that must be done here because it's not done in any layoutlib using
+ * {@link ILayoutBridge}.
+ */
+ private void cleanUp() {
+ try {
+ Class<?> looperClass = mClassLoader.loadClass("android.os.Looper"); //$NON-NLS-1$
+ Field threadLocalField = looperClass.getField("sThreadLocal"); //$NON-NLS-1$
+ if (threadLocalField != null) {
+ threadLocalField.setAccessible(true);
+ // get object. Field is static so no need to pass an object
+ ThreadLocal<?> threadLocal = (ThreadLocal<?>) threadLocalField.get(null);
+ if (threadLocal != null) {
+ threadLocal.remove();
+ }
+ }
+ } catch (Exception e) {
+ // do nothing.
+ }
+ }
+}
diff --git a/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutLibrary.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutLibrary.java
new file mode 100644
index 0000000..5ec7ae5
--- /dev/null
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/LayoutLibrary.java
@@ -0,0 +1,143 @@
+/*
+ * 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.ide.common.layoutlib;
+
+import com.android.ide.common.log.ILogger;
+import com.android.ide.common.sdk.LoadStatus;
+import com.android.layoutlib.api.ILayoutBridge;
+import com.android.layoutlib.api.LayoutBridge;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * Class representing and allowing to load the layoutlib jar file.
+ */
+@SuppressWarnings("deprecation")
+public class LayoutLibrary {
+
+ public final static String CLASS_BRIDGE = "com.android.layoutlib.bridge.Bridge"; //$NON-NLS-1$
+
+ /** Link to the layout bridge */
+ private final LayoutBridge mBridge;
+ /** Status of the layoutlib.jar loading */
+ private final LoadStatus mStatus;
+ /** classloader used to load the jar file */
+ private final ClassLoader mClassLoader;
+
+ /**
+ * Returns the loaded {@link LayoutBridge} object or null if the loading failed.
+ */
+ public LayoutBridge getBridge() {
+ return mBridge;
+ }
+
+ /**
+ * Returns the {@link LoadStatus} of the loading of the layoutlib jar file.
+ */
+ public LoadStatus getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Returns the classloader used to load the classes in the layoutlib jar file.
+ */
+ public ClassLoader getClassLoader() {
+ return mClassLoader;
+ }
+
+ /**
+ * Loads the layoutlib.jar file located at the given path and returns a {@link LayoutLibrary}
+ * object representing the result.
+ * <p/>
+ * If loading failed {@link #getStatus()} will reflect this, and {@link #getBridge()} will
+ * return null.
+ *
+ * @param layoutLibJarOsPath the path of the jar file
+ * @param log an optional log file.
+ * @return a {@link LayoutLibrary} object always.
+ */
+ public static LayoutLibrary load(String layoutLibJarOsPath, ILogger log) {
+
+ LoadStatus status = LoadStatus.LOADING;
+ LayoutBridge bridge = null;
+ ClassLoader classLoader = null;
+
+ try {
+ // get the URL for the file.
+ File f = new File(layoutLibJarOsPath);
+ if (f.isFile() == false) {
+ if (log != null) {
+ log.error(null, "layoutlib.jar is missing!"); //$NON-NLS-1$
+ }
+ } else {
+ URI uri = f.toURI();
+ URL url = uri.toURL();
+
+ // create a class loader. Because this jar reference interfaces
+ // that are in the editors plugin, it's important to provide
+ // a parent class loader.
+ classLoader = new URLClassLoader(
+ new URL[] { url },
+ LayoutLibrary.class.getClassLoader());
+
+ // load the class
+ Class<?> clazz = classLoader.loadClass(CLASS_BRIDGE);
+ if (clazz != null) {
+ // instantiate an object of the class.
+ Constructor<?> constructor = clazz.getConstructor();
+ if (constructor != null) {
+ Object bridgeObject = constructor.newInstance();
+ if (bridgeObject instanceof LayoutBridge) {
+ bridge = (LayoutBridge)bridgeObject;
+ } else if (bridgeObject instanceof ILayoutBridge) {
+ bridge = new LayoutBridgeWrapper((ILayoutBridge) bridgeObject,
+ classLoader);
+ }
+ }
+ }
+
+ if (bridge == null) {
+ status = LoadStatus.FAILED;
+ if (log != null) {
+ log.error(null, "Failed to load " + CLASS_BRIDGE); //$NON-NLS-1$
+ }
+ } else {
+ // mark the lib as loaded.
+ status = LoadStatus.LOADED;
+ }
+ }
+ } catch (Throwable t) {
+ status = LoadStatus.FAILED;
+ // log the error.
+ if (log != null) {
+ log.error(t, "Failed to load the LayoutLib");
+ }
+ }
+
+ return new LayoutLibrary(bridge, classLoader, status);
+ }
+
+ private LayoutLibrary(LayoutBridge bridge, ClassLoader classLoader, LoadStatus status) {
+ mBridge = bridge;
+ mClassLoader = classLoader;
+ mStatus = status;
+ }
+}
diff --git a/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/ResourceValue.java
index 98b4de6..382d961 100644
--- a/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/ResourceValue.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.utils;
+package com.android.ide.common.layoutlib;
import com.android.layoutlib.api.IResourceValue;
diff --git a/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/StyleResourceValue.java
index a32ac1b..721b16c 100644
--- a/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/StyleResourceValue.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.utils;
+package com.android.ide.common.layoutlib;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
diff --git a/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java b/layoutlib_utils/src/com/android/ide/common/layoutlib/ValueResourceParser.java
index 4682d90..c784f1f 100644
--- a/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java
+++ b/layoutlib_utils/src/com/android/ide/common/layoutlib/ValueResourceParser.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.utils;
+package com.android.ide.common.layoutlib;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
diff --git a/layoutlib_utils/src/com/android/ide/common/log/ILogger.java b/layoutlib_utils/src/com/android/ide/common/log/ILogger.java
new file mode 100644
index 0000000..1ad602e
--- /dev/null
+++ b/layoutlib_utils/src/com/android/ide/common/log/ILogger.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ide.common.log;
+
+import java.util.Formatter;
+
+public interface ILogger {
+
+ /**
+ * Prints a warning message on stdout.
+ * <p/>
+ * The message will be tagged with "Warning" on the output so the caller does not
+ * need to put such a prefix in the format string.
+ * <p/>
+ * Implementations should only display warnings in verbose mode.
+ *
+ * @param warningFormat is an optional error format. If non-null, it will be printed
+ * using a {@link Formatter} with the provided arguments.
+ * @param args provides the arguments for warningFormat.
+ */
+ void warning(String warningFormat, Object... args);
+
+ /**
+ * Prints an error message on stderr.
+ * <p/>
+ * The message will be tagged with "Error" on the output so the caller does not
+ * need to put such a prefix in the format string.
+ * <p/>
+ * Implementation should always display errors, independent of verbose mode.
+ *
+ * @param t is an optional {@link Throwable} or {@link Exception}. If non-null, it's
+ * message will be printed out.
+ * @param errorFormat is an optional error format. If non-null, it will be printed
+ * using a {@link Formatter} with the provided arguments.
+ * @param args provides the arguments for errorFormat.
+ */
+ void error(Throwable t, String errorFormat, Object... args);
+
+ /**
+ * Prints a message as-is on stdout.
+ * <p/>
+ * Implementation should always display errors, independent of verbose mode.
+ * No prefix is used, the message is printed as-is after formatting.
+ *
+ * @param msgFormat is an optional error format. If non-null, it will be printed
+ * using a {@link Formatter} with the provided arguments.
+ * @param args provides the arguments for msgFormat.
+ */
+ void printf(String msgFormat, Object... args);
+}
diff --git a/layoutlib_utils/src/com/android/ide/common/sdk/LoadStatus.java b/layoutlib_utils/src/com/android/ide/common/sdk/LoadStatus.java
new file mode 100644
index 0000000..babbd63
--- /dev/null
+++ b/layoutlib_utils/src/com/android/ide/common/sdk/LoadStatus.java
@@ -0,0 +1,24 @@
+/*
+ * 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.ide.common.sdk;
+
+/**
+ * Enum for loading status of various SDK parts.
+ */
+public enum LoadStatus {
+ LOADING, LOADED, FAILED;
+}