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

Commit b63eef76 authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android (Google) Code Review
Browse files

Merge "LayoutLib: implement insert/move/removeChild."

parents 2aeaa3e0 c14e7dd8
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.layoutlib.api.IXmlPullParser;
import com.android.layoutlib.api.LayoutBridge;
import com.android.layoutlib.api.SceneParams;
import com.android.layoutlib.api.SceneResult;
import com.android.layoutlib.api.SceneResult.SceneStatus;
import com.android.layoutlib.bridge.android.BridgeAssetManager;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
@@ -308,8 +309,13 @@ public final class Bridge extends LayoutBridge {

            return new BridgeLayoutScene(scene, lastResult);
        } catch (Throwable t) {
            t.printStackTrace();
            return new BridgeLayoutScene(null, new SceneResult("error!", t));
            // get the real cause of the exception.
            Throwable t2 = t;
            while (t2.getCause() != null) {
                t2 = t.getCause();
            }
            return new BridgeLayoutScene(null,
                    new SceneResult(SceneStatus.ERROR_UNKNOWN, t2.getMessage(), t2));
        }
    }

+79 −2
Original line number Diff line number Diff line
@@ -16,12 +16,16 @@

package com.android.layoutlib.bridge;

import com.android.layoutlib.api.IXmlPullParser;
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.bridge.impl.LayoutSceneImpl;

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

import java.awt.image.BufferedImage;
import java.util.Map;

@@ -92,13 +96,86 @@ public class BridgeLayoutScene extends LayoutScene {
    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub
    public SceneResult insertChild(Object parentView, IXmlPullParser childXml, Object beforeSibling,
            IAnimationListener listener) {
        if (parentView instanceof ViewGroup == false) {
            throw new IllegalArgumentException("parentView is not a ViewGroup");
        }
        if (beforeSibling != null && beforeSibling instanceof View == false) {
            throw new IllegalArgumentException("beforeSibling is not a View");
        }

        try {
            mScene.prepareThread();
            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
            if (mLastResult == SceneResult.SUCCESS) {
                mLastResult = mScene.insertChild((ViewGroup) parentView, childXml,
                        (View) beforeSibling, listener);
            }
        } finally {
            mScene.release();
            mScene.cleanupThread();
        }

        return mLastResult;
    }


    @Override
    public SceneResult moveChild(Object parentView, Object childView, Object beforeSibling,
            IAnimationListener listener) {
        if (parentView instanceof ViewGroup == false) {
            throw new IllegalArgumentException("parentView is not a ViewGroup");
        }
        if (childView instanceof View == false) {
            throw new IllegalArgumentException("childView is not a View");
        }
        if (beforeSibling != null && beforeSibling instanceof View == false) {
            throw new IllegalArgumentException("beforeSibling is not a View");
        }

        try {
            mScene.prepareThread();
            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
            if (mLastResult == SceneResult.SUCCESS) {
                mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView,
                        (View) beforeSibling, listener);
            }
        } finally {
            mScene.release();
            mScene.cleanupThread();
        }

        return mLastResult;
    }

    @Override
    public SceneResult removeChild(Object childView, IAnimationListener listener) {
        if (childView instanceof View == false) {
            throw new IllegalArgumentException("childView is not a View");
        }

        try {
            mScene.prepareThread();
            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
            if (mLastResult == SceneResult.SUCCESS) {
                mLastResult = mScene.removeChild((View) childView, listener);
            }
        } finally {
            mScene.release();
            mScene.cleanupThread();
        }

        return mLastResult;
    }

    @Override
    public void dispose() {
    }

    /*package*/ BridgeLayoutScene(LayoutSceneImpl scene, SceneResult lastResult) {
        mScene = scene;
        mScene.setScene(this);
        mLastResult = lastResult;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ public class AnimationThread extends Thread {
                try {
                    bundle.mTarget.handleMessage(bundle.mMessage);
                    if (mScene.render() == SceneResult.SUCCESS) {
                        mListener.onNewFrame(mScene.getImage());
                        mListener.onNewFrame(mScene.getScene());
                    }
                } finally {
                    mScene.release();
+82 −7
Original line number Diff line number Diff line
@@ -24,13 +24,16 @@ import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
import com.android.layoutlib.api.IXmlPullParser;
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.IDensityBasedResourceValue.Density;
import com.android.layoutlib.api.LayoutScene.IAnimationListener;
import com.android.layoutlib.api.SceneParams.RenderingMode;
import com.android.layoutlib.api.SceneResult.SceneStatus;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
@@ -53,6 +56,7 @@ import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.widget.FrameLayout;
@@ -92,6 +96,7 @@ public class LayoutSceneImpl {
    private final SceneParams mParams;

    // scene state
    private LayoutScene mScene;
    private BridgeContext mContext;
    private BridgeXmlBlockParser mBlockParser;
    private BridgeInflater mInflater;
@@ -362,7 +367,7 @@ public class LayoutSceneImpl {

            return SceneResult.SUCCESS;
        } catch (PostInflateException e) {
            return new SceneResult("Error during post inflation process:\n" + e.getMessage());
            return new SceneResult(SceneStatus.ERROR_INFLATION, e.getMessage(), e);
        } catch (Throwable e) {
            // get the real cause of the exception.
            Throwable t = e;
@@ -373,7 +378,7 @@ public class LayoutSceneImpl {
            // log it
            mParams.getLogger().error(t);

            return new SceneResult("Unknown error during inflation.", t);
            return new SceneResult(SceneStatus.ERROR_INFLATION, t.getMessage(), t);
        }
    }

@@ -391,7 +396,7 @@ public class LayoutSceneImpl {
        try {
            long current = System.currentTimeMillis();
            if (mViewRoot == null) {
                return new SceneResult("Layout has not been inflated!");
                return new SceneResult(SceneStatus.ERROR_NOT_INFLATED);
            }
            // measure the views
            int w_spec, h_spec;
@@ -487,7 +492,7 @@ public class LayoutSceneImpl {
            // log it
            mParams.getLogger().error(t);

            return new SceneResult("Unknown error during rendering.", t);
            return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
        }
    }

@@ -530,12 +535,74 @@ public class LayoutSceneImpl {
                    return SceneResult.SUCCESS;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return new SceneResult("", e);
                // get the real cause of the exception.
                Throwable t = e;
                while (t.getCause() != null) {
                    t = t.getCause();
                }

                return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
            }
        }

        return new SceneResult(SceneStatus.ERROR_ANIM_NOT_FOUND);
    }

    public SceneResult insertChild(ViewGroup parentView, IXmlPullParser childXml,
            View beforeSibling, IAnimationListener listener) {
        checkLock();

        int index = parentView.indexOfChild(beforeSibling);
        if (beforeSibling != null && index == -1) {
            throw new IllegalArgumentException("beforeSibling not in parentView");
        }

        // create a block parser for the XML
        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, mContext,
                false /* platformResourceFlag */);

        // inflate the child without adding it to the root since we want to control where it'll
        // get added. We do pass the parentView however to ensure that the layoutParams will
        // be created correctly.
        View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);

        // add it to the parentView in the correct location
        parentView.addView(child, index);

        return render();
    }

    public SceneResult moveChild(ViewGroup parentView, View childView, View beforeSibling,
            IAnimationListener listener) {
        checkLock();

        int index = parentView.indexOfChild(beforeSibling);
        if (beforeSibling != null && index == -1) {
            throw new IllegalArgumentException("beforeSibling not in parentView");
        }

        return new SceneResult("Failed to find animation");
        ViewParent parent = childView.getParent();
        if (parent instanceof ViewGroup) {
            ViewGroup parentGroup = (ViewGroup) parent;
            parentGroup.removeView(childView);
        }

        // add it to the parentView in the correct location
        parentView.addView(childView, index);

        return render();
    }

    public SceneResult removeChild(View childView, IAnimationListener listener) {
        checkLock();

        ViewParent parent = childView.getParent();
        if (parent instanceof ViewGroup) {
            ViewGroup parentGroup = (ViewGroup) parent;
            parentGroup.removeView(childView);
        }

        return render();
    }

    /**
@@ -915,4 +982,12 @@ public class LayoutSceneImpl {
    public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
        return mContext.getDefaultPropMap(viewObject);
    }

    public void setScene(LayoutScene scene) {
        mScene = scene;
    }

    public LayoutScene getScene() {
        return mScene;
    }
}