• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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             LAUNCH_REASON_RESET_PRIVATE_SPACE_SETTINGS_ACCESS,
64     })
65     @Retention(RetentionPolicy.SOURCE)
66     public @interface LaunchReason {
67     }
68     public static final int LAUNCH_REASON_UNKNOWN = -1;
69     public static final int LAUNCH_REASON_DISABLE_QUIET_MODE = 1;
70     public static final int LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS = 2;
71     public static final int LAUNCH_REASON_RESET_PRIVATE_SPACE_SETTINGS_ACCESS = 3;
72     private @LaunchReason int mReason;
73     private int mOriginUserId;
74 
75     @Override
76     @RequiresPermission(HIDE_OVERLAY_WINDOWS)
onCreate(Bundle savedInstanceState)77     protected void onCreate(Bundle savedInstanceState) {
78         super.onCreate(savedInstanceState);
79         if (!(android.os.Flags.allowPrivateProfile()
80                 && android.multiuser.Flags.showSetScreenLockDialog()
81                 && android.multiuser.Flags.enablePrivateSpaceFeatures())) {
82             finish();
83             return;
84         }
85         Intent intent = getIntent();
86         mReason = intent.getIntExtra(EXTRA_LAUNCH_REASON, LAUNCH_REASON_UNKNOWN);
87         mOriginUserId = intent.getIntExtra(EXTRA_ORIGIN_USER_ID, UserHandle.USER_NULL);
88 
89         if (mReason == LAUNCH_REASON_UNKNOWN) {
90             Log.e(TAG, "Invalid launch reason: " + mReason);
91             finish();
92             return;
93         }
94 
95         final KeyguardManager km = getSystemService(KeyguardManager.class);
96         if (km == null) {
97             Log.e(TAG, "Error fetching keyguard manager");
98             return;
99         }
100         if (km.isDeviceSecure()) {
101             Log.w(TAG, "Closing the activity since screen lock is already set");
102             return;
103         }
104 
105         Log.d(TAG, "Launching screen lock setup dialog due to " + mReason);
106         final AlertDialog.Builder builder = new AlertDialog.Builder(this);
107         builder.setTitle(R.string.set_up_screen_lock_title)
108                 .setOnDismissListener(this)
109                 .setPositiveButton(R.string.set_up_screen_lock_action_label, this)
110                 .setNegativeButton(R.string.cancel, this);
111         setLaunchUserSpecificMessage(builder);
112         final AlertDialog dialog = builder.create();
113         dialog.create();
114         getWindow().setHideOverlayWindows(true);
115         dialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
116         dialog.show();
117     }
118 
119     @Override
onDismiss(DialogInterface dialog)120     public void onDismiss(DialogInterface dialog) {
121         finish();
122     }
123 
124     @Override
onClick(DialogInterface dialog, int which)125     public void onClick(DialogInterface dialog, int which) {
126         if (which == DialogInterface.BUTTON_POSITIVE) {
127             Intent setNewLockIntent = new Intent(ACTION_BIOMETRIC_ENROLL);
128             setNewLockIntent.putExtra(EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, DEVICE_CREDENTIAL);
129             startActivity(setNewLockIntent);
130         } else {
131             finish();
132         }
133     }
134 
135     @RequiresPermission(anyOf = {
136             Manifest.permission.MANAGE_USERS,
137             Manifest.permission.CREATE_USERS,
138             Manifest.permission.QUERY_USERS})
setLaunchUserSpecificMessage(AlertDialog.Builder builder)139     private void setLaunchUserSpecificMessage(AlertDialog.Builder builder) {
140         if (mReason == LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS) {
141             // Always set private space message if launch reason is specific to private space
142             builder.setMessage(R.string.private_space_set_up_screen_lock_message);
143             return;
144         } else if (mReason == LAUNCH_REASON_RESET_PRIVATE_SPACE_SETTINGS_ACCESS) {
145             builder.setMessage(R.string.private_space_set_up_screen_lock_for_reset);
146             return;
147         }
148 
149         final UserManager userManager = getApplicationContext().getSystemService(UserManager.class);
150         if (userManager != null) {
151             UserInfo userInfo = userManager.getUserInfo(mOriginUserId);
152             if (userInfo != null && userInfo.isPrivateProfile()) {
153                 builder.setMessage(R.string.private_space_set_up_screen_lock_message);
154             }
155         }
156     }
157 
158     /** Returns a basic intent to display the screen lock dialog */
createBaseIntent(@aunchReason int launchReason)159     public static Intent createBaseIntent(@LaunchReason int launchReason) {
160         Intent intent = new Intent();
161         intent.setComponent(new ComponentName(PACKAGE_NAME,
162                 SetScreenLockDialogActivity.class.getName()));
163         intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
164         intent.putExtra(EXTRA_LAUNCH_REASON, launchReason);
165         return intent;
166     }
167 }
168