Merge changes from topic 'layoutlib-api-15' into lmp-mr1-dev

* changes:
  Update golden image for tests.
  Update to using LayoutlibCallback.
  Remove implementation of deprecated method.
  Add @empty support.
This commit is contained in:
Deepanshu Gupta
2015-04-16 17:12:41 +00:00
committed by Android (Google) Code Review
18 changed files with 224 additions and 164 deletions

View File

@ -16,7 +16,7 @@
package android.app; package android.app;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.Context; import android.content.Context;
@ -30,19 +30,19 @@ import android.os.Bundle;
* *
* The methods being re-implemented are the ones responsible for instantiating Fragment objects. * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
* Because the classes of these objects are found in the project, these methods need access to * Because the classes of these objects are found in the project, these methods need access to
* {@link IProjectCallback} object. They are however static methods, so the callback is set * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
* before the inflation through {@link #setProjectCallback(IProjectCallback)}. * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
*/ */
public class Fragment_Delegate { public class Fragment_Delegate {
private static IProjectCallback sProjectCallback; private static LayoutlibCallback sLayoutlibCallback;
/** /**
* Sets the current {@link IProjectCallback} to be used to instantiate classes coming * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
* from the project being rendered. * from the project being rendered.
*/ */
public static void setProjectCallback(IProjectCallback projectCallback) { public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
sProjectCallback = projectCallback; sLayoutlibCallback = layoutlibCallback;
} }
/** /**
@ -62,17 +62,17 @@ public class Fragment_Delegate {
* This is currently just used to get its ClassLoader. * This is currently just used to get its ClassLoader.
* @param fname The class name of the fragment to instantiate. * @param fname The class name of the fragment to instantiate.
* @param args Bundle of arguments to supply to the fragment, which it * @param args Bundle of arguments to supply to the fragment, which it
* can retrieve with {@link #getArguments()}. May be null. * can retrieve with {@link Fragment#getArguments()}. May be null.
* @return Returns a new fragment instance. * @return Returns a new fragment instance.
* @throws InstantiationException If there is a failure in instantiating * @throws Fragment.InstantiationException If there is a failure in instantiating
* the given fragment class. This is a runtime exception; it is not * the given fragment class. This is a runtime exception; it is not
* normally expected to happen. * normally expected to happen.
*/ */
@LayoutlibDelegate @LayoutlibDelegate
/*package*/ static Fragment instantiate(Context context, String fname, Bundle args) { /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
try { try {
if (sProjectCallback != null) { if (sLayoutlibCallback != null) {
Fragment f = (Fragment) sProjectCallback.loadView(fname, Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
new Class[0], new Object[0]); new Class[0], new Object[0]);
if (args != null) { if (args != null) {

View File

@ -16,8 +16,8 @@
package android.content.res; package android.content.res;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants; import com.android.layoutlib.bridge.BridgeConstants;
@ -49,7 +49,7 @@ import java.io.InputStream;
public final class BridgeResources extends Resources { public final class BridgeResources extends Resources {
private BridgeContext mContext; private BridgeContext mContext;
private IProjectCallback mProjectCallback; private LayoutlibCallback mLayoutlibCallback;
private boolean[] mPlatformResourceFlag = new boolean[1]; private boolean[] mPlatformResourceFlag = new boolean[1];
private TypedValue mTmpValue = new TypedValue(); private TypedValue mTmpValue = new TypedValue();
@ -94,12 +94,12 @@ public final class BridgeResources extends Resources {
AssetManager assets, AssetManager assets,
DisplayMetrics metrics, DisplayMetrics metrics,
Configuration config, Configuration config,
IProjectCallback projectCallback) { LayoutlibCallback layoutlibCallback) {
return Resources.mSystem = new BridgeResources(context, return Resources.mSystem = new BridgeResources(context,
assets, assets,
metrics, metrics,
config, config,
projectCallback); layoutlibCallback);
} }
/** /**
@ -109,16 +109,16 @@ public final class BridgeResources extends Resources {
public static void disposeSystem() { public static void disposeSystem() {
if (Resources.mSystem instanceof BridgeResources) { if (Resources.mSystem instanceof BridgeResources) {
((BridgeResources)(Resources.mSystem)).mContext = null; ((BridgeResources)(Resources.mSystem)).mContext = null;
((BridgeResources)(Resources.mSystem)).mProjectCallback = null; ((BridgeResources)(Resources.mSystem)).mLayoutlibCallback = null;
} }
Resources.mSystem = null; Resources.mSystem = null;
} }
private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics, private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics,
Configuration config, IProjectCallback projectCallback) { Configuration config, LayoutlibCallback layoutlibCallback) {
super(assets, metrics, config); super(assets, metrics, config);
mContext = context; mContext = context;
mProjectCallback = projectCallback; mLayoutlibCallback = layoutlibCallback;
} }
public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) { public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
@ -138,8 +138,8 @@ public final class BridgeResources extends Resources {
} }
// didn't find a match in the framework? look in the project. // didn't find a match in the framework? look in the project.
if (mProjectCallback != null) { if (mLayoutlibCallback != null) {
resourceInfo = mProjectCallback.resolveResourceId(id); resourceInfo = mLayoutlibCallback.resolveResourceId(id);
if (resourceInfo != null) { if (resourceInfo != null) {
platformResFlag_out[0] = false; platformResFlag_out[0] = false;
@ -153,11 +153,6 @@ public final class BridgeResources extends Resources {
return null; return null;
} }
@Override
public Drawable getDrawable(int id) throws NotFoundException {
return getDrawable(id, null);
}
@Override @Override
public Drawable getDrawable(int id, Theme theme) { public Drawable getDrawable(int id, Theme theme) {
Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
@ -257,7 +252,7 @@ public final class BridgeResources extends Resources {
try { try {
// check if the current parser can provide us with a custom parser. // check if the current parser can provide us with a custom parser.
if (mPlatformResourceFlag[0] == false) { if (mPlatformResourceFlag[0] == false) {
parser = mProjectCallback.getParser(value); parser = mLayoutlibCallback.getParser(value);
} }
// create a new one manually if needed. // create a new one manually if needed.
@ -692,8 +687,8 @@ public final class BridgeResources extends Resources {
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id); Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
// if the name is unknown in the framework, get it from the custom view loader. // if the name is unknown in the framework, get it from the custom view loader.
if (resourceInfo == null && mProjectCallback != null) { if (resourceInfo == null && mLayoutlibCallback != null) {
resourceInfo = mProjectCallback.resolveResourceId(id); resourceInfo = mLayoutlibCallback.resolveResourceId(id);
} }
String message = null; String message = null;

View File

@ -16,6 +16,7 @@
package android.content.res; package android.content.res;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AttrResourceValue; import com.android.ide.common.rendering.api.AttrResourceValue;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.RenderResources;
@ -40,9 +41,12 @@ import android.view.LayoutInflater_Delegate;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import static com.android.ide.common.rendering.api.RenderResources.*;
/** /**
* Custom implementation of TypedArray to handle non compiled resources. * Custom implementation of TypedArray to handle non compiled resources.
*/ */
@ -56,6 +60,11 @@ public final class BridgeTypedArray extends TypedArray {
private final String[] mNames; private final String[] mNames;
private final boolean[] mIsFramework; private final boolean[] mIsFramework;
// Contains ids that are @empty. We still store null in mResourceData for that index, since we
// want to save on the check against empty, each time a resource value is requested.
@Nullable
private int[] mEmptyIds;
public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len, public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
boolean platformFile) { boolean platformFile) {
super(resources, null, null, 0); super(resources, null, null, 0);
@ -90,19 +99,32 @@ public final class BridgeTypedArray extends TypedArray {
// fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
// first count the array size // first count the array size
int count = 0; int count = 0;
ArrayList<Integer> emptyIds = null;
for (int i = 0; i < mResourceData.length; i++) { for (int i = 0; i < mResourceData.length; i++) {
ResourceValue data = mResourceData[i]; ResourceValue data = mResourceData[i];
if (data != null) { if (data != null) {
if (RenderResources.REFERENCE_NULL.equals(data.getValue())) { String dataValue = data.getValue();
// No need to store this resource value. This saves needless checking for if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
// "@null" every time an attribute is requested.
mResourceData[i] = null; mResourceData[i] = null;
} else if (REFERENCE_EMPTY.equals(dataValue)) {
mResourceData[i] = null;
if (emptyIds == null) {
emptyIds = new ArrayList<Integer>(4);
}
emptyIds.add(i);
} else { } else {
count++; count++;
} }
} }
} }
if (emptyIds != null) {
mEmptyIds = new int[emptyIds.size()];
for (int i = 0; i < emptyIds.size(); i++) {
mEmptyIds[i] = emptyIds.get(i);
}
}
// allocate the table with an extra to store the size // allocate the table with an extra to store the size
mIndices = new int[count+1]; mIndices = new int[count+1];
mIndices[0] = count; mIndices[0] = count;
@ -624,7 +646,7 @@ public final class BridgeTypedArray extends TypedArray {
if (isFrameworkId) { if (isFrameworkId) {
idValue = Bridge.getResourceId(ResourceType.ID, idName); idValue = Bridge.getResourceId(ResourceType.ID, idName);
} else { } else {
idValue = mContext.getProjectCallback().getResourceId(ResourceType.ID, idName); idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
} }
return idValue == null ? defValue : idValue; return idValue == null ? defValue : idValue;
} }
@ -644,7 +666,7 @@ public final class BridgeTypedArray extends TypedArray {
idValue = Bridge.getResourceId(resValue.getResourceType(), idValue = Bridge.getResourceId(resValue.getResourceType(),
resValue.getName()); resValue.getName());
} else { } else {
idValue = mContext.getProjectCallback().getResourceId( idValue = mContext.getLayoutlibCallback().getResourceId(
resValue.getResourceType(), resValue.getName()); resValue.getResourceType(), resValue.getName());
} }
@ -748,6 +770,12 @@ public final class BridgeTypedArray extends TypedArray {
return index >= 0 && index < mResourceData.length && mResourceData[index] != null; return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
} }
@Override
public boolean hasValueOrEmpty(int index) {
return hasValue(index) || index >= 0 && index < mResourceData.length &&
mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
}
/** /**
* Retrieve the raw TypedValue for the attribute at <var>index</var> * Retrieve the raw TypedValue for the attribute at <var>index</var>
* and return a temporary object holding its data. This object is only * and return a temporary object holding its data. This object is only

View File

@ -69,8 +69,8 @@ public class BridgeXmlPullAttributes extends XmlPullAttributes {
// this is not an attribute in the android namespace, we query the customviewloader, if // this is not an attribute in the android namespace, we query the customviewloader, if
// the namespaces match. // the namespaces match.
if (mContext.getProjectCallback().getNamespace().equals(ns)) { if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name); Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
if (v != null) { if (v != null) {
return v.intValue(); return v.intValue();
} }
@ -273,7 +273,7 @@ public class BridgeXmlPullAttributes extends XmlPullAttributes {
if (mPlatformFile || resource.isFramework()) { if (mPlatformFile || resource.isFramework()) {
id = Bridge.getResourceId(resource.getResourceType(), resource.getName()); id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
} else { } else {
id = mContext.getProjectCallback().getResourceId( id = mContext.getLayoutlibCallback().getResourceId(
resource.getResourceType(), resource.getName()); resource.getResourceType(), resource.getName());
} }

View File

@ -16,7 +16,7 @@
package android.view; package android.view;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.MergeCookie; import com.android.ide.common.rendering.api.MergeCookie;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
@ -46,7 +46,7 @@ import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
*/ */
public final class BridgeInflater extends LayoutInflater { public final class BridgeInflater extends LayoutInflater {
private final IProjectCallback mProjectCallback; private final LayoutlibCallback mLayoutlibCallback;
private boolean mIsInMerge = false; private boolean mIsInMerge = false;
private ResourceReference mResourceReference; private ResourceReference mResourceReference;
@ -64,21 +64,21 @@ public final class BridgeInflater extends LayoutInflater {
super(original, newContext); super(original, newContext);
newContext = getBaseContext(newContext); newContext = getBaseContext(newContext);
if (newContext instanceof BridgeContext) { if (newContext instanceof BridgeContext) {
mProjectCallback = ((BridgeContext) newContext).getProjectCallback(); mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
} else { } else {
mProjectCallback = null; mLayoutlibCallback = null;
} }
} }
/** /**
* Instantiate a new BridgeInflater with an {@link IProjectCallback} object. * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
* *
* @param context The Android application context. * @param context The Android application context.
* @param projectCallback the {@link IProjectCallback} object. * @param layoutlibCallback the {@link LayoutlibCallback} object.
*/ */
public BridgeInflater(Context context, IProjectCallback projectCallback) { public BridgeInflater(Context context, LayoutlibCallback layoutlibCallback) {
super(context); super(context);
mProjectCallback = projectCallback; mLayoutlibCallback = layoutlibCallback;
mConstructorArgs[0] = context; mConstructorArgs[0] = context;
} }
@ -167,12 +167,13 @@ public final class BridgeInflater extends LayoutInflater {
ResourceValue value = null; ResourceValue value = null;
@SuppressWarnings("deprecation")
Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource); Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
if (layoutInfo != null) { if (layoutInfo != null) {
value = bridgeContext.getRenderResources().getFrameworkResource( value = bridgeContext.getRenderResources().getFrameworkResource(
ResourceType.LAYOUT, layoutInfo.getSecond()); ResourceType.LAYOUT, layoutInfo.getSecond());
} else { } else {
layoutInfo = mProjectCallback.resolveResourceId(resource); layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
if (layoutInfo != null) { if (layoutInfo != null) {
value = bridgeContext.getRenderResources().getProjectResource( value = bridgeContext.getRenderResources().getProjectResource(
@ -203,7 +204,7 @@ public final class BridgeInflater extends LayoutInflater {
} }
private View loadCustomView(String name, AttributeSet attrs) throws Exception { private View loadCustomView(String name, AttributeSet attrs) throws Exception {
if (mProjectCallback != null) { if (mLayoutlibCallback != null) {
// first get the classname in case it's not the node name // first get the classname in case it's not the node name
if (name.equals("view")) { if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class"); name = attrs.getAttributeValue(null, "class");
@ -211,7 +212,7 @@ public final class BridgeInflater extends LayoutInflater {
mConstructorArgs[1] = attrs; mConstructorArgs[1] = attrs;
Object customView = mProjectCallback.loadView(name, mConstructorSignature, Object customView = mLayoutlibCallback.loadView(name, mConstructorSignature,
mConstructorArgs); mConstructorArgs);
if (customView instanceof View) { if (customView instanceof View) {

View File

@ -43,7 +43,7 @@ public class PolicyManager {
} }
public static LayoutInflater makeNewLayoutInflater(Context context) { public static LayoutInflater makeNewLayoutInflater(Context context) {
return new BridgeInflater(context, RenderAction.getCurrentContext().getProjectCallback()); return new BridgeInflater(context, RenderAction.getCurrentContext().getLayoutlibCallback());
} }
public static WindowManagerPolicy makeNewWindowManager() { public static WindowManagerPolicy makeNewWindowManager() {

View File

@ -20,8 +20,8 @@ import android.os.IBinder;
import com.android.annotations.Nullable; import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AssetRepository; import com.android.ide.common.rendering.api.AssetRepository;
import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.ResourceValue;
@ -113,7 +113,7 @@ public final class BridgeContext extends Context {
private final RenderResources mRenderResources; private final RenderResources mRenderResources;
private final Configuration mConfig; private final Configuration mConfig;
private final ApplicationInfo mApplicationInfo; private final ApplicationInfo mApplicationInfo;
private final IProjectCallback mProjectCallback; private final LayoutlibCallback mLayoutlibCallback;
private final WindowManager mWindowManager; private final WindowManager mWindowManager;
private final DisplayManager mDisplayManager; private final DisplayManager mDisplayManager;
@ -147,13 +147,13 @@ public final class BridgeContext extends Context {
public BridgeContext(Object projectKey, DisplayMetrics metrics, public BridgeContext(Object projectKey, DisplayMetrics metrics,
RenderResources renderResources, RenderResources renderResources,
AssetRepository assets, AssetRepository assets,
IProjectCallback projectCallback, LayoutlibCallback layoutlibCallback,
Configuration config, Configuration config,
int targetSdkVersion, int targetSdkVersion,
boolean hasRtlSupport) { boolean hasRtlSupport) {
mProjectKey = projectKey; mProjectKey = projectKey;
mMetrics = metrics; mMetrics = metrics;
mProjectCallback = projectCallback; mLayoutlibCallback = layoutlibCallback;
mRenderResources = renderResources; mRenderResources = renderResources;
mConfig = config; mConfig = config;
@ -172,7 +172,7 @@ public final class BridgeContext extends Context {
/** /**
* Initializes the {@link Resources} singleton to be linked to this {@link Context}, its * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
* {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}. * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
* *
* @see #disposeResources() * @see #disposeResources()
*/ */
@ -184,7 +184,7 @@ public final class BridgeContext extends Context {
assetManager, assetManager,
mMetrics, mMetrics,
mConfig, mConfig,
mProjectCallback); mLayoutlibCallback);
mTheme = mSystemResources.newTheme(); mTheme = mSystemResources.newTheme();
} }
@ -223,8 +223,8 @@ public final class BridgeContext extends Context {
return mMetrics; return mMetrics;
} }
public IProjectCallback getProjectCallback() { public LayoutlibCallback getLayoutlibCallback() {
return mProjectCallback; return mLayoutlibCallback;
} }
public RenderResources getRenderResources() { public RenderResources getRenderResources() {
@ -283,7 +283,7 @@ public final class BridgeContext extends Context {
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid); Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
boolean isFrameworkRes = true; boolean isFrameworkRes = true;
if (resourceInfo == null) { if (resourceInfo == null) {
resourceInfo = mProjectCallback.resolveResourceId(resid); resourceInfo = mLayoutlibCallback.resolveResourceId(resid);
isFrameworkRes = false; isFrameworkRes = false;
} }
@ -339,8 +339,8 @@ public final class BridgeContext extends Context {
} }
// didn't find a match in the framework? look in the project. // didn't find a match in the framework? look in the project.
if (mProjectCallback != null) { if (mLayoutlibCallback != null) {
resourceInfo = mProjectCallback.resolveResourceId(id); resourceInfo = mLayoutlibCallback.resolveResourceId(id);
if (resourceInfo != null) { if (resourceInfo != null) {
return new ResourceReference(resourceInfo.getSecond(), false); return new ResourceReference(resourceInfo.getSecond(), false);
@ -438,9 +438,9 @@ public final class BridgeContext extends Context {
private ILayoutPullParser getParser(ResourceReference resource) { private ILayoutPullParser getParser(ResourceReference resource) {
ILayoutPullParser parser; ILayoutPullParser parser;
if (resource instanceof ResourceValue) { if (resource instanceof ResourceValue) {
parser = mProjectCallback.getParser((ResourceValue) resource); parser = mLayoutlibCallback.getParser((ResourceValue) resource);
} else { } else {
parser = mProjectCallback.getParser(resource.getName()); parser = mLayoutlibCallback.getParser(resource.getName());
} }
return parser; return parser;
} }
@ -665,7 +665,7 @@ public final class BridgeContext extends Context {
boolean isFrameworkRes = true; boolean isFrameworkRes = true;
Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes); Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
if (value == null) { if (value == null) {
value = mProjectCallback.resolveResourceId(defStyleRes); value = mLayoutlibCallback.resolveResourceId(defStyleRes);
isFrameworkRes = false; isFrameworkRes = false;
} }
@ -703,7 +703,7 @@ public final class BridgeContext extends Context {
} }
} }
String appNamespace = mProjectCallback.getNamespace(); String appNamespace = mLayoutlibCallback.getNamespace();
if (attributeList != null) { if (attributeList != null) {
for (int index = 0 ; index < attributeList.size() ; index++) { for (int index = 0 ; index < attributeList.size() ; index++) {
@ -846,7 +846,7 @@ public final class BridgeContext extends Context {
if (resolvedResource != null) { if (resolvedResource != null) {
isFramework = true; isFramework = true;
} else { } else {
resolvedResource = mProjectCallback.resolveResourceId(attr); resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
} }
if (resolvedResource != null) { if (resolvedResource != null) {
@ -872,7 +872,7 @@ public final class BridgeContext extends Context {
return Pair.of(info.getSecond(), Boolean.TRUE); return Pair.of(info.getSecond(), Boolean.TRUE);
} }
info = mProjectCallback.resolveResourceId(attr); info = mLayoutlibCallback.resolveResourceId(attr);
if (info != null) { if (info != null) {
return Pair.of(info.getSecond(), Boolean.FALSE); return Pair.of(info.getSecond(), Boolean.FALSE);
} }
@ -924,8 +924,8 @@ public final class BridgeContext extends Context {
// getResourceId creates a new resource id if an existing resource id isn't found. So, we // getResourceId creates a new resource id if an existing resource id isn't found. So, we
// check for the existence of the resource before calling it. // check for the existence of the resource before calling it.
if (getRenderResources().getProjectResource(resType, resName) != null) { if (getRenderResources().getProjectResource(resType, resName) != null) {
if (mProjectCallback != null) { if (mLayoutlibCallback != null) {
Integer value = mProjectCallback.getResourceId(resType, resName); Integer value = mLayoutlibCallback.getResourceId(resType, resName);
if (value != null) { if (value != null) {
return value; return value;
} }

View File

@ -18,8 +18,8 @@ package com.android.layoutlib.bridge.android.support;
import com.android.annotations.NonNull; import com.android.annotations.NonNull;
import com.android.annotations.Nullable; import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeContext;
@ -30,7 +30,6 @@ import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap;
import static com.android.layoutlib.bridge.util.ReflectionUtils.*; import static com.android.layoutlib.bridge.util.ReflectionUtils.*;
@ -61,7 +60,7 @@ public class RecyclerViewUtil {
public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context, public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
@NonNull SessionParams params) { @NonNull SessionParams params) {
try { try {
setLayoutManager(recyclerView, context, params.getProjectCallback()); setLayoutManager(recyclerView, context, params.getLayoutlibCallback());
Object adapter = createAdapter(params); Object adapter = createAdapter(params);
setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter"); setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
} catch (ReflectionException e) { } catch (ReflectionException e) {
@ -71,7 +70,7 @@ public class RecyclerViewUtil {
} }
private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context, private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
@NonNull IProjectCallback callback) throws ReflectionException { @NonNull LayoutlibCallback callback) throws ReflectionException {
Object cookie = context.getCookie(recyclerView); Object cookie = context.getCookie(recyclerView);
assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String; assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String;
if (!(cookie instanceof LayoutManagerType)) { if (!(cookie instanceof LayoutManagerType)) {
@ -90,7 +89,7 @@ public class RecyclerViewUtil {
@Nullable @Nullable
private static Object createLayoutManager(@Nullable LayoutManagerType type, private static Object createLayoutManager(@Nullable LayoutManagerType type,
@NonNull Context context, @NonNull IProjectCallback callback) @NonNull Context context, @NonNull LayoutlibCallback callback)
throws ReflectionException { throws ReflectionException {
if (type == null) { if (type == null) {
type = LayoutManagerType.getDefault(); type = LayoutManagerType.getDefault();
@ -109,7 +108,7 @@ public class RecyclerViewUtil {
return null; return null;
} }
try { try {
return params.getProjectCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]); return params.getLayoutlibCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
} catch (Exception e) { } catch (Exception e) {
throw new ReflectionException(e); throw new ReflectionException(e);
} }

View File

@ -70,7 +70,7 @@ public class AppCompatActionBar extends BridgeActionBar {
try { try {
Class[] constructorParams = {View.class}; Class[] constructorParams = {View.class};
Object[] constructorArgs = {getDecorContent()}; Object[] constructorArgs = {getDecorContent()};
mWindowDecorActionBar = params.getProjectCallback().loadView(WINDOW_ACTION_BAR_CLASS, mWindowDecorActionBar = params.getLayoutlibCallback().loadView(WINDOW_ACTION_BAR_CLASS,
constructorParams, constructorArgs); constructorParams, constructorArgs);
mWindowActionBarClass = mWindowDecorActionBar == null ? null : mWindowActionBarClass = mWindowDecorActionBar == null ? null :

View File

@ -51,7 +51,7 @@ public abstract class BridgeActionBar {
@NonNull ViewGroup parentView) { @NonNull ViewGroup parentView) {
mBridgeContext = context; mBridgeContext = context;
mParams = params; mParams = params;
mCallback = params.getProjectCallback().getActionBarCallback(); mCallback = params.getLayoutlibCallback().getActionBarCallback();
ResourceValue layoutName = getLayoutResource(context); ResourceValue layoutName = getLayoutResource(context);
if (layoutName == null) { if (layoutName == null) {
throw new RuntimeException("Unable to find the layout for Action Bar."); throw new RuntimeException("Unable to find the layout for Action Bar.");

View File

@ -16,10 +16,6 @@
package com.android.layoutlib.bridge.impl; package com.android.layoutlib.bridge.impl;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderParams; import com.android.ide.common.rendering.api.RenderParams;
@ -43,6 +39,10 @@ import android.view.inputmethod.InputMethodManager_Accessor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
/** /**
* Base class for rendering action. * Base class for rendering action.
* *
@ -120,7 +120,7 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
// build the context // build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
mParams.getAssets(), mParams.getProjectCallback(), getConfiguration(), mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(),
mParams.getTargetSdkVersion(), mParams.isRtlSupported()); mParams.getTargetSdkVersion(), mParams.isRtlSupported());
setUp(); setUp();

View File

@ -16,20 +16,13 @@
package com.android.layoutlib.bridge.impl; package com.android.layoutlib.bridge.impl;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
import com.android.annotations.NonNull; import com.android.annotations.NonNull;
import com.android.annotations.Nullable; import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.IAnimationListener; import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
@ -54,13 +47,13 @@ import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.SessionParamsFlags; import com.android.layoutlib.bridge.android.SessionParamsFlags;
import com.android.layoutlib.bridge.android.support.RecyclerViewUtil; import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.AppCompatActionBar; import com.android.layoutlib.bridge.bars.AppCompatActionBar;
import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.Config; import com.android.layoutlib.bridge.bars.Config;
import com.android.layoutlib.bridge.bars.FrameworkActionBar;
import com.android.layoutlib.bridge.bars.NavigationBar; import com.android.layoutlib.bridge.bars.NavigationBar;
import com.android.layoutlib.bridge.bars.StatusBar; import com.android.layoutlib.bridge.bars.StatusBar;
import com.android.layoutlib.bridge.bars.TitleBar; import com.android.layoutlib.bridge.bars.TitleBar;
import com.android.layoutlib.bridge.bars.FrameworkActionBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.resources.Density; import com.android.resources.Density;
@ -116,6 +109,13 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
/** /**
* Class implementing the render session. * Class implementing the render session.
* <p/> * <p/>
@ -219,7 +219,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
WindowManagerGlobal_Delegate.setWindowManagerService(iwm); WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser. // build the inflater and parser.
mInflater = new BridgeInflater(context, params.getProjectCallback()); mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
context.setBridgeInflater(mInflater); context.setBridgeInflater(mInflater);
mBlockParser = new BridgeXmlBlockParser( mBlockParser = new BridgeXmlBlockParser(
@ -401,7 +401,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// Sets the project callback (custom view loader) to the fragment delegate so that // Sets the project callback (custom view loader) to the fragment delegate so that
// it can instantiate the custom Fragment. // it can instantiate the custom Fragment.
Fragment_Delegate.setProjectCallback(params.getProjectCallback()); Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG); String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG);
boolean isPreference = "PreferenceScreen".equals(rootTag); boolean isPreference = "PreferenceScreen".equals(rootTag);
@ -416,13 +416,13 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// done with the parser, pop it. // done with the parser, pop it.
context.popParser(); context.popParser();
Fragment_Delegate.setProjectCallback(null); Fragment_Delegate.setLayoutlibCallback(null);
// set the AttachInfo on the root view. // set the AttachInfo on the root view.
AttachInfo_Accessor.setAttachInfo(mViewRoot); AttachInfo_Accessor.setAttachInfo(mViewRoot);
// post-inflate process. For now this supports TabHost/TabWidget // post-inflate process. For now this supports TabHost/TabWidget
postInflateProcess(view, params.getProjectCallback(), isPreference ? view : null); postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
// get the background drawable // get the background drawable
if (mWindowBackground != null) { if (mWindowBackground != null) {
@ -675,7 +675,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
animationResource = context.getRenderResources().getProjectResource( animationResource = context.getRenderResources().getProjectResource(
ResourceType.ANIMATOR, animationName); ResourceType.ANIMATOR, animationName);
if (animationResource != null) { if (animationResource != null) {
animationId = context.getProjectCallback().getResourceId( animationId = context.getLayoutlibCallback().getResourceId(
ResourceType.ANIMATOR, animationName); ResourceType.ANIMATOR, animationName);
} }
} }
@ -1246,17 +1246,17 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
* {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
* based on the content of the {@link FrameLayout}. * based on the content of the {@link FrameLayout}.
* @param view the root view to process. * @param view the root view to process.
* @param projectCallback callback to the project. * @param layoutlibCallback callback to the project.
* @param skip the view and it's children are not processed. * @param skip the view and it's children are not processed.
*/ */
@SuppressWarnings("deprecation") // For the use of Pair @SuppressWarnings("deprecation") // For the use of Pair
private void postInflateProcess(View view, IProjectCallback projectCallback, View skip) private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
throws PostInflateException { throws PostInflateException {
if (view == skip) { if (view == skip) {
return; return;
} }
if (view instanceof TabHost) { if (view instanceof TabHost) {
setupTabHost((TabHost) view, projectCallback); setupTabHost((TabHost) view, layoutlibCallback);
} else if (view instanceof QuickContactBadge) { } else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view; QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault(); badge.setImageToDefault();
@ -1275,8 +1275,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// if there was no adapter binding, trying to get it from the call back. // if there was no adapter binding, trying to get it from the call back.
if (binding == null) { if (binding == null) {
binding = params.getProjectCallback().getAdapterBinding(listRef, binding = layoutlibCallback.getAdapterBinding(
context.getViewKey(view), view); listRef, context.getViewKey(view), view);
} }
if (binding != null) { if (binding != null) {
@ -1292,7 +1292,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView( Pair<View, Boolean> pair = context.inflateView(
binding.getHeaderAt(i), binding.getHeaderAt(i),
list, false /*attachToRoot*/, skipCallbackParser); list, false, skipCallbackParser);
if (pair.getFirst() != null) { if (pair.getFirst() != null) {
list.addHeaderView(pair.getFirst()); list.addHeaderView(pair.getFirst());
} }
@ -1304,7 +1304,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView( Pair<View, Boolean> pair = context.inflateView(
binding.getFooterAt(i), binding.getFooterAt(i),
list, false /*attachToRoot*/, skipCallbackParser); list, false, skipCallbackParser);
if (pair.getFirst() != null) { if (pair.getFirst() != null) {
list.addFooterView(pair.getFirst()); list.addFooterView(pair.getFirst());
} }
@ -1315,17 +1315,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
if (view instanceof ExpandableListView) { if (view instanceof ExpandableListView) {
((ExpandableListView) view).setAdapter( ((ExpandableListView) view).setAdapter(
new FakeExpandableAdapter( new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
listRef, binding, params.getProjectCallback()));
} else { } else {
((AbsListView) view).setAdapter( ((AbsListView) view).setAdapter(
new FakeAdapter( new FakeAdapter(listRef, binding, layoutlibCallback));
listRef, binding, params.getProjectCallback()));
} }
} else if (view instanceof AbsSpinner) { } else if (view instanceof AbsSpinner) {
((AbsSpinner) view).setAdapter( ((AbsSpinner) view).setAdapter(
new FakeAdapter( new FakeAdapter(listRef, binding, layoutlibCallback));
listRef, binding, params.getProjectCallback()));
} }
} }
} }
@ -1336,7 +1333,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
final int count = group.getChildCount(); final int count = group.getChildCount();
for (int c = 0; c < count; c++) { for (int c = 0; c < count; c++) {
View child = group.getChildAt(c); View child = group.getChildAt(c);
postInflateProcess(child, projectCallback, skip); postInflateProcess(child, layoutlibCallback, skip);
} }
} }
} }
@ -1360,10 +1357,10 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
/** /**
* Sets up a {@link TabHost} object. * Sets up a {@link TabHost} object.
* @param tabHost the TabHost to setup. * @param tabHost the TabHost to setup.
* @param projectCallback The project callback object to access the project R class. * @param layoutlibCallback The project callback object to access the project R class.
* @throws PostInflateException * @throws PostInflateException
*/ */
private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback) private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
throws PostInflateException { throws PostInflateException {
// look for the TabWidget, and the FrameLayout. They have their own specific names // look for the TabWidget, and the FrameLayout. They have their own specific names
View v = tabHost.findViewById(android.R.id.tabs); View v = tabHost.findViewById(android.R.id.tabs);
@ -1406,8 +1403,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
if (count == 0) { if (count == 0) {
// Create a dummy child to get a single tab // Create a dummy child to get a single tab
TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label", TabSpec spec = tabHost.newTabSpec("tag")
tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details)) .setIndicator("Tab Label", tabHost.getResources()
.getDrawable(android.R.drawable.ic_menu_info_details, null))
.setContent(new TabHost.TabContentFactory() { .setContent(new TabHost.TabContentFactory() {
@Override @Override
public View createTabContent(String tag) { public View createTabContent(String tag) {
@ -1423,7 +1421,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
@SuppressWarnings("ConstantConditions") // child cannot be null. @SuppressWarnings("ConstantConditions") // child cannot be null.
int id = child.getId(); int id = child.getId();
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id); Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
String name; String name;
if (resource != null) { if (resource != null) {
name = resource.getSecond(); name = resource.getSecond();

View File

@ -17,7 +17,7 @@
package com.android.layoutlib.bridge.impl.binding; package com.android.layoutlib.bridge.impl.binding;
import com.android.ide.common.rendering.api.DataBindingItem; import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute; import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
@ -40,7 +40,7 @@ import android.widget.TextView;
public class AdapterHelper { public class AdapterHelper {
static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent, static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) { LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
// we don't care about recycling here because we never scroll. // we don't care about recycling here because we never scroll.
DataBindingItem dataBindingItem = item.getDataBindingItem(); DataBindingItem dataBindingItem = item.getDataBindingItem();
@ -65,7 +65,7 @@ public class AdapterHelper {
} }
private static void fillView(BridgeContext context, View view, AdapterItem item, private static void fillView(BridgeContext context, View view, AdapterItem item,
AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) { AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
if (view instanceof ViewGroup) { if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view; ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount(); final int count = group.getChildCount();

View File

@ -18,7 +18,7 @@ package com.android.layoutlib.bridge.impl.binding;
import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem; import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair; import com.android.util.Pair;
@ -37,18 +37,17 @@ import java.util.List;
* and {@link SpinnerAdapter}. * and {@link SpinnerAdapter}.
* *
*/ */
@SuppressWarnings("deprecation")
public class FakeAdapter extends BaseAdapter { public class FakeAdapter extends BaseAdapter {
// don't use a set because the order is important. // don't use a set because the order is important.
private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>(); private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
private final IProjectCallback mCallback; private final LayoutlibCallback mCallback;
private final ResourceReference mAdapterRef; private final ResourceReference mAdapterRef;
private final List<AdapterItem> mItems = new ArrayList<AdapterItem>(); private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
private boolean mSkipCallbackParser = false; private boolean mSkipCallbackParser = false;
public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding, public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
IProjectCallback callback) { LayoutlibCallback callback) {
mAdapterRef = adapterRef; mAdapterRef = adapterRef;
mCallback = callback; mCallback = callback;
@ -111,11 +110,11 @@ public class FakeAdapter extends BaseAdapter {
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
// we don't care about recycling here because we never scroll. // we don't care about recycling here because we never scroll.
AdapterItem item = mItems.get(position); AdapterItem item = mItems.get(position);
Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent, @SuppressWarnings("deprecation")
mCallback, mAdapterRef, mSkipCallbackParser); Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
mAdapterRef, mSkipCallbackParser);
mSkipCallbackParser = pair.getSecond(); mSkipCallbackParser = pair.getSecond();
return pair.getFirst(); return pair.getFirst();
} }
@Override @Override

View File

@ -18,7 +18,7 @@ package com.android.layoutlib.bridge.impl.binding;
import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem; import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
import com.android.util.Pair; import com.android.util.Pair;
@ -34,7 +34,7 @@ import java.util.List;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList { public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
private final IProjectCallback mCallback; private final LayoutlibCallback mCallback;
private final ResourceReference mAdapterRef; private final ResourceReference mAdapterRef;
private boolean mSkipCallbackParser = false; private boolean mSkipCallbackParser = false;
@ -45,7 +45,7 @@ public class FakeExpandableAdapter implements ExpandableListAdapter, Heterogeneo
private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>(); private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding, public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
IProjectCallback callback) { LayoutlibCallback callback) {
mAdapterRef = adapterRef; mAdapterRef = adapterRef;
mCallback = callback; mCallback = callback;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -20,7 +20,7 @@ import com.android.SdkConstants;
import com.android.ide.common.rendering.api.ActionBarCallback; import com.android.ide.common.rendering.api.ActionBarCallback;
import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.ResourceValue;
import com.android.resources.ResourceType; import com.android.resources.ResourceType;
@ -28,10 +28,7 @@ import com.android.ide.common.resources.IntArrayWrapper;
import com.android.util.Pair; import com.android.util.Pair;
import com.android.utils.ILogger; import com.android.utils.ILogger;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@ -40,7 +37,7 @@ import java.util.Map;
import com.google.android.collect.Maps; import com.google.android.collect.Maps;
@SuppressWarnings("deprecation") // For Pair @SuppressWarnings("deprecation") // For Pair
public class LayoutLibTestCallback extends ClassLoader implements IProjectCallback { public class LayoutLibTestCallback extends LayoutlibCallback {
private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/"; private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication"; private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
@ -48,16 +45,16 @@ public class LayoutLibTestCallback extends ClassLoader implements IProjectCallba
private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap(); private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap(); private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap(); private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
private final Map<String, Class<?>> mClasses = Maps.newHashMap();
private final ILogger mLog; private final ILogger mLog;
private final ActionBarCallback mActionBarCallback = new ActionBarCallback(); private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
private final ClassLoader mModuleClassLoader = new ModuleClassLoader(PROJECT_CLASSES_LOCATION);
public LayoutLibTestCallback(ILogger logger) { public LayoutLibTestCallback(ILogger logger) {
mLog = logger; mLog = logger;
} }
public void initResources() throws ClassNotFoundException { public void initResources() throws ClassNotFoundException {
Class<?> rClass = loadClass(PACKAGE_NAME + ".R"); Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
Class<?>[] nestedClasses = rClass.getDeclaredClasses(); Class<?>[] nestedClasses = rClass.getDeclaredClasses();
for (Class<?> resClass : nestedClasses) { for (Class<?> resClass : nestedClasses) {
final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName()); final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
@ -91,40 +88,11 @@ public class LayoutLibTestCallback extends ClassLoader implements IProjectCallba
} }
} }
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> aClass = mClasses.get(name);
if (aClass != null) {
return aClass;
}
String pathName = PROJECT_CLASSES_LOCATION.concat(name.replace('.', '/')).concat(".class");
InputStream classInputStream = getClass().getResourceAsStream(pathName);
if (classInputStream == null) {
throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
}
byte[] data;
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
data = new byte[16384];
while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
data = buffer.toByteArray();
} catch (IOException e) {
// Wrap the exception with ClassNotFoundException so that caller can deal with it.
throw new ClassNotFoundException("Unable to load class " + name, e);
}
aClass = defineClass(name, data, 0, data.length);
mClasses.put(name, aClass);
return aClass;
}
@Override @Override
public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs) public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
throws Exception { throws Exception {
Class<?> viewClass = findClass(name); Class<?> viewClass = mModuleClassLoader.loadClass(name);
Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature); Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
viewConstructor.setAccessible(true); viewConstructor.setAccessible(true);
return viewConstructor.newInstance(constructorArgs); return viewConstructor.newInstance(constructorArgs);
@ -180,4 +148,9 @@ public class LayoutLibTestCallback extends ClassLoader implements IProjectCallba
public ActionBarCallback getActionBarCallback() { public ActionBarCallback getActionBarCallback() {
return mActionBarCallback; return mActionBarCallback;
} }
@Override
public boolean supports(int ideFeature) {
return false;
}
} }

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2015 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.intensive.setup;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import com.google.android.collect.Maps;
/**
* The ClassLoader to load the project's classes.
*/
public class ModuleClassLoader extends ClassLoader {
private final Map<String, Class<?>> mClasses = Maps.newHashMap();
private final String mClassLocation;
public ModuleClassLoader(String classLocation) {
mClassLocation = classLocation;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> aClass = mClasses.get(name);
if (aClass != null) {
return aClass;
}
String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class");
InputStream classInputStream = getClass().getResourceAsStream(pathName);
if (classInputStream == null) {
throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
}
byte[] data;
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
data = new byte[16384]; // 16k
while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
data = buffer.toByteArray();
} catch (IOException e) {
// Wrap the exception with ClassNotFoundException so that caller can deal with it.
throw new ClassNotFoundException("Unable to load class " + name, e);
}
aClass = defineClass(name, data, 0, data.length);
mClasses.put(name, aClass);
return aClass;
}
}