This change reuses KeyguardViewMediator for the new Keyguard implementation in status bar. KeyguardViewManager is replaced by StatusBarKeyguardManager which handles adding the view, setting the state etc. StatusBarWindowManager is introduced to managed the window of the status bar, which has the logic of both the old Keyguard window and the old status bar window. In the current implementation, Keyguard gets displayed like it would be in the bouncer state, but that's likely to change in the future. Also, setHidden in IKeyguardService is also renamed to setOccluded, as the word hidden interferes with the terminology when dismissing the Keyguard. Bug: 13635952 Change-Id: I1c5d5a49d810d8532089f464cb2efe35e577f517
246 lines
9.2 KiB
Java
246 lines
9.2 KiB
Java
/*
|
|
* Copyright (C) 2012 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.keyguard;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
|
import android.animation.ValueAnimator;
|
|
import android.content.Context;
|
|
import android.content.pm.UserInfo;
|
|
import android.content.res.Resources;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.Color;
|
|
import android.os.UserManager;
|
|
import android.util.AttributeSet;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.widget.FrameLayout;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
|
|
class KeyguardMultiUserAvatar extends FrameLayout {
|
|
private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
|
|
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
|
|
|
private ImageView mUserImage;
|
|
private TextView mUserName;
|
|
private UserInfo mUserInfo;
|
|
private static final float ACTIVE_ALPHA = 1.0f;
|
|
private static final float INACTIVE_ALPHA = 1.0f;
|
|
private static final float ACTIVE_SCALE = 1.5f;
|
|
private static final float ACTIVE_TEXT_ALPHA = 0f;
|
|
private static final float INACTIVE_TEXT_ALPHA = 0.5f;
|
|
private static final int SWITCH_ANIMATION_DURATION = 150;
|
|
|
|
private final float mActiveAlpha;
|
|
private final float mActiveScale;
|
|
private final float mActiveTextAlpha;
|
|
private final float mInactiveAlpha;
|
|
private final float mInactiveTextAlpha;
|
|
private final float mShadowRadius;
|
|
private final float mStroke;
|
|
private final float mIconSize;
|
|
private final int mFrameColor;
|
|
private final int mFrameShadowColor;
|
|
private final int mTextColor;
|
|
private final int mHighlightColor;
|
|
|
|
private boolean mTouched;
|
|
|
|
private boolean mActive;
|
|
private boolean mInit = true;
|
|
private KeyguardMultiUserSelectorView mUserSelector;
|
|
private KeyguardCircleFramedDrawable mFramed;
|
|
private boolean mPressLock;
|
|
private UserManager mUserManager;
|
|
|
|
public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
|
|
KeyguardMultiUserSelectorView userSelector, UserInfo info) {
|
|
KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
|
|
LayoutInflater.from(context).inflate(resId, userSelector, false);
|
|
|
|
icon.init(info, userSelector);
|
|
return icon;
|
|
}
|
|
|
|
public KeyguardMultiUserAvatar(Context context) {
|
|
this(context, null, 0);
|
|
}
|
|
|
|
public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
|
|
this(context, attrs, 0);
|
|
}
|
|
|
|
public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
|
|
super(context, attrs, defStyle);
|
|
|
|
Resources res = mContext.getResources();
|
|
mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
|
|
mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
|
|
mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
|
|
mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
|
|
mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
|
|
mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
|
|
mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
|
|
mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
|
|
mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
|
|
mActiveScale = ACTIVE_SCALE;
|
|
mActiveAlpha = ACTIVE_ALPHA;
|
|
mInactiveAlpha = INACTIVE_ALPHA;
|
|
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
|
|
|
mTouched = false;
|
|
|
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
|
}
|
|
|
|
protected String rewriteIconPath(String path) {
|
|
return path;
|
|
}
|
|
|
|
public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
|
|
mUserInfo = user;
|
|
mUserSelector = userSelector;
|
|
|
|
mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
|
|
mUserName = (TextView) findViewById(R.id.keyguard_user_name);
|
|
|
|
mFramed = (KeyguardCircleFramedDrawable)
|
|
MultiUserAvatarCache.getInstance().get(user.id);
|
|
|
|
// If we can't find it or the params don't match, create the drawable again
|
|
if (mFramed == null
|
|
|| !mFramed.verifyParams(mIconSize, mFrameColor, mStroke, mFrameShadowColor,
|
|
mShadowRadius, mHighlightColor)) {
|
|
Bitmap icon = null;
|
|
try {
|
|
icon = mUserManager.getUserIcon(user.id);
|
|
} catch (Exception e) {
|
|
if (DEBUG) Log.d(TAG, "failed to get profile icon " + user, e);
|
|
}
|
|
|
|
if (icon == null) {
|
|
icon = BitmapFactory.decodeResource(mContext.getResources(),
|
|
com.android.internal.R.drawable.ic_contact_picture);
|
|
}
|
|
|
|
mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
|
|
mFrameShadowColor, mShadowRadius, mHighlightColor);
|
|
MultiUserAvatarCache.getInstance().put(user.id, mFramed);
|
|
}
|
|
|
|
mFramed.reset();
|
|
|
|
mUserImage.setImageDrawable(mFramed);
|
|
mUserName.setText(mUserInfo.name);
|
|
setOnClickListener(mUserSelector);
|
|
mInit = false;
|
|
}
|
|
|
|
public void setActive(boolean active, boolean animate, final Runnable onComplete) {
|
|
if (mActive != active || mInit) {
|
|
mActive = active;
|
|
|
|
if (active) {
|
|
KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
|
|
parent.setTopChild(this);
|
|
// TODO: Create an appropriate asset when string changes are possible.
|
|
setContentDescription(mUserName.getText()
|
|
+ ". " + mContext.getString(R.string.user_switched, ""));
|
|
} else {
|
|
setContentDescription(mUserName.getText());
|
|
}
|
|
}
|
|
updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
|
|
}
|
|
|
|
void updateVisualsForActive(boolean active, boolean animate, int duration,
|
|
final Runnable onComplete) {
|
|
final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
|
|
final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
|
|
final float finalScale = active ? 1f : 1f / mActiveScale;
|
|
final float initScale = mFramed.getScale();
|
|
final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
|
|
(int) (mInactiveTextAlpha * 255);
|
|
final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
|
|
(int) (mActiveTextAlpha * 255);
|
|
int textColor = mTextColor;
|
|
mUserName.setTextColor(textColor);
|
|
|
|
if (animate && mTouched) {
|
|
ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
|
|
va.addUpdateListener(new AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
float r = animation.getAnimatedFraction();
|
|
float scale = (1 - r) * initScale + r * finalScale;
|
|
float alpha = (1 - r) * initAlpha + r * finalAlpha;
|
|
int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
|
|
mFramed.setScale(scale);
|
|
mUserImage.setAlpha(alpha);
|
|
mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
|
|
mUserImage.invalidate();
|
|
}
|
|
});
|
|
va.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
if (onComplete != null) {
|
|
onComplete.run();
|
|
}
|
|
}
|
|
});
|
|
va.setDuration(duration);
|
|
va.start();
|
|
} else {
|
|
mFramed.setScale(finalScale);
|
|
mUserImage.setAlpha(finalAlpha);
|
|
mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
|
|
if (onComplete != null) {
|
|
post(onComplete);
|
|
}
|
|
}
|
|
|
|
mTouched = true;
|
|
}
|
|
|
|
@Override
|
|
public void setPressed(boolean pressed) {
|
|
if (mPressLock && !pressed) {
|
|
return;
|
|
}
|
|
|
|
if (mPressLock || !pressed || isClickable()) {
|
|
super.setPressed(pressed);
|
|
mFramed.setPressed(pressed);
|
|
mUserImage.invalidate();
|
|
}
|
|
}
|
|
|
|
public void lockPressed(boolean pressed) {
|
|
mPressLock = pressed;
|
|
setPressed(pressed);
|
|
}
|
|
|
|
public UserInfo getUserInfo() {
|
|
return mUserInfo;
|
|
}
|
|
}
|