Loading core/java/com/android/internal/app/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/com/android/internal/app/SetScreenLockDialogContract.java 0 → 100644 +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; } } services/core/java/com/android/server/pm/UserManagerService.java +16 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1996,17 +1997,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 " Loading Loading
core/java/com/android/internal/app/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/com/android/internal/app/SetScreenLockDialogContract.java 0 → 100644 +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; } }
services/core/java/com/android/server/pm/UserManagerService.java +16 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1996,17 +1997,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 " Loading