summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2013-05-08 16:43:58 -0700
committerAmith Yamasani <yamasani@google.com>2013-05-09 14:44:38 -0700
commit6fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38 (patch)
treeed2e6217249eb1305202fcbbecbb67c55c5f4e9e /policy
parente2322bdd7865552aa31f93bbf4e60d4d9a7d0973 (diff)
downloadframeworks_base-6fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38.zip
frameworks_base-6fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38.tar.gz
frameworks_base-6fc1d4e8e6549b0d58ea23b4dd3f26329ec19f38.tar.bz2
Cache the scaled avatar drawables in the keyguard user switcher
Loading the avatar icons and drawing them into the sized bitmap turns out to be quite expensive and the cost increases with number of users. Caching them shaves off several hundred milliseconds from Keyguard inflation time during user switching on the lockscreen. For instance, 15ms vs. 750ms with 3 avatars on a certain 7" tablet. Bug: 7986933 Change-Id: I3e2065bfa25aa263133ba204ca364c3b04d7c0ff
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java15
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java34
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java29
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java5
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java15
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java42
6 files changed, 128 insertions, 12 deletions
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 @@ class KeyguardCircleFramedDrawable extends Drawable {
mFramePath = new Path();
}
+ public void reset() {
+ mScale = 1f;
+ mPressed = false;
+ }
+
@Override
public void draw(Canvas canvas) {
// clear background
@@ -157,4 +162,14 @@ class KeyguardCircleFramedDrawable extends Drawable {
@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 @@ class KeyguardMultiUserAvatar extends FrameLayout {
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);
+ 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);
}
- mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
- mFrameShadowColor, mShadowRadius, mHighlightColor);
+ mFramed.reset();
+
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 @@ public class KeyguardUpdateMonitor {
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 @@ public class KeyguardUpdateMonitor {
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 @@ public class KeyguardUpdateMonitor {
}
};
+ 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 @@ public class KeyguardUpdateMonitor {
return sInstance;
}
-
protected void handleSetGenerationId(int clientGeneration, boolean clearing, PendingIntent p) {
mDisplayClientState.clientGeneration = clientGeneration;
mDisplayClientState.clearing = clearing;
@@ -422,6 +436,15 @@ public class KeyguardUpdateMonitor {
}
}
+ 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 @@ public class KeyguardUpdateMonitor {
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 @@ class KeyguardUpdateMonitorCallback {
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 @@ public class KeyguardViewMediator {
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 @@ public class KeyguardViewMediator {
@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 @@ public class KeyguardViewMediator {
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);
+ }
+}