gt:             return (RecyclerView.LayoutParams) v.getLayoutParams();
context: /*
   * Copyright (C) 2014 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.support.v7.widget;
  
  import android.graphics.Rect;
  import android.os.Looper;
  import android.support.v4.view.ViewCompat;
  import android.test.ActivityInstrumentationTestCase2;
  import android.util.Log;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.FrameLayout;
  import android.widget.TextView;
  
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  import java.util.concurrent.CountDownLatch;
  import java.util.concurrent.TimeUnit;
  import java.util.concurrent.atomic.AtomicInteger;
  
  abstract public class BaseRecyclerViewInstrumentationTest extends
          ActivityInstrumentationTestCase2<TestActivity> {
  
      private static final String TAG = "RecyclerViewTest";
  
      private boolean mDebug;
  
      protected RecyclerView mRecyclerView;
  
      protected AdapterHelper mAdapterHelper;
  
      Throwable mainThreadException;
  
      public BaseRecyclerViewInstrumentationTest() {
          this(false);
      }
  
      public BaseRecyclerViewInstrumentationTest(boolean debug) {
          super("android.support.v7.recyclerview", TestActivity.class);
          mDebug = debug;
      }
  
      void checkForMainThreadException() throws Throwable {
          if (mainThreadException != null) {
              throw mainThreadException;
          }
      }
  
      void setHasTransientState(final View view, final boolean value) {
          try {
              runTestOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      ViewCompat.setHasTransientState(view, value);
                  }
              });
          } catch (Throwable throwable) {
              Log.e(TAG, "", throwable);
          }
      }
  
      void setAdapter(final RecyclerView.Adapter adapter) throws Throwable {
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  mRecyclerView.setAdapter(adapter);
              }
          });
      }
  
      void swapAdapter(final RecyclerView.Adapter adapter,
              final boolean removeAndRecycleExistingViews) throws Throwable {
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  try {
                      mRecyclerView.swapAdapter(adapter, removeAndRecycleExistingViews);
                  } catch (Throwable t) {
                      postExceptionToInstrumentation(t);
                  }
              }
          });
          checkForMainThreadException();
      }
  
      void postExceptionToInstrumentation(Throwable t) {
          if (mainThreadException != null) {
              Log.e(TAG, "receiving another main thread exception. dropping.", t);
          } else {
              Log.e(TAG, "captured exception on main thread", t);
              mainThreadException = t;
          }
  
          if (mRecyclerView != null && mRecyclerView
                  .getLayoutManager() instanceof TestLayoutManager) {
              TestLayoutManager lm = (TestLayoutManager) mRecyclerView.getLayoutManager();
              // finish all layouts so that we get the correct exception
              while (lm.layoutLatch.getCount() > 0) {
                  lm.layoutLatch.countDown();
              }
          }
      }
  
      @Override
      protected void tearDown() throws Exception {
          if (mRecyclerView != null) {
              try {
                  removeRecyclerView();
              } catch (Throwable throwable) {
                  throwable.printStackTrace();
              }
          }
          getInstrumentation().waitForIdleSync();
          super.tearDown();
  
          try {
              checkForMainThreadException();
          } catch (Exception e) {
              throw e;
          } catch (Throwable throwable) {
              throw new Exception(throwable);
          }
      }
  
      public Rect getDecoratedRecyclerViewBounds() {
          return new Rect(
                  mRecyclerView.getPaddingLeft(),
                  mRecyclerView.getPaddingTop(),
                  mRecyclerView.getPaddingLeft() + mRecyclerView.getWidth(),
                  mRecyclerView.getPaddingTop() + mRecyclerView.getHeight()
          );
      }
  
      public void removeRecyclerView() throws Throwable {
          if (mRecyclerView == null) {
              return;
          }
          if (!isMainThread()) {
              getInstrumentation().waitForIdleSync();
          }
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  try {
                      final RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
                      if (adapter instanceof AttachDetachCountingAdapter) {
                          ((AttachDetachCountingAdapter) adapter).getCounter()
                                  .validateRemaining(mRecyclerView);
                      }
                      getActivity().mContainer.removeAllViews();
                  } catch (Throwable t) {
                      postExceptionToInstrumentation(t);
                  }
              }
          });
          mRecyclerView = null;
      }
  
      void waitForAnimations(int seconds) throws InterruptedException {
          final CountDownLatch latch = new CountDownLatch(2);
          boolean running = mRecyclerView.mItemAnimator
                  .isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
                      @Override
                      public void onAnimationsFinished() {
                          latch.countDown();
                      }
                  });
          if (running) {
              latch.await(seconds, TimeUnit.SECONDS);
          }
      }
  
      public void setRecyclerView(final RecyclerView recyclerView) throws Throwable {
          setRecyclerView(recyclerView, true);
      }
      public void setRecyclerView(final RecyclerView recyclerView, boolean assignDummyPool)
              throws Throwable {
          setRecyclerView(recyclerView, true, true);
      }
      public void setRecyclerView(final RecyclerView recyclerView, boolean assignDummyPool,
              boolean addPositionCheckItemAnimator)
              throws Throwable {
          mRecyclerView = recyclerView;
          if (assignDummyPool) {
              RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool() {
                  @Override
                  public RecyclerView.ViewHolder getRecycledView(int viewType) {
                      RecyclerView.ViewHolder viewHolder = super.getRecycledView(viewType);
                      if (viewHolder == null) {
                          return null;
                      }
                      viewHolder.addFlags(RecyclerView.ViewHolder.FLAG_BOUND);
                      viewHolder.mPosition = 200;
                      viewHolder.mOldPosition = 300;
                      viewHolder.mPreLayoutPosition = 500;
                      return viewHolder;
                  }
  
                  @Override
                  public void putRecycledView(RecyclerView.ViewHolder scrap) {
                      super.putRecycledView(scrap);
                  }
              };
              mRecyclerView.setRecycledViewPool(pool);
          }
          if (addPositionCheckItemAnimator) {
              mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
                  @Override
                  public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                          RecyclerView.State state) {
                      RecyclerView.ViewHolder vh = parent.getChildViewHolder(view);
                      if (!vh.isRemoved()) {
                          assertNotSame("If getItemOffsets is called, child should have a valid"
                                              + " adapter position unless it is removed",
                                      vh.getAdapterPosition(), RecyclerView.NO_POSITION);
                      }
                  }
              });
          }
          mAdapterHelper = recyclerView.mAdapterHelper;
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  getActivity().mContainer.addView(recyclerView);
              }
          });
      }
  
      protected FrameLayout getRecyclerViewContainer() {
          return getActivity().mContainer;
      }
  
      public void requestLayoutOnUIThread(final View view) {
          try {
              runTestOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      view.requestLayout();
                  }
              });
          } catch (Throwable throwable) {
              Log.e(TAG, "", throwable);
          }
      }
  
      public void scrollBy(final int dt) {
          try {
              runTestOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      if (mRecyclerView.getLayoutManager().canScrollHorizontally()) {
                          mRecyclerView.scrollBy(dt, 0);
                      } else {
                          mRecyclerView.scrollBy(0, dt);
                      }
  
                  }
              });
          } catch (Throwable throwable) {
              Log.e(TAG, "", throwable);
          }
      }
  
      void scrollToPosition(final int position) throws Throwable {
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  mRecyclerView.getLayoutManager().scrollToPosition(position);
              }
          });
      }
  
      void smoothScrollToPosition(final int position)
              throws Throwable {
          Log.d(TAG, "SMOOTH scrolling to " + position);
          runTestOnUiThread(new Runnable() {
              @Override
              public void run() {
                  mRecyclerView.smoothScrollToPosition(position);
              }
          });
          while (mRecyclerView.getLayoutManager().isSmoothScrolling() ||
                  mRecyclerView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) {
              if (mDebug) {
                  Log.d(TAG, "SMOOTH scrolling step");
              }
              Thread.sleep(200);
          }
          Log.d(TAG, "SMOOTH scrolling done");
          getInstrumentation().waitForIdleSync();
      }
  
      class TestViewHolder extends RecyclerView.ViewHolder {
  
          Item mBoundItem;
  
          public TestViewHolder(View itemView) {
              super(itemView);
              itemView.setFocusable(true);
          }
  
          @Override
          public String toString() {
              return super.toString() + " item:" + mBoundItem;
          }
      }
  
      class TestLayoutManager extends RecyclerView.LayoutManager {
  
          CountDownLatch layoutLatch;
  
          public void expectLayouts(int count) {
              layoutLatch = new CountDownLatch(count);
          }
  
          public void waitForLayout(long timeout, TimeUnit timeUnit) throws Throwable {
              layoutLatch.await(timeout * (mDebug ? 100 : 1), timeUnit);
              assertEquals("all expected layouts should be executed at the expected time",
                      0, layoutLatch.getCount());
              getInstrumentation().waitForIdleSync();
          }
  
          public void assertLayoutCount(int count, String msg, long timeout) throws Throwable {
              layoutLatch.await(timeout, TimeUnit.SECONDS);
              assertEquals(msg, count, layoutLatch.getCount());
          }
  
          public void assertNoLayout(String msg, long timeout) throws Throwable {
              layoutLatch.await(timeout, TimeUnit.SECONDS);
              assertFalse(msg, layoutLatch.getCount() == 0);
          }
  
          public void waitForLayout(long timeout) throws Throwable {
              waitForLayout(timeout * (mDebug ? 10000 : 1), TimeUnit.SECONDS);
          }
  
          @Override
          public RecyclerView.LayoutParams generateDefaultLayoutParams() {
              return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                      ViewGroup.LayoutParams.WRAP_CONTENT);
          }
  
          void assertVisibleItemPositions() {
              int i = getChildCount();
              TestAdapter testAdapter = (TestAdapter) mRecyclerView.getAdapter();
              while (i-- > 0) {
                  View view = getChildAt(i);
                  RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams();
                  Item item = ((TestViewHolder) lp.mViewHolder).mBoundItem;
                  if (mDebug) {
                      Log.d(TAG, "testing item " + i);
                  }
                  if (!lp.isItemRemoved()) {
                      RecyclerView.ViewHolder vh = mRecyclerView.getChildViewHolder(view);
                      assertSame("item position in LP should match adapter value :" + vh,
                              testAdapter.mItems.get(vh.mPosition), item);
                  }
              }
          }
  
          RecyclerView.LayoutParams getLp(View v) {
  