Merge "Use new nested scrolling APIs"
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 23c7b14..b4714a3 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -67,7 +67,7 @@
             android:fadingEdge="none"
             android:scrollbarStyle="outsideOverlay"
             android:divider="@null"
-        />
+            android:nestedScrollingEnabled="true" />
         <TextView android:id="@android:id/empty"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/res/layout/phone_favorites_fragment.xml b/res/layout/phone_favorites_fragment.xml
index 76e5e98..0b657df 100644
--- a/res/layout/phone_favorites_fragment.xml
+++ b/res/layout/phone_favorites_fragment.xml
@@ -39,7 +39,8 @@
             android:numColumns="@integer/contact_tile_column_count_in_favorites"
             android:clipToPadding="false"
             android:fadingEdge="none"
-            android:divider="@null" />
+            android:divider="@null"
+            android:nestedScrollingEnabled="true" />
     </FrameLayout>
 
     <include
diff --git a/res/layout/show_all_contacts_fragment.xml b/res/layout/show_all_contacts_fragment.xml
index ddc99e8..6b89847 100644
--- a/res/layout/show_all_contacts_fragment.xml
+++ b/res/layout/show_all_contacts_fragment.xml
@@ -43,7 +43,8 @@
             android:layout_marginStart="?attr/contact_browser_list_padding_left"
             android:layout_marginEnd="?attr/contact_browser_list_padding_right"
             android:fastScrollEnabled="true"
-            android:fadingEdge="none"/>
+            android:fadingEdge="none"
+            android:nestedScrollingEnabled="true" />
     </FrameLayout>
 
 </LinearLayout>
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index 0948151..0f3e405 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -252,7 +252,6 @@
         mStatusMessageView = view.findViewById(R.id.voicemail_status);
         mStatusMessageText = (TextView) view.findViewById(R.id.voicemail_status_message);
         mStatusMessageAction = (TextView) view.findViewById(R.id.voicemail_status_action);
-
         return view;
     }
 
diff --git a/src/com/android/dialer/widget/OverlappingPaneLayout.java b/src/com/android/dialer/widget/OverlappingPaneLayout.java
index 18920df..e17194e 100644
--- a/src/com/android/dialer/widget/OverlappingPaneLayout.java
+++ b/src/com/android/dialer/widget/OverlappingPaneLayout.java
@@ -102,6 +102,11 @@
      */
     private boolean mIsUnableToDrag;
 
+    /**
+     * Tracks whether or not a child view is in the process of a nested scroll.
+     */
+    private boolean mIsInNestedScroll;
+
     private float mInitialMotionX;
     private float mInitialMotionY;
 
@@ -574,12 +579,16 @@
         }
 
         if (!mCanSlide || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) {
-            mDragHelper.cancel();
+            if (!mIsInNestedScroll) {
+                mDragHelper.cancel();
+            }
             return super.onInterceptTouchEvent(ev);
         }
 
         if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-            mDragHelper.cancel();
+            if (!mIsInNestedScroll) {
+                mDragHelper.cancel();
+            }
             return false;
         }
 
@@ -601,7 +610,9 @@
                 final float ady = Math.abs(y - mInitialMotionY);
                 final int slop = mDragHelper.getTouchSlop();
                 if (ady > slop && adx > ady || !isCapturableViewUnder((int) x, (int) y)) {
-                    mDragHelper.cancel();
+                    if (!mIsInNestedScroll) {
+                        mDragHelper.cancel();
+                    }
                     mIsUnableToDrag = true;
                     return false;
                 }
@@ -837,6 +848,27 @@
         mPreservedOpenState = ss.isOpen;
     }
 
+    @Override
+    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
+        final boolean startNestedScroll = (nestedScrollAxes & SCROLL_AXIS_VERTICAL) != 0;
+        if (startNestedScroll) {
+            mIsInNestedScroll = true;
+            mDragHelper.startNestedScroll(mSlideableView);
+        }
+        return startNestedScroll;
+    }
+
+    @Override
+    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
+        mDragHelper.processNestedScroll(mSlideableView, 0, dy, consumed);
+    }
+
+    @Override
+    public void onStopNestedScroll(View child) {
+        mDragHelper.stopNestedScroll(mSlideableView);
+        mIsInNestedScroll = false;
+    }
+
     private class DragHelperCallback extends ViewDragHelper.Callback {
 
         @Override
@@ -883,7 +915,6 @@
                 top += mSlideRange;
             }
 
-            int left;
             mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
             invalidate();
         }
diff --git a/src/com/android/dialer/widget/ViewDragHelper.java b/src/com/android/dialer/widget/ViewDragHelper.java
index 748979f..83e8707 100644
--- a/src/com/android/dialer/widget/ViewDragHelper.java
+++ b/src/com/android/dialer/widget/ViewDragHelper.java
@@ -1447,4 +1447,45 @@
 
         return result;
     }
+
+    /**
+     * Prepares the {@link ViewDragHelper} for the beginning of a nested scroll.
+     *
+     * @param target The child view that is dispatching the nested scroll.
+     */
+    public void startNestedScroll(View target) {
+        setDragState(STATE_DRAGGING);
+        mCapturedView = target;
+    }
+
+    /**
+     * Informs the {@link ViewDragHelper} that a nested scroll has ended.
+     *
+     * @param target The child view that is dispatching the nested scroll.
+     */
+    public void stopNestedScroll(View target) {
+        dispatchViewReleased(0, 0);
+    }
+
+    /**
+     * Update the {@link ViewDragHelper} with a new nested scrolling event.
+     *
+     * @param target The child view that is dispatching the nested scroll.
+     * @param dx The x distance scrolled on the child, in pixels.
+     * @param dy The y distance scroll on the child, in pixels.
+     * @param consumed An int array for the {@link ViewDragHelper} to report back the scroll
+     *         deltas that it consumed.
+     */
+    public void processNestedScroll(View target, int dx, int dy, int[] consumed) {
+        final int targetX = mCapturedView.getLeft() + dx;
+        final int targetY = mCapturedView.getTop() + dy;
+        dragTo(targetX, targetY, dx, dy);
+        if (consumed != null) {
+            final int unconsumedX = targetX - mCapturedView.getLeft();
+            final int unconsumedY = targetY - mCapturedView.getTop();
+            consumed[0] = dx - unconsumedX;
+            consumed[1] = dy - unconsumedY;
+        }
+    }
+
 }