/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.layoutlib.bridge.impl;

import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.ViewType;
import com.android.internal.view.menu.ActionMenuItemView;
import com.android.internal.view.menu.BridgeMenuItemImpl;
import com.android.internal.view.menu.IconMenuItemView;
import com.android.internal.view.menu.ListMenuItemView;
import com.android.internal.view.menu.MenuItemImpl;
import com.android.internal.view.menu.MenuView;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.android.graphics.NopCanvas;
import com.android.layoutlib.bridge.android.support.DesignLibUtil;
import com.android.layoutlib.bridge.android.support.FragmentTabHostUtil;
import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.tools.layoutlib.java.System_Delegate;
import com.android.util.Pair;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Fragment_Delegate;
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
import android.graphics.Canvas;
import android.graphics.NinePatch_Delegate;
import android.os.Looper;
import android.preference.Preference_Delegate;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
import android.view.Choreographer_Delegate;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewParent;
import android.widget.AbsListView;
import android.widget.AbsSpinner;
import android.widget.ActionMenuView;
import android.widget.AdapterView;
import android.widget.ExpandableListView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

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.SUCCESS;
import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf;

/**
 * Class implementing the render session.
 * <p/>
 * A session is a stateful representation of a layout file. It is initialized with data coming
 * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
 * be done on the layout.
 */
public class RenderSessionImpl extends RenderAction<SessionParams> {

    private static final Canvas NOP_CANVAS = new NopCanvas();

    // scene state
    private RenderSession mScene;
    private BridgeXmlBlockParser mBlockParser;
    private BridgeInflater mInflater;
    private ViewGroup mViewRoot;
    private FrameLayout mContentRoot;
    private Canvas mCanvas;
    private int mMeasuredScreenWidth = -1;
    private int mMeasuredScreenHeight = -1;
    private boolean mIsAlphaChannelImage;
    /** If >= 0, a frame will be executed */
    private long mElapsedFrameTimeNanos = -1;
    /** True if one frame has been already executed to start the animations */
    private boolean mFirstFrameExecuted = false;

    // information being returned through the API
    private BufferedImage mImage;
    private List<ViewInfo> mViewInfoList;
    private List<ViewInfo> mSystemViewInfoList;
    private Layout.Builder mLayoutBuilder;
    private boolean mNewRenderSize;

    private static final class PostInflateException extends Exception {
        private static final long serialVersionUID = 1L;

        private PostInflateException(String message) {
            super(message);
        }
    }

    /**
     * Creates a layout scene with all the information coming from the layout bridge API.
     * <p>
     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)},
     * which act as a
     * call to {@link RenderSessionImpl#acquire(long)}
     *
     * @see Bridge#createSession(SessionParams)
     */
    public RenderSessionImpl(SessionParams params) {
        super(new SessionParams(params));
    }

    /**
     * Initializes and acquires the scene, creating various Android objects such as context,
     * inflater, and parser.
     *
     * @param timeout the time to wait if another rendering is happening.
     *
     * @return whether the scene was prepared
     *
     * @see #acquire(long)
     * @see #release()
     */
    @Override
    public Result init(long timeout) {
        Result result = super.init(timeout);
        if (!result.isSuccess()) {
            return result;
        }

        SessionParams params = getParams();
        BridgeContext context = getContext();

        // use default of true in case it's not found to use alpha by default
        mIsAlphaChannelImage =
                ResourceHelper.getBooleanThemeFrameworkAttrValue(params.getResources(),
                        "windowIsFloating", true);

        mLayoutBuilder = new Layout.Builder(params, context);

        // build the inflater and parser.
        mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
        context.setBridgeInflater(mInflater);

        ILayoutPullParser layoutParser = params.getLayoutDescription();
        mBlockParser = new BridgeXmlBlockParser(layoutParser, context, layoutParser.getLayoutNamespace());

        return SUCCESS.createResult();
    }

    /**
     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
     */
    private void measureLayout(@NonNull SessionParams params) {
        // only do the screen measure when needed.
        if (mMeasuredScreenWidth != -1) {
            return;
        }

        RenderingMode renderingMode = params.getRenderingMode();
        HardwareConfig hardwareConfig = params.getHardwareConfig();

        mNewRenderSize = true;
        mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
        mMeasuredScreenHeight = hardwareConfig.getScreenHeight();

        if (renderingMode != RenderingMode.NORMAL) {
            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                    : MeasureSpec.EXACTLY;
            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                    : MeasureSpec.EXACTLY;

            // We used to compare the measured size of the content to the screen size but
            // this does not work anymore due to the 2 following issues:
            // - If the content is in a decor (system bar, title/action bar), the root view
            //   will not resize even with the UNSPECIFIED because of the embedded layout.
            // - If there is no decor, but a dialog frame, then the dialog padding prevents
            //   comparing the size of the content to the screen frame (as it would not
            //   take into account the dialog padding).

            // The solution is to first get the content size in a normal rendering, inside
            // the decor or the dialog padding.
            // Then measure only the content with UNSPECIFIED to see the size difference
            // and apply this to the screen size.

            View measuredView = mContentRoot.getChildAt(0);

            // first measure the full layout, with EXACTLY to get the size of the
            // content as it is inside the decor/dialog
            @SuppressWarnings("deprecation")
            Pair<Integer, Integer> exactMeasure = measureView(
                    mViewRoot, measuredView,
                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);

            // now measure the content only using UNSPECIFIED (where applicable, based on
            // the rendering mode). This will give us the size the content needs.
            @SuppressWarnings("deprecation")
            Pair<Integer, Integer> result = measureView(
                    mContentRoot, mContentRoot.getChildAt(0),
                    mMeasuredScreenWidth, widthMeasureSpecMode,
                    mMeasuredScreenHeight, heightMeasureSpecMode);

            // If measuredView is not null, exactMeasure nor result will be null.
            assert exactMeasure != null;
            assert result != null;

            // now look at the difference and add what is needed.
            if (renderingMode.isHorizExpand()) {
                int measuredWidth = exactMeasure.getFirst();
                int neededWidth = result.getFirst();
                if (neededWidth > measuredWidth) {
                    mMeasuredScreenWidth += neededWidth - measuredWidth;
                }
                if (mMeasuredScreenWidth < measuredWidth) {
                    // If the screen width is less than the exact measured width,
                    // expand to match.
                    mMeasuredScreenWidth = measuredWidth;
                }
            }

            if (renderingMode.isVertExpand()) {
                int measuredHeight = exactMeasure.getSecond();
                int neededHeight = result.getSecond();
                if (neededHeight > measuredHeight) {
                    mMeasuredScreenHeight += neededHeight - measuredHeight;
                }
                if (mMeasuredScreenHeight < measuredHeight) {
                    // If the screen height is less than the exact measured height,
                    // expand to match.
                    mMeasuredScreenHeight = measuredHeight;
                }
            }
        }
    }

    /**
     * Inflates the layout.
     * <p>
     * {@link #acquire(long)} must have been called before this.
     *
     * @throws IllegalStateException if the current context is different than the one owned by
     *      the scene, or if {@link #init(long)} was not called.
     */
    public Result inflate() {
        checkLock();

        try {
            mViewRoot = new Layout(mLayoutBuilder);
            mLayoutBuilder = null;  // Done with the builder.
            mContentRoot = ((Layout) mViewRoot).getContentRoot();
            SessionParams params = getParams();
            BridgeContext context = getContext();

            if (Bridge.isLocaleRtl(params.getLocale())) {
                if (!params.isRtlSupported()) {
                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED,
                            "You are using a right-to-left " +
                                    "(RTL) locale but RTL is not enabled", null);
                } else if (params.getSimulatedPlatformVersion() !=0 &&
                        params.getSimulatedPlatformVersion() < 17) {
                    // This will render ok because we are using the latest layoutlib but at least
                    // warn the user that this might fail in a real device.
                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
                            "right-to-left " +
                            "(RTL) locale but RTL is not supported for API level < 17", null);
                }
            }

            // Sets the project callback (custom view loader) to the fragment delegate so that
            // it can instantiate the custom Fragment.
            Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());

            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
            boolean isPreference = "PreferenceScreen".equals(rootTag) ||
                    SupportPreferencesUtil.isSupportRootTag(rootTag);
            View view;
            if (isPreference) {
                // First try to use the support library inflater. If something fails, fallback
                // to the system preference inflater.
                view = SupportPreferencesUtil.inflatePreference(getContext(), mBlockParser,
                        mContentRoot);
                if (view == null) {
                    view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
                            mContentRoot);
                }
            } else {
                view = mInflater.inflate(mBlockParser, mContentRoot);
            }

            // done with the parser, pop it.
            context.popParser();

            Fragment_Delegate.setLayoutlibCallback(null);

            // set the AttachInfo on the root view.
            AttachInfo_Accessor.setAttachInfo(mViewRoot);

            // post-inflate process. For now this supports TabHost/TabWidget
            postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
            mInflater.onDoneInflation();

            setActiveToolbar(view, context, params);

            measureLayout(params);
            measureView(mViewRoot, null /*measuredView*/,
                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
            mSystemViewInfoList =
                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
                    false);

            Choreographer_Delegate.clearFrames();

            return SUCCESS.createResult();
        } catch (PostInflateException e) {
            return ERROR_INFLATION.createResult(e.getMessage(), e);
        } catch (Throwable e) {
            // get the real cause of the exception.
            Throwable t = e;
            while (t.getCause() != null) {
                t = t.getCause();
            }

            return ERROR_INFLATION.createResult(t.getMessage(), t);
        }
    }

    /**
     * Sets the time for which the next frame will be selected. The time is the elapsed time from
     * the current system nanos time. You
     */
    public void setElapsedFrameTimeNanos(long nanos) {
        mElapsedFrameTimeNanos = nanos;
    }

    /**
     * Runs a layout pass for the given view root
     */
    private static void doLayout(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot,
            int width, int height) {
        // measure again with the size we need
        // This must always be done before the call to layout
        measureView(viewRoot, null /*measuredView*/,
                width, MeasureSpec.EXACTLY,
                height, MeasureSpec.EXACTLY);

        // now do the layout.
        viewRoot.layout(0, 0, width, height);
        handleScrolling(context, viewRoot);
    }

    /**
     * Renders the given view hierarchy to the passed canvas and returns the result of the render
     * operation.
     * @param canvas an optional canvas to render the views to. If null, only the measure and
     * layout steps will be executed.
     */
    private static Result renderAndBuildResult(@NonNull ViewGroup viewRoot, @Nullable Canvas canvas) {
        if (canvas == null) {
            return SUCCESS.createResult();
        }

        AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
        viewRoot.draw(canvas);

        return SUCCESS.createResult();
    }

    /**
     * Renders the scene.
     * <p>
     * {@link #acquire(long)} must have been called before this.
     *
     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
     *      the case where bitmaps are reused). This is typically needed when not playing
     *      animations.)
     *
     * @throws IllegalStateException if the current context is different than the one owned by
     *      the scene, or if {@link #acquire(long)} was not called.
     *
     * @see SessionParams#getRenderingMode()
     * @see RenderSession#render(long)
     */
    public Result render(boolean freshRender) {
        return renderAndBuildResult(freshRender, false);
    }

    /**
     * Measures the layout
     * <p>
     * {@link #acquire(long)} must have been called before this.
     *
     * @throws IllegalStateException if the current context is different than the one owned by
     *      the scene, or if {@link #acquire(long)} was not called.
     *
     * @see SessionParams#getRenderingMode()
     * @see RenderSession#render(long)
     */
    public Result measure() {
        return renderAndBuildResult(false, true);
    }

    /**
     * Renders the scene.
     * <p>
     * {@link #acquire(long)} must have been called before this.
     *
     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
     *      the case where bitmaps are reused). This is typically needed when not playing
     *      animations.)
     *
     * @throws IllegalStateException if the current context is different than the one owned by
     *      the scene, or if {@link #acquire(long)} was not called.
     *
     * @see SessionParams#getRenderingMode()
     * @see RenderSession#render(long)
     */
    private Result renderAndBuildResult(boolean freshRender, boolean onlyMeasure) {
        checkLock();

        SessionParams params = getParams();

        try {
            if (mViewRoot == null) {
                return ERROR_NOT_INFLATED.createResult();
            }

            measureLayout(params);

            HardwareConfig hardwareConfig = params.getHardwareConfig();
            Result renderResult = SUCCESS.createResult();
            if (onlyMeasure) {
                // delete the canvas and image to reset them on the next full rendering
                mImage = null;
                mCanvas = null;
                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
            } else {
                // draw the views
                // create the BufferedImage into which the layout will be rendered.
                boolean newImage = false;

                // When disableBitmapCaching is true, we do not reuse mImage and
                // we create a new one in every render.
                // This is useful when mImage is just a wrapper of Graphics2D so
                // it doesn't get cached.
                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));

                if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
                    mNewRenderSize = false;
                    if (params.getImageFactory() != null) {
                        mImage = params.getImageFactory().getImage(
                                mMeasuredScreenWidth,
                                mMeasuredScreenHeight);
                    } else {
                        mImage = new BufferedImage(
                                mMeasuredScreenWidth,
                                mMeasuredScreenHeight,
                                BufferedImage.TYPE_INT_ARGB);
                        newImage = true;
                    }

                    if (params.isBgColorOverridden()) {
                        // since we override the content, it's the same as if it was a new image.
                        newImage = true;
                        Graphics2D gc = mImage.createGraphics();
                        gc.setColor(new Color(params.getOverrideBgColor(), true));
                        gc.setComposite(AlphaComposite.Src);
                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
                        gc.dispose();
                    }

                    // create an Android bitmap around the BufferedImage
                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
                            true /*isMutable*/, hardwareConfig.getDensity());

                    if (mCanvas == null) {
                        // create a Canvas around the Android bitmap
                        mCanvas = new Canvas(bitmap);
                    } else {
                        mCanvas.setBitmap(bitmap);
                    }

                    boolean enableImageResizing =
                            mImage.getWidth() != mMeasuredScreenWidth &&
                            mImage.getHeight() != mMeasuredScreenHeight &&
                            Boolean.TRUE.equals(params.getFlag(
                                    RenderParamsFlags.FLAG_KEY_RESULT_IMAGE_AUTO_SCALE));

                    if (enableImageResizing) {
                        float scaleX = (float)mImage.getWidth() / mMeasuredScreenWidth;
                        float scaleY = (float)mImage.getHeight() / mMeasuredScreenHeight;
                        mCanvas.scale(scaleX, scaleY);
                    }

                    mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
                }

                if (freshRender && !newImage) {
                    Graphics2D gc = mImage.createGraphics();
                    gc.setComposite(AlphaComposite.Src);

                    gc.setColor(new Color(0x00000000, true));
                    gc.fillRect(0, 0,
                            mMeasuredScreenWidth, mMeasuredScreenHeight);

                    // done
                    gc.dispose();
                }

                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
                if (mElapsedFrameTimeNanos >= 0) {
                    long initialTime = System_Delegate.nanoTime();
                    if (!mFirstFrameExecuted) {
                        // We need to run an initial draw call to initialize the animations
                        renderAndBuildResult(mViewRoot, NOP_CANVAS);

                        // The first frame will initialize the animations
                        Choreographer_Delegate.doFrame(initialTime);
                        mFirstFrameExecuted = true;
                    }
                    // Second frame will move the animations
                    Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
                }
                renderResult = renderAndBuildResult(mViewRoot, mCanvas);
            }

            mSystemViewInfoList =
                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
                    false);

            // success!
            return renderResult;
        } catch (Throwable e) {
            // get the real cause of the exception.
            Throwable t = e;
            while (t.getCause() != null) {
                t = t.getCause();
            }

            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
        }
    }

    /**
     * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
     * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
     *
     * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
     * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
     *
     * @param viewToMeasure the view on which to execute measure().
     * @param measuredView if non null, the view to query for its measured width/height.
     * @param width the width to use in the MeasureSpec.
     * @param widthMode the MeasureSpec mode to use for the width.
     * @param height the height to use in the MeasureSpec.
     * @param heightMode the MeasureSpec mode to use for the height.
     * @return the measured width/height if measuredView is non-null, null otherwise.
     */
    @SuppressWarnings("deprecation")  // For the use of Pair
    private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
            int width, int widthMode, int height, int heightMode) {
        int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
        int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
        viewToMeasure.measure(w_spec, h_spec);

        if (measuredView != null) {
            return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
        }

        return null;
    }

    /**
     * Post process on a view hierarchy that was just inflated.
     * <p/>
     * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
     * based on the content of the {@link FrameLayout}.
     * @param view the root view to process.
     * @param layoutlibCallback callback to the project.
     * @param skip the view and it's children are not processed.
     */
    @SuppressWarnings("deprecation")  // For the use of Pair
    private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
            throws PostInflateException {
        if (view == skip) {
            return;
        }
        if (view instanceof TabHost) {
            setupTabHost((TabHost) view, layoutlibCallback);
        } else if (view instanceof QuickContactBadge) {
            QuickContactBadge badge = (QuickContactBadge) view;
            badge.setImageToDefault();
        } else if (view instanceof AdapterView<?>) {
            // get the view ID.
            int id = view.getId();

            BridgeContext context = getContext();

            // get a ResourceReference from the integer ID.
            ResourceReference listRef = context.resolveId(id);

            if (listRef != null) {
                SessionParams params = getParams();
                AdapterBinding binding = params.getAdapterBindings().get(listRef);

                // if there was no adapter binding, trying to get it from the call back.
                if (binding == null) {
                    binding = layoutlibCallback.getAdapterBinding(
                            listRef, context.getViewKey(view), view);
                }

                if (binding != null) {

                    if (view instanceof AbsListView) {
                        if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
                                view instanceof ListView) {
                            ListView list = (ListView) view;

                            boolean skipCallbackParser = false;

                            int count = binding.getHeaderCount();
                            for (int i = 0; i < count; i++) {
                                Pair<View, Boolean> pair = context.inflateView(
                                        binding.getHeaderAt(i),
                                        list, false, skipCallbackParser);
                                if (pair.getFirst() != null) {
                                    list.addHeaderView(pair.getFirst());
                                }

                                skipCallbackParser |= pair.getSecond();
                            }

                            count = binding.getFooterCount();
                            for (int i = 0; i < count; i++) {
                                Pair<View, Boolean> pair = context.inflateView(
                                        binding.getFooterAt(i),
                                        list, false, skipCallbackParser);
                                if (pair.getFirst() != null) {
                                    list.addFooterView(pair.getFirst());
                                }

                                skipCallbackParser |= pair.getSecond();
                            }
                        }

                        if (view instanceof ExpandableListView) {
                            ((ExpandableListView) view).setAdapter(
                                    new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
                        } else {
                            ((AbsListView) view).setAdapter(
                                    new FakeAdapter(listRef, binding, layoutlibCallback));
                        }
                    } else if (view instanceof AbsSpinner) {
                        ((AbsSpinner) view).setAdapter(
                                new FakeAdapter(listRef, binding, layoutlibCallback));
                    }
                }
            }
        } else if (view instanceof ViewGroup) {
            mInflater.postInflateProcess(view);
            ViewGroup group = (ViewGroup) view;
            final int count = group.getChildCount();
            for (int c = 0; c < count; c++) {
                View child = group.getChildAt(c);
                postInflateProcess(child, layoutlibCallback, skip);
            }
        }
    }

    /**
     * If the root layout is a CoordinatorLayout with an AppBar:
     * Set the title of the AppBar to the title of the activity context.
     */
    private void setActiveToolbar(View view, BridgeContext context, SessionParams params) {
        View coordinatorLayout = findChildView(view, DesignLibUtil.CN_COORDINATOR_LAYOUT);
        if (coordinatorLayout == null) {
            return;
        }
        View appBar = findChildView(coordinatorLayout, DesignLibUtil.CN_APPBAR_LAYOUT);
        if (appBar == null) {
            return;
        }
        ViewGroup collapsingToolbar =
                (ViewGroup) findChildView(appBar, DesignLibUtil.CN_COLLAPSING_TOOLBAR_LAYOUT);
        if (collapsingToolbar == null) {
            return;
        }
        if (!hasToolbar(collapsingToolbar)) {
            return;
        }
        String title = params.getAppLabel();
        DesignLibUtil.setTitle(collapsingToolbar, title);
    }

    private View findChildView(View view, String[] className) {
        if (!(view instanceof ViewGroup)) {
            return null;
        }
        ViewGroup group = (ViewGroup) view;
        for (int i = 0; i < group.getChildCount(); i++) {
            if (isInstanceOf(group.getChildAt(i), className)) {
                return group.getChildAt(i);
            }
        }
        return null;
    }

    private boolean hasToolbar(View collapsingToolbar) {
        if (!(collapsingToolbar instanceof ViewGroup)) {
            return false;
        }
        ViewGroup group = (ViewGroup) collapsingToolbar;
        for (int i = 0; i < group.getChildCount(); i++) {
            if (isInstanceOf(group.getChildAt(i), DesignLibUtil.CN_TOOLBAR)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If
     * the component supports nested scrolling attempt that first, then use the unconsumed scroll
     * part to scroll the content in the component.
     */
    private static void handleScrolling(BridgeContext context, View view) {
        int scrollPosX = context.getScrollXPos(view);
        int scrollPosY = context.getScrollYPos(view);
        if (scrollPosX != 0 || scrollPosY != 0) {
            if (view.isNestedScrollingEnabled()) {
                int[] consumed = new int[2];
                int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0;
                axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0;
                if (view.startNestedScroll(axis)) {
                    view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null);
                    view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY,
                            null);
                    view.stopNestedScroll();
                    scrollPosX -= consumed[0];
                    scrollPosY -= consumed[1];
                }
            }
            if (scrollPosX != 0 || scrollPosY != 0) {
                view.scrollTo(scrollPosX, scrollPosY);
            }
        }

        if (!(view instanceof ViewGroup)) {
            return;
        }
        ViewGroup group = (ViewGroup) view;
        for (int i = 0; i < group.getChildCount(); i++) {
            View child = group.getChildAt(i);
            handleScrolling(context, child);
        }
    }

    /**
     * Sets up a {@link TabHost} object.
     * @param tabHost the TabHost to setup.
     * @param layoutlibCallback The project callback object to access the project R class.
     * @throws PostInflateException if TabHost is missing the required ids for TabHost
     */
    private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
            throws PostInflateException {
        // look for the TabWidget, and the FrameLayout. They have their own specific names
        View v = tabHost.findViewById(android.R.id.tabs);

        if (v == null) {
            throw new PostInflateException(
                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
        }

        if (!(v instanceof TabWidget)) {
            throw new PostInflateException(String.format(
                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
        }

        v = tabHost.findViewById(android.R.id.tabcontent);

        if (v == null) {
            // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty)
            //noinspection SpellCheckingInspection
            throw new PostInflateException(
                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
        }

        if (!(v instanceof FrameLayout)) {
            //noinspection SpellCheckingInspection
            throw new PostInflateException(String.format(
                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
        }

        FrameLayout content = (FrameLayout)v;

        // now process the content of the frameLayout and dynamically create tabs for it.
        final int count = content.getChildCount();

        // this must be called before addTab() so that the TabHost searches its TabWidget
        // and FrameLayout.
        if (isInstanceOf(tabHost, FragmentTabHostUtil.CN_FRAGMENT_TAB_HOST)) {
            FragmentTabHostUtil.setup(tabHost, getContext());
        } else {
            tabHost.setup();
        }

        if (count == 0) {
            // Create a dummy child to get a single tab
            TabSpec spec = tabHost.newTabSpec("tag")
                    .setIndicator("Tab Label", tabHost.getResources()
                            .getDrawable(android.R.drawable.ic_menu_info_details, null))
                    .setContent(tag -> new LinearLayout(getContext()));
            tabHost.addTab(spec);
        } else {
            // for each child of the frameLayout, add a new TabSpec
            for (int i = 0 ; i < count ; i++) {
                View child = content.getChildAt(i);
                String tabSpec = String.format("tab_spec%d", i+1);
                @SuppressWarnings("ConstantConditions")  // child cannot be null.
                int id = child.getId();
                @SuppressWarnings("deprecation")
                ResourceReference resource = layoutlibCallback.resolveResourceId(id);
                String name;
                if (resource != null) {
                    name = resource.getName();
                } else {
                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
                }
                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
            }
        }
    }

    /**
     * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the
     * bounds of all the views.
     *
     * @param view the root View
     * @param hOffset horizontal offset for the view bounds.
     * @param vOffset vertical offset for the view bounds.
     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
     *                       content frame.
     *
     * @return {@code ViewInfo} containing the bounds of the view and it children otherwise.
     */
    private ViewInfo visit(View view, int hOffset, int vOffset, boolean setExtendedInfo,
            boolean isContentFrame) {
        ViewInfo result = createViewInfo(view, hOffset, vOffset, setExtendedInfo, isContentFrame);

        if (view instanceof ViewGroup) {
            ViewGroup group = ((ViewGroup) view);
            result.setChildren(visitAllChildren(group, isContentFrame ? 0 : hOffset,
                    isContentFrame ? 0 : vOffset,
                    setExtendedInfo, isContentFrame));
        }
        return result;
    }

    /**
     * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo}
     * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with
     * the children of the {@code mContentRoot}.
     *
     * @param viewGroup the root View
     * @param hOffset horizontal offset from the top for the content view frame.
     * @param vOffset vertical offset from the top for the content view frame.
     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
     *                       content frame. {@code false} if the {@code ViewInfo} to be created is
     *                       part of the system decor.
     */
    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int hOffset, int vOffset,
            boolean setExtendedInfo, boolean isContentFrame) {
        if (viewGroup == null) {
            return null;
        }

        if (!isContentFrame) {
            vOffset += viewGroup.getTop();
            hOffset += viewGroup.getLeft();
        }

        int childCount = viewGroup.getChildCount();
        if (viewGroup == mContentRoot) {
            List<ViewInfo> childrenWithoutOffset = new ArrayList<>(childCount);
            List<ViewInfo> childrenWithOffset = new ArrayList<>(childCount);
            for (int i = 0; i < childCount; i++) {
                ViewInfo[] childViewInfo =
                        visitContentRoot(viewGroup.getChildAt(i), hOffset, vOffset,
                        setExtendedInfo);
                childrenWithoutOffset.add(childViewInfo[0]);
                childrenWithOffset.add(childViewInfo[1]);
            }
            mViewInfoList = childrenWithOffset;
            return childrenWithoutOffset;
        } else {
            List<ViewInfo> children = new ArrayList<>(childCount);
            for (int i = 0; i < childCount; i++) {
                children.add(visit(viewGroup.getChildAt(i), hOffset, vOffset, setExtendedInfo,
                        isContentFrame));
            }
            return children;
        }
    }

    /**
     * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the
     * bounds of all the views. It returns two {@code ViewInfo} objects with the same children,
     * one with the {@code offset} and other without the {@code offset}. The offset is needed to
     * get the right bounds if the {@code ViewInfo} hierarchy is accessed from
     * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the
     * offset is not needed.
     *
     * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at
     *         index 1 is with the offset.
     */
    @NonNull
    private ViewInfo[] visitContentRoot(View view, int hOffset, int vOffset,
            boolean setExtendedInfo) {
        ViewInfo[] result = new ViewInfo[2];
        if (view == null) {
            return result;
        }

        result[0] = createViewInfo(view, 0, 0, setExtendedInfo, true);
        result[1] = createViewInfo(view, hOffset, vOffset, setExtendedInfo, true);
        if (view instanceof ViewGroup) {
            List<ViewInfo> children =
                    visitAllChildren((ViewGroup) view, 0, 0, setExtendedInfo, true);
            result[0].setChildren(children);
            result[1].setChildren(children);
        }
        return result;
    }

    /**
     * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children
     * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not
     * set.
     * @param hOffset horizontal offset for the view bounds. Used only if view is part of the
     * content frame.
     * @param vOffset vertial an offset for the view bounds. Used only if view is part of the
     * content frame.
     */
    private ViewInfo createViewInfo(View view, int hOffset, int vOffset, boolean setExtendedInfo,
            boolean isContentFrame) {
        if (view == null) {
            return null;
        }

        ViewParent parent = view.getParent();
        ViewInfo result;
        if (isContentFrame) {
            // Account for parent scroll values when calculating the bounding box
            int scrollX = parent != null ? ((View)parent).getScrollX() : 0;
            int scrollY = parent != null ? ((View)parent).getScrollY() : 0;

            // The view is part of the layout added by the user. Hence,
            // the ViewCookie may be obtained only through the Context.
            int shiftX = -scrollX + Math.round(view.getTranslationX()) + hOffset;
            int shiftY = -scrollY + Math.round(view.getTranslationY()) + vOffset;
            result = new ViewInfo(view.getClass().getName(),
                    getContext().getViewKey(view),
                    shiftX + view.getLeft(),
                    shiftY + view.getTop(),
                    shiftX + view.getRight(),
                    shiftY + view.getBottom(),
                    view, view.getLayoutParams());
        } else {
            // We are part of the system decor.
            SystemViewInfo r = new SystemViewInfo(view.getClass().getName(),
                    getViewKey(view),
                    view.getLeft(), view.getTop(), view.getRight(),
                    view.getBottom(), view, view.getLayoutParams());
            result = r;
            // We currently mark three kinds of views:
            // 1. Menus in the Action Bar
            // 2. Menus in the Overflow popup.
            // 3. The overflow popup button.
            if (view instanceof ListMenuItemView) {
                // Mark 2.
                // All menus in the popup are of type ListMenuItemView.
                r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
            } else {
                // Mark 3.
                ViewGroup.LayoutParams lp = view.getLayoutParams();
                if (lp instanceof ActionMenuView.LayoutParams &&
                        ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
                    r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
                } else {
                    // Mark 1.
                    // A view is a menu in the Action Bar is it is not the overflow button and of
                    // its parent is of type ActionMenuView. We can also check if the view is
                    // instanceof ActionMenuItemView but that will fail for menus using
                    // actionProviderClass.
                    while (parent != mViewRoot && parent instanceof ViewGroup) {
                        if (parent instanceof ActionMenuView) {
                            r.setViewType(ViewType.ACTION_BAR_MENU);
                            break;
                        }
                        parent = parent.getParent();
                    }
                }
            }
        }

        if (setExtendedInfo) {
            MarginLayoutParams marginParams = null;
            LayoutParams params = view.getLayoutParams();
            if (params instanceof MarginLayoutParams) {
                marginParams = (MarginLayoutParams) params;
            }
            result.setExtendedInfo(view.getBaseline(),
                    marginParams != null ? marginParams.leftMargin : 0,
                    marginParams != null ? marginParams.topMargin : 0,
                    marginParams != null ? marginParams.rightMargin : 0,
                    marginParams != null ? marginParams.bottomMargin : 0);
        }

        return result;
    }

    /* (non-Javadoc)
     * The cookie for menu items are stored in menu item and not in the map from View stored in
     * BridgeContext.
     */
    @Nullable
    private Object getViewKey(View view) {
        BridgeContext context = getContext();
        if (!(view instanceof MenuView.ItemView)) {
            return context.getViewKey(view);
        }
        MenuItemImpl menuItem;
        if (view instanceof ActionMenuItemView) {
            menuItem = ((ActionMenuItemView) view).getItemData();
        } else if (view instanceof ListMenuItemView) {
            menuItem = ((ListMenuItemView) view).getItemData();
        } else if (view instanceof IconMenuItemView) {
            menuItem = ((IconMenuItemView) view).getItemData();
        } else {
            menuItem = null;
        }
        if (menuItem instanceof BridgeMenuItemImpl) {
            return ((BridgeMenuItemImpl) menuItem).getViewCookie();
        }

        return null;
    }

    public void invalidateRenderingSize() {
        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
    }

    public BufferedImage getImage() {
        return mImage;
    }

    public boolean isAlphaChannelImage() {
        return mIsAlphaChannelImage;
    }

    public List<ViewInfo> getViewInfos() {
        return mViewInfoList;
    }

    public List<ViewInfo> getSystemViewInfos() {
        return mSystemViewInfoList;
    }

    public Map<Object, Map<ResourceReference, ResourceValue>> getDefaultNamespacedProperties() {
        return getContext().getDefaultProperties();
    }

    public Map<Object, String> getDefaultStyles() {
        Map<Object, String> defaultStyles = new IdentityHashMap<>();
        Map<Object, ResourceReference> namespacedStyles = getDefaultNamespacedStyles();
        for (Object key : namespacedStyles.keySet()) {
            ResourceReference style = namespacedStyles.get(key);
            defaultStyles.put(key, style.getQualifiedName());
        }
        return defaultStyles;
    }

    public Map<Object, ResourceReference> getDefaultNamespacedStyles() {
        return getContext().getDefaultNamespacedStyles();
    }

    public void setScene(RenderSession session) {
        mScene = session;
    }

    public RenderSession getSession() {
        return mScene;
    }

    public void dispose() {
        boolean createdLooper = false;
        if (Looper.myLooper() == null) {
            // Detaching the root view from the window will try to stop any running animations.
            // The stop method checks that it can run in the looper so, if there is no current
            // looper, we create a temporary one to complete the shutdown.
            Bridge.prepareThread();
            createdLooper = true;
        }
        AttachInfo_Accessor.detachFromWindow(mViewRoot);
        if (mCanvas != null) {
            mCanvas.release();
            mCanvas = null;
        }
        if (mViewInfoList != null) {
            mViewInfoList.clear();
        }
        if (mSystemViewInfoList != null) {
            mSystemViewInfoList.clear();
        }
        mImage = null;
        mViewRoot = null;
        mContentRoot = null;
        NinePatch_Delegate.clearCache();

        if (createdLooper) {
            Choreographer_Delegate.dispose();
            Bridge.cleanupThread();
        }
    }
}
