1 /* 2 * Copyright (C) 2020 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 17 package com.google.android.car.kitchensink.users; 18 19 import android.annotation.NonNull; 20 import android.annotation.UserIdInt; 21 import android.app.ActivityManager; 22 import android.app.admin.DevicePolicyManager; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.pm.UserInfo; 26 import android.graphics.Bitmap; 27 import android.os.UserHandle; 28 import android.os.UserManager; 29 import android.util.AttributeSet; 30 import android.util.Log; 31 import android.widget.EditText; 32 import android.widget.LinearLayout; 33 import android.widget.TextView; 34 35 import com.android.car.admin.ui.UserAvatarView; 36 import com.android.internal.util.UserIcons; 37 38 import com.google.android.car.kitchensink.R; 39 40 /** 41 * Custom {@link android.view.View} that shows an Android user info. 42 */ 43 public final class UserInfoView extends LinearLayout { 44 45 private static final String TAG = UserInfoView.class.getSimpleName(); 46 47 private UserAvatarView mUserAvatarView; 48 private EditText mUserIdEditText; 49 private EditText mUserNameEditText; 50 private EditText mUserTypeEditText; 51 private EditText mUserFlagsEditText; 52 private EditText mUserStatusEditText; 53 private TextView mManagedTextView; 54 UserInfoView(Context context, AttributeSet attrs)55 public UserInfoView(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 58 inflate(context, R.layout.user_info_view, this); 59 mUserAvatarView = findViewById(R.id.user_avatar); 60 mUserIdEditText = findViewById(R.id.user_id); 61 mUserNameEditText = findViewById(R.id.user_name); 62 mUserTypeEditText = findViewById(R.id.user_type); 63 mUserFlagsEditText = findViewById(R.id.user_flags); 64 mUserStatusEditText = findViewById(R.id.user_status); 65 mManagedTextView = findViewById(R.id.managed); 66 } 67 68 /** 69 * Initializes the widget with the given user. 70 */ update(@onNull UserInfo user)71 public void update(@NonNull UserInfo user) { 72 Log.v(TAG, "initializing with " + user.toFullString()); 73 74 setUserIcon(user.id); 75 mUserIdEditText.setText(String.valueOf(user.id)); 76 mUserNameEditText.setText(user.name); 77 mUserTypeEditText.setText(user.userType); 78 mUserFlagsEditText.setText(UserInfo.flagsToString(user.flags)); 79 mUserStatusEditText.setText(getStatus(user)); 80 setManagedStatus(user.id); 81 } 82 getStatus(@onNull UserInfo user)83 private String getStatus(@NonNull UserInfo user) { 84 ActivityManager am = (ActivityManager) getContext() 85 .getSystemService(Context.ACTIVITY_SERVICE); 86 int currentUserId = ActivityManager.getCurrentUser(); 87 boolean current = user.id == currentUserId; 88 boolean running = am.isUserRunning(user.id); 89 boolean visible = isUserVisible(user.id); 90 String s = new StringBuilder() 91 .append(user.partial ? " (partial)" : "") 92 .append(running ? " (running)" : "") 93 .append(current ? " (current)" : "") 94 .append(visible ? " (visible)" : "") 95 .toString(); 96 return s; 97 } 98 isUserVisible(@serIdInt int userId)99 private boolean isUserVisible(@UserIdInt int userId) { 100 UserHandle user = UserHandle.of(userId); 101 Context context = mContext.createContextAsUser(user, /* flags= */ 0); 102 boolean visible = context.getSystemService(UserManager.class).isUserVisible(); 103 Log.v(TAG, "isUserVisible(" + userId + "): " + visible); 104 return visible; 105 } 106 setUserIcon(@serIdInt int userId)107 private void setUserIcon(@UserIdInt int userId) { 108 UserManager um = UserManager.get(getContext()); 109 Bitmap icon = um.getUserIcon(userId); 110 if (icon == null) { 111 Log.v(TAG, "No icon for user " + userId); // Happens on system user 112 icon = UserIcons.convertToBitmap( 113 UserIcons.getDefaultUserIcon(getResources(), userId, /* light= */ false)); 114 } 115 mUserAvatarView.setAvatarWithBadge(icon, userId); 116 } 117 setManagedStatus(@serIdInt int userId)118 private void setManagedStatus(@UserIdInt int userId) { 119 // Check managed status 120 DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class); 121 if (dpm == null) return; 122 123 UserHandle deviceOwner = dpm.getDeviceOwnerUser(); 124 Log.v(TAG, "Device owner is " + deviceOwner); 125 126 if (deviceOwner != null && deviceOwner.getIdentifier() == userId) { 127 setManagedText("DeviceOwner"); 128 return; 129 } 130 131 ComponentName profileOwner = dpm.getProfileOwnerAsUser(userId); 132 if (profileOwner != null) { 133 Log.v(TAG, "User " + userId + " has profile owner: " + profileOwner); 134 setManagedText("ProfileOwner"); 135 return; 136 } 137 mManagedTextView.setVisibility(GONE); 138 } 139 setManagedText(@onNull CharSequence text)140 private void setManagedText(@NonNull CharSequence text) { 141 mManagedTextView.setText(text); 142 mManagedTextView.setVisibility(VISIBLE); 143 } 144 } 145