/*
 * Copyright (C) 2008 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 android.widget.cts;

import junit.framework.Assert;

import org.xmlpull.v1.XmlPullParser;

import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.cts.util.PollingCheck;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.Xml;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.animation.LayoutAnimationController;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.cts.R;
import android.widget.cts.util.ViewTestUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

public class ListViewTest extends ActivityInstrumentationTestCase2<ListViewCtsActivity> {
    private final String[] mCountryList = new String[] {
        "Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States"
    };
    private final String[] mNameList = new String[] {
        "Jacky", "David", "Kevin", "Michael", "Andy"
    };
    private final String[] mEmptyList = new String[0];

    private ListView mListView;
    private Activity mActivity;
    private Instrumentation mInstrumentation;
    private AttributeSet mAttributeSet;
    private ArrayAdapter<String> mAdapter_countries;
    private ArrayAdapter<String> mAdapter_names;
    private ArrayAdapter<String> mAdapter_empty;

    public ListViewTest() {
        super("android.widget.cts", ListViewCtsActivity.class);
    }

    protected void setUp() throws Exception {
        super.setUp();

        mActivity = getActivity();
        mInstrumentation = getInstrumentation();
        XmlPullParser parser = mActivity.getResources().getXml(R.layout.listview_layout);
        mAttributeSet = Xml.asAttributeSet(parser);

        mAdapter_countries = new ArrayAdapter<String>(mActivity,
                android.R.layout.simple_list_item_1, mCountryList);
        mAdapter_names = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
                mNameList);
        mAdapter_empty = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
                mEmptyList);

        mListView = (ListView) mActivity.findViewById(R.id.listview_default);
    }

    public void testConstructor() {
        new ListView(mActivity);
        new ListView(mActivity, mAttributeSet);
        new ListView(mActivity, mAttributeSet, 0);

        try {
            new ListView(null);
            fail("There should be a NullPointerException thrown out. ");
        } catch (NullPointerException e) {
            // expected, test success.
        }

        try {
            new ListView(null, null);
            fail("There should be a NullPointerException thrown out. ");
        } catch (NullPointerException e) {
            // expected, test success.
        }

        try {
            new ListView(null, null, -1);
            fail("There should be a NullPointerException thrown out. ");
        } catch (NullPointerException e) {
            // expected, test success.
        }
    }

    public void testGetMaxScrollAmount() {
        setAdapter(mAdapter_empty);
        int scrollAmount = mListView.getMaxScrollAmount();
        assertEquals(0, scrollAmount);

        setAdapter(mAdapter_names);
        scrollAmount = mListView.getMaxScrollAmount();
        assertTrue(scrollAmount > 0);
    }

    private void setAdapter(final ArrayAdapter<String> adapter) {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(adapter));
    }

    public void testAccessDividerHeight() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        Drawable d = mListView.getDivider();
        final Rect r = d.getBounds();
        new PollingCheck() {
            @Override
            protected boolean check() {
                return r.bottom - r.top > 0;
            }
        }.run();

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setDividerHeight(20));

        assertEquals(20, mListView.getDividerHeight());
        assertEquals(20, r.bottom - r.top);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setDividerHeight(10));

        assertEquals(10, mListView.getDividerHeight());
        assertEquals(10, r.bottom - r.top);
    }

    public void testAccessItemsCanFocus() {
        mListView.setItemsCanFocus(true);
        assertTrue(mListView.getItemsCanFocus());

        mListView.setItemsCanFocus(false);
        assertFalse(mListView.getItemsCanFocus());

        // TODO: how to check?
    }

    public void testAccessAdapter() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        assertSame(mAdapter_countries, mListView.getAdapter());
        assertEquals(mCountryList.length, mListView.getCount());

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_names));

        assertSame(mAdapter_names, mListView.getAdapter());
        assertEquals(mNameList.length, mListView.getCount());
    }

    @UiThreadTest
    public void testAccessItemChecked() {
        // NONE mode
        mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
        assertEquals(ListView.CHOICE_MODE_NONE, mListView.getChoiceMode());

        mListView.setItemChecked(1, true);
        assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
        assertFalse(mListView.isItemChecked(1));

        // SINGLE mode
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        assertEquals(ListView.CHOICE_MODE_SINGLE, mListView.getChoiceMode());

        mListView.setItemChecked(2, true);
        assertEquals(2, mListView.getCheckedItemPosition());
        assertTrue(mListView.isItemChecked(2));

        mListView.setItemChecked(3, true);
        assertEquals(3, mListView.getCheckedItemPosition());
        assertTrue(mListView.isItemChecked(3));
        assertFalse(mListView.isItemChecked(2));

        // test attempt to uncheck a item that wasn't checked to begin with
        mListView.setItemChecked(4, false);
        // item three should still be checked
        assertEquals(3, mListView.getCheckedItemPosition());
        assertFalse(mListView.isItemChecked(4));
        assertTrue(mListView.isItemChecked(3));
        assertFalse(mListView.isItemChecked(2));

        mListView.setItemChecked(4, true);
        assertTrue(mListView.isItemChecked(4));
        mListView.clearChoices();
        assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
        assertFalse(mListView.isItemChecked(4));

        // MULTIPLE mode
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        assertEquals(ListView.CHOICE_MODE_MULTIPLE, mListView.getChoiceMode());

        mListView.setItemChecked(1, true);
        assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
        SparseBooleanArray array = mListView.getCheckedItemPositions();
        assertTrue(array.get(1));
        assertFalse(array.get(2));
        assertTrue(mListView.isItemChecked(1));
        assertFalse(mListView.isItemChecked(2));

        mListView.setItemChecked(2, true);
        mListView.setItemChecked(3, false);
        mListView.setItemChecked(4, true);

        assertTrue(array.get(1));
        assertTrue(array.get(2));
        assertFalse(array.get(3));
        assertTrue(array.get(4));
        assertTrue(mListView.isItemChecked(1));
        assertTrue(mListView.isItemChecked(2));
        assertFalse(mListView.isItemChecked(3));
        assertTrue(mListView.isItemChecked(4));

        mListView.clearChoices();
        assertFalse(array.get(1));
        assertFalse(array.get(2));
        assertFalse(array.get(3));
        assertFalse(array.get(4));
        assertFalse(mListView.isItemChecked(1));
        assertFalse(mListView.isItemChecked(2));
        assertFalse(mListView.isItemChecked(3));
        assertFalse(mListView.isItemChecked(4));
    }

    public void testAccessFooterView() {
        final TextView footerView1 = new TextView(mActivity);
        footerView1.setText("footerview1");
        final TextView footerView2 = new TextView(mActivity);
        footerView2.setText("footerview2");

        mInstrumentation.runOnMainSync(() -> mListView.setFooterDividersEnabled(true));
        assertEquals(0, mListView.getFooterViewsCount());

        mInstrumentation.runOnMainSync(() -> mListView.addFooterView(footerView1, null, true));
        assertEquals(1, mListView.getFooterViewsCount());

        mInstrumentation.runOnMainSync(() -> mListView.addFooterView(footerView2));

        mInstrumentation.waitForIdleSync();
        assertEquals(2, mListView.getFooterViewsCount());

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.removeFooterView(footerView1));
        assertEquals(1, mListView.getFooterViewsCount());

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.removeFooterView(footerView2));
        assertEquals(0, mListView.getFooterViewsCount());
    }

    public void testAccessHeaderView() {
        final TextView headerView1 = (TextView) mActivity.findViewById(R.id.headerview1);
        final TextView headerView2 = (TextView) mActivity.findViewById(R.id.headerview2);

        mInstrumentation.runOnMainSync(() -> mListView.setHeaderDividersEnabled(true));
        assertEquals(0, mListView.getHeaderViewsCount());

        mInstrumentation.runOnMainSync(() -> mListView.addHeaderView(headerView2, null, true));
        assertEquals(1, mListView.getHeaderViewsCount());

        mInstrumentation.runOnMainSync(() -> mListView.addHeaderView(headerView1));
        assertEquals(2, mListView.getHeaderViewsCount());
    }

    public void testHeaderFooterType() throws Throwable {
        final TextView headerView = new TextView(getActivity());
        final List<Pair<View, View>> mismatch = new ArrayList<Pair<View, View>>();
        final ArrayAdapter adapter = new ArrayAdapter<String>(mActivity,
                android.R.layout.simple_list_item_1, mNameList) {
            @Override
            public int getItemViewType(int position) {
                return position == 0 ? AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER :
                        super.getItemViewType(position - 1);
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (position == 0) {
                    if (convertView != null && convertView != headerView) {
                        mismatch.add(new Pair<View, View>(headerView, convertView));
                    }
                    return headerView;
                } else {
                    return super.getView(position - 1, convertView, parent);
                }
            }

            @Override
            public int getCount() {
                return super.getCount() + 1;
            }
        };
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(adapter));

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> adapter.notifyDataSetChanged());

        assertEquals(0, mismatch.size());
    }

    public void testAccessDivider() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        Drawable defaultDrawable = mListView.getDivider();
        final Rect r = defaultDrawable.getBounds();
        new PollingCheck() {
            @Override
            protected boolean check() {
                return r.bottom - r.top > 0;
            }
        }.run();

        final Drawable d = mActivity.getResources().getDrawable(R.drawable.scenery);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setDivider(d));
        assertSame(d, mListView.getDivider());
        assertEquals(d.getBounds().height(), mListView.getDividerHeight());

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setDividerHeight(10));
        assertEquals(10, mListView.getDividerHeight());
        assertEquals(10, d.getBounds().height());
    }

    public void testSetSelection() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setSelection(1));
        String item = (String) mListView.getSelectedItem();
        assertEquals(mCountryList[1], item);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setSelectionFromTop(5, 0));
        item = (String) mListView.getSelectedItem();
        assertEquals(mCountryList[5], item);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setSelectionAfterHeaderView());
        item = (String) mListView.getSelectedItem();
        assertEquals(mCountryList[0], item);
    }

    public void testOnKeyUpDown() {
        // implementation details, do NOT test
    }

    public void testPerformItemClick() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setSelection(2));

        final TextView child = (TextView) mAdapter_countries.getView(2, null, mListView);
        assertNotNull(child);
        assertEquals(mCountryList[2], child.getText().toString());
        final long itemID = mAdapter_countries.getItemId(2);
        assertEquals(2, itemID);

        mInstrumentation.runOnMainSync(() -> mListView.performItemClick(child, 2, itemID));
        mInstrumentation.waitForIdleSync();

        OnItemClickListener onClickListener = mock(OnItemClickListener.class);
        mListView.setOnItemClickListener(onClickListener);
        verify(onClickListener, never()).onItemClick(any(AdapterView.class), any(View.class),
                anyInt(), anyLong());

        mInstrumentation.runOnMainSync(() -> mListView.performItemClick(child, 2, itemID));
        mInstrumentation.waitForIdleSync();

        verify(onClickListener, times(1)).onItemClick(mListView, child, 2, 2L);
        verifyNoMoreInteractions(onClickListener);
    }

    public void testSaveAndRestoreInstanceState() {
        // implementation details, do NOT test
    }

    public void testDispatchKeyEvent() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> {
                    mListView.setAdapter(mAdapter_countries);
                    mListView.requestFocus();
                });
        assertTrue(mListView.hasFocus());

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setSelection(1));
        String item = (String) mListView.getSelectedItem();
        assertEquals(mCountryList[1], item);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () ->  {
                    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
                    mListView.dispatchKeyEvent(keyEvent);
                });

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> {
                    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DPAD_DOWN);
                    mListView.dispatchKeyEvent(keyEvent);
                    mListView.dispatchKeyEvent(keyEvent);
                    mListView.dispatchKeyEvent(keyEvent);
                });
        item = (String)mListView.getSelectedItem();
        assertEquals(mCountryList[4], item);
    }

    public void testRequestChildRectangleOnScreen() {
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> mListView.setAdapter(mAdapter_countries));

        TextView child = (TextView) mAdapter_countries.getView(0, null, mListView);
        assertNotNull(child);
        assertEquals(mCountryList[0], child.getText().toString());

        Rect rect = new Rect(0, 0, 10, 10);
        assertFalse(mListView.requestChildRectangleOnScreen(child, rect, false));

        // TODO: how to check?
    }

    public void testOnTouchEvent() {
        // implementation details, do NOT test
    }

    @UiThreadTest
    public void testCanAnimate() {
        MyListView listView = new MyListView(mActivity, mAttributeSet);

        assertFalse(listView.canAnimate());
        listView.setAdapter(mAdapter_countries);
        assertFalse(listView.canAnimate());

        LayoutAnimationController controller = new LayoutAnimationController(
                mActivity, mAttributeSet);
        listView.setLayoutAnimation(controller);

        assertTrue(listView.canAnimate());
    }

    @UiThreadTest
    public void testDispatchDraw() {
        // implementation details, do NOT test
    }

    @UiThreadTest
    public void testFindViewTraversal() {
        MyListView listView = new MyListView(mActivity, mAttributeSet);
        TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);

        assertNull(listView.findViewTraversal(R.id.headerview1));

        listView.addHeaderView(headerView);
        assertNotNull(listView.findViewTraversal(R.id.headerview1));
        assertSame(headerView, listView.findViewTraversal(R.id.headerview1));
    }

    @UiThreadTest
    public void testFindViewWithTagTraversal() {
        MyListView listView = new MyListView(mActivity, mAttributeSet);
        TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);

        assertNull(listView.findViewWithTagTraversal("header"));

        headerView.setTag("header");
        listView.addHeaderView(headerView);
        assertNotNull(listView.findViewWithTagTraversal("header"));
        assertSame(headerView, listView.findViewWithTagTraversal("header"));
    }

    public void testLayoutChildren() {
        // TODO: how to test?
    }

    public void testOnFinishInflate() {
        // implementation details, do NOT test
    }

    public void testOnFocusChanged() {
        // implementation details, do NOT test
    }

    public void testOnMeasure() {
        // implementation details, do NOT test
    }

    /**
     * MyListView for test
     */
    private static class MyListView extends ListView {
        public MyListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        protected boolean canAnimate() {
            return super.canAnimate();
        }

        @Override
        protected void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
        }

        @Override
        protected View findViewTraversal(int id) {
            return super.findViewTraversal(id);
        }

        @Override
        protected View findViewWithTagTraversal(Object tag) {
            return super.findViewWithTagTraversal(tag);
        }

        @Override
        protected void layoutChildren() {
            super.layoutChildren();
        }
    }

    /**
     * The following functions are merged from frameworktest.
     */
    @MediumTest
    public void testRequestLayoutCallsMeasure() throws Exception {
        ListView listView = new ListView(mActivity);
        List<String> items = new ArrayList<>();
        items.add("hello");
        Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
        listView.setAdapter(adapter);

        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);

        adapter.notifyDataSetChanged();
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);

        MockView childView = (MockView) listView.getChildAt(0);

        childView.requestLayout();
        childView.onMeasureCalled = false;
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);
        Assert.assertTrue(childView.onMeasureCalled);
    }

    @MediumTest
    public void testNoSelectableItems() throws Exception {
        ListView listView = new ListView(mActivity);
        // We use a header as the unselectable item to remain after the selectable one is removed.
        listView.addHeaderView(new View(mActivity), null, false);
        List<String> items = new ArrayList<>();
        items.add("hello");
        Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
        listView.setAdapter(adapter);

        listView.setSelection(1);

        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);

        adapter.notifyDataSetChanged();
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);

        items.remove(0);

        adapter.notifyDataSetChanged();
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);
    }

    @MediumTest
    public void testFullDetachHeaderViewOnScroll() {
        final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000));
            mListView.addHeaderView(header);
        });
        assertEquals("test sanity", 1, header.mOnAttachCount);
        assertEquals("test sanity", 0, header.mOnDetachCount);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.scrollListBy(mListView.getHeight() * 3);
        });
        assertNull("test sanity, header should be removed", header.getParent());
        assertEquals("header view should be detached", 1, header.mOnDetachCount);
        assertFalse(header.isTemporarilyDetached());
    }

    @MediumTest
    public void testFullDetachHeaderViewOnRelayout() {
        final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000));
            mListView.addHeaderView(header);
        });
        assertEquals("test sanity", 1, header.mOnAttachCount);
        assertEquals("test sanity", 0, header.mOnDetachCount);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setSelection(800);
        });
        assertNull("test sanity, header should be removed", header.getParent());
        assertEquals("header view should be detached", 1, header.mOnDetachCount);
        assertFalse(header.isTemporarilyDetached());
    }

    @MediumTest
    public void testFullDetachHeaderViewOnScrollForFocus() {
        final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000));
            mListView.addHeaderView(header);
        });
        assertEquals("test sanity", 1, header.mOnAttachCount);
        assertEquals("test sanity", 0, header.mOnDetachCount);
        while(header.getParent() != null) {
            assertEquals("header view should NOT be detached", 0, header.mOnDetachCount);
            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
            ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
        }
        assertEquals("header view should be detached", 1, header.mOnDetachCount);
        assertFalse(header.isTemporarilyDetached());
    }

    @MediumTest
    public void testFullyDetachUnusedViewOnScroll() {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000, theView));
        });
        assertEquals("test sanity", 1, theView.mOnAttachCount);
        assertEquals("test sanity", 0, theView.mOnDetachCount);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.scrollListBy(mListView.getHeight() * 2);
        });
        assertNull("test sanity, unused view should be removed", theView.getParent());
        assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.scrollListBy(-mListView.getHeight() * 2);
            // listview limits scroll to 1 page which is why we call it twice here.
            mListView.scrollListBy(-mListView.getHeight() * 2);
        });
        assertNotNull("test sanity, view should be re-added", theView.getParent());
        assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
        assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
    }

    @MediumTest
    public void testFullyDetachUnusedViewOnReLayout() {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000, theView));
        });
        assertEquals("test sanity", 1, theView.mOnAttachCount);
        assertEquals("test sanity", 0, theView.mOnDetachCount);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setSelection(800);
        });
        assertNull("test sanity, unused view should be removed", theView.getParent());
        assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setSelection(0);
        });
        assertNotNull("test sanity, view should be re-added", theView.getParent());
        assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
        assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
    }

    @MediumTest
    public void testFullyDetachUnusedViewOnScrollForFocus() {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setAdapter(new DummyAdapter(1000, theView));
        });
        assertEquals("test sanity", 1, theView.mOnAttachCount);
        assertEquals("test sanity", 0, theView.mOnDetachCount);
        while(theView.getParent() != null) {
            assertEquals("the view should NOT be detached", 0, theView.mOnDetachCount);
            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
            ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
        }
        assertEquals("the view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        while(theView.getParent() == null) {
            sendKeys(KeyEvent.KEYCODE_DPAD_UP);
            ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
        }
        assertEquals("the view should be re-attached", 2, theView.mOnAttachCount);
        assertEquals("the view should not recieve another detach", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
    }

    @MediumTest
    public void testSetPadding() {
        View view = new View(mActivity);
        view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        view.setMinimumHeight(30);
        final DummyAdapter adapter = new DummyAdapter(2, view);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setLayoutParams(new LinearLayout.LayoutParams(200, 100));
            mListView.setAdapter(adapter);
        });
        assertEquals("test sanity", 200, mListView.getWidth());
        assertEquals(200, view.getWidth());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setPadding(10, 0, 5, 0);
            assertTrue(view.isLayoutRequested());
        });
        assertEquals(185, view.getWidth());
        assertFalse(view.isLayoutRequested());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setPadding(10, 0, 5, 0);
            assertFalse(view.isLayoutRequested());
        });
    }

    @MediumTest
    public void testResolveRtlOnReAttach() {
        View spacer = new View(getActivity());
        spacer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                250));
        final DummyAdapter adapter = new DummyAdapter(50, spacer);
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
            mListView.setLayoutParams(new LinearLayout.LayoutParams(200, 150));
            mListView.setAdapter(adapter);
        });
        assertEquals("test sanity", 1, mListView.getChildCount());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            // we scroll in pieces because list view caps scroll by its height
            mListView.scrollListBy(100);
            mListView.scrollListBy(100);
            mListView.scrollListBy(60);
        });
        assertEquals("test sanity", 1, mListView.getChildCount());
        assertEquals("test sanity", 1, mListView.getFirstVisiblePosition());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.scrollListBy(-100);
            mListView.scrollListBy(-100);
            mListView.scrollListBy(-60);
        });
        assertEquals("test sanity", 1, mListView.getChildCount());
        assertEquals("item 0 should be visible", 0, mListView.getFirstVisiblePosition());
        ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
            mListView.scrollListBy(100);
            mListView.scrollListBy(100);
            mListView.scrollListBy(60);
        });
        assertEquals("test sanity", 1, mListView.getChildCount());
        assertEquals("test sanity", 1, mListView.getFirstVisiblePosition());

        assertEquals("the view's RTL properties must be resolved",
                mListView.getChildAt(0).getLayoutDirection(), View.LAYOUT_DIRECTION_RTL);
    }

    private class MockView extends View {

        public boolean onMeasureCalled = false;

        public MockView(Context context) {
            super(context);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            onMeasureCalled = true;
        }
    }

    private class Adapter<T> extends ArrayAdapter<T> {

        public Adapter(Context context, int resource, List<T> objects) {
            super(context, resource, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return new MockView(getContext());
        }
    }

    @MediumTest
    public void testRequestLayoutWithTemporaryDetach() throws Exception {
        ListView listView = new ListView(mActivity);
        List<String> items = new ArrayList<>();
        items.add("0");
        items.add("1");
        items.add("2");
        final TemporarilyDetachableMockViewAdapter<String> adapter =
                new TemporarilyDetachableMockViewAdapter<>(
                        mActivity, android.R.layout.simple_list_item_1, items);
        mInstrumentation.runOnMainSync(() -> {
            listView.setAdapter(adapter);
            mActivity.setContentView(listView);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(items.size(), listView.getCount());
        final TemporarilyDetachableMockView childView0 =
                (TemporarilyDetachableMockView) listView.getChildAt(0);
        final TemporarilyDetachableMockView childView1 =
                (TemporarilyDetachableMockView) listView.getChildAt(1);
        final TemporarilyDetachableMockView childView2 =
                (TemporarilyDetachableMockView) listView.getChildAt(2);
        assertNotNull(childView0);
        assertNotNull(childView1);
        assertNotNull(childView2);

        // Make sure that the childView1 has focus.
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, childView1, childView1::requestFocus);
        assertTrue(childView1.isFocused());

        // Make sure that ListView#requestLayout() is optimized when nothing is changed.
        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView, listView::requestLayout);
        assertEquals(childView0, listView.getChildAt(0));
        assertEquals(childView1, listView.getChildAt(1));
        assertEquals(childView2, listView.getChildAt(2));
    }

    private static final int EXACTLY_500_PX = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);

    @MediumTest
    public void testJumpDrawables() {
        FrameLayout layout = new FrameLayout(mActivity);
        ListView listView = new ListView(mActivity);
        ArrayAdapterWithMockDrawable adapter = new ArrayAdapterWithMockDrawable(mActivity);
        for (int i = 0; i < 50; i++) {
            adapter.add(Integer.toString(i));
        }

        // Initial state should jump exactly once during attach.
        mInstrumentation.runOnMainSync(() -> {
            listView.setAdapter(adapter);
            layout.addView(listView, new LayoutParams(LayoutParams.MATCH_PARENT, 200));
            mActivity.setContentView(layout);
        });
        mInstrumentation.waitForIdleSync();
        assertTrue("List is not showing any children", listView.getChildCount() > 0);
        Drawable firstBackground = listView.getChildAt(0).getBackground();
        verify(firstBackground, times(1)).jumpToCurrentState();

        // Lay out views without recycling. This should not jump again.
        mInstrumentation.runOnMainSync(() -> listView.requestLayout());
        mInstrumentation.waitForIdleSync();
        assertSame(firstBackground, listView.getChildAt(0).getBackground());
        verify(firstBackground, times(1)).jumpToCurrentState();

        // If we're on a really big display, we might be in a position where
        // the position we're going to scroll to is already visible, in which
        // case we won't be able to test jump behavior when recycling.
        int lastVisiblePosition = listView.getLastVisiblePosition();
        int targetPosition = adapter.getCount() - 1;
        if (targetPosition <= lastVisiblePosition) {
            return;
        }

        // Reset the call counts before continuing, since the backgrounds may
        // be recycled from either views that were on-screen or in the scrap
        // heap, and those would have slightly different call counts.
        adapter.resetMockBackgrounds();

        // Scroll so that we have new views on screen. This should jump at
        // least once when the view is recycled in a new position (but may be
        // more if it was recycled from a view that was previously on-screen).
        mInstrumentation.runOnMainSync(() -> listView.setSelection(targetPosition));
        mInstrumentation.waitForIdleSync();

        View lastChild = listView.getChildAt(listView.getChildCount() - 1);
        verify(lastChild.getBackground(), atLeast(1)).jumpToCurrentState();

        // Reset the call counts before continuing.
        adapter.resetMockBackgrounds();

        // Scroll back to the top. This should jump at least once when the view
        // is recycled in a new position (but may be more if it was recycled
        // from a view that was previously on-screen).
        mInstrumentation.runOnMainSync(() -> listView.setSelection(0));
        mInstrumentation.waitForIdleSync();

        View firstChild = listView.getChildAt(0);
        verify(firstChild.getBackground(), atLeast(1)).jumpToCurrentState();
    }

    private static class ArrayAdapterWithMockDrawable extends ArrayAdapter<String> {
        private SparseArray<Drawable> mBackgrounds = new SparseArray<>();

        public ArrayAdapterWithMockDrawable(Context context) {
            super(context, android.R.layout.simple_list_item_1);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final View view = super.getView(position, convertView, parent);
            if (view.getBackground() == null) {
                view.setBackground(spy(new ColorDrawable(Color.BLACK)));
            }
            return view;
        }

        public void resetMockBackgrounds() {
            for (int i = 0; i < mBackgrounds.size(); i++) {
                Drawable background = mBackgrounds.valueAt(i);
                reset(background);
            }
        }
    }

    private class TemporarilyDetachableMockView extends View {

        private boolean mIsDispatchingStartTemporaryDetach = false;
        private boolean mIsDispatchingFinishTemporaryDetach = false;

        public TemporarilyDetachableMockView(Context context) {
            super(context);
        }

        @Override
        public void dispatchStartTemporaryDetach() {
            mIsDispatchingStartTemporaryDetach = true;
            super.dispatchStartTemporaryDetach();
            mIsDispatchingStartTemporaryDetach = false;
        }

        @Override
        public void dispatchFinishTemporaryDetach() {
            mIsDispatchingFinishTemporaryDetach = true;
            super.dispatchFinishTemporaryDetach();
            mIsDispatchingFinishTemporaryDetach = false;
        }

        @Override
        public void onStartTemporaryDetach() {
            super.onStartTemporaryDetach();
            if (!mIsDispatchingStartTemporaryDetach) {
                throw new IllegalStateException("#onStartTemporaryDetach() must be indirectly"
                        + " called via #dispatchStartTemporaryDetach()");
            }
        }

        @Override
        public void onFinishTemporaryDetach() {
            super.onFinishTemporaryDetach();
            if (!mIsDispatchingFinishTemporaryDetach) {
                throw new IllegalStateException("#onStartTemporaryDetach() must be indirectly"
                        + " called via #dispatchFinishTemporaryDetach()");
            }
        }
    }

    private class TemporarilyDetachableMockViewAdapter<T> extends ArrayAdapter<T> {
        ArrayList<TemporarilyDetachableMockView> views = new ArrayList<>();

        public TemporarilyDetachableMockViewAdapter(Context context, int textViewResourceId,
                List<T> objects) {
            super(context, textViewResourceId, objects);
            for (int i = 0; i < objects.size(); i++) {
                views.add(new TemporarilyDetachableMockView(context));
                views.get(i).setFocusable(true);
            }
        }

        @Override
        public int getCount() {
            return views.size();
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return views.get(position);
        }
    }

    public void testTransientStateUnstableIds() throws Exception {
        final ListView listView = mListView;
        final ArrayList<String> items = new ArrayList<String>(Arrays.asList(mCountryList));
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity,
                android.R.layout.simple_list_item_1, items);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
                () -> listView.setAdapter(adapter));

        final View oldItem = listView.getChildAt(2);
        final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
                .getText();
        oldItem.setHasTransientState(true);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
                () -> {
                    adapter.remove(adapter.getItem(0));
                    adapter.notifyDataSetChanged();
                });

        final View newItem = listView.getChildAt(2);
        final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
                .getText();

        Assert.assertFalse(oldText.equals(newText));
    }

    public void testTransientStateStableIds() throws Exception {
        final ListView listView = mListView;
        final ArrayList<String> items = new ArrayList<String>(Arrays.asList(mCountryList));
        final StableArrayAdapter<String> adapter = new StableArrayAdapter<String>(mActivity,
                android.R.layout.simple_list_item_1, items);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView,
                () -> listView.setAdapter(adapter));

        final Object tag = new Object();
        final View oldItem = listView.getChildAt(2);
        final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
                .getText();
        oldItem.setHasTransientState(true);
        oldItem.setTag(tag);

        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView,
                () -> {
                    adapter.remove(adapter.getItem(0));
                    adapter.notifyDataSetChanged();
                });

        final View newItem = listView.getChildAt(1);
        final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
                .getText();

        Assert.assertTrue(newItem.hasTransientState());
        Assert.assertEquals(oldText, newText);
        Assert.assertEquals(tag, newItem.getTag());
    }

    private static class StableArrayAdapter<T> extends ArrayAdapter<T> {
        public StableArrayAdapter(Context context, int resource, List<T> objects) {
            super(context, resource, objects);
        }

        @Override
        public long getItemId(int position) {
            return getItem(position).hashCode();
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
}
