Home | History | Annotate | Download | only in policy
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.systemui.statusbar.policy;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.ObjectAnimator;
     22 import android.animation.ValueAnimator;
     23 import android.content.Context;
     24 import android.database.DataSetObserver;
     25 import android.view.LayoutInflater;
     26 import android.view.View;
     27 import android.view.ViewGroup;
     28 import android.view.ViewStub;
     29 import android.view.animation.AnimationUtils;
     30 import android.widget.TextView;
     31 
     32 import com.android.keyguard.AppearAnimationUtils;
     33 import com.android.systemui.R;
     34 import com.android.systemui.qs.tiles.UserDetailItemView;
     35 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
     36 import com.android.systemui.statusbar.phone.NotificationPanelView;
     37 import com.android.systemui.statusbar.phone.PhoneStatusBar;
     38 import com.android.systemui.statusbar.phone.StatusBarHeaderView;
     39 import com.android.systemui.statusbar.phone.UserAvatarView;
     40 
     41 /**
     42  * Manages the user switcher on the Keyguard.
     43  */
     44 public class KeyguardUserSwitcher {
     45 
     46     private static final String TAG = "KeyguardUserSwitcher";
     47     private static final boolean ALWAYS_ON = false;
     48 
     49     private final ViewGroup mUserSwitcher;
     50     private final KeyguardStatusBarView mStatusBarView;
     51     private final Adapter mAdapter;
     52     private final AppearAnimationUtils mAppearAnimationUtils;
     53     private final KeyguardUserSwitcherScrim mBackground;
     54     private ObjectAnimator mBgAnimator;
     55     private UserSwitcherController mUserSwitcherController;
     56 
     57     public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
     58             KeyguardStatusBarView statusBarView, NotificationPanelView panelView,
     59             UserSwitcherController userSwitcherController) {
     60         if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher) || ALWAYS_ON) {
     61             mUserSwitcher = (ViewGroup) userSwitcher.inflate();
     62             mBackground = new KeyguardUserSwitcherScrim(mUserSwitcher);
     63             mUserSwitcher.setBackground(mBackground);
     64             mStatusBarView = statusBarView;
     65             mStatusBarView.setKeyguardUserSwitcher(this);
     66             panelView.setKeyguardUserSwitcher(this);
     67             mAdapter = new Adapter(context, userSwitcherController);
     68             mAdapter.registerDataSetObserver(mDataSetObserver);
     69             mUserSwitcherController = userSwitcherController;
     70             mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
     71                     AnimationUtils.loadInterpolator(
     72                             context, android.R.interpolator.fast_out_slow_in));
     73         } else {
     74             mUserSwitcher = null;
     75             mStatusBarView = null;
     76             mAdapter = null;
     77             mAppearAnimationUtils = null;
     78             mBackground = null;
     79         }
     80     }
     81 
     82     public void setKeyguard(boolean keyguard, boolean animate) {
     83         if (mUserSwitcher != null) {
     84             if (keyguard && shouldExpandByDefault()) {
     85                 show(animate);
     86             } else {
     87                 hide(animate);
     88             }
     89         }
     90     }
     91 
     92     /**
     93      * @return true if the user switcher should be expanded by default on the lock screen.
     94      * @see android.os.UserManager#isUserSwitcherEnabled()
     95      */
     96     private boolean shouldExpandByDefault() {
     97         return (mUserSwitcherController != null) && mUserSwitcherController.isSimpleUserSwitcher();
     98     }
     99 
    100     public void show(boolean animate) {
    101         if (mUserSwitcher != null && mUserSwitcher.getVisibility() != View.VISIBLE) {
    102             cancelAnimations();
    103             mUserSwitcher.setVisibility(View.VISIBLE);
    104             mStatusBarView.setKeyguardUserSwitcherShowing(true, animate);
    105             if (animate) {
    106                 startAppearAnimation();
    107             }
    108         }
    109     }
    110 
    111     public void hide(boolean animate) {
    112         if (mUserSwitcher != null && mUserSwitcher.getVisibility() == View.VISIBLE) {
    113             cancelAnimations();
    114             if (animate) {
    115                 startDisappearAnimation();
    116             } else {
    117                 mUserSwitcher.setVisibility(View.GONE);
    118             }
    119             mStatusBarView.setKeyguardUserSwitcherShowing(false, animate);
    120         }
    121     }
    122 
    123     private void cancelAnimations() {
    124         int count = mUserSwitcher.getChildCount();
    125         for (int i = 0; i < count; i++) {
    126             mUserSwitcher.getChildAt(i).animate().cancel();
    127         }
    128         if (mBgAnimator != null) {
    129             mBgAnimator.cancel();
    130         }
    131         mUserSwitcher.animate().cancel();
    132     }
    133 
    134     private void startAppearAnimation() {
    135         int count = mUserSwitcher.getChildCount();
    136         View[] objects = new View[count];
    137         for (int i = 0; i < count; i++) {
    138             objects[i] = mUserSwitcher.getChildAt(i);
    139         }
    140         mUserSwitcher.setClipChildren(false);
    141         mUserSwitcher.setClipToPadding(false);
    142         mAppearAnimationUtils.startAppearAnimation(objects, new Runnable() {
    143             @Override
    144             public void run() {
    145                 mUserSwitcher.setClipChildren(true);
    146                 mUserSwitcher.setClipToPadding(true);
    147             }
    148         });
    149         mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
    150         mBgAnimator.setDuration(400);
    151         mBgAnimator.setInterpolator(PhoneStatusBar.ALPHA_IN);
    152         mBgAnimator.addListener(new AnimatorListenerAdapter() {
    153             @Override
    154             public void onAnimationEnd(Animator animation) {
    155                 mBgAnimator = null;
    156             }
    157         });
    158         mBgAnimator.start();
    159     }
    160 
    161     private void startDisappearAnimation() {
    162         mUserSwitcher.animate()
    163                 .alpha(0f)
    164                 .setDuration(300)
    165                 .setInterpolator(PhoneStatusBar.ALPHA_OUT)
    166                 .withEndAction(new Runnable() {
    167                     @Override
    168                     public void run() {
    169                         mUserSwitcher.setVisibility(View.GONE);
    170                         mUserSwitcher.setAlpha(1f);
    171                     }
    172                 });
    173     }
    174 
    175     private void refresh() {
    176         final int childCount = mUserSwitcher.getChildCount();
    177         final int adapterCount = mAdapter.getCount();
    178         final int N = Math.max(childCount, adapterCount);
    179         for (int i = 0; i < N; i++) {
    180             if (i < adapterCount) {
    181                 View oldView = null;
    182                 if (i < childCount) {
    183                     oldView = mUserSwitcher.getChildAt(i);
    184                 }
    185                 View newView = mAdapter.getView(i, oldView, mUserSwitcher);
    186                 if (oldView == null) {
    187                     // We ran out of existing views. Add it at the end.
    188                     mUserSwitcher.addView(newView);
    189                 } else if (oldView != newView) {
    190                     // We couldn't rebind the view. Replace it.
    191                     mUserSwitcher.removeViewAt(i);
    192                     mUserSwitcher.addView(newView, i);
    193                 }
    194             } else {
    195                 int lastIndex = mUserSwitcher.getChildCount() - 1;
    196                 mUserSwitcher.removeViewAt(lastIndex);
    197             }
    198         }
    199     }
    200 
    201     public final DataSetObserver mDataSetObserver = new DataSetObserver() {
    202         @Override
    203         public void onChanged() {
    204             refresh();
    205         }
    206     };
    207 
    208     public static class Adapter extends UserSwitcherController.BaseUserAdapter implements
    209             View.OnClickListener {
    210 
    211         private Context mContext;
    212 
    213         public Adapter(Context context, UserSwitcherController controller) {
    214             super(controller);
    215             mContext = context;
    216         }
    217 
    218         @Override
    219         public View getView(int position, View convertView, ViewGroup parent) {
    220             UserSwitcherController.UserRecord item = getItem(position);
    221 
    222             if (!(convertView instanceof UserDetailItemView)
    223                     || !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) {
    224                 convertView = LayoutInflater.from(mContext).inflate(
    225                         R.layout.keyguard_user_switcher_item, parent, false);
    226                 convertView.setOnClickListener(this);
    227             }
    228             UserDetailItemView v = (UserDetailItemView) convertView;
    229 
    230             String name = getName(mContext, item);
    231             if (item.picture == null) {
    232                 v.bind(name, getDrawable(mContext, item));
    233             } else {
    234                 v.bind(name, item.picture);
    235             }
    236             convertView.setActivated(item.isCurrent);
    237             convertView.setTag(item);
    238             return convertView;
    239         }
    240 
    241         @Override
    242         public void onClick(View v) {
    243             switchTo(((UserSwitcherController.UserRecord)v.getTag()));
    244         }
    245     }
    246 }
    247