| // CHECKSTYLE:OFF Generated code |
| /* This file is auto-generated from BrowseSupportFragmentTest.java. DO NOT MODIFY. */ |
| |
| /* |
| * Copyright (C) 2015 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 androidx.leanback.app; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Matchers.any; |
| import static org.mockito.Mockito.timeout; |
| import static org.mockito.Mockito.verify; |
| |
| import android.app.Fragment; |
| import android.app.Instrumentation; |
| import android.content.Intent; |
| import android.os.Build; |
| import android.os.Bundle; |
| import android.os.SystemClock; |
| import android.support.test.InstrumentationRegistry; |
| import android.support.test.filters.LargeTest; |
| import android.support.test.rule.ActivityTestRule; |
| import android.support.test.runner.AndroidJUnit4; |
| import android.view.KeyEvent; |
| import android.view.LayoutInflater; |
| import android.view.MotionEvent; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.FrameLayout; |
| |
| import androidx.annotation.NonNull; |
| import androidx.annotation.Nullable; |
| import androidx.leanback.testutils.PollingCheck; |
| import androidx.leanback.widget.ArrayObjectAdapter; |
| import androidx.leanback.widget.ItemBridgeAdapter; |
| import androidx.leanback.widget.ListRowPresenter; |
| import androidx.leanback.widget.Presenter; |
| import androidx.leanback.widget.Row; |
| import androidx.leanback.widget.RowPresenter; |
| import androidx.recyclerview.widget.RecyclerView; |
| |
| import org.junit.After; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mockito; |
| |
| @LargeTest |
| @RunWith(AndroidJUnit4.class) |
| public class BrowseFragmentTest { |
| |
| static final String TAG = "BrowseFragmentTest"; |
| static final long WAIT_TRANSIITON_TIMEOUT = 10000; |
| |
| @Rule |
| public ActivityTestRule<BrowseFragmentTestActivity> activityTestRule = |
| new ActivityTestRule<>(BrowseFragmentTestActivity.class, false, false); |
| private BrowseFragmentTestActivity mActivity; |
| |
| @After |
| public void afterTest() throws Throwable { |
| activityTestRule.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| if (mActivity != null) { |
| mActivity.finish(); |
| mActivity = null; |
| } |
| } |
| }); |
| } |
| |
| void waitForEntranceTransitionFinished() { |
| PollingCheck.waitFor(WAIT_TRANSIITON_TIMEOUT, new PollingCheck.PollingCheckCondition() { |
| @Override |
| public boolean canProceed() { |
| if (Build.VERSION.SDK_INT >= 21) { |
| return mActivity.getBrowseTestFragment() != null |
| && mActivity.getBrowseTestFragment().mEntranceTransitionEnded; |
| } else { |
| // when entrance transition not supported, wait main fragment loaded. |
| return mActivity.getBrowseTestFragment() != null |
| && mActivity.getBrowseTestFragment().getMainFragment() != null; |
| } |
| } |
| }); |
| } |
| |
| void waitForHeaderTransitionFinished() { |
| View row = mActivity.getBrowseTestFragment().getRowsFragment().getRowViewHolder( |
| mActivity.getBrowseTestFragment().getSelectedPosition()).view; |
| PollingCheck.waitFor(WAIT_TRANSIITON_TIMEOUT, new PollingCheck.ViewStableOnScreen(row)); |
| PollingCheck.waitFor(WAIT_TRANSIITON_TIMEOUT, new PollingCheck.PollingCheckCondition() { |
| public boolean canProceed() { |
| return !mActivity.getBrowseTestFragment().isInHeadersTransition(); |
| } |
| }); |
| } |
| |
| @Test |
| public void testTouchMode() throws Throwable { |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , true); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY , 0L); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| waitForEntranceTransitionFinished(); |
| |
| ListRowPresenter.ViewHolder rowVh = (ListRowPresenter.ViewHolder) mActivity |
| .getBrowseTestFragment().getRowsFragment().getRowViewHolder(0); |
| View card = rowVh.getGridView().getChildAt(0); |
| tapView(card); |
| waitForHeaderTransitionFinished(); |
| assertTrue(card.hasFocus()); |
| assertTrue(card.isInTouchMode()); |
| sendKeys(KeyEvent.KEYCODE_BACK); |
| waitForHeaderTransitionFinished(); |
| assertTrue((mActivity.getBrowseTestFragment().getHeadersFragment() |
| .getVerticalGridView().getChildAt(0)).hasFocus()); |
| } |
| |
| @Test |
| public void testTwoBackKeysWithBackStack() throws Throwable { |
| final long dataLoadingDelay = 0L; |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , true); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| waitForEntranceTransitionFinished(); |
| |
| assertNotNull(mActivity.getBrowseTestFragment().getMainFragment()); |
| sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); |
| waitForHeaderTransitionFinished(); |
| sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK); |
| } |
| |
| @Test |
| public void testTwoBackKeysWithoutBackStack() throws Throwable { |
| final long dataLoadingDelay = 0L; |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| waitForEntranceTransitionFinished(); |
| |
| assertNotNull(mActivity.getBrowseTestFragment().getMainFragment()); |
| sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); |
| waitForHeaderTransitionFinished(); |
| sendKeys(KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_BACK); |
| } |
| |
| @Test |
| public void testPressRightBeforeMainFragmentCreated() throws Throwable { |
| final long dataLoadingDelay = 1000; |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| assertNull(mActivity.getBrowseTestFragment().getMainFragment()); |
| sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT); |
| } |
| |
| public static class MyRow extends Row { |
| } |
| |
| public static class MyFragment extends Fragment implements |
| BrowseFragment.MainFragmentAdapterProvider { |
| BrowseFragment.MainFragmentAdapter mMainFragmentAdapter = new BrowseFragment |
| .MainFragmentAdapter(this); |
| |
| @Nullable |
| @Override |
| public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, |
| @Nullable Bundle savedInstanceState) { |
| return new FrameLayout(container.getContext()); |
| } |
| |
| @Override |
| public BrowseFragment.MainFragmentAdapter getMainFragmentAdapter() { |
| return mMainFragmentAdapter; |
| } |
| } |
| |
| public static class MyFragmentFactory extends |
| BrowseFragment.FragmentFactory<MyFragment> { |
| public MyFragment createFragment(Object row) { |
| return new MyFragment(); |
| } |
| } |
| |
| @Test |
| public void testPressCenterBeforeMainFragmentCreated() throws Throwable { |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, 0L); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| final BrowseFragment fragment = mActivity.getBrowseTestFragment(); |
| fragment.getMainFragmentRegistry().registerFragment(MyRow.class, new MyFragmentFactory()); |
| |
| final ArrayObjectAdapter adapter = new ArrayObjectAdapter(new RowPresenter() { |
| protected ViewHolder createRowViewHolder(ViewGroup parent) { |
| View view = new FrameLayout(parent.getContext()); |
| return new RowPresenter.ViewHolder(view); |
| } |
| }); |
| adapter.add(new MyRow()); |
| activityTestRule.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| fragment.setAdapter(adapter); |
| } |
| }); |
| activityTestRule.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| KeyEvent kv; |
| kv = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER); |
| fragment.getView().dispatchKeyEvent(kv); |
| kv = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER); |
| fragment.getView().dispatchKeyEvent(kv); |
| } |
| }); |
| } |
| |
| @Test |
| public void testSelectCardOnARow() throws Throwable { |
| final int selectRow = 10; |
| final int selectItem = 20; |
| Intent intent = new Intent(); |
| final long dataLoadingDelay = 0L; |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , true); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| waitForEntranceTransitionFinished(); |
| |
| Presenter.ViewHolderTask itemTask = Mockito.spy( |
| new ItemSelectionTask(mActivity, selectRow)); |
| |
| final ListRowPresenter.SelectItemViewHolderTask task = |
| new ListRowPresenter.SelectItemViewHolderTask(selectItem); |
| task.setItemTask(itemTask); |
| |
| mActivity.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| mActivity.getBrowseTestFragment().setSelectedPosition(selectRow, true, task); |
| } |
| }); |
| |
| verify(itemTask, timeout(5000).times(1)).run(any(Presenter.ViewHolder.class)); |
| |
| activityTestRule.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| ListRowPresenter.ViewHolder row = (ListRowPresenter.ViewHolder) mActivity |
| .getBrowseTestFragment().getRowsFragment().getRowViewHolder(selectRow); |
| assertNotNull(dumpRecyclerView(mActivity.getBrowseTestFragment().getGridView()), row); |
| assertNotNull(row.getGridView()); |
| assertEquals(selectItem, row.getGridView().getSelectedPosition()); |
| } |
| }); |
| } |
| |
| @Test |
| public void activityRecreate_notCrash() throws Throwable { |
| final long dataLoadingDelay = 0L; |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_ADD_TO_BACKSTACK , false); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_SET_ADAPTER_AFTER_DATA_LOAD, true); |
| mActivity = activityTestRule.launchActivity(intent); |
| |
| waitForEntranceTransitionFinished(); |
| |
| InstrumentationRegistry.getInstrumentation().callActivityOnRestart(mActivity); |
| activityTestRule.runOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| mActivity.recreate(); |
| } |
| }); |
| } |
| |
| |
| @Test |
| public void lateLoadingHeaderDisabled() throws Throwable { |
| final long dataLoadingDelay = 0L; |
| Intent intent = new Intent(); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_LOAD_DATA_DELAY, dataLoadingDelay); |
| intent.putExtra(BrowseFragmentTestActivity.EXTRA_HEADERS_STATE, |
| BrowseFragment.HEADERS_DISABLED); |
| mActivity = activityTestRule.launchActivity(intent); |
| waitForEntranceTransitionFinished(); |
| PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() { |
| @Override |
| public boolean canProceed() { |
| return mActivity.getBrowseTestFragment().getGridView() != null |
| && mActivity.getBrowseTestFragment().getGridView().getChildCount() > 0; |
| } |
| }); |
| } |
| |
| static void tapView(View v) { |
| Instrumentation inst = InstrumentationRegistry.getInstrumentation(); |
| int[] xy = new int[2]; |
| v.getLocationOnScreen(xy); |
| |
| final int viewWidth = v.getWidth(); |
| final int viewHeight = v.getHeight(); |
| |
| final float x = xy[0] + (viewWidth / 2.0f); |
| float y = xy[1] + (viewHeight / 2.0f); |
| |
| long downTime = SystemClock.uptimeMillis(); |
| long eventTime = SystemClock.uptimeMillis(); |
| |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, |
| MotionEvent.ACTION_DOWN, x, y, 0); |
| inst.sendPointerSync(event); |
| inst.waitForIdleSync(); |
| |
| eventTime = SystemClock.uptimeMillis(); |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); |
| inst.sendPointerSync(event); |
| inst.waitForIdleSync(); |
| } |
| |
| private void sendKeys(int ...keys) { |
| for (int i = 0; i < keys.length; i++) { |
| InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]); |
| } |
| } |
| |
| public static class ItemSelectionTask extends Presenter.ViewHolderTask { |
| |
| private final BrowseFragmentTestActivity activity; |
| private final int expectedRow; |
| |
| public ItemSelectionTask(BrowseFragmentTestActivity activity, int expectedRow) { |
| this.activity = activity; |
| this.expectedRow = expectedRow; |
| } |
| |
| @Override |
| public void run(Presenter.ViewHolder holder) { |
| android.util.Log.d(TAG, dumpRecyclerView(activity.getBrowseTestFragment() |
| .getGridView())); |
| android.util.Log.d(TAG, "Row " + expectedRow + " " + activity.getBrowseTestFragment() |
| .getRowsFragment().getRowViewHolder(expectedRow), new Exception()); |
| } |
| } |
| |
| static String dumpRecyclerView(RecyclerView recyclerView) { |
| StringBuffer b = new StringBuffer(); |
| for (int i = 0; i < recyclerView.getChildCount(); i++) { |
| View child = recyclerView.getChildAt(i); |
| ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder) |
| recyclerView.getChildViewHolder(child); |
| b.append("child").append(i).append(":").append(vh); |
| if (vh != null) { |
| b.append(",").append(vh.getViewHolder()); |
| } |
| b.append(";"); |
| } |
| return b.toString(); |
| } |
| } |