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

Commit 52edc7c2 authored by android-build-team Robot's avatar android-build-team Robot Committed by Android (Google) Code Review
Browse files

Merge "Enforce that the user switcher icons are circular" into pi-dev

parents dbeff868 e3110e4d
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.widget.TextView;

import androidx.car.widget.PagedListView;

import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import com.android.internal.util.UserIcons;
import com.android.settingslib.users.UserManagerHelper;
import com.android.systemui.R;
@@ -193,7 +195,10 @@ public class UserGridRecyclerView extends PagedListView implements
        @Override
        public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
            UserRecord userRecord = mUsers.get(position);
            holder.mUserAvatarImageView.setImageBitmap(getUserRecordIcon(userRecord));
            RoundedBitmapDrawable circleIcon = RoundedBitmapDrawableFactory.create(mRes,
                getUserRecordIcon(userRecord));
            circleIcon.setCircular(true);
            holder.mUserAvatarImageView.setImageDrawable(circleIcon);
            holder.mUserNameTextView.setText(userRecord.mInfo.name);
            holder.mView.setOnClickListener(v -> {
                if (userRecord == null) {
+104 −10
Original line number Diff line number Diff line
@@ -20,26 +20,34 @@ 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.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserManager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.R;
import com.android.server.pm.UserManagerService;
import java.io.FileDescriptor;


/**
 * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
 * screen immediately after the dialog shows so that the user is informed that something is
 * happening in the background rather than just freeze the screen and not know if the user-switch
 * affordance was being handled.
 *
 */
final class CarUserSwitchingDialog extends UserSwitchingDialog {

    private static final String TAG = "ActivityManagerCarUserSwitchingDialog";

    public CarUserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
@@ -64,12 +72,98 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
                (UserManager) getContext().getSystemService(Context.USER_SERVICE);
        Bitmap bitmap = userManager.getUserIcon(mNewUser.id);
        if (bitmap != null) {
            CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(bitmap,
                    res.getDimension(R.dimen.car_fullscreen_user_pod_image_avatar_height));
            ((ImageView) view.findViewById(R.id.user_loading_avatar))
                    .setImageBitmap(bitmap);
                    .setImageDrawable(drawable);
        }

        ((TextView) view.findViewById(R.id.user_loading))
                .setText(res.getString(R.string.car_loading_profile));
        setView(view);
    }

    /**
     * Converts the user icon to a circularly clipped one.  This is used in the User Picker and
     * Settings.
     */
    static class CircleFramedDrawable extends Drawable {

        private final Bitmap mBitmap;
        private final int mSize;
        private final Paint mPaint;

        private float mScale;
        private Rect mSrcRect;
        private RectF mDstRect;

        public static CircleFramedDrawable getInstance(Bitmap icon, float iconSize) {
            CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
            return instance;
        }

        public CircleFramedDrawable(Bitmap icon, int size) {
            super();
            mSize = size;

            mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
            final Canvas canvas = new Canvas(mBitmap);

            final int width = icon.getWidth();
            final int height = icon.getHeight();
            final int square = Math.min(width, height);

            final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2,
                    square, square);
            final RectF circleRect = new RectF(0f, 0f, mSize, mSize);

            final Path fillPath = new Path();
            fillPath.addArc(circleRect, 0f, 360f);

            canvas.drawColor(0, PorterDuff.Mode.CLEAR);

            // opaque circle
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.BLACK);
            mPaint.setStyle(Paint.Style.FILL);
            canvas.drawPath(fillPath, mPaint);

            // mask in the icon where the bitmap is opaque
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(icon, cropRect, circleRect, mPaint);

            // prepare paint for frame drawing
            mPaint.setXfermode(null);

            mScale = 1f;

            mSrcRect = new Rect(0, 0, mSize, mSize);
            mDstRect = new RectF(0, 0, mSize, mSize);
        }

        @Override
        public void draw(Canvas canvas) {
            final float inside = mScale * mSize;
            final float pad = (mSize - inside) / 2f;

            mDstRect.set(pad, pad, mSize - pad, mSize - pad);
            canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }

        @Override
        public void setAlpha(int alpha) {
            // Needed to implement abstract method.  Do nothing.
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {
            // Needed to implement abstract method.  Do nothing.
        }
    }
}