summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java7
-rw-r--r--services/core/java/com/android/server/am/CarUserSwitchingDialog.java114
2 files changed, 110 insertions, 11 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 5768fa2384e4..fc76f78e0b1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -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) {
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index 1149e8703a4f..7599afa3e04d 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -20,33 +20,41 @@ 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,
- UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
- String switchingToSystemUserMessage) {
+ UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
+ String switchingToSystemUserMessage) {
super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
- switchingToSystemUserMessage);
+ switchingToSystemUserMessage);
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
@@ -58,18 +66,104 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
Resources res = getContext().getResources();
// Custom view due to alignment and font size requirements
View view = LayoutInflater.from(getContext()).inflate(R.layout.car_user_switching_dialog,
- null);
+ null);
UserManager userManager =
(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));
+ .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.
+ }
+ }
}