KeyguardMultiUserAvatar.java revision 25a272a9f6323f6a3513bb522d45e839449878ce
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
17package com.android.internal.policy.impl.keyguard;
18
19import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.ValueAnimator.AnimatorUpdateListener;
22import android.animation.ValueAnimator;
23import android.content.Context;
24import android.content.pm.UserInfo;
25import android.content.res.Resources;
26import android.graphics.Bitmap;
27import android.graphics.BitmapFactory;
28import android.graphics.Color;
29import android.util.AttributeSet;
30import android.util.Log;
31import android.view.LayoutInflater;
32import android.view.View;
33import android.widget.FrameLayout;
34import android.widget.ImageView;
35import android.widget.TextView;
36
37import com.android.internal.R;
38
39class KeyguardMultiUserAvatar extends FrameLayout {
40    private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
41    private static final boolean DEBUG = KeyguardHostView.DEBUG;
42
43    private ImageView mUserImage;
44    private TextView mUserName;
45    private UserInfo mUserInfo;
46    private static final float ACTIVE_ALPHA = 1.0f;
47    private static final float INACTIVE_ALPHA = 1.0f;
48    private static final float ACTIVE_SCALE = 1.5f;
49    private static final float ACTIVE_TEXT_ALPHA = 0f;
50    private static final float INACTIVE_TEXT_ALPHA = 0.5f;
51    private static final int SWITCH_ANIMATION_DURATION = 150;
52
53    private final float mActiveAlpha;
54    private final float mActiveScale;
55    private final float mActiveTextAlpha;
56    private final float mInactiveAlpha;
57    private final float mInactiveTextAlpha;
58    private final float mShadowRadius;
59    private final float mStroke;
60    private final float mIconSize;
61    private final int mFrameColor;
62    private final int mFrameShadowColor;
63    private final int mTextColor;
64    private final int mHighlightColor;
65
66    private boolean mTouched;
67
68    private boolean mActive;
69    private boolean mInit = true;
70    private KeyguardMultiUserSelectorView mUserSelector;
71    private KeyguardCircleFramedDrawable mFramed;
72    private boolean mPressLock;
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
108        mTouched = false;
109
110        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
111    }
112
113    protected String rewriteIconPath(String path) {
114        if (!this.getClass().getName().contains("internal")) {
115            return path.replace("system", "data");
116        }
117        return path;
118    }
119
120    public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
121        mUserInfo = user;
122        mUserSelector = userSelector;
123
124        mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
125        mUserName = (TextView) findViewById(R.id.keyguard_user_name);
126
127        Bitmap icon = null;
128        try {
129            icon = BitmapFactory.decodeFile(rewriteIconPath(user.iconPath));
130        } catch (Exception e) {
131            if (DEBUG) Log.d(TAG, "failed to open profile icon " + user.iconPath, e);
132        }
133
134        if (icon == null) {
135            icon = BitmapFactory.decodeResource(mContext.getResources(),
136                    com.android.internal.R.drawable.ic_contact_picture);
137        }
138
139        mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
140                mFrameShadowColor, mShadowRadius, mHighlightColor);
141        mUserImage.setImageDrawable(mFramed);
142        mUserName.setText(mUserInfo.name);
143        setOnClickListener(mUserSelector);
144        mInit = false;
145    }
146
147    public void setActive(boolean active, boolean animate, final Runnable onComplete) {
148        if (mActive != active || mInit) {
149            mActive = active;
150
151            if (active) {
152                KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
153                parent.setTopChild(this);
154                // TODO: Create an appropriate asset when string changes are possible.
155                setContentDescription(mUserName.getText()
156                        + ". " + mContext.getString(R.string.user_switched, ""));
157            } else {
158                setContentDescription(mUserName.getText());
159            }
160        }
161        updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
162    }
163
164    void updateVisualsForActive(boolean active, boolean animate, int duration,
165            final Runnable onComplete) {
166        final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
167        final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
168        final float finalScale = active ? 1f : 1f / mActiveScale;
169        final float initScale = mFramed.getScale();
170        final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
171                (int) (mInactiveTextAlpha * 255);
172        final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
173                (int) (mActiveTextAlpha * 255);
174        int textColor = mTextColor;
175        mUserName.setTextColor(textColor);
176
177        if (animate && mTouched) {
178            ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
179            va.addUpdateListener(new AnimatorUpdateListener() {
180                @Override
181                public void onAnimationUpdate(ValueAnimator animation) {
182                    float r = animation.getAnimatedFraction();
183                    float scale = (1 - r) * initScale + r * finalScale;
184                    float alpha = (1 - r) * initAlpha + r * finalAlpha;
185                    int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
186                    mFramed.setScale(scale);
187                    mUserImage.setAlpha(alpha);
188                    mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
189                    mUserImage.invalidate();
190                }
191            });
192            va.addListener(new AnimatorListenerAdapter() {
193                @Override
194                public void onAnimationEnd(Animator animation) {
195                    if (onComplete != null) {
196                        onComplete.run();
197                    }
198                }
199            });
200            va.setDuration(duration);
201            va.start();
202        } else {
203            mFramed.setScale(finalScale);
204            mUserImage.setAlpha(finalAlpha);
205            mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
206            if (onComplete != null) {
207                post(onComplete);
208            }
209        }
210
211        mTouched = true;
212    }
213
214    @Override
215    public void setPressed(boolean pressed) {
216        if (mPressLock && !pressed) {
217            return;
218        }
219
220        if (mPressLock || !pressed || isClickable()) {
221            super.setPressed(pressed);
222            mFramed.setPressed(pressed);
223            mUserImage.invalidate();
224        }
225    }
226
227    public void lockPressed(boolean pressed) {
228        mPressLock = pressed;
229        setPressed(pressed);
230    }
231
232    public UserInfo getUserInfo() {
233        return mUserInfo;
234    }
235}
236