Home | History | Annotate | Download | only in keyguard
      1 /*
      2  * Copyright (C) 2012 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.keyguard;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.ValueAnimator.AnimatorUpdateListener;
     22 import android.animation.ValueAnimator;
     23 import android.content.Context;
     24 import android.content.pm.UserInfo;
     25 import android.content.res.Resources;
     26 import android.graphics.Bitmap;
     27 import android.graphics.BitmapFactory;
     28 import android.graphics.Color;
     29 import android.os.UserManager;
     30 import android.util.AttributeSet;
     31 import android.util.Log;
     32 import android.view.LayoutInflater;
     33 import android.view.View;
     34 import android.widget.FrameLayout;
     35 import android.widget.ImageView;
     36 import android.widget.TextView;
     37 
     38 class KeyguardMultiUserAvatar extends FrameLayout {
     39     private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
     40     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     41 
     42     private ImageView mUserImage;
     43     private TextView mUserName;
     44     private UserInfo mUserInfo;
     45     private static final float ACTIVE_ALPHA = 1.0f;
     46     private static final float INACTIVE_ALPHA = 1.0f;
     47     private static final float ACTIVE_SCALE = 1.5f;
     48     private static final float ACTIVE_TEXT_ALPHA = 0f;
     49     private static final float INACTIVE_TEXT_ALPHA = 0.5f;
     50     private static final int SWITCH_ANIMATION_DURATION = 150;
     51 
     52     private final float mActiveAlpha;
     53     private final float mActiveScale;
     54     private final float mActiveTextAlpha;
     55     private final float mInactiveAlpha;
     56     private final float mInactiveTextAlpha;
     57     private final float mShadowRadius;
     58     private final float mStroke;
     59     private final float mIconSize;
     60     private final int mFrameColor;
     61     private final int mFrameShadowColor;
     62     private final int mTextColor;
     63     private final int mHighlightColor;
     64 
     65     private boolean mTouched;
     66 
     67     private boolean mActive;
     68     private boolean mInit = true;
     69     private KeyguardMultiUserSelectorView mUserSelector;
     70     private KeyguardCircleFramedDrawable mFramed;
     71     private boolean mPressLock;
     72     private UserManager mUserManager;
     73 
     74     public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
     75             KeyguardMultiUserSelectorView userSelector, UserInfo info) {
     76         KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
     77                 LayoutInflater.from(context).inflate(resId, userSelector, false);
     78 
     79         icon.init(info, userSelector);
     80         return icon;
     81     }
     82 
     83     public KeyguardMultiUserAvatar(Context context) {
     84         this(context, null, 0);
     85     }
     86 
     87     public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
     88         this(context, attrs, 0);
     89     }
     90 
     91     public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
     92         super(context, attrs, defStyle);
     93 
     94         Resources res = mContext.getResources();
     95         mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
     96         mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
     97         mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
     98         mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
     99         mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
    100         mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
    101         mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
    102         mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
    103         mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
    104         mActiveScale = ACTIVE_SCALE;
    105         mActiveAlpha = ACTIVE_ALPHA;
    106         mInactiveAlpha = INACTIVE_ALPHA;
    107         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    108 
    109         mTouched = false;
    110 
    111         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    112     }
    113 
    114     protected String rewriteIconPath(String path) {
    115         return path;
    116     }
    117 
    118     public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
    119         mUserInfo = user;
    120         mUserSelector = userSelector;
    121 
    122         mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
    123         mUserName = (TextView) findViewById(R.id.keyguard_user_name);
    124 
    125         mFramed = (KeyguardCircleFramedDrawable)
    126                 MultiUserAvatarCache.getInstance().get(user.id);
    127 
    128         // If we can't find it or the params don't match, create the drawable again
    129         if (mFramed == null
    130                 || !mFramed.verifyParams(mIconSize, mFrameColor, mStroke, mFrameShadowColor,
    131                         mShadowRadius, mHighlightColor)) {
    132             Bitmap icon = null;
    133             try {
    134                 icon = mUserManager.getUserIcon(user.id);
    135             } catch (Exception e) {
    136                 if (DEBUG) Log.d(TAG, "failed to get profile icon " + user, e);
    137             }
    138 
    139             if (icon == null) {
    140                 icon = BitmapFactory.decodeResource(mContext.getResources(),
    141                         com.android.internal.R.drawable.ic_contact_picture);
    142             }
    143 
    144             mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
    145                     mFrameShadowColor, mShadowRadius, mHighlightColor);
    146             MultiUserAvatarCache.getInstance().put(user.id, mFramed);
    147         }
    148 
    149         mFramed.reset();
    150 
    151         mUserImage.setImageDrawable(mFramed);
    152         mUserName.setText(mUserInfo.name);
    153         setOnClickListener(mUserSelector);
    154         mInit = false;
    155     }
    156 
    157     public void setActive(boolean active, boolean animate, final Runnable onComplete) {
    158         if (mActive != active || mInit) {
    159             mActive = active;
    160 
    161             if (active) {
    162                 KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
    163                 parent.setTopChild(this);
    164                 // TODO: Create an appropriate asset when string changes are possible.
    165                 setContentDescription(mUserName.getText()
    166                         + ". " + mContext.getString(R.string.user_switched, ""));
    167             } else {
    168                 setContentDescription(mUserName.getText());
    169             }
    170         }
    171         updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
    172     }
    173 
    174     void updateVisualsForActive(boolean active, boolean animate, int duration,
    175             final Runnable onComplete) {
    176         final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
    177         final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
    178         final float finalScale = active ? 1f : 1f / mActiveScale;
    179         final float initScale = mFramed.getScale();
    180         final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
    181                 (int) (mInactiveTextAlpha * 255);
    182         final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
    183                 (int) (mActiveTextAlpha * 255);
    184         int textColor = mTextColor;
    185         mUserName.setTextColor(textColor);
    186 
    187         if (animate && mTouched) {
    188             ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
    189             va.addUpdateListener(new AnimatorUpdateListener() {
    190                 @Override
    191                 public void onAnimationUpdate(ValueAnimator animation) {
    192                     float r = animation.getAnimatedFraction();
    193                     float scale = (1 - r) * initScale + r * finalScale;
    194                     float alpha = (1 - r) * initAlpha + r * finalAlpha;
    195                     int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
    196                     mFramed.setScale(scale);
    197                     mUserImage.setAlpha(alpha);
    198                     mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
    199                     mUserImage.invalidate();
    200                 }
    201             });
    202             va.addListener(new AnimatorListenerAdapter() {
    203                 @Override
    204                 public void onAnimationEnd(Animator animation) {
    205                     if (onComplete != null) {
    206                         onComplete.run();
    207                     }
    208                 }
    209             });
    210             va.setDuration(duration);
    211             va.start();
    212         } else {
    213             mFramed.setScale(finalScale);
    214             mUserImage.setAlpha(finalAlpha);
    215             mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
    216             if (onComplete != null) {
    217                 post(onComplete);
    218             }
    219         }
    220 
    221         mTouched = true;
    222     }
    223 
    224     @Override
    225     public void setPressed(boolean pressed) {
    226         if (mPressLock && !pressed) {
    227             return;
    228         }
    229 
    230         if (mPressLock || !pressed || isClickable()) {
    231             super.setPressed(pressed);
    232             mFramed.setPressed(pressed);
    233             mUserImage.invalidate();
    234         }
    235     }
    236 
    237     public void lockPressed(boolean pressed) {
    238         mPressLock = pressed;
    239         setPressed(pressed);
    240     }
    241 
    242     public UserInfo getUserInfo() {
    243         return mUserInfo;
    244     }
    245 }
    246