Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59ad257e authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

Extracts dialogs out of old UserSwitcherController.

In later CLs, we need to access the same dialog classes from our
interactor.

Bug: 246631653
Test: verified manually with followup CLs
Change-Id: I6962b902f5b75302ff9779f9d95bbd76038cc79c
parent 0271aa49
Loading
Loading
Loading
Loading
+25 −137
Original line number Original line Diff line number Diff line
@@ -20,14 +20,12 @@ import static android.os.UserManager.SWITCHABILITY_STATUS_OK;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;


import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Dialog;
import android.app.IActivityManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
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.QSUserSwitcherEvent;
import com.android.systemui.qs.user.UserSwitchDialogController.DialogShower;
import com.android.systemui.qs.user.UserSwitchDialogController.DialogShower;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.telephony.TelephonyListenerManager;
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.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.GlobalSettings;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.settings.SecureSettings;


@@ -608,12 +606,23 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
        showExitGuestDialog(id, isGuestEphemeral, newId, dialogShower);
        showExitGuestDialog(id, isGuestEphemeral, newId, dialogShower);
    }
    }


    private void showExitGuestDialog(int id, boolean isGuestEphemeral,
    private void showExitGuestDialog(
                        int targetId, DialogShower dialogShower) {
            int id,
            boolean isGuestEphemeral,
            int targetId,
            DialogShower dialogShower) {
        if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
        if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
            mExitGuestDialog.cancel();
            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) {
        if (dialogShower != null) {
            dialogShower.showDialog(mExitGuestDialog, new DialogCuj(
            dialogShower.showDialog(mExitGuestDialog, new DialogCuj(
                    InteractionJankMonitor.CUJ_USER_DIALOG_OPEN,
                    InteractionJankMonitor.CUJ_USER_DIALOG_OPEN,
@@ -639,7 +648,15 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
        if (mAddUserDialog != null && mAddUserDialog.isShowing()) {
        if (mAddUserDialog != null && mAddUserDialog.isShowing()) {
            mAddUserDialog.cancel();
            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) {
        if (dialogShower != null) {
            dialogShower.showDialog(mAddUserDialog,
            dialogShower.showDialog(mAddUserDialog,
                    new DialogCuj(
                    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());
            }
        }
    }

}
}
+107 −0
Original line number Original line Diff line number Diff line
/*
 * 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)
    }
}
+132 −0
Original line number Original line Diff line number Diff line
/*
 * 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)
    }
}