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

Unverified Commit a284bbb2 authored by Michael Bestas's avatar Michael Bestas
Browse files

GlobalActions: Use circular user avatars

* Use circular & smaller avatars, logic copied from SystemUI
* Improve current user indication (thanks to maxwen)

Change-Id: I81e6c4afd604f5cb8b22e2c4db9b174bbe7fb3f0
Ticket-Id: OPO-456, CYNGNOS-1901
parent fb3b6c52
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2016 The CyanogenMod 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.
-->
<resources>
    <!-- Largest size an avatar might need to be drawn in the power menu user picker -->
    <dimen name="global_actions_avatar_size">40dp</dimen>
</resources>
+3 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
    <!-- label for item that opens the profile choosing dialog -->
    <string name="global_action_choose_profile">Profile</string>

    <!-- label for current user in phone options dialog -->
    <string name="global_action_current_user">Current</string>

    <!-- Reboot menu -->
    <!-- Button to reboot the phone, within the Reboot Options dialog -->
    <string name="reboot_reboot">Reboot</string>
+3 −0
Original line number Diff line number Diff line
@@ -72,4 +72,7 @@
    <!-- Automatic brightness enhancements -->
    <java-symbol type="integer" name="config_autoBrightnessBrighteningLightFastDebounce"/>

    <java-symbol type="string" name="global_action_current_user" />
    <java-symbol type="dimen" name="global_actions_avatar_size" />

</resources>
+62 −9
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.internal.policy.EmergencyAffordanceManager;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.R;
import com.android.internal.util.UserIcons;
import com.android.internal.widget.LockPatternUtils;

import android.app.ActivityManager;
@@ -40,6 +41,14 @@ import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.content.ServiceConnection;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.Manifest;
import android.media.AudioManager;
@@ -649,16 +658,24 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        if (um.isUserSwitcherEnabled()) {
            List<UserInfo> users = um.getUsers();
            UserInfo currentUser = getCurrentUser();
            final int avatarSize = mContext.getResources().getDimensionPixelSize(
                    com.android.internal.R.dimen.global_actions_avatar_size);
            for (final UserInfo user : users) {
                if (user.supportsSwitchToByUser()) {
                    boolean isCurrentUser = currentUser == null
                            ? user.id == 0 : (currentUser.id == user.id);
                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
                            : null;
                    Drawable avatar = null;
                    Bitmap rawAvatar = um.getUserIcon(user.id);
                    if (rawAvatar == null) {
                        rawAvatar = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
                                user.isGuest() ? UserHandle.USER_NULL : user.id, /*light=*/ false));
                    }
                    avatar = new BitmapDrawable(mContext.getResources(),
                            createCircularClip(rawAvatar, avatarSize, avatarSize));

                    SinglePressAction switchToUser = new SinglePressAction(
                            com.android.internal.R.drawable.ic_lock_user, icon,
                            (user.name != null ? user.name : "Primary")
                            + (isCurrentUser ? " \u2714" : "")) {
                            com.android.internal.R.drawable.ic_lock_user, avatar,
                            (user.name != null ? user.name : "Primary")) {
                        public void onPress() {
                            try {
                                ActivityManagerNative.getDefault().switchUser(user.id);
@@ -675,6 +692,10 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
                            return false;
                        }
                    };
                    if (isCurrentUser) {
                        switchToUser.setStatus(mContext.getString(
                                R.string.global_action_current_user));
                    }
                    items.add(switchToUser);
                }
            }
@@ -926,6 +947,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        private final Drawable mIcon;
        private final int mMessageResId;
        private final CharSequence mMessage;
        private CharSequence mStatusMessage;

        protected SinglePressAction(int iconResId, int messageResId) {
            mIconResId = iconResId;
@@ -945,8 +967,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            return true;
        }

        public String getStatus() {
            return null;
        public CharSequence getStatus() {
            return mStatusMessage;
        }

        public void setStatus(CharSequence status) {
            mStatusMessage = status;
        }

        abstract public void onPress();
@@ -967,7 +993,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            TextView messageView = (TextView) v.findViewById(R.id.message);

            TextView statusView = (TextView) v.findViewById(R.id.status);
            final String status = getStatus();
            final CharSequence status = getStatus();
            if (!TextUtils.isEmpty(status)) {
                statusView.setText(status);
            } else {
@@ -975,7 +1001,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            }
            if (mIcon != null) {
                icon.setImageDrawable(mIcon);
                icon.setScaleType(ScaleType.CENTER_CROP);
                icon.setScaleType(ScaleType.CENTER);
            } else if (mIconResId != 0) {
                icon.setImageDrawable(context.getDrawable(mIconResId));
            }
@@ -1328,6 +1354,33 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        }
    }

    /**
     * Generate a new bitmap (width x height pixels, ARGB_8888) with the input bitmap scaled
     * to fit and clipped to an inscribed circle.
     * @param input Bitmap to resize and clip
     * @param width Width of output bitmap (and diameter of circle)
     * @param height Height of output bitmap
     * @return A shiny new bitmap for you to use
     */
    private static Bitmap createCircularClip(Bitmap input, int width, int height) {
        if (input == null) return null;

        final int inWidth = input.getWidth();
        final int inHeight = input.getHeight();
        final Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(output);
        final Paint paint = new Paint();
        paint.setShader(new BitmapShader(input, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        final RectF srcRect = new RectF(0, 0, inWidth, inHeight);
        final RectF dstRect = new RectF(0, 0, width, height);
        final Matrix m = new Matrix();
        m.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.CENTER);
        canvas.setMatrix(m);
        canvas.drawCircle(inWidth / 2, inHeight / 2, inWidth / 2, paint);
        return output;
    }

    private static final class GlobalActionsDialog extends Dialog implements DialogInterface {
        private final Context mContext;
        private final int mWindowTouchSlop;