Reenable touches to notifications in expanded QS

Revert "Closing the QS when tapping on the notifications now."
This reverts commit 3bb0bb8817690728a40edd3f8f665b09907a451b.

Revert "Disabled touch interaction when in Quick settings."
This reverts commit 5cd19bc6a4fac0513bb285fdaf08b1d19c87f4ae.

Also, shuffle order of notifications and quick settings such that
scrolling still works and delegate touches from stack scroller to
the scroll view for expanded QS panel.

In addition, make the panel close transition work when QS is expanded
and scrolled.

Last but not least, decrease scrim amount so the notifications still
look 100% interactive.

Change-Id: I17710e078cff84bcdf303c22986a31135dae2aee
diff --git a/packages/SystemUI/res/drawable/notification_scrim.xml b/packages/SystemUI/res/drawable/notification_scrim.xml
index 745bfae..53ba213 100644
--- a/packages/SystemUI/res/drawable/notification_scrim.xml
+++ b/packages/SystemUI/res/drawable/notification_scrim.xml
@@ -17,6 +17,6 @@
   -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#34000000" />
+    <solid android:color="#08000000" />
     <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 91a6f11..830cd21 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -56,12 +56,6 @@
         android:clipToPadding="false"
         android:clipChildren="false">
 
-        <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
-            android:id="@+id/notification_stack_scroller"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginBottom="@dimen/close_handle_underlap"/>
-
         <ViewStub
                 android:id="@+id/keyguard_user_switcher"
                 android:layout_height="wrap_content"
@@ -93,10 +87,18 @@
                 <!-- Layout height: notification_min_height + bottom_stack_peek_amount -->
                 <View
                     android:layout_height="76dp"
-                    android:layout_width="match_parent"/>
+                    android:layout_width="match_parent"
+                    android:layout_marginTop="@dimen/notifications_top_padding"
+                    android:layout_marginBottom="@dimen/notification_side_padding"/>
             </LinearLayout>
         </com.android.systemui.statusbar.phone.ObservableScrollView>
 
+        <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
+            android:id="@+id/notification_stack_scroller"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="@dimen/close_handle_underlap"/>
+
     </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
 
     <include layout="@layout/status_bar_expanded_header" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6334930..b80a03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -92,6 +92,7 @@
     private boolean mQsExpandedWhenExpandingStarted;
     private boolean mQsFullyExpanded;
     private boolean mKeyguardShowing;
+    private int mStatusBarState;
     private float mInitialHeightOnTouch;
     private float mInitialTouchX;
     private float mInitialTouchY;
@@ -125,7 +126,12 @@
     private boolean mBlockTouches;
     private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
     private int mNotificationScrimWaitDistance;
-    private boolean mOnNotificationsOnDown;
+
+    /**
+     * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still
+     * need to take this into account in our panel height calculation.
+     */
+    private int mScrollYOverride = -1;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -152,6 +158,7 @@
                 findViewById(R.id.notification_stack_scroller);
         mNotificationStackScroller.setOnHeightChangedListener(this);
         mNotificationStackScroller.setOverscrollTopChangedListener(this);
+        mNotificationStackScroller.setScrollView(mScrollView);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
         mFastOutLinearInterpolator = AnimationUtils.loadInterpolator(getContext(),
@@ -347,7 +354,6 @@
                 mInitialTouchX = x;
                 initVelocityTracker();
                 trackMovement(event);
-                mOnNotificationsOnDown = isOnNotifications(x, y);
                 if (shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
                     getParent().requestDisallowInterceptTouchEvent(true);
                 }
@@ -395,8 +401,6 @@
                 if (mQsTracking) {
                     flingQsWithCurrentVelocity();
                     mQsTracking = false;
-                } else if (mQsFullyExpanded && mOnNotificationsOnDown) {
-                    flingSettings(0 /* vel */, false /* expand */);
                 }
                 mIntercepting = false;
                 break;
@@ -404,10 +408,6 @@
         return !mQsExpanded && super.onInterceptTouchEvent(event);
     }
 
-    private boolean isOnNotifications(float x, float y) {
-        return mNotificationStackScroller.getChildAtPosition(x, y) != null;
-    }
-
     @Override
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
@@ -561,7 +561,6 @@
         }
     }
 
-
     @Override
     public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
         cancelAnimation();
@@ -580,6 +579,7 @@
             public void run() {
                 mStackScrollerOverscrolling = false;
                 mQsExpansionFromOverscroll = false;
+                updateQsState();
             }
         });
     }
@@ -603,14 +603,18 @@
             mQsExpanded = expanded;
             updateQsState();
             requestPanelHeightUpdate();
+            mNotificationStackScroller.setInterceptDelegateEnabled(expanded);
         }
     }
 
-    public void setKeyguardShowing(boolean keyguardShowing) {
+    public void setBarState(int statusBarState) {
+        boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD
+                || statusBarState == StatusBarState.SHADE_LOCKED;
         if (!mKeyguardShowing && keyguardShowing) {
             setQsTranslation(mQsExpansionHeight);
             mHeader.setTranslationY(0f);
         }
+        mStatusBarState = statusBarState;
         mKeyguardShowing = keyguardShowing;
         updateQsState();
     }
@@ -618,12 +622,12 @@
     private void updateQsState() {
         boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling;
         mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling);
-        mNotificationStackScroller.setEnabled(!mQsExpanded || mQsExpansionFromOverscroll);
+        mNotificationStackScroller.setScrollingEnabled(mStatusBarState != StatusBarState.KEYGUARD
+                && (!mQsExpanded || mQsExpansionFromOverscroll));
         mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
         mQsContainer.setVisibility(
                 mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE);
         mScrollView.setTouchEnabled(mQsExpanded);
-        mNotificationStackScroller.setTouchEnabled(!mQsExpanded || mQsExpansionFromOverscroll);
     }
 
     private void setQsExpansion(float height) {
@@ -823,8 +827,12 @@
             float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
             float t = (expandedHeight - panelHeightQsCollapsed)
                     / (panelHeightQsExpanded - panelHeightQsCollapsed);
+            int qsTempMaxExpansion = mQsMaxExpansionHeight;
+            if (mScrollYOverride != -1) {
+                qsTempMaxExpansion -= mScrollYOverride;
+            }
             setQsExpansion(mQsMinExpansionHeight
-                    + t * (mQsMaxExpansionHeight - mQsMinExpansionHeight));
+                    + t * (qsTempMaxExpansion - mQsMinExpansionHeight));
         }
         mNotificationStackScroller.setStackHeight(expandedHeight);
         updateHeader();
@@ -841,12 +849,20 @@
         if (totalHeight > mNotificationStackScroller.getHeight()) {
             float fullyCollapsedHeight = mQsMaxExpansionHeight
                     + mNotificationStackScroller.getMinStackHeight()
-                    + mNotificationStackScroller.getNotificationTopPadding();
+                    + mNotificationStackScroller.getNotificationTopPadding()
+                    - getScrollViewScrollY();
             totalHeight = Math.max(fullyCollapsedHeight, mNotificationStackScroller.getHeight());
         }
         return totalHeight;
     }
 
+    private int getScrollViewScrollY() {
+        if (mScrollYOverride != -1) {
+            return mScrollYOverride;
+        } else {
+            return mScrollView.getScrollY();
+        }
+    }
     private void updateNotificationTranslucency() {
         float alpha = (mNotificationStackScroller.getNotificationsTopY()
                 + mNotificationStackScroller.getItemHeight())
@@ -957,6 +973,10 @@
         mNotificationStackScroller.onExpansionStarted();
         mIsExpanding = true;
         mQsExpandedWhenExpandingStarted = mQsExpanded;
+        if (mQsExpanded) {
+            mScrollYOverride = mScrollView.getScrollY();
+            onQsExpansionStarted();
+        }
     }
 
     @Override
@@ -964,6 +984,7 @@
         super.onExpandingFinished();
         mNotificationStackScroller.onExpansionStopped();
         mIsExpanding = false;
+        mScrollYOverride = -1;
         if (mExpandedHeight == 0f) {
             mHeader.setListening(false);
             mQsPanel.setListening(false);
@@ -1044,6 +1065,7 @@
     public void onScrollChanged() {
         if (mQsExpanded) {
             requestScrollerTopPaddingUpdate(false /* animate */);
+            requestPanelHeightUpdate();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index ea5b309..45f3632 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -31,6 +31,7 @@
     private int mLastOverscrollAmount;
     private boolean mDispatchingTouchEvent;
     private boolean mTouchEnabled = true;
+    private boolean mInTouchEvent;
 
     public ObservableScrollView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -49,7 +50,7 @@
     }
 
     public boolean isDispatchingTouchEvent() {
-        return mDispatchingTouchEvent;
+        return mDispatchingTouchEvent || mInTouchEvent;
     }
 
     private int getMaxScrollY() {
@@ -63,6 +64,22 @@
     }
 
     @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        mInTouchEvent = true;
+        boolean result = super.onTouchEvent(ev);
+        mInTouchEvent = false;
+        return result;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        mInTouchEvent = true;
+        boolean result = super.onInterceptTouchEvent(ev);
+        mInTouchEvent = false;
+        return result;
+    }
+
+    @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (!mTouchEnabled) {
             return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index c4d4655..3fd3175 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2841,14 +2841,13 @@
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mKeyguardBottomArea.setVisibility(View.VISIBLE);
             mHeader.setKeyguardShowing(true);
-            mNotificationPanel.setKeyguardShowing(true);
             mScrimController.setKeyguardShowing(true);
         } else {
             mKeyguardBottomArea.setVisibility(View.GONE);
             mHeader.setKeyguardShowing(false);
-            mNotificationPanel.setKeyguardShowing(false);
             mScrimController.setKeyguardShowing(false);
         }
+        mNotificationPanel.setBarState(mState);
         updateDozingState();
         updateStackScrollerState();
         updatePublicMode();
@@ -2883,7 +2882,6 @@
         mStackScroller.setDimmed(onKeyguard, false /* animate */);
         mStackScroller.setVisibility(!mShowLockscreenNotifications && onKeyguard
                 ? View.INVISIBLE : View.VISIBLE);
-        mStackScroller.setScrollingEnabled(!onKeyguard);
         mStackScroller.setExpandingEnabled(!onKeyguard);
         ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
         mStackScroller.setActivatedChild(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index b46d523..2fc4ff3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -30,6 +30,8 @@
 import android.view.ViewTreeObserver;
 import android.view.animation.AnimationUtils;
 import android.widget.OverScroller;
+import android.widget.ScrollView;
+
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
@@ -166,7 +168,10 @@
      * animating.
      */
     private boolean mOnlyScrollingInThisMotion;
-    private boolean mTouchEnabled = true;
+    private ViewGroup mScrollView;
+    private boolean mInterceptDelegateEnabled;
+    private boolean mDelegateToScrollView;
+
     private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
         @Override
@@ -465,6 +470,14 @@
         mLongClickListener = listener;
     }
 
+    public void setScrollView(ViewGroup scrollView) {
+        mScrollView = scrollView;
+    }
+
+    public void setInterceptDelegateEnabled(boolean interceptDelegateEnabled) {
+        mInterceptDelegateEnabled = interceptDelegateEnabled;
+    }
+
     public void onChildDismissed(View v) {
         if (DEBUG) Log.v(TAG, "onChildDismissed: " + v);
         final View veto = v.findViewById(R.id.veto);
@@ -535,7 +548,7 @@
             }
             float childTop = slidingChild.getTranslationY();
             float top = childTop + slidingChild.getClipTopAmount();
-            float bottom = childTop + slidingChild.getActualHeight();
+            float bottom = top + slidingChild.getActualHeight();
             int left = slidingChild.getLeft();
             int right = slidingChild.getRight();
 
@@ -618,11 +631,15 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        if (!isEnabled()) {
-            return false;
-        }
         boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
                 || ev.getActionMasked()== MotionEvent.ACTION_UP;
+        if (mDelegateToScrollView) {
+            if (isCancelOrUp) {
+                mDelegateToScrollView = false;
+            }
+            transformTouchEvent(ev, this, mScrollView);
+            return mScrollView.onTouchEvent(ev);
+        }
         boolean expandWantsIt = false;
         if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) {
             if (isCancelOrUp) {
@@ -1341,8 +1358,22 @@
         }
     }
 
+    private void transformTouchEvent(MotionEvent ev, View sourceView, View targetView) {
+        ev.offsetLocation(sourceView.getX(), sourceView.getY());
+        ev.offsetLocation(-targetView.getX(), -targetView.getY());
+    }
+
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mInterceptDelegateEnabled) {
+            transformTouchEvent(ev, this, mScrollView);
+            if (mScrollView.onInterceptTouchEvent(ev)) {
+                mDelegateToScrollView = true;
+                removeLongPressCallback();
+                return true;
+            }
+            transformTouchEvent(ev, mScrollView, this);
+        }
         initDownStates(ev);
         boolean expandWantsIt = false;
         if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) {
@@ -1879,18 +1910,6 @@
         return mTopPadding + getTranslationY();
     }
 
-    public void setTouchEnabled(boolean touchEnabled) {
-        mTouchEnabled = touchEnabled;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        if (!mTouchEnabled) {
-            return false;
-        }
-        return super.dispatchTouchEvent(ev);
-    }
-
     @Override
     public boolean shouldDelayChildPressedState() {
         return true;