User switcher - Fix broken user addition
Adding users from accounts other than the non-system user was not functional. Simply use the context to launch the CreateUserActivity in a new task stack. Also, address test failures where Dependency.get() was being used by other tests with the wrong context, creating failures in the user switcher tests. Remove this call from SystemUIDialog and update it everywhere. Fixes: 218989709 Fixes: 218824658 Test: atest KeyguardUserSwitcherAdapterTest UserDetailViewAdapterTest KeyguardSecurityContainerTest UserSwitcherControllerTest InternetDialogTest SystemUIDialogTest Change-Id: Iaceb3dd2add7d2372f9ec646610c8e147c516e63
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
android:id="@+id/user_switcher_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="64dp"
|
||||
android:layout_marginBottom="40dp"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:layout_marginStart="60dp">
|
||||
|
||||
|
||||
@@ -754,11 +754,10 @@
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.CreateUser" parent="@style/Theme.SystemUI">
|
||||
<style name="Theme.CreateUser" parent="@android:style/Theme.DeviceDefault.NoActionBar">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowBackground">#33000000</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.PeopleTileConfigActivity" parent="@style/Theme.SystemUI">
|
||||
|
||||
@@ -199,7 +199,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
|
||||
holder.init(dialog);
|
||||
SystemUIDialog.setShowForAllUsers(dialog, true);
|
||||
SystemUIDialog.registerDismissListener(dialog);
|
||||
SystemUIDialog.setWindowOnTop(dialog);
|
||||
SystemUIDialog.setWindowOnTop(dialog, mKeyguard.isShowing());
|
||||
|
||||
mUiHandler.post(() -> {
|
||||
if (view != null) {
|
||||
|
||||
@@ -59,6 +59,7 @@ import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
|
||||
import com.android.systemui.statusbar.connectivity.NetworkController;
|
||||
import com.android.systemui.statusbar.connectivity.SignalCallback;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -68,7 +69,7 @@ public class CellularTile extends QSTileImpl<SignalState> {
|
||||
|
||||
private final NetworkController mController;
|
||||
private final DataUsageController mDataController;
|
||||
|
||||
private final KeyguardStateController mKeyguard;
|
||||
private final CellSignalCallback mSignalCallback = new CellSignalCallback();
|
||||
|
||||
@Inject
|
||||
@@ -81,11 +82,14 @@ public class CellularTile extends QSTileImpl<SignalState> {
|
||||
StatusBarStateController statusBarStateController,
|
||||
ActivityStarter activityStarter,
|
||||
QSLogger qsLogger,
|
||||
NetworkController networkController
|
||||
NetworkController networkController,
|
||||
KeyguardStateController keyguardStateController
|
||||
|
||||
) {
|
||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
||||
statusBarStateController, activityStarter, qsLogger);
|
||||
mController = networkController;
|
||||
mKeyguard = keyguardStateController;
|
||||
mDataController = mController.getMobileDataController();
|
||||
mController.observe(getLifecycle(), mSignalCallback);
|
||||
}
|
||||
@@ -145,7 +149,7 @@ public class CellularTile extends QSTileImpl<SignalState> {
|
||||
dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
|
||||
SystemUIDialog.setShowForAllUsers(dialog, true);
|
||||
SystemUIDialog.registerDismissListener(dialog);
|
||||
SystemUIDialog.setWindowOnTop(dialog);
|
||||
SystemUIDialog.setWindowOnTop(dialog, mKeyguard.isShowing());
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import java.util.List;
|
||||
@@ -130,6 +131,7 @@ public class InternetDialog extends SystemUIDialog implements
|
||||
private Button mDoneButton;
|
||||
private Button mAirplaneModeButton;
|
||||
private Drawable mBackgroundOn;
|
||||
private KeyguardStateController mKeyguard;
|
||||
@Nullable
|
||||
private Drawable mBackgroundOff = null;
|
||||
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
@@ -159,7 +161,8 @@ public class InternetDialog extends SystemUIDialog implements
|
||||
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
||||
InternetDialogController internetDialogController, boolean canConfigMobileData,
|
||||
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
|
||||
@Main Handler handler, @Background Executor executor) {
|
||||
@Main Handler handler, @Background Executor executor,
|
||||
KeyguardStateController keyguardStateController) {
|
||||
super(context);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Init InternetDialog");
|
||||
@@ -177,6 +180,7 @@ public class InternetDialog extends SystemUIDialog implements
|
||||
mWifiManager = mInternetDialogController.getWifiManager();
|
||||
mCanConfigMobileData = canConfigMobileData;
|
||||
mCanConfigWifi = canConfigWifi;
|
||||
mKeyguard = keyguardStateController;
|
||||
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mAdapter = new InternetAdapter(mInternetDialogController);
|
||||
@@ -615,7 +619,7 @@ public class InternetDialog extends SystemUIDialog implements
|
||||
mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
||||
SystemUIDialog.setShowForAllUsers(mAlertDialog, true);
|
||||
SystemUIDialog.registerDismissListener(mAlertDialog);
|
||||
SystemUIDialog.setWindowOnTop(mAlertDialog);
|
||||
SystemUIDialog.setWindowOnTop(mAlertDialog, mKeyguard.isShowing());
|
||||
mAlertDialog.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.android.systemui.animation.DialogLaunchAnimator
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -40,7 +41,8 @@ class InternetDialogFactory @Inject constructor(
|
||||
private val internetDialogController: InternetDialogController,
|
||||
private val context: Context,
|
||||
private val uiEventLogger: UiEventLogger,
|
||||
private val dialogLaunchAnimator: DialogLaunchAnimator
|
||||
private val dialogLaunchAnimator: DialogLaunchAnimator,
|
||||
private val keyguardStateController: KeyguardStateController
|
||||
) {
|
||||
companion object {
|
||||
var internetDialog: InternetDialog? = null
|
||||
@@ -61,7 +63,7 @@ class InternetDialogFactory @Inject constructor(
|
||||
} else {
|
||||
internetDialog = InternetDialog(context, this, internetDialogController,
|
||||
canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
|
||||
executor)
|
||||
executor, keyguardStateController)
|
||||
if (view != null) {
|
||||
dialogLaunchAnimator.showFromView(internetDialog!!, view,
|
||||
animateBackgroundBoundsChange = true)
|
||||
|
||||
@@ -43,7 +43,6 @@ import androidx.annotation.Nullable;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
/**
|
||||
* Base class for dialogs that should appear over panels and keyguard.
|
||||
@@ -220,10 +219,13 @@ public class SystemUIDialog extends AlertDialog implements ViewRootImpl.ConfigCh
|
||||
}
|
||||
}
|
||||
|
||||
public static void setWindowOnTop(Dialog dialog) {
|
||||
/**
|
||||
* Ensure the window type is set properly to show over all other screens
|
||||
*/
|
||||
public static void setWindowOnTop(Dialog dialog, boolean isKeyguardShowing) {
|
||||
final Window window = dialog.getWindow();
|
||||
window.setType(LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
|
||||
if (Dependency.get(KeyguardStateController.class).isShowing()) {
|
||||
if (isKeyguardShowing) {
|
||||
window.getAttributes().setFitInsetsTypes(
|
||||
window.getAttributes().getFitInsetsTypes() & ~Type.statusBars());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.IActivityTaskManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -39,7 +38,6 @@ import android.graphics.ColorFilter;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
@@ -78,11 +76,14 @@ import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.qs.QSUserSwitcherEvent;
|
||||
import com.android.systemui.qs.user.UserSwitchDialogController.DialogShower;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.user.CreateUserActivity;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import dagger.Lazy;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -125,10 +126,10 @@ public class UserSwitcherController implements Dumpable {
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private final IActivityTaskManager mActivityTaskManager;
|
||||
private final InteractionJankMonitor mInteractionJankMonitor;
|
||||
private final LatencyTracker mLatencyTracker;
|
||||
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||
private final Lazy<ShadeController> mShadeController;
|
||||
|
||||
private ArrayList<UserRecord> mUsers = new ArrayList<>();
|
||||
@VisibleForTesting
|
||||
@@ -149,6 +150,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
private final UiEventLogger mUiEventLogger;
|
||||
private final IActivityManager mActivityManager;
|
||||
private final Executor mBgExecutor;
|
||||
private final Executor mUiExecutor;
|
||||
private final boolean mGuestUserAutoCreated;
|
||||
private final AtomicBoolean mGuestIsResetting;
|
||||
private final AtomicBoolean mGuestCreationScheduled;
|
||||
@@ -170,19 +172,19 @@ public class UserSwitcherController implements Dumpable {
|
||||
UiEventLogger uiEventLogger,
|
||||
FalsingManager falsingManager,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
IActivityTaskManager activityTaskManager,
|
||||
SecureSettings secureSettings,
|
||||
@Background Executor bgExecutor,
|
||||
@Main Executor uiExecutor,
|
||||
InteractionJankMonitor interactionJankMonitor,
|
||||
LatencyTracker latencyTracker,
|
||||
DumpManager dumpManager,
|
||||
Lazy<ShadeController> shadeController,
|
||||
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||
mContext = context;
|
||||
mActivityManager = activityManager;
|
||||
mUserTracker = userTracker;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mActivityTaskManager = activityTaskManager;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mFalsingManager = falsingManager;
|
||||
mInteractionJankMonitor = interactionJankMonitor;
|
||||
@@ -190,6 +192,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
|
||||
this, mUserTracker, mUiEventLogger, secureSettings);
|
||||
mBgExecutor = bgExecutor;
|
||||
mUiExecutor = uiExecutor;
|
||||
if (!UserManager.isGuestUserEphemeral()) {
|
||||
mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
|
||||
}
|
||||
@@ -204,6 +207,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
mActivityStarter = activityStarter;
|
||||
mUserManager = userManager;
|
||||
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||
mShadeController = shadeController;
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_USER_ADDED);
|
||||
@@ -289,109 +293,100 @@ public class UserSwitcherController implements Dumpable {
|
||||
mForcePictureLoadForUserId.clear();
|
||||
|
||||
final boolean addUsersWhenLocked = mAddUsersFromLockScreen;
|
||||
new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) {
|
||||
final SparseArray<Bitmap> bitmaps = params[0];
|
||||
List<UserInfo> infos = mUserManager.getAliveUsers();
|
||||
if (infos == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<UserRecord> records = new ArrayList<>(infos.size());
|
||||
int currentId = mUserTracker.getUserId();
|
||||
// Check user switchability of the foreground user since SystemUI is running in
|
||||
// User 0
|
||||
boolean canSwitchUsers = mUserManager.getUserSwitchability(
|
||||
UserHandle.of(mUserTracker.getUserId())) == SWITCHABILITY_STATUS_OK;
|
||||
UserRecord guestRecord = null;
|
||||
mBgExecutor.execute(() -> {
|
||||
List<UserInfo> infos = mUserManager.getAliveUsers();
|
||||
if (infos == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<UserRecord> records = new ArrayList<>(infos.size());
|
||||
int currentId = mUserTracker.getUserId();
|
||||
// Check user switchability of the foreground user since SystemUI is running in
|
||||
// User 0
|
||||
boolean canSwitchUsers = mUserManager.getUserSwitchability(
|
||||
UserHandle.of(mUserTracker.getUserId())) == SWITCHABILITY_STATUS_OK;
|
||||
UserRecord guestRecord = null;
|
||||
|
||||
for (UserInfo info : infos) {
|
||||
boolean isCurrent = currentId == info.id;
|
||||
boolean switchToEnabled = canSwitchUsers || isCurrent;
|
||||
if (info.isEnabled()) {
|
||||
if (info.isGuest()) {
|
||||
// Tapping guest icon triggers remove and a user switch therefore
|
||||
// the icon shouldn't be enabled even if the user is current
|
||||
guestRecord = new UserRecord(info, null /* picture */,
|
||||
true /* isGuest */, isCurrent, false /* isAddUser */,
|
||||
false /* isRestricted */, canSwitchUsers,
|
||||
false /* isAddSupervisedUser */);
|
||||
} else if (info.supportsSwitchToByUser()) {
|
||||
Bitmap picture = bitmaps.get(info.id);
|
||||
if (picture == null) {
|
||||
picture = mUserManager.getUserIcon(info.id);
|
||||
|
||||
if (picture != null) {
|
||||
int avatarSize = mContext.getResources()
|
||||
.getDimensionPixelSize(R.dimen.max_avatar_size);
|
||||
picture = Bitmap.createScaledBitmap(
|
||||
picture, avatarSize, avatarSize, true);
|
||||
}
|
||||
}
|
||||
records.add(new UserRecord(info, picture, false /* isGuest */,
|
||||
isCurrent, false /* isAddUser */, false /* isRestricted */,
|
||||
switchToEnabled, false /* isAddSupervisedUser */));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (records.size() > 1 || guestRecord != null) {
|
||||
Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
|
||||
}
|
||||
|
||||
if (guestRecord == null) {
|
||||
if (mGuestUserAutoCreated) {
|
||||
// If mGuestIsResetting=true, the switch should be disabled since
|
||||
// we will just use it as an indicator for "Resetting guest...".
|
||||
// Otherwise, default to canSwitchUsers.
|
||||
boolean isSwitchToGuestEnabled =
|
||||
!mGuestIsResetting.get() && canSwitchUsers;
|
||||
guestRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
true /* isGuest */, false /* isCurrent */,
|
||||
false /* isAddUser */, false /* isRestricted */,
|
||||
isSwitchToGuestEnabled, false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(guestRecord);
|
||||
records.add(guestRecord);
|
||||
} else if (canCreateGuest(guestRecord != null)) {
|
||||
guestRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
true /* isGuest */, false /* isCurrent */,
|
||||
false /* isAddUser */, createIsRestricted(), canSwitchUsers,
|
||||
for (UserInfo info : infos) {
|
||||
boolean isCurrent = currentId == info.id;
|
||||
boolean switchToEnabled = canSwitchUsers || isCurrent;
|
||||
if (info.isEnabled()) {
|
||||
if (info.isGuest()) {
|
||||
// Tapping guest icon triggers remove and a user switch therefore
|
||||
// the icon shouldn't be enabled even if the user is current
|
||||
guestRecord = new UserRecord(info, null /* picture */,
|
||||
true /* isGuest */, isCurrent, false /* isAddUser */,
|
||||
false /* isRestricted */, canSwitchUsers,
|
||||
false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(guestRecord);
|
||||
records.add(guestRecord);
|
||||
} else if (info.supportsSwitchToByUser()) {
|
||||
Bitmap picture = bitmaps.get(info.id);
|
||||
if (picture == null) {
|
||||
picture = mUserManager.getUserIcon(info.id);
|
||||
|
||||
if (picture != null) {
|
||||
int avatarSize = mContext.getResources()
|
||||
.getDimensionPixelSize(R.dimen.max_avatar_size);
|
||||
picture = Bitmap.createScaledBitmap(
|
||||
picture, avatarSize, avatarSize, true);
|
||||
}
|
||||
}
|
||||
records.add(new UserRecord(info, picture, false /* isGuest */,
|
||||
isCurrent, false /* isAddUser */, false /* isRestricted */,
|
||||
switchToEnabled, false /* isAddSupervisedUser */));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if (records.size() > 1 || guestRecord != null) {
|
||||
Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
|
||||
}
|
||||
|
||||
if (guestRecord == null) {
|
||||
if (mGuestUserAutoCreated) {
|
||||
// If mGuestIsResetting=true, the switch should be disabled since
|
||||
// we will just use it as an indicator for "Resetting guest...".
|
||||
// Otherwise, default to canSwitchUsers.
|
||||
boolean isSwitchToGuestEnabled = !mGuestIsResetting.get() && canSwitchUsers;
|
||||
guestRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
true /* isGuest */, false /* isCurrent */,
|
||||
false /* isAddUser */, false /* isRestricted */,
|
||||
isSwitchToGuestEnabled, false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(guestRecord);
|
||||
records.add(guestRecord);
|
||||
} else if (canCreateGuest(guestRecord != null)) {
|
||||
guestRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
true /* isGuest */, false /* isCurrent */,
|
||||
false /* isAddUser */, createIsRestricted(), canSwitchUsers,
|
||||
false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(guestRecord);
|
||||
records.add(guestRecord);
|
||||
}
|
||||
|
||||
if (canCreateUser()) {
|
||||
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
|
||||
createIsRestricted(), canSwitchUsers,
|
||||
false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
|
||||
records.add(addUserRecord);
|
||||
}
|
||||
|
||||
if (canCreateSupervisedUser()) {
|
||||
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
false /* isGuest */, false /* isCurrent */, false /* isAddUser */,
|
||||
createIsRestricted(), canSwitchUsers, true /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
|
||||
records.add(addUserRecord);
|
||||
}
|
||||
|
||||
return records;
|
||||
} else {
|
||||
records.add(guestRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList<UserRecord> userRecords) {
|
||||
if (userRecords != null) {
|
||||
mUsers = userRecords;
|
||||
if (canCreateUser()) {
|
||||
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
|
||||
createIsRestricted(), canSwitchUsers,
|
||||
false /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
|
||||
records.add(addUserRecord);
|
||||
}
|
||||
|
||||
if (canCreateSupervisedUser()) {
|
||||
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
|
||||
false /* isGuest */, false /* isCurrent */, false /* isAddUser */,
|
||||
createIsRestricted(), canSwitchUsers, true /* isAddSupervisedUser */);
|
||||
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
|
||||
records.add(addUserRecord);
|
||||
}
|
||||
|
||||
mUiExecutor.execute(() -> {
|
||||
if (records != null) {
|
||||
mUsers = records;
|
||||
notifyAdapters();
|
||||
}
|
||||
}
|
||||
}.execute((SparseArray) bitmaps);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
boolean systemCanCreateUsers() {
|
||||
@@ -1159,7 +1154,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
context.getString(mGuestUserAutoCreated
|
||||
? com.android.settingslib.R.string.guest_reset_guest_confirm_button
|
||||
: R.string.guest_exit_guest_dialog_remove), this);
|
||||
SystemUIDialog.setWindowOnTop(this);
|
||||
SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing());
|
||||
setCanceledOnTouchOutside(false);
|
||||
mGuestId = guestId;
|
||||
mTargetId = targetId;
|
||||
@@ -1194,7 +1189,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
context.getString(android.R.string.cancel), this);
|
||||
setButton(DialogInterface.BUTTON_POSITIVE,
|
||||
context.getString(android.R.string.ok), this);
|
||||
SystemUIDialog.setWindowOnTop(this);
|
||||
SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1211,33 +1206,8 @@ public class UserSwitcherController implements Dumpable {
|
||||
if (ActivityManager.isUserAMonkey()) {
|
||||
return;
|
||||
}
|
||||
Intent intent = CreateUserActivity.createIntentForStart(getContext());
|
||||
|
||||
// There are some differences between ActivityStarter and ActivityTaskManager in
|
||||
// terms of how they start an activity. ActivityStarter hides the notification bar
|
||||
// before starting the activity to make sure nothing is in front of the new
|
||||
// activity. ActivityStarter also tries to unlock the device if it's locked.
|
||||
// When locked with PIN/pattern/password then it shows the prompt, if there are no
|
||||
// security steps then it dismisses the keyguard and then starts the activity.
|
||||
// ActivityTaskManager doesn't hide the notification bar or unlocks the device, but
|
||||
// it can start an activity on top of the locked screen.
|
||||
if (!mKeyguardStateController.isUnlocked()
|
||||
&& !mKeyguardStateController.canDismissLockScreen()) {
|
||||
// Device is locked and can't be unlocked without a PIN/pattern/password so we
|
||||
// need to use ActivityTaskManager to start the activity on top of the locked
|
||||
// screen.
|
||||
try {
|
||||
mActivityTaskManager.startActivity(null,
|
||||
mContext.getBasePackageName(), mContext.getAttributionTag(), intent,
|
||||
intent.resolveTypeIfNeeded(mContext.getContentResolver()), null,
|
||||
null, 0, 0, null, null);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Couldn't start create user activity", e);
|
||||
}
|
||||
} else {
|
||||
mActivityStarter.startActivity(intent, true);
|
||||
}
|
||||
mShadeController.get().collapsePanel();
|
||||
getContext().startActivity(CreateUserActivity.createIntentForStart(getContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@ public class CreateUserActivity extends Activity {
|
||||
* Creates an intent to start this activity.
|
||||
*/
|
||||
public static Intent createIntentForStart(Context context) {
|
||||
return new Intent(context, CreateUserActivity.class);
|
||||
Intent intent = new Intent(context, CreateUserActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return intent;
|
||||
}
|
||||
|
||||
private static final String TAG = "CreateUserActivity";
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.android.systemui.R
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
|
||||
import com.android.systemui.statusbar.phone.ShadeController
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController.BaseUserAdapter
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController.UserRecord
|
||||
@@ -63,7 +64,8 @@ class UserSwitcherActivity @Inject constructor(
|
||||
private val broadcastDispatcher: BroadcastDispatcher,
|
||||
private val layoutInflater: LayoutInflater,
|
||||
private val falsingManager: FalsingManager,
|
||||
private val userManager: UserManager
|
||||
private val userManager: UserManager,
|
||||
private val shadeController: ShadeController
|
||||
) : LifecycleActivity() {
|
||||
|
||||
private lateinit var parent: ViewGroup
|
||||
@@ -250,7 +252,9 @@ class UserSwitcherActivity @Inject constructor(
|
||||
dismiss()
|
||||
popupMenu = null
|
||||
|
||||
this@UserSwitcherActivity.finish()
|
||||
if (!item.isAddUser) {
|
||||
this@UserSwitcherActivity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
show()
|
||||
|
||||
@@ -29,6 +29,7 @@ import androidx.test.filters.SmallTest;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
@@ -68,6 +69,8 @@ public class InternetDialogTest extends SysuiTestCase {
|
||||
private InternetAdapter mInternetAdapter;
|
||||
@Mock
|
||||
private InternetDialogController mInternetDialogController;
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguard;
|
||||
|
||||
private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
private InternetDialog mInternetDialog;
|
||||
@@ -100,7 +103,7 @@ public class InternetDialogTest extends SysuiTestCase {
|
||||
|
||||
mInternetDialog = new InternetDialog(mContext, mock(InternetDialogFactory.class),
|
||||
mInternetDialogController, true, true, true, mock(UiEventLogger.class), mHandler,
|
||||
mBgExecutor);
|
||||
mBgExecutor, mKeyguard);
|
||||
mInternetDialog.mAdapter = mInternetAdapter;
|
||||
mInternetDialog.mConnectedWifiEntry = mInternetWifiEntry;
|
||||
mInternetDialog.mWifiEntriesCount = mWifiEntries.size();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.statusbar.policy
|
||||
|
||||
import android.app.IActivityManager
|
||||
import android.app.IActivityTaskManager
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
@@ -49,6 +48,7 @@ import com.android.systemui.qs.QSUserSwitcherEvent
|
||||
import com.android.systemui.qs.user.UserSwitchDialogController
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.phone.NotificationShadeWindowView
|
||||
import com.android.systemui.statusbar.phone.ShadeController
|
||||
import com.android.systemui.telephony.TelephonyListenerManager
|
||||
import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
@@ -85,7 +85,6 @@ class UserSwitcherControllerTest : SysuiTestCase() {
|
||||
@Mock private lateinit var userManager: UserManager
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
|
||||
@Mock private lateinit var activityTaskManager: IActivityTaskManager
|
||||
@Mock private lateinit var telephonyListenerManager: TelephonyListenerManager
|
||||
@Mock private lateinit var secureSettings: SecureSettings
|
||||
@Mock private lateinit var falsingManager: FalsingManager
|
||||
@@ -96,8 +95,10 @@ class UserSwitcherControllerTest : SysuiTestCase() {
|
||||
@Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView
|
||||
@Mock private lateinit var threadedRenderer: ThreadedRenderer
|
||||
@Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
|
||||
@Mock private lateinit var shadeController: ShadeController
|
||||
private lateinit var testableLooper: TestableLooper
|
||||
private lateinit var uiBgExecutor: FakeExecutor
|
||||
private lateinit var bgExecutor: FakeExecutor
|
||||
private lateinit var uiExecutor: FakeExecutor
|
||||
private lateinit var uiEventLogger: UiEventLoggerFake
|
||||
private lateinit var userSwitcherController: UserSwitcherController
|
||||
private lateinit var picture: Bitmap
|
||||
@@ -116,10 +117,11 @@ class UserSwitcherControllerTest : SysuiTestCase() {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
testableLooper = TestableLooper.get(this)
|
||||
uiBgExecutor = FakeExecutor(FakeSystemClock())
|
||||
bgExecutor = FakeExecutor(FakeSystemClock())
|
||||
uiExecutor = FakeExecutor(FakeSystemClock())
|
||||
uiEventLogger = UiEventLoggerFake()
|
||||
|
||||
context.orCreateTestableResources.addOverride(
|
||||
mContext.orCreateTestableResources.addOverride(
|
||||
com.android.internal.R.bool.config_guestUserAutoCreated, false)
|
||||
|
||||
mContext.addMockSystemService(Context.FACE_SERVICE, mock(FaceManager::class.java))
|
||||
@@ -141,12 +143,16 @@ class UserSwitcherControllerTest : SysuiTestCase() {
|
||||
|
||||
picture = UserIcons.convertToBitmap(context.getDrawable(R.drawable.ic_avatar_user))
|
||||
|
||||
// Create defaults for the current user
|
||||
`when`(userTracker.userId).thenReturn(ownerId)
|
||||
`when`(userTracker.userInfo).thenReturn(ownerInfo)
|
||||
|
||||
setupController()
|
||||
}
|
||||
|
||||
private fun setupController() {
|
||||
userSwitcherController = UserSwitcherController(
|
||||
context,
|
||||
mContext,
|
||||
activityManager,
|
||||
userManager,
|
||||
userTracker,
|
||||
@@ -159,14 +165,14 @@ class UserSwitcherControllerTest : SysuiTestCase() {
|
||||
uiEventLogger,
|
||||
falsingManager,
|
||||
telephonyListenerManager,
|
||||
activityTaskManager,
|
||||
secureSettings,
|
||||
uiBgExecutor,
|
||||
bgExecutor,
|
||||
uiExecutor,
|
||||
interactionJankMonitor,
|
||||
latencyTracker,
|
||||
dumpManager,
|
||||
{ shadeController },
|
||||
dialogLaunchAnimator)
|
||||
userSwitcherController.mPauseRefreshUsers = true
|
||||
userSwitcherController.init(notificationShadeWindowView)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user