Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 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 | |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 17 | package com.android.keyguard; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 18 | |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 19 | import android.animation.Animator; |
| 20 | import android.animation.AnimatorListenerAdapter; |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 21 | import android.animation.ValueAnimator.AnimatorUpdateListener; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 22 | import android.animation.ValueAnimator; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 23 | import android.content.Context; |
| 24 | import android.content.pm.UserInfo; |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 25 | import android.content.res.Resources; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 26 | import android.graphics.Bitmap; |
| 27 | import android.graphics.BitmapFactory; |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 28 | import android.graphics.Color; |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 29 | import android.os.UserManager; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 30 | import android.util.AttributeSet; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 31 | import android.util.Log; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 32 | import android.view.LayoutInflater; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 33 | import android.view.View; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 34 | import android.widget.FrameLayout; |
| 35 | import android.widget.ImageView; |
| 36 | import android.widget.TextView; |
| 37 | |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 38 | class KeyguardMultiUserAvatar extends FrameLayout { |
Chris Wren | 28c5ee9 | 2012-10-24 16:05:14 -0400 | [diff] [blame] | 39 | private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName(); |
Jorim Jaggi | 5cf1787 | 2014-03-26 18:31:48 +0100 | [diff] [blame] | 40 | private static final boolean DEBUG = KeyguardConstants.DEBUG; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 41 | |
| 42 | private ImageView mUserImage; |
| 43 | private TextView mUserName; |
| 44 | private UserInfo mUserInfo; |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 45 | private static final float ACTIVE_ALPHA = 1.0f; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 46 | private static final float INACTIVE_ALPHA = 1.0f; |
| 47 | private static final float ACTIVE_SCALE = 1.5f; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 48 | private static final float ACTIVE_TEXT_ALPHA = 0f; |
| 49 | private static final float INACTIVE_TEXT_ALPHA = 0.5f; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 50 | private static final int SWITCH_ANIMATION_DURATION = 150; |
| 51 | |
| 52 | private final float mActiveAlpha; |
| 53 | private final float mActiveScale; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 54 | private final float mActiveTextAlpha; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 55 | private final float mInactiveAlpha; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 56 | private final float mInactiveTextAlpha; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 57 | private final float mShadowRadius; |
| 58 | private final float mStroke; |
| 59 | private final float mIconSize; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 60 | private final int mFrameColor; |
| 61 | private final int mFrameShadowColor; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 62 | private final int mTextColor; |
| 63 | private final int mHighlightColor; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 64 | |
| 65 | private boolean mTouched; |
| 66 | |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 67 | private boolean mActive; |
| 68 | private boolean mInit = true; |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 69 | private KeyguardMultiUserSelectorView mUserSelector; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 70 | private KeyguardCircleFramedDrawable mFramed; |
Chris Wren | f41c61b | 2012-11-29 15:19:54 -0500 | [diff] [blame] | 71 | private boolean mPressLock; |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 72 | private UserManager mUserManager; |
Adam Cohen | 9654329 | 2012-09-28 18:13:14 -0700 | [diff] [blame] | 73 | |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 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 | |
Adam Cohen | 0a8d326 | 2012-10-03 13:50:55 -0700 | [diff] [blame] | 79 | icon.init(info, userSelector); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 80 | return icon; |
| 81 | } |
| 82 | |
| 83 | public KeyguardMultiUserAvatar(Context context) { |
Adam Cohen | 0a8d326 | 2012-10-03 13:50:55 -0700 | [diff] [blame] | 84 | this(context, null, 0); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) { |
Adam Cohen | 0a8d326 | 2012-10-03 13:50:55 -0700 | [diff] [blame] | 88 | this(context, attrs, 0); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) { |
| 92 | super(context, attrs, defStyle); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 93 | |
Jim Miller | 6bcd732 | 2012-10-02 16:32:04 -0700 | [diff] [blame] | 94 | Resources res = mContext.getResources(); |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 95 | mTextColor = res.getColor(R.color.keyguard_avatar_nick_color); |
| 96 | mIconSize = res.getDimension(R.dimen.keyguard_avatar_size); |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 97 | mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width); |
| 98 | mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius); |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 99 | mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color); |
| 100 | mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color); |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 101 | mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color); |
| 102 | mActiveTextAlpha = ACTIVE_TEXT_ALPHA; |
| 103 | mInactiveTextAlpha = INACTIVE_TEXT_ALPHA; |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 104 | mActiveScale = ACTIVE_SCALE; |
| 105 | mActiveAlpha = ACTIVE_ALPHA; |
| 106 | mInactiveAlpha = INACTIVE_ALPHA; |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 107 | mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 108 | |
| 109 | mTouched = false; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 110 | |
| 111 | setLayerType(View.LAYER_TYPE_SOFTWARE, null); |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | protected String rewriteIconPath(String path) { |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 115 | return path; |
| 116 | } |
| 117 | |
Adam Cohen | 0a8d326 | 2012-10-03 13:50:55 -0700 | [diff] [blame] | 118 | public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) { |
| 119 | mUserInfo = user; |
| 120 | mUserSelector = userSelector; |
Jim Miller | 6bcd732 | 2012-10-02 16:32:04 -0700 | [diff] [blame] | 121 | |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 122 | mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar); |
Jim Miller | 71b3cd5 | 2012-10-10 19:02:40 -0700 | [diff] [blame] | 123 | mUserName = (TextView) findViewById(R.id.keyguard_user_name); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 124 | |
Amith Yamasani | 6fc1d4e | 2013-05-08 16:43:58 -0700 | [diff] [blame] | 125 | mFramed = (KeyguardCircleFramedDrawable) |
Jorim Jaggi | 5cf1787 | 2014-03-26 18:31:48 +0100 | [diff] [blame] | 126 | MultiUserAvatarCache.getInstance().get(user.id); |
Amith Yamasani | 6fc1d4e | 2013-05-08 16:43:58 -0700 | [diff] [blame] | 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 { |
Amith Yamasani | 99f7fae | 2013-05-13 16:08:31 -0700 | [diff] [blame] | 134 | icon = mUserManager.getUserIcon(user.id); |
Amith Yamasani | 6fc1d4e | 2013-05-08 16:43:58 -0700 | [diff] [blame] | 135 | } catch (Exception e) { |
Amith Yamasani | 99f7fae | 2013-05-13 16:08:31 -0700 | [diff] [blame] | 136 | if (DEBUG) Log.d(TAG, "failed to get profile icon " + user, e); |
Amith Yamasani | 6fc1d4e | 2013-05-08 16:43:58 -0700 | [diff] [blame] | 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); |
Jorim Jaggi | 5cf1787 | 2014-03-26 18:31:48 +0100 | [diff] [blame] | 146 | MultiUserAvatarCache.getInstance().put(user.id, mFramed); |
Chris Wren | 28c5ee9 | 2012-10-24 16:05:14 -0400 | [diff] [blame] | 147 | } |
| 148 | |
Amith Yamasani | 6fc1d4e | 2013-05-08 16:43:58 -0700 | [diff] [blame] | 149 | mFramed.reset(); |
Chris Wren | 28c5ee9 | 2012-10-24 16:05:14 -0400 | [diff] [blame] | 150 | |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 151 | mUserImage.setImageDrawable(mFramed); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 152 | mUserName.setText(mUserInfo.name); |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 153 | setOnClickListener(mUserSelector); |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 154 | mInit = false; |
| 155 | } |
| 156 | |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 157 | public void setActive(boolean active, boolean animate, final Runnable onComplete) { |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 158 | if (mActive != active || mInit) { |
| 159 | mActive = active; |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 160 | |
| 161 | if (active) { |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 162 | KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent(); |
| 163 | parent.setTopChild(this); |
Svetoslav Ganov | fc9c4cd | 2012-11-02 11:49:22 -0700 | [diff] [blame] | 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()); |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 169 | } |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 170 | } |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 171 | updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete); |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 172 | } |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 173 | |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 174 | void updateVisualsForActive(boolean active, boolean animate, int duration, |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 175 | final Runnable onComplete) { |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 176 | final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha; |
| 177 | final float initAlpha = active ? mInactiveAlpha : mActiveAlpha; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 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; |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 185 | mUserName.setTextColor(textColor); |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 186 | |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 187 | if (animate && mTouched) { |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 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; |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 195 | int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha); |
| 196 | mFramed.setScale(scale); |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 197 | mUserImage.setAlpha(alpha); |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 198 | mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255)); |
| 199 | mUserImage.invalidate(); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 200 | } |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 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 { |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 213 | mFramed.setScale(finalScale); |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 214 | mUserImage.setAlpha(finalAlpha); |
Chris Wren | 692bb13 | 2012-10-23 13:37:36 -0400 | [diff] [blame] | 215 | mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255)); |
Adam Cohen | 61cd69c | 2012-10-02 21:42:54 -0700 | [diff] [blame] | 216 | if (onComplete != null) { |
| 217 | post(onComplete); |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 218 | } |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 219 | } |
Jim Miller | 022554e | 2012-10-22 19:03:06 -0700 | [diff] [blame] | 220 | |
| 221 | mTouched = true; |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 222 | } |
| 223 | |
Adam Cohen | 9654329 | 2012-09-28 18:13:14 -0700 | [diff] [blame] | 224 | @Override |
| 225 | public void setPressed(boolean pressed) { |
Chris Wren | f41c61b | 2012-11-29 15:19:54 -0500 | [diff] [blame] | 226 | if (mPressLock && !pressed) { |
| 227 | return; |
| 228 | } |
| 229 | |
| 230 | if (mPressLock || !pressed || isClickable()) { |
Chris Wren | f0fd172 | 2012-10-26 09:45:43 -0400 | [diff] [blame] | 231 | super.setPressed(pressed); |
| 232 | mFramed.setPressed(pressed); |
| 233 | mUserImage.invalidate(); |
| 234 | } |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 235 | } |
| 236 | |
Chris Wren | f41c61b | 2012-11-29 15:19:54 -0500 | [diff] [blame] | 237 | public void lockPressed(boolean pressed) { |
| 238 | mPressLock = pressed; |
| 239 | setPressed(pressed); |
| 240 | } |
| 241 | |
Adam Cohen | 24b351a | 2012-09-14 15:02:27 -0700 | [diff] [blame] | 242 | public UserInfo getUserInfo() { |
| 243 | return mUserInfo; |
| 244 | } |
Adam Cohen | 66b9fb166 | 2012-09-05 16:23:58 -0700 | [diff] [blame] | 245 | } |