/*
 * 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 static com.android.compatibility.common.util.CtsMockitoUtils.within;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.ActionMode;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EdgeEffect;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.cts.util.TestUtils;
import android.widget.cts.util.TestUtilsMatchers;

import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.compatibility.common.util.CtsKeyEventUtil;
import com.android.compatibility.common.util.CtsTouchUtils;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.WidgetTestUtils;

import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.invocation.InvocationOnMock;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

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

@SmallTest
@RunWith(AndroidJUnit4.class)
public class AbsListViewTest {
    private static final String[] SHORT_LIST = new String[] { "This", "is", "short", "!" };

    private static final String[] COUNTRY_LIST = new String[] {
            "Argentina", "Armenia", "Aruba", "Australia", "Belarus", "Belgium", "Belize", "Benin",
            "Botswana", "Brazil", "Cameroon", "China", "Colombia", "Costa Rica", "Cyprus",
            "Denmark", "Djibouti", "Ethiopia", "Fiji", "Finland", "France", "Gabon", "Germany",
            "Ghana", "Haiti", "Honduras", "Iceland", "India", "Indonesia", "Ireland", "Italy",
            "Japan", "Kiribati", "Laos", "Lesotho", "Liberia", "Malaysia", "Mongolia", "Myanmar",
            "Nauru", "Norway", "Oman", "Pakistan", "Philippines", "Portugal", "Romania", "Russia",
            "Rwanda", "Singapore", "Slovakia", "Slovenia", "Somalia", "Swaziland", "Togo", "Tuvalu",
            "Uganda", "Ukraine", "United States", "Vanuatu", "Venezuela", "Zimbabwe"
    };

    @Rule
    public ActivityTestRule<ListViewCtsActivity> mActivityRule =
            new ActivityTestRule<>(ListViewCtsActivity.class);

    private Instrumentation mInstrumentation;
    private AbsListView mListView;
    private Context mContext;
    private AttributeSet mAttributeSet;
    private ArrayAdapter<String> mShortAdapter;
    private ArrayAdapter<String> mCountriesAdapter;
    private AbsListView.MultiChoiceModeListener mMultiChoiceModeListener;

    private static final float DELTA = 0.001f;

    @Before
    public void setup() throws Throwable {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        final Activity activity = mActivityRule.getActivity();
        // Always use the activity context
        mContext = activity;

        PollingCheck.waitFor(activity::hasWindowFocus);

        XmlPullParser parser = mContext.getResources().getXml(R.layout.listview_layout);
        WidgetTestUtils.beginDocument(parser, "FrameLayout");
        mAttributeSet = Xml.asAttributeSet(parser);

        mShortAdapter = new ArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, SHORT_LIST);
        mCountriesAdapter = new ArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, COUNTRY_LIST);

        mListView = (ListView) activity.findViewById(R.id.listview_default);

        // Full-height drag gestures clash with system navigation gestures (such as
        // swipe up from the bottom of the screen to go home). Get the system
        // gesture insets and apply bottom padding on the entire content so
        // that our own drag gestures are processed within the activity.
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, () -> {
            ViewGroup content = activity.findViewById(R.id.content);
            WindowInsets rootWindowInsets = content.getRootWindowInsets();
            Insets systemGestureInsets = rootWindowInsets.getSystemGestureInsets();
            content.setPadding(0, 0, 0, systemGestureInsets.bottom);
        });
    }

    private boolean isWatch() {
        return (mContext.getResources().getConfiguration().uiMode
                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
    }

    @Test
    @UiThreadTest
    public void testAccessFastScrollEnabled_UiThread() {
        mListView.setFastScrollAlwaysVisible(false);
        mListView.setFastScrollEnabled(false);
        assertFalse(mListView.isFastScrollEnabled());

        mListView.setFastScrollAlwaysVisible(true);
        mListView.setFastScrollEnabled(true);
        assertTrue(mListView.isFastScrollEnabled());
    }

    @Test
    public void testAccessFastScrollEnabled() {
        mListView.setFastScrollAlwaysVisible(false);
        mListView.setFastScrollEnabled(false);
        PollingCheck.waitFor(() -> !mListView.isFastScrollEnabled());

        mListView.setFastScrollAlwaysVisible(true);
        mListView.setFastScrollEnabled(true);
        PollingCheck.waitFor(mListView::isFastScrollEnabled);
    }

    @Test
    public void testAccessSmoothScrollbarEnabled() {
        mListView.setSmoothScrollbarEnabled(false);
        assertFalse(mListView.isSmoothScrollbarEnabled());

        mListView.setSmoothScrollbarEnabled(true);
        assertTrue(mListView.isSmoothScrollbarEnabled());
    }

    @Test
    public void testAccessScrollingCacheEnabled() {
        mListView.setScrollingCacheEnabled(false);
        assertFalse(mListView.isScrollingCacheEnabled());

        mListView.setScrollingCacheEnabled(true);
        assertTrue(mListView.isScrollingCacheEnabled());
    }

    private void setAdapter() throws Throwable {
        setAdapter(mCountriesAdapter);
    }

    private void setAdapter(final ListAdapter adapter) throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setAdapter(adapter));
    }

    private void setListSelection(int index) throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setSelection(index));
    }

    @LargeTest
    @Test
    public void testSetOnScrollListener() throws Throwable {
        mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        AbsListView.OnScrollListener mockScrollListener =
                mock(AbsListView.OnScrollListener.class);

        verifyZeroInteractions(mockScrollListener);

        mListView.setOnScrollListener(mockScrollListener);
        verify(mockScrollListener, times(1)).onScroll(mListView, 0, 0, 0);
        verifyNoMoreInteractions(mockScrollListener);

        reset(mockScrollListener);

        setAdapter();
        verify(mockScrollListener, times(1)).onScroll(mListView, 0, mListView.getChildCount(),
                COUNTRY_LIST.length);
        verifyNoMoreInteractions(mockScrollListener);

        reset(mockScrollListener);

        CtsTouchUtils.emulateScrollToBottom(mInstrumentation, mActivityRule, mListView);

        ArgumentCaptor<Integer> firstVisibleItemCaptor = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> visibleItemCountCaptor = ArgumentCaptor.forClass(Integer.class);
        verify(mockScrollListener, atLeastOnce()).onScroll(eq(mListView),
                firstVisibleItemCaptor.capture(), visibleItemCountCaptor.capture(),
                eq(COUNTRY_LIST.length));

        // We expect the first visible item values to be increasing
        MatcherAssert.assertThat(firstVisibleItemCaptor.getAllValues(),
                TestUtilsMatchers.inAscendingOrder());
        // The number of visible items during scrolling may change depending on the specific
        // scroll position. As such we only test this number at the very end
        final List<Integer> capturedVisibleItemCounts = visibleItemCountCaptor.getAllValues();
        assertEquals(mListView.getChildCount(),
                (int) capturedVisibleItemCounts.get(capturedVisibleItemCounts.size() - 1));

        ArgumentCaptor<Integer> scrollStateCaptor = ArgumentCaptor.forClass(Integer.class);
        verify(mockScrollListener, atLeastOnce()).onScrollStateChanged(eq(mListView),
                scrollStateCaptor.capture());

        // Verify that the last scroll state is IDLE
        final List<Integer> capturedScrollStates = scrollStateCaptor.getAllValues();
        assertEquals(AbsListView.OnScrollListener.SCROLL_STATE_IDLE,
                (int) capturedScrollStates.get(capturedScrollStates.size() - 1));
    }

    @LargeTest
    @Test
    public void testFling() throws Throwable {
        AbsListView.OnScrollListener mockScrollListener = mock(AbsListView.OnScrollListener.class);
        mListView.setOnScrollListener(mockScrollListener);

        setAdapter();

        // Fling down from top, expect a scroll.
        fling(10000, mockScrollListener);
        ArgumentCaptor<Integer> firstVisibleItemCaptor = ArgumentCaptor.forClass(Integer.class);
        verify(mockScrollListener, atLeastOnce()).onScroll(eq(mListView),
                firstVisibleItemCaptor.capture(), anyInt(), eq(COUNTRY_LIST.length));
        List<Integer> capturedFirstVisibleItems = firstVisibleItemCaptor.getAllValues();
        assertTrue(capturedFirstVisibleItems.get(capturedFirstVisibleItems.size() - 1) > 0);

        // Fling up the same amount, expect a scroll to the original position.
        fling(-10000, mockScrollListener);
        firstVisibleItemCaptor = ArgumentCaptor.forClass(Integer.class);
        verify(mockScrollListener, atLeastOnce()).onScroll(eq(mListView),
                firstVisibleItemCaptor.capture(), anyInt(), eq(COUNTRY_LIST.length));
        capturedFirstVisibleItems = firstVisibleItemCaptor.getAllValues();
        assertTrue(capturedFirstVisibleItems.get(capturedFirstVisibleItems.size() - 1) == 0);

        // Fling up again, expect no scroll, as the viewport is already at top.
        fling(-10000, mockScrollListener);
        verify(mockScrollListener, never()).onScroll(any(AbsListView.class), anyInt(), anyInt(),
                anyInt());

        // Fling up again with a huge velocity, expect no scroll.
        fling(-50000, mockScrollListener);
        verify(mockScrollListener, never()).onScroll(any(AbsListView.class), anyInt(), anyInt(),
                anyInt());
    }

    private void fling(int velocityY, OnScrollListener mockScrollListener) throws Throwable {
        reset(mockScrollListener);

        // Fling the list view
        mActivityRule.runOnUiThread(() -> mListView.fling(velocityY));

        // and wait until our mock listener is invoked with IDLE state
        verify(mockScrollListener, within(20000)).onScrollStateChanged(
                mListView, OnScrollListener.SCROLL_STATE_IDLE);
    }

    @Test
    public void testGetFocusedRect() throws Throwable {
        setAdapter(mShortAdapter);
        setListSelection(0);

        Rect r1 = new Rect();
        mListView.getFocusedRect(r1);

        assertEquals(0, r1.top);
        assertTrue(r1.bottom > 0);
        assertEquals(0, r1.left);
        assertTrue(r1.right > 0);

        setListSelection(3);
        Rect r2 = new Rect();
        mListView.getFocusedRect(r2);
        assertTrue(r2.top > 0);
        assertTrue(r2.bottom > 0);
        assertEquals(0, r2.left);
        assertTrue(r2.right > 0);

        assertTrue(r2.top > r1.top);
        assertEquals(r1.bottom - r1.top, r2.bottom - r2.top);
        assertEquals(r1.right, r2.right);
    }

    @Test
    public void testAccessStackFromBottom() throws Throwable {
        setAdapter();

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setStackFromBottom(false));
        assertFalse(mListView.isStackFromBottom());
        assertEquals(0, mListView.getSelectedItemPosition());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setStackFromBottom(true));
        assertTrue(mListView.isStackFromBottom());
        // ensure last item in list is selected
        assertEquals(COUNTRY_LIST.length-1, mListView.getSelectedItemPosition());
    }

    @Test
    public void testAccessSelectedItem() throws Throwable {
        assertNull(mListView.getSelectedView());

        setAdapter();

        final int lastVisiblePosition = mListView.getLastVisiblePosition();

        TextView tv = (TextView) mListView.getSelectedView();
        assertEquals(COUNTRY_LIST[0], tv.getText().toString());

        if (lastVisiblePosition >= 5) {
            setListSelection(5);
            tv = (TextView) mListView.getSelectedView();
            assertEquals(COUNTRY_LIST[5], tv.getText().toString());
        }

        if (lastVisiblePosition >= 2) {
            setListSelection(2);
            tv = (TextView) mListView.getSelectedView();
            assertEquals(COUNTRY_LIST[2], tv.getText().toString());
        }
    }

    @Test
    public void testAccessListPadding() throws Throwable {
        setAdapter();

        assertEquals(0, mListView.getListPaddingLeft());
        assertEquals(0, mListView.getListPaddingTop());
        assertEquals(0, mListView.getListPaddingRight());
        assertEquals(0, mListView.getListPaddingBottom());

        final Rect r = new Rect(0, 0, 40, 60);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setPadding(r.left, r.top, r.right, r.bottom));

        assertEquals(r.left, mListView.getListPaddingLeft());
        assertEquals(r.top, mListView.getListPaddingTop());
        assertEquals(r.right, mListView.getListPaddingRight());
        assertEquals(r.bottom, mListView.getListPaddingBottom());
    }

    @Test
    public void testAccessSelector() throws Throwable {
        setAdapter();

        final Drawable d = mContext.getDrawable(R.drawable.pass);
        mListView.setSelector(d);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, mListView::requestLayout);
        assertSame(d, mListView.getSelector());
        assertTrue(mListView.verifyDrawable(d));

        mListView.setSelector(R.drawable.failed);
        mListView.setDrawSelectorOnTop(true);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, mListView::requestLayout);

        Drawable drawable = mListView.getSelector();
        assertNotNull(drawable);
        final Rect r = drawable.getBounds();

        final TextView v = (TextView) mListView.getSelectedView();
        PollingCheck.waitFor(() -> v.getRight() == r.right);
        assertEquals(v.getLeft(), r.left);
        assertEquals(v.getTop(), r.top);
        assertEquals(v.getBottom(), r.bottom);
    }

    @Test
    public void testSelectorOnScreen() throws Throwable {
        // leave touch-mode
        mInstrumentation.setInTouchMode(false);
        setAdapter();
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, null);
        // Entering touch mode hides selector
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
            // make sure we've left touchmode (including message sending. instrumentation just sets
            // a variable without any broadcast).
            mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_TAB);
            WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, () -> {
                mListView.requestFocus();
                mListView.setSelectionFromTop(1, 0);
            });
            assertEquals(1, mListView.getSelectedItemPosition());
            final int[] pt = new int[2];
            mListView.getLocationOnScreen(pt);
            CtsTouchUtils.emulateDragGesture(mInstrumentation, mActivityRule,
                    pt[0] + 2, pt[1] + 2, 0, 10);
            assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
            // leave touch-mode
            mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_TAB);
        }

        // Scroll off-screen hides selector, but shows up again when on-screen
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, () -> {
            mListView.requestFocus();
            mListView.setSelectionFromTop(1, 0);
        });
        assertEquals(1, mListView.getSelectedItemPosition());
        int selViewHeight = mListView.getSelectedView().getHeight();
        final int[] pt = new int[2];
        mListView.getLocationOnScreen(pt);
        pt[0] += mListView.getWidth() / 2;
        pt[1] += selViewHeight / 2;
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.scrollListBy(selViewHeight * 2));
        assertEquals(1, mListView.getSelectedItemPosition());
        assertFalse(mListView.shouldDrawSelector());
        mActivityRule.runOnUiThread(() -> mListView.scrollListBy(-(selViewHeight * 4) / 3));
        assertEquals(1, mListView.getSelectedItemPosition());
        assertTrue(mListView.shouldDrawSelector());
    }

    @Test
    public void testSetScrollIndicators() throws Throwable {
        final Activity activity = mActivityRule.getActivity();
        TextView tv1 = (TextView) activity.findViewById(R.id.headerview1);
        TextView tv2 = (TextView) activity.findViewById(R.id.footerview1);

        setAdapter();

        mListView.setScrollIndicators(tv1, tv2);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, mListView::requestLayout);
    }

    @Test
    public void testShowContextMenuForChild() throws Throwable {
        setAdapter();
        setListSelection(1);

        TextView tv = (TextView) mListView.getSelectedView();
        assertFalse(mListView.showContextMenuForChild(tv));

        // TODO: how to show the contextMenu success
    }

    @Test
    public void testPointToPosition() throws Throwable {
        assertEquals(AbsListView.INVALID_POSITION, mListView.pointToPosition(-1, -1));
        assertEquals(AbsListView.INVALID_ROW_ID, mListView.pointToRowId(-1, -1));

        setAdapter();

        View row = mListView.getChildAt(0);
        int rowHeight = row.getHeight();
        int middleOfSecondRow = rowHeight + rowHeight/2;

        int position1 = mListView.pointToPosition(0, 0);
        int position2 = mListView.pointToPosition(50, middleOfSecondRow);

        assertEquals(mCountriesAdapter.getItemId(position1), mListView.pointToRowId(0, 0));
        assertEquals(mCountriesAdapter.getItemId(position2),
                mListView.pointToRowId(50, middleOfSecondRow));

        assertTrue(position2 > position1);
    }

    @Test
    public void testSetRecyclerListener() throws Throwable {
        setAdapter();

        AbsListView.RecyclerListener mockRecyclerListener =
                mock(AbsListView.RecyclerListener.class);
        verifyZeroInteractions(mockRecyclerListener);

        mListView.setRecyclerListener(mockRecyclerListener);
        List<View> views = new ArrayList<>();
        mActivityRule.runOnUiThread(() -> mListView.reclaimViews(views));

        assertTrue(views.size() > 0);

        // Verify that onMovedToScrapHeap was called on each view in the order that they were
        // put in the list that we passed to reclaimViews
        final InOrder reclaimedOrder = inOrder(mockRecyclerListener);
        for (View reclaimed : views) {
            reclaimedOrder.verify(mockRecyclerListener, times(1)).onMovedToScrapHeap(reclaimed);
        }
        verifyNoMoreInteractions(mockRecyclerListener);
    }

    @Test
    public void testAccessCacheColorHint() {
        mListView.setCacheColorHint(Color.RED);
        assertEquals(Color.RED, mListView.getCacheColorHint());
        assertEquals(Color.RED, mListView.getSolidColor());

        mListView.setCacheColorHint(Color.LTGRAY);
        assertEquals(Color.LTGRAY, mListView.getCacheColorHint());
        assertEquals(Color.LTGRAY, mListView.getSolidColor());

        mListView.setCacheColorHint(Color.GRAY);
        assertEquals(Color.GRAY, mListView.getCacheColorHint());
        assertEquals(Color.GRAY, mListView.getSolidColor());
    }

    @Test
    public void testAccessTranscriptMode() {
        mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        assertEquals(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL, mListView.getTranscriptMode());

        mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
        assertEquals(AbsListView.TRANSCRIPT_MODE_DISABLED, mListView.getTranscriptMode());

        mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);
        assertEquals(AbsListView.TRANSCRIPT_MODE_NORMAL, mListView.getTranscriptMode());
    }

    @Test
    public void testCheckLayoutParams() {
        MyListView listView = new MyListView(mContext);

        AbsListView.LayoutParams param1 = new AbsListView.LayoutParams(10, 10);
        assertTrue(listView.checkLayoutParams(param1));

        ViewGroup.LayoutParams param2 = new ViewGroup.LayoutParams(10, 10);
        assertFalse(listView.checkLayoutParams(param2));
    }

    @Test
    public void testComputeVerticalScrollValues() {
        MyListView listView = new MyListView(mContext);
        assertEquals(0, listView.computeVerticalScrollRange());
        assertEquals(0, listView.computeVerticalScrollOffset());
        assertEquals(0, listView.computeVerticalScrollExtent());

        listView.setAdapter(mCountriesAdapter);
        listView.setSmoothScrollbarEnabled(false);
        assertEquals(mCountriesAdapter.getCount(), listView.computeVerticalScrollRange());
        assertEquals(0, listView.computeVerticalScrollOffset());
        assertEquals(0, listView.computeVerticalScrollExtent());

        listView.setSmoothScrollbarEnabled(true);
        assertEquals(0, listView.computeVerticalScrollOffset());
        assertEquals(0, listView.computeVerticalScrollExtent());
    }

    @Test
    public void testGenerateLayoutParams() throws XmlPullParserException, IOException {
        ViewGroup.LayoutParams res = mListView.generateLayoutParams(mAttributeSet);
        assertNotNull(res);
        assertTrue(res instanceof AbsListView.LayoutParams);

        MyListView listView = new MyListView(mContext);
        ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        res = listView.generateLayoutParams(p);
        assertNotNull(res);
        assertTrue(res instanceof AbsListView.LayoutParams);
        assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, res.width);
        assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, res.height);
    }

    @UiThreadTest
    @Test
    public void testBeforeAndAfterTextChanged() {
        // The java doc says these two methods do nothing
        CharSequence str = "test";
        SpannableStringBuilder sb = new SpannableStringBuilder();

        mListView.beforeTextChanged(str, 0, str.length(), str.length());
        mListView.afterTextChanged(sb);

        // test callback
        MyListView listView = new MyListView(mContext);
        TextView tv = new TextView(mContext);

        assertFalse(listView.isBeforeTextChangedCalled());
        assertFalse(listView.isOnTextChangedCalled());
        assertFalse(listView.isAfterTextChangedCalled());

        tv.addTextChangedListener(listView);
        assertFalse(listView.isBeforeTextChangedCalled());
        assertFalse(listView.isOnTextChangedCalled());
        assertFalse(listView.isAfterTextChangedCalled());

        tv.setText("abc");
        assertTrue(listView.isBeforeTextChangedCalled());
        assertTrue(listView.isOnTextChangedCalled());
        assertTrue(listView.isAfterTextChangedCalled());
    }

    @Test
    public void testAddTouchables() throws Throwable {
        ArrayList<View> views = new ArrayList<>();
        assertEquals(0, views.size());

        setAdapter();

        mListView.addTouchables(views);
        assertEquals(mListView.getChildCount(), views.size());
    }

    @Test
    public void testInvalidateViews() throws Throwable {
        final Activity activity = mActivityRule.getActivity();
        TextView tv1 = (TextView) activity.findViewById(R.id.headerview1);
        TextView tv2 = (TextView) activity.findViewById(R.id.footerview1);

        setAdapter();

        mListView.setScrollIndicators(tv1, tv2);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView, mListView::invalidateViews);
    }

    @Test
    public void testGetContextMenuInfo() throws Throwable {
        final MyListView listView = new MyListView(mContext, mAttributeSet);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, listView, () ->  {
            mActivityRule.getActivity().setContentView(listView);
            listView.setAdapter(mCountriesAdapter);
            listView.setSelection(2);
        });

        final TextView v = (TextView) listView.getSelectedView();
        assertNull(listView.getContextMenuInfo());

        final AbsListView.OnItemLongClickListener mockOnItemLongClickListener =
                mock(AbsListView.OnItemLongClickListener.class);
        listView.setOnItemLongClickListener(mockOnItemLongClickListener);

        verifyZeroInteractions(mockOnItemLongClickListener);

        // Now long click our view
        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mActivityRule, v, 500);
        // and wait until our mock listener is invoked with the expected view
        verify(mockOnItemLongClickListener, within(5000)).onItemLongClick(listView, v, 2,
                listView.getItemIdAtPosition(2));

        ContextMenuInfo cmi = listView.getContextMenuInfo();
        assertNotNull(cmi);
    }

    @Test
    public void testGetTopBottomFadingEdgeStrength() {
        MyListView listView = new MyListView(mContext);

        assertEquals(0.0f, listView.getTopFadingEdgeStrength(), DELTA);
        assertEquals(0.0f, listView.getBottomFadingEdgeStrength(), DELTA);
    }

    @Test
    public void testHandleDataChanged() {
        MyListView listView = new MyListView(mContext, mAttributeSet, 0);
        listView.handleDataChanged();
        // TODO: how to check?
    }

    @UiThreadTest
    @Test
    public void testSetFilterText() {
        MyListView listView = new MyListView(mContext, mAttributeSet, 0);
        String filterText = "xyz";

        assertFalse(listView.isTextFilterEnabled());
        assertFalse(listView.hasTextFilter());
        assertFalse(listView.isInFilterMode());
        assertTrue(mListView.checkInputConnectionProxy(null));

        listView.setTextFilterEnabled(false);
        listView.setFilterText(filterText);
        assertFalse(listView.isTextFilterEnabled());
        assertFalse(listView.hasTextFilter());
        assertFalse(listView.isInFilterMode());

        listView.setTextFilterEnabled(true);
        listView.setFilterText(null);
        assertTrue(listView.isTextFilterEnabled());
        assertFalse(listView.hasTextFilter());
        assertFalse(listView.isInFilterMode());

        listView.setTextFilterEnabled(true);
        listView.setFilterText(filterText);
        assertTrue(listView.isTextFilterEnabled());
        assertTrue(listView.hasTextFilter());
        assertTrue(listView.isInFilterMode());

        listView.clearTextFilter();
        assertTrue(listView.isTextFilterEnabled());
        assertFalse(listView.hasTextFilter());
        assertFalse(listView.isInFilterMode());
    }

    @MediumTest
    @Test
    public void testSetItemChecked_multipleModeSameValue() throws Throwable {
        // Calling setItemChecked with the same value in multiple choice mode should not cause
        // requestLayout
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
    }

    @MediumTest
    @Test
    public void testSetItemChecked_singleModeSameValue() throws Throwable {
        // Calling setItemChecked with the same value in single choice mode should not cause
        // requestLayout
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
    }
    private boolean checkResult = false;

    @MediumTest
    @Test
    public void testSetItemChecked_multipleModeDifferentValue() throws Throwable {
        // Calling setItemChecked with a different value in multiple choice mode should cause
        // requestLayout
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
        checkResult = false;
        mActivityRule.runOnUiThread(() -> {
            mListView.setItemChecked(0, true);
            checkResult = mListView.isLayoutRequested();
        });
        assertTrue(checkResult);
    }

    @MediumTest
    @Test
    public void testSetItemChecked_singleModeDifferentValue() throws Throwable {
        // Calling setItemChecked with a different value in single choice mode should cause
        // requestLayout
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setItemChecked(0, false));
        assertFalse(mListView.isLayoutRequested());
        checkResult = false;
        mActivityRule.runOnUiThread(() -> {
            mListView.setItemChecked(0, true);
            checkResult = mListView.isLayoutRequested();
        });
        assertTrue(checkResult);
    }

    @LargeTest
    @Test
    public void testTextFilter() throws Throwable {
        setAdapter();

        // Default state - no text filter
        assertFalse(mListView.isTextFilterEnabled());
        assertFalse(mListView.hasTextFilter());
        assertTrue(TextUtils.isEmpty(mListView.getTextFilter()));

        // Enable text filter and verify that while it's enabled, the filtering is
        // still no on
        mActivityRule.runOnUiThread(() -> mListView.setTextFilterEnabled(true));
        assertTrue(mListView.isTextFilterEnabled());
        assertFalse(mListView.hasTextFilter());
        assertTrue(TextUtils.isEmpty(mListView.getTextFilter()));

        // Verify the initial content of the list
        assertEquals(COUNTRY_LIST.length, mListView.getCount());

        // Set text filter to A - we expect four entries to be left displayed in the list
        mActivityRule.runOnUiThread(() -> mListView.setFilterText("A"));
        PollingCheck.waitFor(() -> mListView.getCount() == 4);
        assertTrue(mListView.isTextFilterEnabled());
        assertTrue(mListView.hasTextFilter());
        assertTrue(TextUtils.equals("A", mListView.getTextFilter()));

        // Set text filter to Ar - we expect three entries to be left displayed in the list
        mActivityRule.runOnUiThread(() -> mListView.setFilterText("Ar"));
        PollingCheck.waitFor(() -> mListView.getCount() == 3);
        assertTrue(mListView.isTextFilterEnabled());
        assertTrue(mListView.hasTextFilter());
        assertTrue(TextUtils.equals("Ar", mListView.getTextFilter()));

        // Clear text filter - we expect to go back to the initial content
        mActivityRule.runOnUiThread(() -> mListView.clearTextFilter());
        PollingCheck.waitFor(() -> mListView.getCount() == COUNTRY_LIST.length);
        assertTrue(mListView.isTextFilterEnabled());
        assertFalse(mListView.hasTextFilter());
        assertTrue(TextUtils.isEmpty(mListView.getTextFilter()));

        // Set text filter to Be - we expect four entries to be left displayed in the list
        mActivityRule.runOnUiThread(() -> mListView.setFilterText("Be"));
        PollingCheck.waitFor(() -> mListView.getCount() == 4);
        assertTrue(mListView.isTextFilterEnabled());
        assertTrue(mListView.hasTextFilter());
        assertTrue(TextUtils.equals("Be", mListView.getTextFilter()));

        // Set text filter to Q - we no entries displayed in the list
        mActivityRule.runOnUiThread(() -> mListView.setFilterText("Q"));
        PollingCheck.waitFor(() -> mListView.getCount() == 0);
        assertTrue(mListView.isTextFilterEnabled());
        assertTrue(mListView.hasTextFilter());
        assertTrue(TextUtils.equals("Q", mListView.getTextFilter()));
    }

    @Test
    public void testOnFilterComplete() throws Throwable {
        // Note that we're not using spy() due to Mockito not being able to spy on ListView,
        // at least yet.
        final MyListView listView = new MyListView(mContext, mAttributeSet);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, listView, () -> {
            mActivityRule.getActivity().setContentView(listView);
            listView.setAdapter(mCountriesAdapter);
            listView.setTextFilterEnabled(true);
        });

        // Set text filter to A - we expect four entries to be left displayed in the list
        mActivityRule.runOnUiThread(() -> listView.setFilterText("A"));
        PollingCheck.waitFor(() -> listView.getCount() == 4);
        assertTrue(listView.isTextFilterEnabled());
        assertTrue(listView.hasTextFilter());
        assertTrue(TextUtils.equals("A", listView.getTextFilter()));

        assertEquals(4, listView.getOnFilterCompleteCount());
    }

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

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

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

    private void verifyCheckedState(final long[] expectedCheckedItems) {
        TestUtils.assertIdentical(expectedCheckedItems, mListView.getCheckedItemIds());

        assertEquals(expectedCheckedItems.length, mListView.getCheckedItemCount());

        final long expectedCheckedItemPosition =
                (mListView.getChoiceMode() == AbsListView.CHOICE_MODE_SINGLE) &&
                        (expectedCheckedItems.length == 1)
                        ? expectedCheckedItems[0]
                        : AbsListView.INVALID_POSITION;
        assertEquals(expectedCheckedItemPosition, mListView.getCheckedItemPosition());

        // Note that getCheckedItemPositions doesn't have a guarantee that it only holds
        // true values, which is why we're not doing the size() == 0 check even in the initial
        // state
        TestUtils.assertTrueValuesAtPositions(
                expectedCheckedItems, mListView.getCheckedItemPositions());
    }

    @Test
    @UiThreadTest
    public void testCheckItemCount() throws Throwable {
        final ArrayList<String> items = new ArrayList<>(Arrays.asList(COUNTRY_LIST));
        final ArrayAdapter<String> adapter = new PositionArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, items);
        mListView.setAdapter(adapter);
        mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
        mListView.setItemChecked(0, true);
        mListView.setItemChecked(1, true);
        assertEquals(2, mListView.getCheckedItemCount());

        mListView.setAdapter(adapter);
        assertEquals(0, mListView.getCheckedItemCount());
    }

    @MediumTest
    @Test
    public void testCheckedItemsUnderNoneChoiceMode() throws Throwable {
        final ArrayList<String> items = new ArrayList<>(Arrays.asList(COUNTRY_LIST));
        final ArrayAdapter<String> adapter = new PositionArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, items);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setAdapter(adapter));

        mActivityRule.runOnUiThread(
                () -> mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, true));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, true));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, false));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, false));
        verifyCheckedState(new long[] {});
    }

    @MediumTest
    @Test
    public void testCheckedItemsUnderSingleChoiceMode() throws Throwable {
        final ArrayList<String> items = new ArrayList<>(Arrays.asList(COUNTRY_LIST));
        final ArrayAdapter<String> adapter = new PositionArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, items);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setAdapter(adapter));

        mActivityRule.runOnUiThread(
                () -> mListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, true));
        verifyCheckedState(new long[] { 2 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, true));
        verifyCheckedState(new long[] { 4 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, false));
        verifyCheckedState(new long[] { 4 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, false));
        verifyCheckedState(new long[] {});
    }

    @MediumTest
    @Test
    public void testCheckedItemsUnderMultipleChoiceMode() throws Throwable {
        final ArrayList<String> items = new ArrayList<>(Arrays.asList(COUNTRY_LIST));
        final ArrayAdapter<String> adapter = new PositionArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, items);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setAdapter(adapter));

        mActivityRule.runOnUiThread(
                () -> mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE));
        verifyCheckedState(new long[] {});

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, true));
        verifyCheckedState(new long[] { 2 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, true));
        verifyCheckedState(new long[] { 2, 4 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, false));
        verifyCheckedState(new long[] { 4 });

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, false));
        verifyCheckedState(new long[] {});
    }

    private void configureMultiChoiceModalState() throws Throwable {
        final ArrayList<String> items = new ArrayList<>(Arrays.asList(COUNTRY_LIST));
        final ArrayAdapter<String> adapter = new PositionArrayAdapter<>(mContext,
                android.R.layout.simple_list_item_1, items);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setAdapter(adapter));

        // Configure a multi-choice mode listener to configure our test contextual action bar
        // content. We will subsequently query that listener for calls to its
        // onItemCheckedStateChanged method
        mMultiChoiceModeListener =
                mock(AbsListView.MultiChoiceModeListener.class);
        doAnswer((InvocationOnMock invocation) -> {
            final ActionMode actionMode = (ActionMode) invocation.getArguments() [0];
            final Menu menu = (Menu) invocation.getArguments() [1];
            actionMode.getMenuInflater().inflate(R.menu.cab_menu, menu);
            return true;
        }).when(mMultiChoiceModeListener).onCreateActionMode(
                any(ActionMode.class), any(Menu.class));
        mListView.setMultiChoiceModeListener(mMultiChoiceModeListener);

        mActivityRule.runOnUiThread(
                () -> mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL));
        verifyCheckedState(new long[] {});
    }

    @MediumTest
    @Test
    public void testCheckedItemsUnderMultipleModalChoiceMode() throws Throwable {
        configureMultiChoiceModalState();

        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, true));
        verifyCheckedState(new long[] { 2 });
        if (!isWatch()) {
            verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(2), eq(2L), eq(true));
        }

        reset(mMultiChoiceModeListener);
        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, true));
        verifyCheckedState(new long[] { 2, 4 });
        if (!isWatch()) {
            verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(4), eq(4L), eq(true));
        }

        reset(mMultiChoiceModeListener);
        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, false));
        verifyCheckedState(new long[] { 4 });
        if (!isWatch()) {
            verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(2), eq(2L), eq(false));
        }

        reset(mMultiChoiceModeListener);
        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, false));
        verifyCheckedState(new long[] {});
        mListView.setMultiChoiceModeListener(mMultiChoiceModeListener);
        if (!isWatch()) {
            verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(4), eq(4L), eq(false));
        }
    }

    @LargeTest
    @Test
    public void testMultiSelectionWithLongPressAndTaps() throws Throwable {
        if (isWatch()) {
            return; // watch type devices do not support multichoice action mode
        }
        configureMultiChoiceModalState();
        mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);

        final int firstVisiblePosition = mListView.getFirstVisiblePosition();
        final int lastVisiblePosition = mListView.getLastVisiblePosition();

        // Emulate long-click on the middle item of the currently visible content
        final int positionForInitialSelection = (firstVisiblePosition + lastVisiblePosition) / 2;
        CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mActivityRule,
                mListView.getChildAt(positionForInitialSelection));
        // wait until our listener has been notified that the item has been checked
        verify(mMultiChoiceModeListener, within(1000)).onItemCheckedStateChanged(
                any(ActionMode.class), eq(positionForInitialSelection),
                eq((long) positionForInitialSelection), eq(true));
        // and verify the overall checked state of our list
        verifyCheckedState(new long[] { positionForInitialSelection });

        if (firstVisiblePosition != positionForInitialSelection) {
            // Tap the first element in our list
            CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule,
                    mListView.getChildAt(firstVisiblePosition));
            // wait until our listener has been notified that the item has been checked
            verify(mMultiChoiceModeListener, within(1000)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(firstVisiblePosition),
                    eq((long) firstVisiblePosition), eq(true));
            // and verify the overall checked state of our list
            verifyCheckedState(new long[] { firstVisiblePosition, positionForInitialSelection });
        }

        // Scroll down
        CtsTouchUtils.emulateScrollToBottom(mInstrumentation, mActivityRule, mListView);
        final int lastListPosition = COUNTRY_LIST.length - 1;
        if (lastListPosition != positionForInitialSelection) {
            // Tap the last element in our list
            CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule,
                    mListView.getChildAt(mListView.getChildCount() - 1));
            // wait until our listener has been notified that the item has been checked
            verify(mMultiChoiceModeListener, within(1000)).onItemCheckedStateChanged(
                    any(ActionMode.class), eq(lastListPosition),
                    eq((long) lastListPosition), eq(true));
            // and verify the overall checked state of our list
            verifyCheckedState(new long[] { firstVisiblePosition, positionForInitialSelection,
                    lastListPosition });
        }
    }

    @SmallTest
    @UiThreadTest
    @Test
    public void testEdgeEffectColors() {
        int defaultColor = new EdgeEffect(mListView.getContext()).getColor();
        assertEquals(mListView.getTopEdgeEffectColor(), defaultColor);
        assertEquals(mListView.getBottomEdgeEffectColor(), defaultColor);

        mListView.setEdgeEffectColor(Color.BLUE);
        assertEquals(mListView.getTopEdgeEffectColor(), Color.BLUE);
        assertEquals(mListView.getBottomEdgeEffectColor(), Color.BLUE);

        mListView.setTopEdgeEffectColor(Color.RED);
        assertEquals(mListView.getTopEdgeEffectColor(), Color.RED);
        assertEquals(mListView.getBottomEdgeEffectColor(), Color.BLUE);

        mListView.setBottomEdgeEffectColor(Color.GREEN);
        assertEquals(mListView.getTopEdgeEffectColor(), Color.RED);
        assertEquals(mListView.getBottomEdgeEffectColor(), Color.GREEN);
    }

    // Helper method that emulates fast scroll by dragging along the right edge of our ListView.
    private void verifyFastScroll() throws Throwable {
        setAdapter();

        final int lastVisiblePosition = mListView.getLastVisiblePosition();
        if (lastVisiblePosition == (COUNTRY_LIST.length - 1)) {
            // This can happen on very large screens - the entire content fits and there's
            // nothing to scroll
            return;
        }

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mListView,
                () -> mListView.setFastScrollAlwaysVisible(true));
        assertTrue(mListView.isFastScrollEnabled());
        assertTrue(mListView.isFastScrollAlwaysVisible());

        final int[] listViewOnScreenXY = new int[2];
        mListView.getLocationOnScreen(listViewOnScreenXY);

        final int topEdgeY = listViewOnScreenXY[1];
        final int bottomEdgeY = listViewOnScreenXY[1] + mListView.getHeight();
        final int rightEdgeX = listViewOnScreenXY[0] + mListView.getWidth();

        // Emulate a downwards gesture that should bring us all the way to the last element
        // of the list (when fast scroll is enabled)
        CtsTouchUtils.emulateDragGesture(mInstrumentation, mActivityRule,
                rightEdgeX - 1,              // X start of the drag
                topEdgeY + 1,                // Y start of the drag
                0,                           // X amount of the drag (vertical)
                mListView.getHeight() - 2);  // Y amount of the drag (downwards)

        assertEquals(COUNTRY_LIST.length - 1, mListView.getLastVisiblePosition());

        // Emulate an upwards gesture that should bring us all the way to the first element
        // of the list (when fast scroll is enabled)
        CtsTouchUtils.emulateDragGesture(mInstrumentation, mActivityRule,
                rightEdgeX - 1,               // X start of the drag
                bottomEdgeY - 1,              // Y start of the drag
                0,                            // X amount of the drag (vertical)
                -mListView.getHeight() + 2);  // Y amount of the drag (upwards)

        assertEquals(0, mListView.getFirstVisiblePosition());
    }

    @LargeTest
    @Test
    public void testFastScroll() throws Throwable {
        verifyFastScroll();
    }

    @LargeTest
    @Test
    public void testFastScrollStyle() throws Throwable {
        mListView.setFastScrollStyle(R.style.FastScrollCustomStyle);

        verifyFastScroll();
    }

    @Test
    public void testRequestChildRectangleOnScreen_onScrollChangedCalled() throws Throwable {
        final MyListView listView = new MyListView(mContext, mAttributeSet);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, listView, () -> {
            mActivityRule.getActivity().setContentView(listView);
            listView.setAdapter(mCountriesAdapter);
        });

        View row = listView.getChildAt(0);
        Rect r = new Rect();
        r.set(0, listView.getHeight() - (row.getHeight() >> 1),
                row.getWidth(), listView.getHeight() + (row.getHeight() >> 1));

        listView.resetIsOnScrollChangedCalled();
        assertFalse(listView.isOnScrollChangedCalled());
        listView.requestChildRectangleOnScreen(row, r, true);
        assertTrue(listView.isOnScrollChangedCalled());
    }

    @Test
    public void testEnterKey() throws Throwable {
        final MyListView listView = new MyListView(mContext, mAttributeSet);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, listView, () -> {
            mActivityRule.getActivity().setContentView(listView);
            listView.setAdapter(mCountriesAdapter);
            listView.setTextFilterEnabled(true);
            listView.requestFocus();
        });

        // KEYCODE_ENTER is handled by isConfirmKey, so it comsumed before sendToTextFilter called.
        // because of this, make keyevent with repeat count.
        KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 1);
        CtsKeyEventUtil.sendKey(mInstrumentation, listView, event);
        assertTrue(listView.isTextFilterEnabled());

        // we expect keyevent will be passed with nothing to do
        assertFalse(listView.hasTextFilter());
        assertEquals(-1, listView.getOnFilterCompleteCount());

        // KEYCODE_NUMPAD_ENTER is handled by isConfirmKey, too.
        // so make keyevent with repeat count.
        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_NUMPAD_ENTER, 1);
        CtsKeyEventUtil.sendKey(mInstrumentation, listView, event);
        assertTrue(listView.isTextFilterEnabled());

        // we expect keyevent will be passed with nothing to do, like KEYCODE_ENTER
        assertFalse(listView.hasTextFilter());
        assertEquals(-1, listView.getOnFilterCompleteCount());
    }

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

        public MyListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public MyListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        @Override
        protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
            return super.checkLayoutParams(p);
        }

        @Override
        protected int computeVerticalScrollExtent() {
            return super.computeVerticalScrollExtent();
        }

        @Override
        protected int computeVerticalScrollOffset() {
            return super.computeVerticalScrollOffset();
        }

        @Override
        protected int computeVerticalScrollRange() {
            return super.computeVerticalScrollRange();
        }

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

        @Override
        protected void dispatchSetPressed(boolean pressed) {
            super.dispatchSetPressed(pressed);
        }

        @Override
        protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
            return super.generateLayoutParams(p);
        }

        @Override
        protected float getBottomFadingEdgeStrength() {
            return super.getBottomFadingEdgeStrength();
        }

        @Override
        protected ContextMenuInfo getContextMenuInfo() {
            return super.getContextMenuInfo();
        }

        @Override
        protected float getTopFadingEdgeStrength() {
            return super.getTopFadingEdgeStrength();
        }

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

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

        private boolean mIsBeforeTextChangedCalled;
        private boolean mIsOnTextChangedCalled;
        private boolean mIsAfterTextChangedCalled;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            mIsBeforeTextChangedCalled = true;
            super.beforeTextChanged(s, start, count, after);
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            mIsOnTextChangedCalled = true;
            super.onTextChanged(s, start, before, count);
        }

        @Override
        public void afterTextChanged(Editable s) {
            mIsAfterTextChangedCalled = true;
            super.afterTextChanged(s);
        }

        public boolean isBeforeTextChangedCalled() {
            return mIsBeforeTextChangedCalled;
        }

        public boolean isOnTextChangedCalled() {
            return mIsOnTextChangedCalled;
        }

        public boolean isAfterTextChangedCalled() {
            return mIsAfterTextChangedCalled;
        }

        private int mOnFilterCompleteCount = -1;

        @Override
        public void onFilterComplete(int count) {
            super.onFilterComplete(count);
            mOnFilterCompleteCount = count;
        }

        public int getOnFilterCompleteCount() {
            return mOnFilterCompleteCount;
        }

        private boolean mIsOnScrollChangedCalled;

        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            mIsOnScrollChangedCalled = true;
            super.onScrollChanged(l, t, oldl, oldt);
        }

        public boolean isOnScrollChangedCalled() {
            return mIsOnScrollChangedCalled;
        }

        public void resetIsOnScrollChangedCalled() {
            mIsOnScrollChangedCalled = false;
        }
    }
}
