Close keyguard user switcher on tap outside

Also closes when tapping the current user.
Also fixes a bug, where the background alpha was
not properly initialized. And while we're at it,
fixes a bug where the user switcher was closable
in simple mode by extending quick settings.

Bug: 17691134
Change-Id: I5444fe42a8a2887ab012ef6cbdcc57ba81a8c1c2
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher.xml b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
index 3730bbe..773da9a 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
@@ -14,13 +14,18 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.keyguard.AlphaOptimizedLinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/keyguard_user_switcher"
-        android:orientation="vertical"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:gravity="end"
-        android:visibility="gone"
-        android:paddingTop="4dp">
-</com.android.keyguard.AlphaOptimizedLinearLayout>
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+        class="com.android.systemui.statusbar.policy.KeyguardUserSwitcher$Container"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+    <com.android.keyguard.AlphaOptimizedLinearLayout
+            android:id="@+id/keyguard_user_switcher_inner"
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
+            android:layout_gravity="end"
+            android:gravity="end"
+            android:paddingTop="4dp">
+    </com.android.keyguard.AlphaOptimizedLinearLayout>
+</view>
\ 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 96f9b91..f6d4be5 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -101,11 +101,9 @@
 
         <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" />
+            android:layout="@layout/keyguard_user_switcher"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent" />
 
         <include
             layout="@layout/keyguard_status_bar"
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 c19bdff..bc2196a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1012,7 +1012,7 @@
                         ? View.VISIBLE
                         : View.INVISIBLE);
         if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
-            mKeyguardUserSwitcher.hide(true /* animate */);
+            mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
         }
     }
 
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 8f0000f..297ff70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -19,15 +19,16 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.database.DataSetObserver;
+import android.util.AttributeSet;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.view.animation.AnimationUtils;
-import android.widget.TextView;
+import android.widget.FrameLayout;
 
 import com.android.keyguard.AppearAnimationUtils;
 import com.android.systemui.R;
@@ -35,8 +36,6 @@
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.phone.StatusBarHeaderView;
-import com.android.systemui.statusbar.phone.UserAvatarView;
 
 /**
  * Manages the user switcher on the Keyguard.
@@ -46,6 +45,7 @@
     private static final String TAG = "KeyguardUserSwitcher";
     private static final boolean ALWAYS_ON = false;
 
+    private final Container mUserSwitcherContainer;
     private final ViewGroup mUserSwitcher;
     private final KeyguardStatusBarView mStatusBarView;
     private final Adapter mAdapter;
@@ -53,24 +53,29 @@
     private final KeyguardUserSwitcherScrim mBackground;
     private ObjectAnimator mBgAnimator;
     private UserSwitcherController mUserSwitcherController;
+    private boolean mAnimating;
 
     public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
             KeyguardStatusBarView statusBarView, NotificationPanelView panelView,
             UserSwitcherController userSwitcherController) {
         if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher) || ALWAYS_ON) {
-            mUserSwitcher = (ViewGroup) userSwitcher.inflate();
+            mUserSwitcherContainer = (Container) userSwitcher.inflate();
+            mUserSwitcher = (ViewGroup)
+                    mUserSwitcherContainer.findViewById(R.id.keyguard_user_switcher_inner);
             mBackground = new KeyguardUserSwitcherScrim(mUserSwitcher);
             mUserSwitcher.setBackground(mBackground);
             mStatusBarView = statusBarView;
             mStatusBarView.setKeyguardUserSwitcher(this);
             panelView.setKeyguardUserSwitcher(this);
-            mAdapter = new Adapter(context, userSwitcherController);
+            mAdapter = new Adapter(context, userSwitcherController, this);
             mAdapter.registerDataSetObserver(mDataSetObserver);
             mUserSwitcherController = userSwitcherController;
             mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
                     AnimationUtils.loadInterpolator(
                             context, android.R.interpolator.fast_out_slow_in));
+            mUserSwitcherContainer.setKeyguardUserSwitcher(this);
         } else {
+            mUserSwitcherContainer = null;
             mUserSwitcher = null;
             mStatusBarView = null;
             mAdapter = null;
@@ -98,9 +103,9 @@
     }
 
     public void show(boolean animate) {
-        if (mUserSwitcher != null && mUserSwitcher.getVisibility() != View.VISIBLE) {
+        if (mUserSwitcher != null && mUserSwitcherContainer.getVisibility() != View.VISIBLE) {
             cancelAnimations();
-            mUserSwitcher.setVisibility(View.VISIBLE);
+            mUserSwitcherContainer.setVisibility(View.VISIBLE);
             mStatusBarView.setKeyguardUserSwitcherShowing(true, animate);
             if (animate) {
                 startAppearAnimation();
@@ -108,13 +113,13 @@
         }
     }
 
-    public void hide(boolean animate) {
-        if (mUserSwitcher != null && mUserSwitcher.getVisibility() == View.VISIBLE) {
+    private void hide(boolean animate) {
+        if (mUserSwitcher != null && mUserSwitcherContainer.getVisibility() == View.VISIBLE) {
             cancelAnimations();
             if (animate) {
                 startDisappearAnimation();
             } else {
-                mUserSwitcher.setVisibility(View.GONE);
+                mUserSwitcherContainer.setVisibility(View.GONE);
             }
             mStatusBarView.setKeyguardUserSwitcherShowing(false, animate);
         }
@@ -129,6 +134,7 @@
             mBgAnimator.cancel();
         }
         mUserSwitcher.animate().cancel();
+        mAnimating = false;
     }
 
     private void startAppearAnimation() {
@@ -146,6 +152,7 @@
                 mUserSwitcher.setClipToPadding(true);
             }
         });
+        mAnimating = true;
         mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
         mBgAnimator.setDuration(400);
         mBgAnimator.setInterpolator(PhoneStatusBar.ALPHA_IN);
@@ -153,12 +160,14 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mBgAnimator = null;
+                mAnimating = false;
             }
         });
         mBgAnimator.start();
     }
 
     private void startDisappearAnimation() {
+        mAnimating = true;
         mUserSwitcher.animate()
                 .alpha(0f)
                 .setDuration(300)
@@ -166,8 +175,9 @@
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
-                        mUserSwitcher.setVisibility(View.GONE);
+                        mUserSwitcherContainer.setVisibility(View.GONE);
                         mUserSwitcher.setAlpha(1f);
+                        mAnimating = false;
                     }
                 });
     }
@@ -198,6 +208,16 @@
         }
     }
 
+    public void hideIfNotSimple(boolean animate) {
+        if (mUserSwitcherContainer != null && !mUserSwitcherController.isSimpleUserSwitcher()) {
+            hide(animate);
+        }
+    }
+
+    boolean isAnimating() {
+        return mAnimating;
+    }
+
     public final DataSetObserver mDataSetObserver = new DataSetObserver() {
         @Override
         public void onChanged() {
@@ -209,10 +229,13 @@
             View.OnClickListener {
 
         private Context mContext;
+        private KeyguardUserSwitcher mKeyguardUserSwitcher;
 
-        public Adapter(Context context, UserSwitcherController controller) {
+        public Adapter(Context context, UserSwitcherController controller,
+                KeyguardUserSwitcher kgu) {
             super(controller);
             mContext = context;
+            mKeyguardUserSwitcher = kgu;
         }
 
         @Override
@@ -240,7 +263,37 @@
 
         @Override
         public void onClick(View v) {
-            switchTo(((UserSwitcherController.UserRecord)v.getTag()));
+            UserSwitcherController.UserRecord user = (UserSwitcherController.UserRecord) v.getTag();
+            if (user.isCurrent && !user.isGuest) {
+                // Close the switcher if tapping the current user. Guest is excluded because
+                // tapping the guest user while it's current clears the session.
+                mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
+            } else {
+                switchTo(user);
+            }
+        }
+    }
+
+    public static class Container extends FrameLayout {
+
+        private KeyguardUserSwitcher mKeyguardUserSwitcher;
+
+        public Container(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            setClipChildren(false);
+        }
+
+        public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
+            mKeyguardUserSwitcher = keyguardUserSwitcher;
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            // Hide switcher if it didn't handle the touch event (and let the event go through).
+            if (mKeyguardUserSwitcher != null && !mKeyguardUserSwitcher.isAnimating()) {
+                mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
+            }
+            return false;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
index 4363037..a5fc2fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
@@ -42,7 +42,7 @@
 
     private int mDarkColor;
     private int mTop;
-    private int mAlpha;
+    private int mAlpha = 255;
     private Paint mRadialGradientPaint = new Paint();
     private int mLayoutWidth;