Merge "GridLayoutManager: fix scroll bug" into lmp-preview-dev
diff --git a/v17/leanback/res/layout/lb_vertical_grid_fragment.xml b/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
index 0720501..4cd3a22 100644
--- a/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
+++ b/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
@@ -14,17 +14,24 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/browse_dummy"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent" >
 
-    <include layout="@layout/lb_browse_title" />
-
-    <FrameLayout
-        android:id="@+id/browse_grid_dock"
+    <android.support.v17.leanback.app.BrowseFrameLayout
+        android:id="@+id/browse_frame"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent" >
 
-</FrameLayout>
\ No newline at end of file
+        <include layout="@layout/lb_browse_title" />
+
+        <FrameLayout
+            android:id="@+id/browse_grid_dock"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </android.support.v17.leanback.app.BrowseFrameLayout>
+</FrameLayout>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index f364307..8758381 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -27,6 +27,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -43,6 +44,7 @@
     // TODO: remove Params
     private Params mParams;
 
+    private BrowseFrameLayout mBrowseFrame;
     private String mTitle;
     private Drawable mBadgeDrawable;
     private ObjectAdapter mAdapter;
@@ -272,12 +274,35 @@
         }
     }
 
+    private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
+            new BrowseFrameLayout.OnFocusSearchListener() {
+        @Override
+        public View onFocusSearch(View focused, int direction) {
+            if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);
+
+            if (focused == mSearchOrbView && (
+                    direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT)) {
+                return mGridViewHolder.view;
+
+            } else if (focused != mSearchOrbView && mSearchOrbView.getVisibility() == View.VISIBLE
+                    && direction == View.FOCUS_UP) {
+                return mSearchOrbView;
+
+            } else {
+                return null;
+            }
+        }
+    };
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment,
                 container, false);
 
+        mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame);
+        mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
+
         mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group);
         mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge);
         mTitleView = (TextView) mBrowseTitle.findViewById(R.id.browse_title);
@@ -292,13 +317,13 @@
         mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
             @Override
             public void run() {
-                mBrowseTitle.setVisibility(View.VISIBLE);
+                showTitle(true);
             }
         });
         mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
             @Override
             public void run() {
-                mBrowseTitle.setVisibility(View.GONE);
+                showTitle(false);
             }
         });
         mTitleTransition = sTransitionHelper.createTransitionSet(false);
@@ -311,6 +336,12 @@
         return root;
     }
 
+    private void showTitle(boolean show) {
+        MarginLayoutParams lp = (MarginLayoutParams) mBrowseTitle.getLayoutParams();
+        lp.topMargin = show ? 0 : -mBrowseTitle.getHeight();
+        mBrowseTitle.setLayoutParams(lp);
+    }
+
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
index 90d834e..7113383 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
@@ -467,16 +467,8 @@
     }
 
     /**
-     * Get if view has same row sibling next to it.
-     *
-     * @param position Position in adapter.
-     */
-    public boolean hasNextViewInSameRow(int position) {
-        return mLayoutManager.hasNextViewInSameRow(position);
-    }
-
-    /**
-     * Get if view has same row sibling in front of it.
+     * Returns true if the view at the given position has a same row sibling
+     * in front of it.
      *
      * @param position Position in adapter.
      */
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
index 64f1c49..91a96fa 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -2117,27 +2117,13 @@
         return null;
     }
 
-    boolean hasNextViewInSameRow(int pos) {
-        if (mGrid == null || pos == NO_POSITION) {
-            return false;
-        }
-        final int focusedRow = mGrid.getLocation(pos).row;
-        for (int i = 0, count = getChildCount(); i < count; i++) {
-            int position = getPositionByIndex(i);
-            StaggeredGrid.Location loc = mGrid.getLocation(position);
-            if (loc != null && loc.row == focusedRow) {
-                if (position > pos) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     boolean hasPreviousViewInSameRow(int pos) {
         if (mGrid == null || pos == NO_POSITION) {
             return false;
         }
+        if (mFirstVisiblePos > 0) {
+            return true;
+        }
         final int focusedRow = mGrid.getLocation(pos).row;
         for (int i = getChildCount() - 1; i >= 0; i--) {
             int position = getPositionByIndex(i);