1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.app; 18 19 import static android.Manifest.permission.HIDE_OVERLAY_WINDOWS; 20 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 21 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 22 import static android.hardware.biometrics.BiometricManager.Authenticators.DEVICE_CREDENTIAL; 23 import static android.provider.Settings.ACTION_BIOMETRIC_ENROLL; 24 import static android.provider.Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED; 25 26 import android.Manifest; 27 import android.annotation.IntDef; 28 import android.annotation.RequiresPermission; 29 import android.app.AlertDialog; 30 import android.app.KeyguardManager; 31 import android.content.ComponentName; 32 import android.content.DialogInterface; 33 import android.content.Intent; 34 import android.content.pm.UserInfo; 35 import android.os.Bundle; 36 import android.os.UserHandle; 37 import android.os.UserManager; 38 import android.util.Log; 39 40 import com.android.internal.R; 41 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 45 /** 46 * A dialog shown to the user that prompts them to set the screen lock for the current foreground 47 * user. Should be called from the context of foreground user. 48 */ 49 public class SetScreenLockDialogActivity extends AlertActivity 50 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { 51 private static final String TAG = "SetScreenLockDialog"; 52 public static final String EXTRA_LAUNCH_REASON = "launch_reason"; 53 /** 54 * User id associated with the workflow that wants to launch the prompt to set up the 55 * screen lock 56 */ 57 public static final String EXTRA_ORIGIN_USER_ID = "origin_user_id"; 58 private static final String PACKAGE_NAME = "android"; 59 @IntDef(prefix = "LAUNCH_REASON_", value = { 60 LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS, 61 LAUNCH_REASON_DISABLE_QUIET_MODE, 62 LAUNCH_REASON_UNKNOWN, 63 }) 64 @Retention(RetentionPolicy.SOURCE) 65 public @interface LaunchReason { 66 } 67 public static final int LAUNCH_REASON_UNKNOWN = -1; 68 public static final int LAUNCH_REASON_DISABLE_QUIET_MODE = 1; 69 public static final int LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS = 2; 70 private @LaunchReason int mReason; 71 private int mOriginUserId; 72 73 @Override 74 @RequiresPermission(HIDE_OVERLAY_WINDOWS) onCreate(Bundle savedInstanceState)75 protected void onCreate(Bundle savedInstanceState) { 76 super.onCreate(savedInstanceState); 77 if (!(android.os.Flags.allowPrivateProfile() 78 && android.multiuser.Flags.showSetScreenLockDialog() 79 && android.multiuser.Flags.enablePrivateSpaceFeatures())) { 80 finish(); 81 return; 82 } 83 Intent intent = getIntent(); 84 mReason = intent.getIntExtra(EXTRA_LAUNCH_REASON, LAUNCH_REASON_UNKNOWN); 85 mOriginUserId = intent.getIntExtra(EXTRA_ORIGIN_USER_ID, UserHandle.USER_NULL); 86 87 if (mReason == LAUNCH_REASON_UNKNOWN) { 88 Log.e(TAG, "Invalid launch reason: " + mReason); 89 finish(); 90 return; 91 } 92 93 final KeyguardManager km = getSystemService(KeyguardManager.class); 94 if (km == null) { 95 Log.e(TAG, "Error fetching keyguard manager"); 96 return; 97 } 98 if (km.isDeviceSecure()) { 99 Log.w(TAG, "Closing the activity since screen lock is already set"); 100 return; 101 } 102 103 Log.d(TAG, "Launching screen lock setup dialog due to " + mReason); 104 final AlertDialog.Builder builder = new AlertDialog.Builder(this); 105 builder.setTitle(R.string.set_up_screen_lock_title) 106 .setOnDismissListener(this) 107 .setPositiveButton(R.string.set_up_screen_lock_action_label, this) 108 .setNegativeButton(R.string.cancel, this); 109 setLaunchUserSpecificMessage(builder); 110 final AlertDialog dialog = builder.create(); 111 dialog.create(); 112 getWindow().setHideOverlayWindows(true); 113 dialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true); 114 dialog.show(); 115 } 116 117 @Override onDismiss(DialogInterface dialog)118 public void onDismiss(DialogInterface dialog) { 119 finish(); 120 } 121 122 @Override onClick(DialogInterface dialog, int which)123 public void onClick(DialogInterface dialog, int which) { 124 if (which == DialogInterface.BUTTON_POSITIVE) { 125 Intent setNewLockIntent = new Intent(ACTION_BIOMETRIC_ENROLL); 126 setNewLockIntent.putExtra(EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, DEVICE_CREDENTIAL); 127 startActivity(setNewLockIntent); 128 } else { 129 finish(); 130 } 131 } 132 133 @RequiresPermission(anyOf = { 134 Manifest.permission.MANAGE_USERS, 135 Manifest.permission.CREATE_USERS, 136 Manifest.permission.QUERY_USERS}) setLaunchUserSpecificMessage(AlertDialog.Builder builder)137 private void setLaunchUserSpecificMessage(AlertDialog.Builder builder) { 138 if (mReason == LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS) { 139 // Always set private space message if launch reason is specific to private space 140 builder.setMessage(R.string.private_space_set_up_screen_lock_message); 141 return; 142 } 143 final UserManager userManager = getApplicationContext().getSystemService(UserManager.class); 144 if (userManager != null) { 145 UserInfo userInfo = userManager.getUserInfo(mOriginUserId); 146 if (userInfo != null && userInfo.isPrivateProfile()) { 147 builder.setMessage(R.string.private_space_set_up_screen_lock_message); 148 } 149 } 150 } 151 152 /** Returns a basic intent to display the screen lock dialog */ createBaseIntent(@aunchReason int launchReason)153 public static Intent createBaseIntent(@LaunchReason int launchReason) { 154 Intent intent = new Intent(); 155 intent.setComponent(new ComponentName(PACKAGE_NAME, 156 SetScreenLockDialogActivity.class.getName())); 157 intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 158 intent.putExtra(EXTRA_LAUNCH_REASON, launchReason); 159 return intent; 160 } 161 } 162