Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fc1d4e8 authored by Amith Yamasani's avatar Amith Yamasani
Browse files

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
parent e2322bdd
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2567,8 +2567,7 @@ public class Intent implements Parcelable, Cloneable {
    /**
     * 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 =
+4 −2
Original line number Diff line number Diff line
@@ -819,8 +819,10 @@ class QuickSettings {
            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) {
+15 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+23 −11
Original line number Diff line number Diff line
@@ -124,6 +124,13 @@ class KeyguardMultiUserAvatar extends FrameLayout {
        mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
        mUserName = (TextView) findViewById(R.id.keyguard_user_name);

        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));
@@ -138,6 +145,11 @@ class KeyguardMultiUserAvatar extends FrameLayout {

            mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
                    mFrameShadowColor, mShadowRadius, mHighlightColor);
            KeyguardViewMediator.getAvatarCache().put(user.id, mFramed);
        }

        mFramed.reset();

        mUserImage.setImageDrawable(mFramed);
        mUserName.setText(mUserInfo.name);
        setOnClickListener(mUserSelector);
+28 −1
Original line number Diff line number Diff line
@@ -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() {
Loading