/*
 * 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 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.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
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 android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.test.ViewAsserts;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.GridLayoutAnimationController.AnimationParameters;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListAdapter;

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.PollingCheck;
import com.android.compatibility.common.util.WidgetTestUtils;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Test {@link GridView}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class GridViewTest {
    private Instrumentation mInstrumentation;
    private Activity mActivity;
    private GridView mGridView;

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

    @Before
    public void setup() {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivity = mActivityRule.getActivity();
        mGridView = (GridView) mActivity.findViewById(R.id.gridview);

        PollingCheck.waitFor(mActivity::hasWindowFocus);
    }

    @Test
    public void testConstructor() {
        new GridView(mActivity);

        new GridView(mActivity, null);

        new GridView(mActivity, null, android.R.attr.gridViewStyle);

        new GridView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_GridView);

        new GridView(mActivity, null, 0, android.R.style.Widget_DeviceDefault_Light_GridView);

        new GridView(mActivity, null, 0, android.R.style.Widget_Material_GridView);

        new GridView(mActivity, null, 0, android.R.style.Widget_Material_Light_GridView);

        XmlPullParser parser = mActivity.getResources().getXml(R.layout.gridview_layout);
        AttributeSet attrs = Xml.asAttributeSet(parser);
        new GridView(mActivity, attrs);
        new GridView(mActivity, attrs, 0);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorNullContext1() {
        new GridView(null);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorNullContext2() {
        new GridView(null, null);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorNullContext3() {
        new GridView(null, null, 0);
    }

    @UiThreadTest
    @Test
    public void testAccessAdapter() {
        // set Adapter
        ImageAdapter adapter = new ImageAdapter(mActivity);
        mGridView.setAdapter(adapter);
        assertSame(adapter, mGridView.getAdapter());

        mGridView.setAdapter(null);
        assertNull(mGridView.getAdapter());
    }

    @UiThreadTest
    @Test
    public void testSetSelection() {
        mGridView.setSelection(0);
        assertEquals(0, mGridView.getSelectedItemPosition());

        mGridView.setSelection(-1);
        assertEquals(-1, mGridView.getSelectedItemPosition());

        mGridView.setSelection(mGridView.getCount());
        assertEquals(mGridView.getCount(), mGridView.getSelectedItemPosition());
    }

    @Test
    public void testPressKey() throws Throwable {
        final int NUM_COLUMNS = 3;

        GridView.OnItemClickListener mockItemClickListener =
                mock(GridView.OnItemClickListener.class);
        mGridView.setOnItemClickListener(mockItemClickListener);

        // this test case can not be ran in UI thread.
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new ImageAdapter(mActivity));
            mGridView.setNumColumns(NUM_COLUMNS);
            mGridView.invalidate();
            mGridView.requestLayout();
            mGridView.requestFocus();
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(0, mGridView.getSelectedItemPosition());
        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
        mInstrumentation.sendKeySync(event);
        assertEquals(1, mGridView.getSelectedItemPosition());

        event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT);
        mInstrumentation.sendKeySync(event);
        assertEquals(0, mGridView.getSelectedItemPosition());

        assertEquals(0, mGridView.getSelectedItemPosition());
        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_RIGHT);
        assertEquals(1, mGridView.getSelectedItemPosition());

        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_LEFT);
        assertEquals(0, mGridView.getSelectedItemPosition());

        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_TAB);
        assertEquals(1, mGridView.getSelectedItemPosition());

        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_TAB, 0,
                KeyEvent.META_SHIFT_LEFT_ON);
        mInstrumentation.sendKeySync(event);
        event = new KeyEvent(0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_TAB, 0,
                KeyEvent.META_SHIFT_LEFT_ON);
        mInstrumentation.sendKeySync(event);
        assertEquals(0, mGridView.getSelectedItemPosition());

        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
        assertEquals(NUM_COLUMNS, mGridView.getSelectedItemPosition());

        verify(mockItemClickListener, never()).onItemClick(any(AdapterView.class), any(View.class),
                anyInt(), anyLong());
        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
        verify(mockItemClickListener, times(1)).onItemClick(eq(mGridView), any(View.class),
                eq(NUM_COLUMNS), eq((long) NUM_COLUMNS));

        reset(mockItemClickListener);
        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
        verify(mockItemClickListener, times(1)).onItemClick(eq(mGridView), any(View.class),
                eq(NUM_COLUMNS), eq((long) NUM_COLUMNS));
    }

    @Test
    public void testSetGravity() throws Throwable {
        final int NUM_COLUMNS = 1;
        // this test case can not be ran in UI thread.
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new ImageAdapter(mActivity));
            mGridView.setNumColumns(NUM_COLUMNS);
            mGridView.setHorizontalSpacing(0);
            mGridView.setVerticalSpacing(0);
        });
        mInstrumentation.waitForIdleSync();

        mActivityRule.runOnUiThread(() -> {
            mGridView.setGravity(Gravity.CENTER_HORIZONTAL);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(Gravity.CENTER_HORIZONTAL, mGridView.getGravity());
        ViewAsserts.assertHorizontalCenterAligned(mGridView, mGridView.getChildAt(0));

        mActivityRule.runOnUiThread(() -> {
            mGridView.setGravity(Gravity.LEFT);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(Gravity.LEFT, mGridView.getGravity());
        ViewAsserts.assertLeftAligned(mGridView, mGridView.getChildAt(0),
                mGridView.getListPaddingLeft());

        mActivityRule.runOnUiThread(() -> {
            mGridView.setGravity(Gravity.RIGHT);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(Gravity.RIGHT, mGridView.getGravity());
        ViewAsserts.assertRightAligned(mGridView, mGridView.getChildAt(0),
                mGridView.getListPaddingRight());
    }

    @Test
    public void testAccessHorizontalSpacing() throws Throwable {
        verifyAccessHorizontalSpacing(View.LAYOUT_DIRECTION_LTR);
    }

    @Test
    public void testAccessHorizontalSpacingRTL() throws Throwable {
        verifyAccessHorizontalSpacing(View.LAYOUT_DIRECTION_RTL);
    }

    private void verifyAccessHorizontalSpacing(final int layoutDir) throws Throwable {
        mActivityRule.runOnUiThread(() -> mGridView.setLayoutDirection(layoutDir));
        mGridView.setStretchMode(GridView.NO_STRETCH);
        // Number of columns should be big enough, otherwise the
        // horizontal spacing cannot be correctly verified.
        mGridView.setNumColumns(28);

        mActivityRule.runOnUiThread(() ->  {
            mGridView.setAdapter(new MockGridViewAdapter(3));
            mGridView.setHorizontalSpacing(0);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(0, mGridView.getRequestedHorizontalSpacing());
        assertEquals(0, mGridView.getHorizontalSpacing());
        View child0 = mGridView.getChildAt(0);
        View child1 = mGridView.getChildAt(1);
        if (layoutDir == View.LAYOUT_DIRECTION_LTR) {
            assertEquals(0, child1.getLeft() - child0.getRight());
        } else {
            assertEquals(0, child0.getLeft() - child1.getRight());
        }

        mActivityRule.runOnUiThread(() -> mGridView.setHorizontalSpacing(5));
        mInstrumentation.waitForIdleSync();

        assertEquals(5, mGridView.getRequestedHorizontalSpacing());
        assertEquals(5, mGridView.getHorizontalSpacing());
        child0 = mGridView.getChildAt(0);
        child1 = mGridView.getChildAt(1);
        if (layoutDir == View.LAYOUT_DIRECTION_LTR) {
            assertEquals(5, child1.getLeft() - child0.getRight());
        } else {
            assertEquals(5, child0.getLeft() - child1.getRight());
        }
    }

    @Test
    public void testAccessVerticalSpacing() throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new MockGridViewAdapter(3));
            mGridView.setVerticalSpacing(0);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(0, mGridView.getVerticalSpacing());
        View child0 = mGridView.getChildAt(0);
        View child1 = mGridView.getChildAt(1);
        assertEquals(0, child1.getTop() - child0.getBottom());

        mActivityRule.runOnUiThread(() -> mGridView.setVerticalSpacing(5));
        mInstrumentation.waitForIdleSync();

        assertEquals(5, mGridView.getVerticalSpacing());
        child0 = mGridView.getChildAt(0);
        child1 = mGridView.getChildAt(1);
        assertEquals(5, child1.getTop() - child0.getBottom());
    }

    @Test
    public void testAccessStretchMode() throws Throwable {
        View child;

        final int NUM_COLUMNS = 8;
        // this test case can not be ran in UI thread.
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new ImageAdapter(mActivity));
            mGridView.setColumnWidth(10);
            mGridView.setNumColumns(NUM_COLUMNS);
            mGridView.setHorizontalSpacing(0);
            mGridView.setVerticalSpacing(0);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();

        int[][] childRight = new int[3][3];
        int STRETCH_SPACING = 0;
        int STRETCH_COLUMN_WIDTH = 1;
        int STRETCH_SPACING_UNIFORM = 2;
        int INDEX_RIGHTMOST = 0;
        int INDEX_0 = 1;
        int INDEX_1 = 2;

        mActivityRule.runOnUiThread(() -> {
            mGridView.setColumnWidth(15);
            mGridView.setStretchMode(GridView.STRETCH_SPACING);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();
        assertEquals(GridView.STRETCH_SPACING, mGridView.getStretchMode());
        child = mGridView.getChildAt(NUM_COLUMNS - 1); // get the rightmost view at the first line.
        childRight[STRETCH_SPACING][INDEX_RIGHTMOST] = child.getRight();

        child = mGridView.getChildAt(0);
        childRight[STRETCH_SPACING][INDEX_0] = child.getRight();

        child = mGridView.getChildAt(1);
        childRight[STRETCH_SPACING][INDEX_1] = child.getRight();

        mActivityRule.runOnUiThread(() -> {
            mGridView.setColumnWidth(15);
            mGridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();
        assertEquals(GridView.STRETCH_COLUMN_WIDTH, mGridView.getStretchMode());
        child = mGridView.getChildAt(NUM_COLUMNS - 1); // get the rightmost view at the first line.
        childRight[STRETCH_COLUMN_WIDTH][INDEX_RIGHTMOST] = child.getRight();

        child = mGridView.getChildAt(0);
        childRight[STRETCH_COLUMN_WIDTH][INDEX_0] = child.getRight();

        child = mGridView.getChildAt(1);
        childRight[STRETCH_COLUMN_WIDTH][INDEX_1] = child.getRight();

        mActivityRule.runOnUiThread(() -> {
            mGridView.setColumnWidth(15);
            mGridView.setStretchMode(GridView.STRETCH_SPACING_UNIFORM);
            mGridView.invalidate();
            mGridView.requestLayout();
        });
        mInstrumentation.waitForIdleSync();
        assertEquals(GridView.STRETCH_SPACING_UNIFORM, mGridView.getStretchMode());
        child = mGridView.getChildAt(NUM_COLUMNS - 1); // get the rightmost view at the first line.
        childRight[STRETCH_SPACING_UNIFORM][INDEX_RIGHTMOST] = child.getRight();

        child = mGridView.getChildAt(0);
        childRight[STRETCH_SPACING_UNIFORM][INDEX_0] = child.getRight();

        child = mGridView.getChildAt(1);
        childRight[STRETCH_SPACING_UNIFORM][INDEX_1] = child.getRight();

        assertTrue(childRight[STRETCH_SPACING][INDEX_RIGHTMOST]
                > childRight[STRETCH_COLUMN_WIDTH][INDEX_RIGHTMOST]);
        assertTrue(childRight[STRETCH_SPACING][INDEX_RIGHTMOST]
                > childRight[STRETCH_SPACING_UNIFORM][INDEX_RIGHTMOST]);
        assertTrue(childRight[STRETCH_SPACING][INDEX_0]
                == childRight[STRETCH_COLUMN_WIDTH][INDEX_0]);
        assertTrue(childRight[STRETCH_SPACING][INDEX_0]
                < childRight[STRETCH_SPACING_UNIFORM][INDEX_0]);
        assertTrue(childRight[STRETCH_SPACING][INDEX_1]
                > childRight[STRETCH_COLUMN_WIDTH][INDEX_1]);
        assertTrue(childRight[STRETCH_SPACING][INDEX_1]
                < childRight[STRETCH_SPACING_UNIFORM][INDEX_1]);
    }

    @Test
    public void testSetNumColumns() throws Throwable {
        // this test case can not be ran in UI thread.
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new MockGridViewAdapter(10));
            mGridView.setHorizontalSpacing(0);
            mGridView.setVerticalSpacing(0);
            mGridView.setNumColumns(10);
        });
        mInstrumentation.waitForIdleSync();

        View child0 = mGridView.getChildAt(0);
        View child9 = mGridView.getChildAt(9);
        assertEquals(child0.getBottom(), child9.getBottom());

        mActivityRule.runOnUiThread(() -> mGridView.setNumColumns(9));
        mInstrumentation.waitForIdleSync();

        child0 = mGridView.getChildAt(0);
        child9 = mGridView.getChildAt(9);
        assertEquals(child0.getBottom(), child9.getTop());
        assertEquals(child0.getLeft(), child9.getLeft());

        mActivityRule.runOnUiThread(() -> mGridView.setNumColumns(1));
        mInstrumentation.waitForIdleSync();

        for (int i = 0; i < mGridView.getChildCount(); i++) {
            View child = mGridView.getChildAt(i);
            assertEquals(0, child.getLeft() - mGridView.getListPaddingLeft());
        }
    }

    @Test
    public void testDefaultNumColumns() {
        final GridView gridView = new GridView(mActivity);
        assertEquals(gridView.getNumColumns(), GridView.AUTO_FIT);
    }

    @Test
    public void testGetNumColumns() throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new MockGridViewAdapter(10));
            mGridView.setNumColumns(10);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(mGridView.getNumColumns(), 10);

        mActivityRule.runOnUiThread(() -> mGridView.setNumColumns(1));
        mInstrumentation.waitForIdleSync();

        assertEquals(mGridView.getNumColumns(), 1);

        mActivityRule.runOnUiThread(() -> mGridView.setNumColumns(0));
        mInstrumentation.waitForIdleSync();

        //although setNumColumns(0) was called, the number of columns should be 1
        assertEquals(mGridView.getNumColumns(), 1);
    }

    @Test
    public void testAttachLayoutAnimationParameters() {
        MockGridView mockGridView = new MockGridView(mActivity);
        ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(320, 480);
        mockGridView.attachLayoutAnimationParameters(null, p, 1, 2);
        AnimationParameters animationParams = (AnimationParameters) p.layoutAnimationParameters;
        assertEquals(1, animationParams.index);
        assertEquals(2, animationParams.count);
    }

    @Test
    public void testLayoutChildren() {
        MockGridView mockGridView = new MockGridView(mActivity);
        mockGridView.layoutChildren();
    }

    @UiThreadTest
    @Test
    public void testOnFocusChanged() {
        final MockGridView mockGridView = new MockGridView(mActivity);

        assertFalse(mockGridView.hasCalledOnFocusChanged());
        mockGridView.setAdapter(new MockGridViewAdapter(10));
        mockGridView.setFocusable(true);
        mockGridView.requestFocus();

        assertTrue(mockGridView.hasCalledOnFocusChanged());
        mockGridView.reset();
        assertFalse(mockGridView.hasCalledOnFocusChanged());

        mockGridView.clearFocus();

        assertTrue(mockGridView.hasCalledOnFocusChanged());
    }

    @Test
    public void testAccessColumnWidth() throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new MockGridViewAdapter(10));
            mGridView.setNumColumns(GridView.AUTO_FIT);
            mGridView.setHorizontalSpacing(0);
            mGridView.setVerticalSpacing(0);
            mGridView.setColumnWidth(0);
        });
        mInstrumentation.waitForIdleSync();

        // Verify whether column number equals 2.
        assertEquals(0, mGridView.getRequestedColumnWidth());
        assertEquals(mGridView.getWidth() / 2, mGridView.getColumnWidth());
        View child0 = mGridView.getChildAt(0);
        View child1 = mGridView.getChildAt(1);
        View child2 = mGridView.getChildAt(2);
        assertEquals(child0.getBottom(), child1.getBottom());
        assertEquals(child0.getLeft(), child2.getLeft());

        mActivityRule.runOnUiThread(() -> {
            mGridView.setNumColumns(GridView.AUTO_FIT);
            mGridView.setColumnWidth(Integer.MAX_VALUE);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(Integer.MAX_VALUE, mGridView.getRequestedColumnWidth());
        assertEquals(mGridView.getWidth(), mGridView.getColumnWidth());
        child0 = mGridView.getChildAt(0);
        child1 = mGridView.getChildAt(1);
        assertEquals(child0.getBottom(), child1.getTop());
        assertEquals(child0.getLeft(), child1.getLeft());
    }

    @MediumTest
    @Test
    public void testFullyDetachUnusedViewOnScroll() throws Throwable {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.setAdapter(new DummyAdapter(1000, theView));
        });
        assertEquals("test sanity", 1, theView.mOnAttachCount);
        assertEquals("test sanity", 0, theView.mOnDetachCount);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.scrollListBy(mGridView.getHeight() * 2);
        });
        assertNull("test sanity, unused view should be removed", theView.getParent());
        assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.scrollListBy(-mGridView.getHeight() * 2);
            // listview limits scroll to 1 page which is why we call it twice here.
            mGridView.scrollListBy(-mGridView.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
    @Test
    public void testFullyDetachUnusedViewOnReLayout() throws Throwable {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.setAdapter(new DummyAdapter(1000, theView));
        });
        assertEquals("test sanity", 1, theView.mOnAttachCount);
        assertEquals("test sanity", 0, theView.mOnDetachCount);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.setSelection(800);
        });
        assertNull("test sanity, unused view should be removed", theView.getParent());
        assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.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
    @Test
    public void testFullyDetachUnusedViewOnScrollForFocus() throws Throwable {
        final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, () -> {
            mGridView.setAdapter(new DummyAdapter(1000, theView));
            mGridView.requestFocus();
        });
        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);
            CtsKeyEventUtil.sendKeys(mInstrumentation, mGridView, KeyEvent.KEYCODE_DPAD_DOWN);
            WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, null);
        }
        assertEquals("the view should be detached", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
        while(theView.getParent() == null) {
            CtsKeyEventUtil.sendKeys(mInstrumentation, mGridView, KeyEvent.KEYCODE_DPAD_UP);
            WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mGridView, null);
        }
        assertEquals("the view should be re-attached", 2, theView.mOnAttachCount);
        assertEquals("the view should not receive another detach", 1, theView.mOnDetachCount);
        assertFalse(theView.isTemporarilyDetached());
    }

    @LargeTest
    @Test
    public void testSmoothScrollByOffset() throws Throwable {
        final int itemCount = 300;
        mActivityRule.runOnUiThread(() -> {
            mGridView.setAdapter(new MockGridViewAdapter(itemCount));
            mGridView.setNumColumns(GridView.AUTO_FIT);
            mGridView.setHorizontalSpacing(0);
            mGridView.setVerticalSpacing(0);
            mGridView.setColumnWidth(Integer.MAX_VALUE);
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(0, mGridView.getFirstVisiblePosition());

        // Register a scroll listener on our GridView. The listener will notify our latch
        // when the "target" item comes into view. If that never happens, the latch will
        // time out and fail the test.
        final CountDownLatch latch = new CountDownLatch(1);
        final int positionToScrollTo = itemCount - 10;
        mGridView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                    int totalItemCount) {
                if ((positionToScrollTo >= firstVisibleItem) &&
                        (positionToScrollTo <= (firstVisibleItem + visibleItemCount))) {
                    latch.countDown();
                }
            }
        });
        int offset = positionToScrollTo - mGridView.getLastVisiblePosition();
        mActivityRule.runOnUiThread(() -> mGridView.smoothScrollByOffset(offset));

        boolean result = false;
        try {
            result = latch.await(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            // ignore
        }
        assertTrue("Timed out while waiting for the target view to be scrolled into view", result);
    }

    private static class MockGridView extends GridView {
        private boolean mCalledOnFocusChanged = false;

        public boolean hasCalledOnFocusChanged() {
            return mCalledOnFocusChanged;
        }

        public void reset() {
            mCalledOnFocusChanged = false;
        }

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

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

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

        @Override
        public void attachLayoutAnimationParameters(View child,
                ViewGroup.LayoutParams params, int index, int count) {
            super.attachLayoutAnimationParameters(child, params, index, count);
        }

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

        @Override
        protected void onFocusChanged(boolean gainFocus, int direction,
                Rect previouslyFocusedRect) {
            mCalledOnFocusChanged = true;
            super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        }
    }

    private class MockGridViewAdapter implements ListAdapter, Filterable {
        private final int mCount;

        MockGridViewAdapter(int count) {
            mCount = count;
        }

        public boolean areAllItemsEnabled() {
            return true;
        }

        public boolean isEnabled(int position) {
            return true;
        }

        public void registerDataSetObserver(DataSetObserver observer) {
        }

        public void unregisterDataSetObserver(DataSetObserver observer) {
        }

        public int getCount() {
            return mCount;
        }

        public Object getItem(int position) {
            return position;
        }

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

        public boolean hasStableIds() {
            return false;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            if ((convertView != null) && (convertView instanceof ImageView)) {
                ((ImageView) convertView).setImageResource(R.drawable.size_48x48);
                return convertView;
            }

            ImageView newView = new ImageView(mActivity);
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                                                  AbsListView.LayoutParams.WRAP_CONTENT,
                                                  AbsListView.LayoutParams.WRAP_CONTENT);
            newView.setLayoutParams(params);
            newView.setImageResource(R.drawable.size_48x48);
            return newView;
        }

        public int getItemViewType(int position) {
            return 0;
        }

        public int getViewTypeCount() {
            return 1;
        }

        public boolean isEmpty() {
            return false;
        }

        public Filter getFilter() {
            return new FilterTest();
        }
    }

    private static class FilterTest extends Filter {
        @Override
        protected Filter.FilterResults performFiltering(CharSequence constraint) {
            return null;
        }

        @Override
        protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
        }
    }

    private class ImageAdapter implements ListAdapter {
        public ImageAdapter(Context c) {
            mContext = c;
        }

        public int getCount() {
            return mThumbIds.length;
        }

        public Object getItem(int position) {
            return position;
        }

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

        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView;
            if (convertView == null) {
                imageView = new ImageView(mContext);
                int layoutSize = (int)(50 * mContext.getResources().getDisplayMetrics().density);
                imageView.setLayoutParams(new GridView.LayoutParams(layoutSize, layoutSize));
                imageView.setAdjustViewBounds(false);
                imageView.setScaleType(ImageView.ScaleType.CENTER);
                imageView.setPadding(0, 0, 0, 0);
            } else {
                imageView = (ImageView) convertView;
            }

            imageView.setImageResource(mThumbIds[position]);

            return imageView;
        }

        private Context mContext;

        private Integer[] mThumbIds = {
                R.drawable.failed, R.drawable.pass,
                R.drawable.animated, R.drawable.black,
                R.drawable.blue, R.drawable.red,
                R.drawable.animated, R.drawable.black,
                R.drawable.blue, R.drawable.failed,
                R.drawable.pass, R.drawable.red,
        };

        private final DataSetObservable mDataSetObservable = new DataSetObservable();

        public boolean hasStableIds() {
            return false;
        }

        public void registerDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.registerObserver(observer);
        }

        public void unregisterDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.unregisterObserver(observer);
        }

        public boolean areAllItemsEnabled() {
            return true;
        }

        public boolean isEnabled(int position) {
            return true;
        }

        public int getItemViewType(int position) {
            return 0;
        }

        public int getViewTypeCount() {
            return 1;
        }

        public boolean isEmpty() {
            return getCount() == 0;
        }
    }
}
