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

Commit 8c2bf557 authored by Kasia Krejszeff's avatar Kasia Krejszeff
Browse files

Send intent to settings to open screen lock dialog

Add ScreenLockDialogContract and use the intent it builds to launch the
dialog that promtps the user to set up a screen lock before interacting
with the Private Space.

The dialog is being moved to the Settings app to allow theming.

Bug: 406130727, 407327874
Test: manual and presubmit
Flag: android.multiuser.move_set_screen_lock_dialog_to_settings_app
Change-Id: I466fc310fba22b16f992a6fbcc4000cef83a1d36
parent c89e6b1c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ per-file IntentForwarderActivity.java = file:/core/java/android/app/admin/WorkPr
per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
per-file *SoundTrigger* = file:/media/java/android/media/soundtrigger/OWNERS
per-file SetScreenLockDialogContract.java = file:platform/packages/apps/Settings:/src/com/android/settings/privatespace/OWNERS

# Chooser and Resolver.
per-file *Chooser* = file:chooser/OWNERS
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.internal.app;

import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

import android.annotation.IntDef;
import android.annotation.UserIdInt;
import android.content.Intent;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Contract class for building the {@code SET_SCREEN_LOCK_PROMPT_ACTION} intent.
 *
 * <p>This class defines the intent action, extras, and launch reasons for handling the {@code
 * SET_SCREEN_LOCK_PROMPT_ACTION} action which is intended to launch a dialog prompting the user to
 * set a screen lock.
 */
public final class SetScreenLockDialogContract {

    public static final String EXTRA_LAUNCH_REASON = "launch_reason";

    /**
     * User id associated with the workflow that wants to launch the prompt to set up the screen
     * lock
     */
    public static final String EXTRA_ORIGIN_USER_ID = "origin_user_id";

    private static final String SET_SCREEN_LOCK_PROMPT_ACTION =
            "com.android.internal.app.ScreenLockDialogContract.SET_SCREEN_LOCK_PROMPT_ACTION";
    private static final String SETTINGS_PACKAGE = "com.android.settings";

    @IntDef(
            prefix = "LAUNCH_REASON_",
            value = {
                LAUNCH_REASON_UNKNOWN,
                LAUNCH_REASON_DISABLE_QUIET_MODE,
                LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS,
                LAUNCH_REASON_RESET_PRIVATE_SPACE_SETTINGS_ACCESS,
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface LaunchReason {}

    public static final int LAUNCH_REASON_UNKNOWN = -1;
    public static final int LAUNCH_REASON_DISABLE_QUIET_MODE = 1;
    public static final int LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS = 2;
    public static final int LAUNCH_REASON_RESET_PRIVATE_SPACE_SETTINGS_ACCESS = 3;

    /** Returns an intent to display the screen lock dialog */
    public static Intent createDialogIntent(
            @SetScreenLockDialogActivity.LaunchReason int launchReason) {
        Intent intent = new Intent(SET_SCREEN_LOCK_PROMPT_ACTION);
        // Allow only the settings app to receive the intent.
        intent.setPackage(SETTINGS_PACKAGE);
        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        intent.putExtra(EXTRA_LAUNCH_REASON, launchReason);
        return intent;
    }

    /** Returns an intent to display the screen lock dialog with a user specific message. */
    public static Intent createUserSpecificDialogIntent(
            @SetScreenLockDialogActivity.LaunchReason int launchReason,
            @UserIdInt int originUserId) {
        Intent intent = createDialogIntent(launchReason);
        intent.putExtra(EXTRA_ORIGIN_USER_ID, originUserId);
        return intent;
    }
}
+16 −9
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.SetScreenLockDialogActivity;
import com.android.internal.app.SetScreenLockDialogContract;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -1991,17 +1992,23 @@ public class UserManagerService extends IUserManager.Stub {
                        showConfirmCredentialToDisableQuietMode(userId, target, callingPackage);
                        return false;
                    } else if (km != null && !km.isDeviceSecure(parentUserId)
                            && android.multiuser.Flags.showSetScreenLockDialog()
                            // TODO(b/330720545): Add a better way to accomplish this, also use it
                            //  to block profile creation w/o device credentials present.
                            && Settings.Secure.getIntForUser(mContext.getContentResolver(),
                                Settings.Secure.USER_SETUP_COMPLETE, 0, userId) == 1) {
                        Intent setScreenLockPromptIntent =
                                SetScreenLockDialogActivity
                                        .createBaseIntent(LAUNCH_REASON_DISABLE_QUIET_MODE);
                        final Intent setScreenLockPromptIntent;
                        if (android.multiuser.Flags.moveSetScreenLockDialogToSettingsApp()) {
                            setScreenLockPromptIntent =
                                    SetScreenLockDialogContract.createUserSpecificDialogIntent(
                                            SetScreenLockDialogContract
                                                    .LAUNCH_REASON_DISABLE_QUIET_MODE,
                                            userId);
                        } else {
                            setScreenLockPromptIntent =
                                    SetScreenLockDialogActivity.createBaseIntent(
                                            LAUNCH_REASON_DISABLE_QUIET_MODE);
                            setScreenLockPromptIntent.putExtra(EXTRA_ORIGIN_USER_ID, userId);
                        mContext.startActivityAsUser(setScreenLockPromptIntent,
                                UserHandle.of(parentUserId));
                        }
                        mContext.startActivityAsUser(
                                setScreenLockPromptIntent, UserHandle.of(parentUserId));
                        return false;
                    } else {
                        Slog.w(LOG_TAG, "Allowing profile unlock even when device credentials "