Fix ordering of notifications, user switcher and QS panel

Also closes the user switcher when opening QS on Keyguard because
touch logic would interleave with QS.

Change-Id: I391dc9bcba7f9e2e99c0854d34ed0ec6efbb2f44
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1f68cd8..9af2879 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -56,14 +56,6 @@
         android:clipToPadding="false"
         android:clipChildren="false">
 
-        <ViewStub
-                android:id="@+id/keyguard_user_switcher"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
-                android:layout_gravity="end"
-                android:layout="@layout/keyguard_user_switcher" />
-
         <com.android.systemui.statusbar.phone.ObservableScrollView
             android:id="@+id/scroll_view"
             android:layout_width="match_parent"
@@ -103,6 +95,14 @@
             android:layout_height="match_parent"
             android:layout_marginBottom="@dimen/close_handle_underlap"/>
 
+        <ViewStub
+            android:id="@+id/keyguard_user_switcher"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
+            android:layout_gravity="end"
+            android:layout="@layout/keyguard_user_switcher" />
+
     </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
 
     <include layout="@layout/status_bar_expanded_header" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index f41e78d..7c6e47c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -17,23 +17,71 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewStub;
 import android.widget.FrameLayout;
 
+import com.android.systemui.R;
+
 /**
  * The container with notification stack scroller and quick settings inside.
  */
-public class NotificationsQuickSettingsContainer extends FrameLayout {
+public class NotificationsQuickSettingsContainer extends FrameLayout
+        implements ViewStub.OnInflateListener {
+
+    private View mScrollView;
+    private View mUserSwitcher;
+    private View mStackScroller;
+    private boolean mInflated;
 
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mScrollView = findViewById(R.id.scroll_view);
+        mStackScroller = findViewById(R.id.notification_stack_scroller);
+        ViewStub userSwitcher = (ViewStub) findViewById(R.id.keyguard_user_switcher);
+        userSwitcher.setOnInflateListener(this);
+        mUserSwitcher = userSwitcher;
+    }
+
+    @Override
     protected boolean fitSystemWindows(Rect insets) {
         setPadding(0, 0, 0, insets.bottom);
         insets.bottom = 0;
         return true;
     }
+
+    @Override
+    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
+
+        // Invert the order of the scroll view and user switcher such that the notifications receive
+        // touches first but the panel gets drawn above.
+        if (child == mScrollView) {
+            return super.drawChild(canvas, mStackScroller, drawingTime);
+        } else if (child == mStackScroller) {
+            return super.drawChild(canvas, userSwitcherVisible ? mUserSwitcher : mScrollView,
+                    drawingTime);
+        } else if (child == mUserSwitcher) {
+            return super.drawChild(canvas, userSwitcherVisible ? mScrollView : mUserSwitcher,
+                    drawingTime);
+        } else {
+            return super.drawChild(canvas, child, drawingTime);
+        }
+    }
+
+    @Override
+    public void onInflate(ViewStub stub, View inflated) {
+        if (stub == mUserSwitcher) {
+            mUserSwitcher = inflated;
+            mInflated = true;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index bac1d5b..65359ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -98,7 +98,7 @@
     private ActivityStarter mActivityStarter;
     private BatteryController mBatteryController;
     private QSPanel mQSPanel;
-    private boolean mHasKeyguardUserSwitcher;
+    private KeyguardUserSwitcher mKeyguardUserSwitcher;
 
     private final Rect mClipBounds = new Rect();
     private final StatusIconClipper mStatusIconClipper = new StatusIconClipper();
@@ -300,6 +300,9 @@
                 ? VISIBLE : GONE);
         mBatteryLevel.setVisibility(mKeyguardShowing && mCharging || mExpanded && !mOverscrolled
                 ? View.VISIBLE : View.GONE);
+        if (mExpanded && !mOverscrolled && mKeyguardUserSwitcherShowing) {
+            mKeyguardUserSwitcher.hide();
+        }
     }
 
     private void updateSystemIconsLayoutParams() {
@@ -377,7 +380,7 @@
         mDateTime.setClickable(mExpanded);
 
         boolean keyguardSwitcherAvailable =
-                mHasKeyguardUserSwitcher && mKeyguardShowing && !mExpanded;
+                mKeyguardUserSwitcher != null && mKeyguardShowing && !mExpanded;
         mMultiUserSwitch.setClickable(mExpanded || keyguardSwitcherAvailable);
         mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable);
         mSystemIconsSuperContainer.setClickable(mExpanded);
@@ -516,7 +519,7 @@
     }
 
     public void setKeyguarUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
-        mHasKeyguardUserSwitcher = true;
+        mKeyguardUserSwitcher = keyguardUserSwitcher;
         mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index b0bab48..2be566c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -88,7 +88,7 @@
         }
     }
 
-    private void hide() {
+    public void hide() {
         if (mUserSwitcher != null) {
             // TODO: animate
             mUserSwitcher.setVisibility(View.GONE);