diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java index 938fa880bbefd..9cfe7a7e48cea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java @@ -20,14 +20,12 @@ import static android.os.UserManager.SWITCHABILITY_STATUS_OK; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.annotation.UserIdInt; -import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Dialog; import android.app.IActivityManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; @@ -73,10 +71,10 @@ 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.SystemUIDialog; import com.android.systemui.telephony.TelephonyListenerManager; -import com.android.systemui.user.CreateUserActivity; import com.android.systemui.user.data.source.UserRecord; +import com.android.systemui.user.ui.dialog.AddUserDialog; +import com.android.systemui.user.ui.dialog.ExitGuestDialog; import com.android.systemui.util.settings.GlobalSettings; import com.android.systemui.util.settings.SecureSettings; @@ -608,12 +606,23 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController { showExitGuestDialog(id, isGuestEphemeral, newId, dialogShower); } - private void showExitGuestDialog(int id, boolean isGuestEphemeral, - int targetId, DialogShower dialogShower) { + private void showExitGuestDialog( + int id, + boolean isGuestEphemeral, + int targetId, + DialogShower dialogShower) { if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { mExitGuestDialog.cancel(); } - mExitGuestDialog = new ExitGuestDialog(mContext, id, isGuestEphemeral, targetId); + mExitGuestDialog = new ExitGuestDialog( + mContext, + id, + isGuestEphemeral, + targetId, + mKeyguardStateController.isShowing(), + mFalsingManager, + mDialogLaunchAnimator, + this::exitGuestUser); if (dialogShower != null) { dialogShower.showDialog(mExitGuestDialog, new DialogCuj( InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, @@ -639,7 +648,15 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController { if (mAddUserDialog != null && mAddUserDialog.isShowing()) { mAddUserDialog.cancel(); } - mAddUserDialog = new AddUserDialog(mContext); + final UserInfo currentUser = mUserTracker.getUserInfo(); + mAddUserDialog = new AddUserDialog( + mContext, + currentUser.getUserHandle(), + mKeyguardStateController.isShowing(), + /* showEphemeralMessage= */currentUser.isGuest() && currentUser.isEphemeral(), + mFalsingManager, + mBroadcastSender, + mDialogLaunchAnimator); if (dialogShower != null) { dialogShower.showDialog(mAddUserDialog, new DialogCuj( @@ -1061,133 +1078,4 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController { } } }; - - - private final class ExitGuestDialog extends SystemUIDialog implements - DialogInterface.OnClickListener { - - private final int mGuestId; - private final int mTargetId; - private final boolean mIsGuestEphemeral; - - ExitGuestDialog(Context context, int guestId, boolean isGuestEphemeral, - int targetId) { - super(context); - if (isGuestEphemeral) { - setTitle(context.getString( - com.android.settingslib.R.string.guest_exit_dialog_title)); - setMessage(context.getString( - com.android.settingslib.R.string.guest_exit_dialog_message)); - setButton(DialogInterface.BUTTON_NEUTRAL, - context.getString(android.R.string.cancel), this); - setButton(DialogInterface.BUTTON_POSITIVE, - context.getString( - com.android.settingslib.R.string.guest_exit_dialog_button), this); - } else { - setTitle(context.getString( - com.android.settingslib - .R.string.guest_exit_dialog_title_non_ephemeral)); - setMessage(context.getString( - com.android.settingslib - .R.string.guest_exit_dialog_message_non_ephemeral)); - setButton(DialogInterface.BUTTON_NEUTRAL, - context.getString(android.R.string.cancel), this); - setButton(DialogInterface.BUTTON_NEGATIVE, - context.getString( - com.android.settingslib.R.string.guest_exit_clear_data_button), - this); - setButton(DialogInterface.BUTTON_POSITIVE, - context.getString( - com.android.settingslib.R.string.guest_exit_save_data_button), - this); - } - SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing()); - setCanceledOnTouchOutside(false); - mGuestId = guestId; - mTargetId = targetId; - mIsGuestEphemeral = isGuestEphemeral; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - int penalty = which == BUTTON_NEGATIVE ? FalsingManager.NO_PENALTY - : FalsingManager.HIGH_PENALTY; - if (mFalsingManager.isFalseTap(penalty)) { - return; - } - if (mIsGuestEphemeral) { - if (which == DialogInterface.BUTTON_POSITIVE) { - mDialogLaunchAnimator.dismissStack(this); - // Ephemeral guest: exit guest, guest is removed by the system - // on exit, since its marked ephemeral - exitGuestUser(mGuestId, mTargetId, false); - } else if (which == DialogInterface.BUTTON_NEGATIVE) { - // Cancel clicked, do nothing - cancel(); - } - } else { - if (which == DialogInterface.BUTTON_POSITIVE) { - mDialogLaunchAnimator.dismissStack(this); - // Non-ephemeral guest: exit guest, guest is not removed by the system - // on exit, since its marked non-ephemeral - exitGuestUser(mGuestId, mTargetId, false); - } else if (which == DialogInterface.BUTTON_NEGATIVE) { - mDialogLaunchAnimator.dismissStack(this); - // Non-ephemeral guest: remove guest and then exit - exitGuestUser(mGuestId, mTargetId, true); - } else if (which == DialogInterface.BUTTON_NEUTRAL) { - // Cancel clicked, do nothing - cancel(); - } - } - } - } - - @VisibleForTesting - final class AddUserDialog extends SystemUIDialog implements - DialogInterface.OnClickListener { - - AddUserDialog(Context context) { - super(context); - - setTitle(com.android.settingslib.R.string.user_add_user_title); - String message = context.getString( - com.android.settingslib.R.string.user_add_user_message_short); - UserInfo currentUser = mUserTracker.getUserInfo(); - if (currentUser != null && currentUser.isGuest() && currentUser.isEphemeral()) { - message += context.getString(R.string.user_add_user_message_guest_remove); - } - setMessage(message); - setButton(DialogInterface.BUTTON_NEUTRAL, - context.getString(android.R.string.cancel), this); - setButton(DialogInterface.BUTTON_POSITIVE, - context.getString(android.R.string.ok), this); - SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing()); - } - - @Override - public void onClick(DialogInterface dialog, int which) { - int penalty = which == BUTTON_NEGATIVE ? FalsingManager.NO_PENALTY - : FalsingManager.MODERATE_PENALTY; - if (mFalsingManager.isFalseTap(penalty)) { - return; - } - if (which == BUTTON_NEUTRAL) { - cancel(); - } else { - mDialogLaunchAnimator.dismissStack(this); - if (ActivityManager.isUserAMonkey()) { - return; - } - // Use broadcast instead of ShadeController, as this dialog may have started in - // another process and normal dagger bindings are not available - mBroadcastSender.sendBroadcastAsUser( - new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT); - getContext().startActivityAsUser( - CreateUserActivity.createIntentForStart(getContext()), - mUserTracker.getUserHandle()); - } - } - } - } diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt new file mode 100644 index 0000000000000..a9d66de118e0d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.android.systemui.user.ui.dialog + +import android.app.ActivityManager +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.os.UserHandle +import com.android.settingslib.R +import com.android.systemui.animation.DialogLaunchAnimator +import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.user.CreateUserActivity + +/** Dialog for adding a new user to the device. */ +class AddUserDialog( + context: Context, + userHandle: UserHandle, + isKeyguardShowing: Boolean, + showEphemeralMessage: Boolean, + private val falsingManager: FalsingManager, + private val broadcastSender: BroadcastSender, + private val dialogLaunchAnimator: DialogLaunchAnimator +) : SystemUIDialog(context) { + + private val onClickListener = + object : DialogInterface.OnClickListener { + override fun onClick(dialog: DialogInterface, which: Int) { + val penalty = + if (which == BUTTON_NEGATIVE) { + FalsingManager.NO_PENALTY + } else { + FalsingManager.MODERATE_PENALTY + } + if (falsingManager.isFalseTap(penalty)) { + return + } + + if (which == BUTTON_NEUTRAL) { + cancel() + return + } + + dialogLaunchAnimator.dismissStack(this@AddUserDialog) + if (ActivityManager.isUserAMonkey()) { + return + } + + // Use broadcast instead of ShadeController, as this dialog may have started in + // another + // process where normal dagger bindings are not available. + broadcastSender.sendBroadcastAsUser( + Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), + UserHandle.CURRENT + ) + + context.startActivityAsUser( + CreateUserActivity.createIntentForStart(context), + userHandle, + ) + } + } + + init { + setTitle(R.string.user_add_user_title) + val message = + context.getString(R.string.user_add_user_message_short) + + if (showEphemeralMessage) { + context.getString( + com.android.systemui.R.string.user_add_user_message_guest_remove + ) + } else { + "" + } + setMessage(message) + + setButton( + BUTTON_NEUTRAL, + context.getString(android.R.string.cancel), + onClickListener, + ) + + setButton( + BUTTON_POSITIVE, + context.getString(android.R.string.ok), + onClickListener, + ) + + setWindowOnTop(this, isKeyguardShowing) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/ExitGuestDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/ExitGuestDialog.kt new file mode 100644 index 0000000000000..19ad44d8649f4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/ExitGuestDialog.kt @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.android.systemui.user.ui.dialog + +import android.annotation.UserIdInt +import android.content.Context +import android.content.DialogInterface +import com.android.settingslib.R +import com.android.systemui.animation.DialogLaunchAnimator +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.phone.SystemUIDialog + +/** Dialog for exiting the guest user. */ +class ExitGuestDialog( + context: Context, + private val guestUserId: Int, + private val isGuestEphemeral: Boolean, + private val targetUserId: Int, + isKeyguardShowing: Boolean, + private val falsingManager: FalsingManager, + private val dialogLaunchAnimator: DialogLaunchAnimator, + private val onExitGuestUserListener: OnExitGuestUserListener, +) : SystemUIDialog(context) { + + fun interface OnExitGuestUserListener { + fun onExitGuestUser( + @UserIdInt guestId: Int, + @UserIdInt targetId: Int, + forceRemoveGuest: Boolean, + ) + } + + private val onClickListener = + object : DialogInterface.OnClickListener { + override fun onClick(dialog: DialogInterface, which: Int) { + val penalty = + if (which == BUTTON_NEGATIVE) { + FalsingManager.NO_PENALTY + } else { + FalsingManager.MODERATE_PENALTY + } + if (falsingManager.isFalseTap(penalty)) { + return + } + + if (isGuestEphemeral) { + if (which == BUTTON_POSITIVE) { + dialogLaunchAnimator.dismissStack(this@ExitGuestDialog) + // Ephemeral guest: exit guest, guest is removed by the system + // on exit, since its marked ephemeral + onExitGuestUserListener.onExitGuestUser(guestUserId, targetUserId, false) + } else if (which == BUTTON_NEGATIVE) { + // Cancel clicked, do nothing + cancel() + } + } else { + when (which) { + BUTTON_POSITIVE -> { + dialogLaunchAnimator.dismissStack(this@ExitGuestDialog) + // Non-ephemeral guest: exit guest, guest is not removed by the system + // on exit, since its marked non-ephemeral + onExitGuestUserListener.onExitGuestUser( + guestUserId, + targetUserId, + false + ) + } + BUTTON_NEGATIVE -> { + dialogLaunchAnimator.dismissStack(this@ExitGuestDialog) + // Non-ephemeral guest: remove guest and then exit + onExitGuestUserListener.onExitGuestUser(guestUserId, targetUserId, true) + } + BUTTON_NEUTRAL -> { + // Cancel clicked, do nothing + cancel() + } + } + } + } + } + + init { + if (isGuestEphemeral) { + setTitle(context.getString(R.string.guest_exit_dialog_title)) + setMessage(context.getString(R.string.guest_exit_dialog_message)) + setButton( + BUTTON_NEUTRAL, + context.getString(android.R.string.cancel), + onClickListener, + ) + setButton( + BUTTON_POSITIVE, + context.getString(R.string.guest_exit_dialog_button), + onClickListener, + ) + } else { + setTitle(context.getString(R.string.guest_exit_dialog_title_non_ephemeral)) + setMessage(context.getString(R.string.guest_exit_dialog_message_non_ephemeral)) + setButton( + BUTTON_NEUTRAL, + context.getString(android.R.string.cancel), + onClickListener, + ) + setButton( + BUTTON_NEGATIVE, + context.getString(R.string.guest_exit_clear_data_button), + onClickListener, + ) + setButton( + BUTTON_POSITIVE, + context.getString(R.string.guest_exit_save_data_button), + onClickListener, + ) + } + setWindowOnTop(this, isKeyguardShowing) + setCanceledOnTouchOutside(false) + } +}