• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = KeyguardHostView.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 
fromXml(int resId, Context context, KeyguardMultiUserSelectorView userSelector, UserInfo info)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 
KeyguardMultiUserAvatar(Context context)83     public KeyguardMultiUserAvatar(Context context) {
84         this(context, null, 0);
85     }
86 
KeyguardMultiUserAvatar(Context context, AttributeSet attrs)87     public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
88         this(context, attrs, 0);
89     }
90 
KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle)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 
rewriteIconPath(String path)114     protected String rewriteIconPath(String path) {
115         return path;
116     }
117 
init(UserInfo user, KeyguardMultiUserSelectorView userSelector)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                 KeyguardViewMediator.getAvatarCache().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             KeyguardViewMediator.getAvatarCache().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 
setActive(boolean active, boolean animate, final Runnable onComplete)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 
updateVisualsForActive(boolean active, boolean animate, int duration, final Runnable onComplete)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
setPressed(boolean pressed)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 
lockPressed(boolean pressed)237     public void lockPressed(boolean pressed) {
238         mPressLock = pressed;
239         setPressed(pressed);
240     }
241 
getUserInfo()242     public UserInfo getUserInfo() {
243         return mUserInfo;
244     }
245 }
246