Merge "Cache the scaled avatar drawables in the keyguard user switcher" into jb-mr2-dev
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index bfc7bf5..65f904f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2567,8 +2567,7 @@
/**
* Broadcast sent to the system when a user's information changes. Carries an extra
* {@link #EXTRA_USER_HANDLE} to indicate which user's information changed.
- * This is only sent to registered receivers, not manifest receivers. It is sent to the user
- * whose information has changed.
+ * This is only sent to registered receivers, not manifest receivers. It is sent to all users.
* @hide
*/
public static final String ACTION_USER_INFO_CHANGED =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index d826282..df1eb67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -819,8 +819,10 @@
if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) ||
Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
try {
- final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
- if (getSendingUserId() == userId) {
+ final int currentUser = ActivityManagerNative.getDefault().getCurrentUser().id;
+ final int changedUser =
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId());
+ if (changedUser == currentUser) {
reloadUserInfo();
}
} catch (RemoteException e) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java
index 79b66f4..fe32099 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java
@@ -100,6 +100,11 @@
mFramePath = new Path();
}
+ public void reset() {
+ mScale = 1f;
+ mPressed = false;
+ }
+
@Override
public void draw(Canvas canvas) {
// clear background
@@ -157,4 +162,14 @@
@Override
public void setColorFilter(ColorFilter cf) {
}
+
+ public boolean verifyParams(float iconSize, int frameColor, float stroke,
+ int frameShadowColor, float shadowRadius, int highlightColor) {
+ return mSize == iconSize
+ && mFrameColor == frameColor
+ && mStrokeWidth == stroke
+ && mFrameShadowColor == frameShadowColor
+ && mShadowRadius == shadowRadius
+ && mHighlightColor == highlightColor;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
index 9d1f041..387e0ce 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
@@ -124,20 +124,32 @@
mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
mUserName = (TextView) findViewById(R.id.keyguard_user_name);
- Bitmap icon = null;
- try {
- icon = BitmapFactory.decodeFile(rewriteIconPath(user.iconPath));
- } catch (Exception e) {
- if (DEBUG) Log.d(TAG, "failed to open profile icon " + user.iconPath, e);
+ mFramed = (KeyguardCircleFramedDrawable)
+ KeyguardViewMediator.getAvatarCache().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 = BitmapFactory.decodeFile(rewriteIconPath(user.iconPath));
+ } catch (Exception e) {
+ if (DEBUG) Log.d(TAG, "failed to open profile icon " + user.iconPath, 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);
+ KeyguardViewMediator.getAvatarCache().put(user.id, mFramed);
}
- if (icon == null) {
- icon = BitmapFactory.decodeResource(mContext.getResources(),
- com.android.internal.R.drawable.ic_contact_picture);
- }
+ mFramed.reset();
- mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
- mFrameShadowColor, mShadowRadius, mHighlightColor);
mUserImage.setImageDrawable(mFramed);
mUserName.setText(mUserInfo.name);
setOnClickListener(mUserSelector);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 986dc49..5a64586 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -91,6 +91,7 @@
private static final int MSG_USER_SWITCH_COMPLETE = 314;
private static final int MSG_SET_CURRENT_CLIENT_ID = 315;
protected static final int MSG_SET_PLAYBACK_STATE = 316;
+ protected static final int MSG_USER_INFO_CHANGED = 317;
private static KeyguardUpdateMonitor sInstance;
@@ -178,6 +179,9 @@
case MSG_SET_PLAYBACK_STATE:
handleSetPlaybackState(msg.arg1, msg.arg2, (Long) msg.obj);
break;
+ case MSG_USER_INFO_CHANGED:
+ handleUserInfoChanged(msg.arg1);
+ break;
}
}
};
@@ -280,6 +284,17 @@
}
};
+ private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
+
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
+ }
+ }
+ };
+
/**
* When we receive a
* {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
@@ -389,7 +404,6 @@
return sInstance;
}
-
protected void handleSetGenerationId(int clientGeneration, boolean clearing, PendingIntent p) {
mDisplayClientState.clientGeneration = clientGeneration;
mDisplayClientState.clearing = clearing;
@@ -422,6 +436,15 @@
}
}
+ private void handleUserInfoChanged(int userId) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onUserInfoChanged(userId);
+ }
+ }
+ }
+
private KeyguardUpdateMonitor(Context context) {
mContext = context;
@@ -456,6 +479,10 @@
bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
+ final IntentFilter userInfoFilter = new IntentFilter(Intent.ACTION_USER_INFO_CHANGED);
+ context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, userInfoFilter,
+ null, null);
+
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(
new IUserSwitchObserver.Stub() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
index 368ccb3..41816db 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
@@ -107,6 +107,11 @@
void onUserRemoved(int userId) { }
/**
+ * Called when the user's info changed.
+ */
+ void onUserInfoChanged(int userId) { }
+
+ /**
* Called when boot completed.
*
* Note, this callback will only be received if boot complete occurs after registering with
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 08a95a6..885cb45 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -254,6 +254,11 @@
private final float mLockSoundVolume;
/**
+ * Cache of avatar drawables, for use by KeyguardMultiUserAvatar.
+ */
+ private static MultiUserAvatarCache sMultiUserAvatarCache = new MultiUserAvatarCache();
+
+ /**
* The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
* various things.
*/
@@ -333,6 +338,12 @@
@Override
public void onUserRemoved(int userId) {
mLockPatternUtils.removeUser(userId);
+ sMultiUserAvatarCache.clear(userId);
+ }
+
+ @Override
+ public void onUserInfoChanged(int userId) {
+ sMultiUserAvatarCache.clear(userId);
}
@Override
@@ -1431,4 +1442,8 @@
return mSearchManager != null
&& mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
}
+
+ public static MultiUserAvatarCache getAvatarCache() {
+ return sMultiUserAvatarCache;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java
new file mode 100644
index 0000000..7969c7d
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 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.internal.policy.impl.keyguard;
+
+import android.graphics.drawable.Drawable;
+
+import java.util.HashMap;
+
+public class MultiUserAvatarCache {
+
+ private final HashMap<Integer, Drawable> mCache;
+
+ public MultiUserAvatarCache() {
+ mCache = new HashMap<Integer, Drawable>();
+ }
+
+ public void clear(int userId) {
+ mCache.remove(userId);
+ }
+
+ public Drawable get(int userId) {
+ return mCache.get(userId);
+ }
+
+ public void put(int userId, Drawable image) {
+ mCache.put(userId, image);
+ }
+}
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index 11c6dab..1323c93 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -296,7 +296,7 @@
Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- mContext.sendBroadcastAsUser(changedIntent, new UserHandle(userId));
+ mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL);
}
@Override