Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c2f85d9 authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android Git Automerger
Browse files

am d0054160: am 6d040a7f: am 738c5e60: am 2fae858d: LayoutLib: implement data...

am d0054160: am 6d040a7f: am 738c5e60: am 2fae858d: LayoutLib: implement data binding for most AdapterView

* commit 'd0054160':
  LayoutLib: implement data binding for most AdapterView
parents ba4990c7 d0054160
Loading
Loading
Loading
Loading
+40 −1
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.Result.Status;
import com.android.layoutlib.bridge.android.BridgeAssetManager;
import com.android.layoutlib.bridge.android.BridgeAssetManager;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.RenderDrawable;
import com.android.layoutlib.bridge.impl.RenderDrawable;
@@ -39,6 +40,9 @@ import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.Typeface;
import android.graphics.Typeface_Delegate;
import android.graphics.Typeface_Delegate;
import android.os.Looper;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;


import java.io.File;
import java.io.File;
import java.lang.ref.SoftReference;
import java.lang.ref.SoftReference;
@@ -196,7 +200,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
                Capability.EMBEDDED_LAYOUT,
                Capability.EMBEDDED_LAYOUT,
                Capability.VIEW_MANIPULATION,
                Capability.VIEW_MANIPULATION,
                Capability.PLAY_ANIMATION,
                Capability.PLAY_ANIMATION,
                Capability.ANIMATED_VIEW_MANIPULATION);
                Capability.ANIMATED_VIEW_MANIPULATION,
                Capability.ADAPTER_BINDING);




        BridgeAssetManager.initSystem();
        BridgeAssetManager.initSystem();
@@ -369,6 +374,40 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
        }
        }
    }
    }


    @Override
    public Result getViewParent(Object viewObject) {
        if (viewObject instanceof View) {
            return Status.SUCCESS.createResult(((View)viewObject).getParent());
        }

        throw new IllegalArgumentException("viewObject is not a View");
    }

    @Override
    public Result getViewIndex(Object viewObject) {
        if (viewObject instanceof View) {
            View view = (View) viewObject;
            ViewParent parentView = view.getParent();

            if (parentView instanceof ViewGroup) {
                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
            }

            return Status.SUCCESS.createResult();
        }

        throw new IllegalArgumentException("viewObject is not a View");
    }

    @Override
    public int getViewBaseline(Object viewObject) {
        if (viewObject instanceof View) {
            return ((View) viewObject).getBaseline();
        }

        throw new IllegalArgumentException("viewObject is not a View");
    }

    /**
    /**
     * Returns the lock for the bridge
     * Returns the lock for the bridge
     */
     */
+0 −27
Original line number Original line Diff line number Diff line
@@ -22,12 +22,10 @@ import com.android.ide.common.rendering.api.RenderParams;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.Result.Status;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;


import android.view.View;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.view.ViewParent;


import java.awt.image.BufferedImage;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.List;
@@ -82,31 +80,6 @@ public class BridgeRenderSession extends RenderSession {
        return super.setProperty(objectView, propertyName, propertyValue);
        return super.setProperty(objectView, propertyName, propertyValue);
    }
    }


    @Override
    public Result getViewParent(Object viewObject) {
        if (viewObject instanceof View) {
            return Status.SUCCESS.createResult(((View)viewObject).getParent());
        }

        throw new IllegalArgumentException("viewObject is not a View");
    }

    @Override
    public Result getViewIndex(Object viewObject) {
        if (viewObject instanceof View) {
            View view = (View) viewObject;
            ViewParent parentView = view.getParent();

            if (parentView instanceof ViewGroup) {
                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
            }

            return Status.SUCCESS.createResult();
        }

        throw new IllegalArgumentException("viewObject is not a View");
    }

    @Override
    @Override
    public Result render(long timeout) {
    public Result render(long timeout) {
        try {
        try {
+109 −0
Original line number Original line Diff line number Diff line
@@ -16,9 +16,11 @@


package com.android.layoutlib.bridge.android;
package com.android.layoutlib.bridge.android;


import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
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.RenderResources;
import com.android.ide.common.rendering.api.RenderResources;
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.ide.common.rendering.api.StyleResourceValue;
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.Bridge;
@@ -27,6 +29,10 @@ import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
import com.android.resources.ResourceType;
import com.android.util.Pair;
import com.android.util.Pair;


import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.Activity;
import android.app.Fragment;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
@@ -59,11 +65,13 @@ import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View;
import android.view.ViewGroup;


import java.io.File;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashMap;
@@ -270,6 +278,107 @@ public final class BridgeContext extends Activity {
    }
    }




    public ResourceReference resolveId(int id) {
        // first get the String related to this id in the framework
        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);

        if (resourceInfo != null) {
            return new ResourceReference(resourceInfo.getSecond(), true);
        }

        // didn't find a match in the framework? look in the project.
        if (mProjectCallback != null) {
            resourceInfo = mProjectCallback.resolveResourceId(id);

            if (resourceInfo != null) {
                return new ResourceReference(resourceInfo.getSecond(), false);
            }
        }

        return null;
    }

    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
            boolean attachToRoot, boolean skipCallbackParser) {
        String layoutName = resource.getName();
        boolean isPlatformLayout = resource.isFramework();

        if (isPlatformLayout == false && skipCallbackParser == false) {
            // check if the project callback can provide us with a custom parser.
            ILayoutPullParser parser = mProjectCallback.getParser(layoutName);
            if (parser != null) {
                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
                        this, resource.isFramework());
                try {
                    pushParser(blockParser);
                    return Pair.of(
                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
                            true);
                } finally {
                    popParser();
                }
            }
        }

        ResourceValue resValue;
        if (resource instanceof ResourceValue) {
            resValue = (ResourceValue) resource;
        } else {
            if (isPlatformLayout) {
                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
                        resource.getName());
            } else {
                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
                        resource.getName());
            }
        }

        if (resValue != null) {

            File xml = new File(resValue.getValue());
            if (xml.isFile()) {
                // we need to create a pull parser around the layout XML file, and then
                // give that to our XmlBlockParser
                try {
                    KXmlParser parser = new KXmlParser();
                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                    parser.setInput(new FileReader(xml));

                    // set the resource ref to have correct view cookies
                    mBridgeInflater.setResourceReference(resource);

                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
                            this, resource.isFramework());
                    try {
                        pushParser(blockParser);
                        return Pair.of(
                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
                                false);
                    } finally {
                        popParser();
                    }
                } catch (XmlPullParserException e) {
                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                            "Failed to configure parser for " + xml, e, null /*data*/);
                    // we'll return null below.
                } catch (FileNotFoundException e) {
                    // this shouldn't happen since we check above.
                } finally {
                    mBridgeInflater.setResourceReference(null);
                }
            } else {
                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                        String.format("File %s is missing!", xml), null);
            }
        } else {
            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
                            layoutName), null);
        }

        return Pair.of(null, false);
    }

    // ------------- Activity Methods
    // ------------- Activity Methods


    @Override
    @Override
+27 −11
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.layoutlib.bridge.android;
import com.android.ide.common.rendering.api.IProjectCallback;
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.MergeCookie;
import com.android.ide.common.rendering.api.MergeCookie;
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.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.Bridge;
import com.android.resources.ResourceType;
import com.android.resources.ResourceType;
@@ -44,6 +45,7 @@ public final class BridgeInflater extends LayoutInflater {


    private final IProjectCallback mProjectCallback;
    private final IProjectCallback mProjectCallback;
    private boolean mIsInMerge = false;
    private boolean mIsInMerge = false;
    private ResourceReference mResourceReference;


    /**
    /**
     * List of class prefixes which are tried first by default.
     * List of class prefixes which are tried first by default.
@@ -223,23 +225,33 @@ public final class BridgeInflater extends LayoutInflater {
                // get the view key
                // get the view key
                Object viewKey = parser.getViewCookie();
                Object viewKey = parser.getViewCookie();


                // if there's no view key and the depth is 1 (ie this is the first tag), or 2
                if (viewKey == null) {
                // (this is first item in included merge layout)
                    int currentDepth = parser.getDepth();
                // look for a previous parser in the context, and check if this one has a viewkey.

                int testDepth = mIsInMerge ? 2 : 1;
                    // test whether we are in an included file or in a adapter binding view.
                if (viewKey == null && parser.getDepth() == testDepth) {
                    BridgeXmlBlockParser previousParser = bc.getPreviousParser();
                    BridgeXmlBlockParser previousParser = bc.getPreviousParser();
                    if (previousParser != null) {
                    if (previousParser != null) {
                        // looks like we inside an embedded layout.
                        // only apply the cookie of the calling node (<include>) if we are at the
                        // top level of the embedded layout. If there is a merge tag, then
                        // skip it and look for the 2nd level
                        int testDepth = mIsInMerge ? 2 : 1;
                        if (currentDepth == testDepth) {
                            viewKey = previousParser.getViewCookie();
                            viewKey = previousParser.getViewCookie();
                            // if we are in a merge, wrap the cookie in a MergeCookie.
                            if (viewKey != null && mIsInMerge) {
                                viewKey = new MergeCookie(viewKey);
                            }
                            }
                        }
                        }

                    } else if (mResourceReference != null && currentDepth == 1) {
                if (viewKey != null) {
                        // else if there's a resource reference, this means we are in an adapter
                    if (testDepth == 2) {
                        // binding case. Set the resource ref as the view cookie only for the top
                        // include-merge case
                        // level view.
                        viewKey = new MergeCookie(viewKey);
                        viewKey = mResourceReference;
                    }
                }
                }


                if (viewKey != null) {
                    bc.addViewKey(view, viewKey);
                    bc.addViewKey(view, viewKey);
                }
                }
            }
            }
@@ -250,6 +262,10 @@ public final class BridgeInflater extends LayoutInflater {
        mIsInMerge = isInMerge;
        mIsInMerge = isInMerge;
    }
    }


    public void setResourceReference(ResourceReference reference) {
        mResourceReference = reference;
    }

    @Override
    @Override
    public LayoutInflater cloneInContext(Context newContext) {
    public LayoutInflater cloneInContext(Context newContext) {
        return new BridgeInflater(this, newContext);
        return new BridgeInflater(this, newContext);
+2 −3
Original line number Original line Diff line number Diff line
@@ -232,9 +232,8 @@ 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.
                BridgeXmlBlockParser currentParser = mContext.getCurrentParser();
                if (mPlatformResourceFlag[0] == false) {
                if (currentParser != null) {
                    parser = mProjectCallback.getParser(value.getName());
                    parser = currentParser.getParser(value.getName());
                }
                }


                // create a new one manually if needed.
                // create a new one manually if needed.
Loading