Merge "Consume pending updates before focus failure" into nyc-dev am: e603e6fc9d
am: 80ed025f8b

* commit '80ed025f8b2e1e48076995c557d2dd656f01d17f':
  Consume pending updates before focus failure

Change-Id: I339c2462ac28960830a9a5e65a4a9ce011ad700b
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 3355e1e..222656b 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -2132,6 +2132,7 @@
                 needsFocusFailureLayout = found == null;
             }
             if (needsFocusFailureLayout) {
+                consumePendingUpdateOperations();
                 eatRequestLayout();
                 mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
                 resumeRequestLayout(false);
@@ -2140,6 +2141,7 @@
         } else {
             result = ff.findNextFocus(this, focused, direction);
             if (result == null && canRunFocusFailure) {
+                consumePendingUpdateOperations();
                 eatRequestLayout();
                 result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
                 resumeRequestLayout(false);
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
index 252ca6b..75a3efd 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
@@ -561,6 +561,53 @@
     }
 
     @Test
+    public void testFocusSearchAfterChangedData() throws Throwable {
+        final RecyclerView recyclerView = new RecyclerView(getActivity());
+        TestLayoutManager tlm = new TestLayoutManager() {
+            @Override
+            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+                layoutRange(recycler, 0, 2);
+                layoutLatch.countDown();
+            }
+
+            @Nullable
+            @Override
+            public View onFocusSearchFailed(View focused, int direction,
+                                            RecyclerView.Recycler recycler,
+                                            RecyclerView.State state) {
+                try {
+                    View view = recycler.getViewForPosition(state.getItemCount() - 1);
+                } catch (Throwable t) {
+                    postExceptionToInstrumentation(t);
+                }
+                return null;
+            }
+        };
+        recyclerView.setLayoutManager(tlm);
+        final TestAdapter adapter = new TestAdapter(10) {
+            @Override
+            public void onBindViewHolder(TestViewHolder holder, int position) {
+                super.onBindViewHolder(holder, position);
+                holder.itemView.setFocusable(false);
+                holder.itemView.setFocusableInTouchMode(false);
+            }
+        };
+        recyclerView.setAdapter(adapter);
+        tlm.expectLayouts(1);
+        setRecyclerView(recyclerView);
+        tlm.waitForLayout(1);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                adapter.mItems.remove(9);
+                adapter.notifyItemRemoved(9);
+                recyclerView.focusSearch(recyclerView.getChildAt(1), View.FOCUS_DOWN);
+            }
+        });
+        checkForMainThreadException();
+    }
+
+    @Test
     public void  testFocusSearchFailFrozen() throws Throwable {
         RecyclerView recyclerView = new RecyclerView(getActivity());
         final CountDownLatch focusLatch = new CountDownLatch(1);