blob: c7de7b17b1c2cfaeaa8be0d64c12fb1e1c2e2b64 [file] [log] [blame]
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import android.content.Context;
20import android.content.pm.UserInfo;
21import android.content.res.Resources;
22import android.graphics.Bitmap;
Aarthi Balachandere3110e42018-04-30 18:16:26 -070023import android.graphics.Canvas;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070024import android.graphics.Color;
Aarthi Balachandere3110e42018-04-30 18:16:26 -070025import android.graphics.ColorFilter;
26import android.graphics.Paint;
27import android.graphics.Path;
28import android.graphics.PixelFormat;
29import android.graphics.PorterDuff;
30import android.graphics.PorterDuffXfermode;
31import android.graphics.Rect;
32import android.graphics.RectF;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070033import android.graphics.drawable.ColorDrawable;
Aarthi Balachandere3110e42018-04-30 18:16:26 -070034import android.graphics.drawable.Drawable;
jovanak6639c4d2018-04-25 14:45:18 -070035import android.os.UserManager;
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070036import android.view.LayoutInflater;
37import android.view.View;
38import android.widget.ImageView;
39import android.widget.TextView;
40import com.android.internal.R;
Aarthi Balachandere3110e42018-04-30 18:16:26 -070041
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070042
43/**
44 * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
45 * screen immediately after the dialog shows so that the user is informed that something is
46 * happening in the background rather than just freeze the screen and not know if the user-switch
47 * affordance was being handled.
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070048 */
49final class CarUserSwitchingDialog extends UserSwitchingDialog {
Aarthi Balachandere3110e42018-04-30 18:16:26 -070050
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070051 private static final String TAG = "ActivityManagerCarUserSwitchingDialog";
52
53 public CarUserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
Aarthi Balachandere3110e42018-04-30 18:16:26 -070054 UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
55 String switchingToSystemUserMessage) {
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070056 super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
Aarthi Balachandere3110e42018-04-30 18:16:26 -070057 switchingToSystemUserMessage);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070058
59 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
60 }
61
62 @Override
63 void inflateContent() {
64 // Set up the dialog contents
65 setCancelable(false);
66 Resources res = getContext().getResources();
67 // Custom view due to alignment and font size requirements
Aarthi Balachander62df70b2018-08-29 15:18:17 -070068 getContext().setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert_UserSwitchingDialog);
69 View view = LayoutInflater.from(getContext()).inflate(
70 R.layout.car_user_switching_dialog,
Aarthi Balachandere3110e42018-04-30 18:16:26 -070071 null);
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070072
jovanak6639c4d2018-04-25 14:45:18 -070073 UserManager userManager =
74 (UserManager) getContext().getSystemService(Context.USER_SERVICE);
75 Bitmap bitmap = userManager.getUserIcon(mNewUser.id);
76 if (bitmap != null) {
Aarthi Balachandere3110e42018-04-30 18:16:26 -070077 CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(bitmap,
78 res.getDimension(R.dimen.car_fullscreen_user_pod_image_avatar_height));
jovanak6639c4d2018-04-25 14:45:18 -070079 ((ImageView) view.findViewById(R.id.user_loading_avatar))
Aarthi Balachandere3110e42018-04-30 18:16:26 -070080 .setImageDrawable(drawable);
jovanak6639c4d2018-04-25 14:45:18 -070081 }
82
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070083 ((TextView) view.findViewById(R.id.user_loading))
Aarthi Balachandere3110e42018-04-30 18:16:26 -070084 .setText(res.getString(R.string.car_loading_profile));
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -070085 setView(view);
86 }
Aarthi Balachandere3110e42018-04-30 18:16:26 -070087
88 /**
89 * Converts the user icon to a circularly clipped one. This is used in the User Picker and
90 * Settings.
91 */
92 static class CircleFramedDrawable extends Drawable {
93
94 private final Bitmap mBitmap;
95 private final int mSize;
96 private final Paint mPaint;
97
98 private float mScale;
99 private Rect mSrcRect;
100 private RectF mDstRect;
101
102 public static CircleFramedDrawable getInstance(Bitmap icon, float iconSize) {
103 CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
104 return instance;
105 }
106
107 public CircleFramedDrawable(Bitmap icon, int size) {
108 super();
109 mSize = size;
110
111 mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
112 final Canvas canvas = new Canvas(mBitmap);
113
114 final int width = icon.getWidth();
115 final int height = icon.getHeight();
116 final int square = Math.min(width, height);
117
118 final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2,
119 square, square);
120 final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
121
122 final Path fillPath = new Path();
123 fillPath.addArc(circleRect, 0f, 360f);
124
125 canvas.drawColor(0, PorterDuff.Mode.CLEAR);
126
127 // opaque circle
128 mPaint = new Paint();
129 mPaint.setAntiAlias(true);
130 mPaint.setColor(Color.BLACK);
131 mPaint.setStyle(Paint.Style.FILL);
132 canvas.drawPath(fillPath, mPaint);
133
134 // mask in the icon where the bitmap is opaque
135 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
136 canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
137
138 // prepare paint for frame drawing
139 mPaint.setXfermode(null);
140
141 mScale = 1f;
142
143 mSrcRect = new Rect(0, 0, mSize, mSize);
144 mDstRect = new RectF(0, 0, mSize, mSize);
145 }
146
147 @Override
148 public void draw(Canvas canvas) {
149 final float inside = mScale * mSize;
150 final float pad = (mSize - inside) / 2f;
151
152 mDstRect.set(pad, pad, mSize - pad, mSize - pad);
153 canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
154 }
155
156 @Override
157 public int getOpacity() {
158 return PixelFormat.TRANSLUCENT;
159 }
160
161 @Override
162 public void setAlpha(int alpha) {
163 // Needed to implement abstract method. Do nothing.
164 }
165
166 @Override
167 public void setColorFilter(ColorFilter colorFilter) {
168 // Needed to implement abstract method. Do nothing.
169 }
170 }
Aarthi Balachandercf6ca0c2018-04-10 19:26:45 -0700171}