blob: 3ecb5870416f29648d57b2d9c30fb56a6699a909 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
17package android.app;
18
Tor Norbye672055e2015-04-23 17:30:56 -070019import android.Manifest;
Jorim Jaggi241ae102016-11-02 21:57:33 -070020import android.annotation.NonNull;
21import android.annotation.Nullable;
Lenka Trochtova66c492a2018-12-06 11:29:21 +010022import android.annotation.RequiresFeature;
Tor Norbye672055e2015-04-23 17:30:56 -070023import android.annotation.RequiresPermission;
Adrian Roos4f3ba352017-12-14 15:12:40 +010024import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060025import android.annotation.SystemService;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010026import android.annotation.UnsupportedAppUsage;
Adrian Roosbcd07652014-10-22 16:57:16 +020027import android.app.trust.ITrustManager;
28import android.content.Context;
Jim Miller66093a92014-08-13 14:47:47 -070029import android.content.Intent;
Nancy Zheng43f166d2016-11-18 18:15:09 -080030import android.content.pm.PackageManager;
Nancy Zhenge256a182016-11-21 15:46:08 -080031import android.content.pm.ResolveInfo;
Kevin Chyn1b2137c2019-01-24 16:32:38 -080032import android.hardware.biometrics.BiometricPrompt;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.Binder;
Mathew Inwood8c854f82018-09-14 12:35:36 +010034import android.os.Build;
Jorim Jaggi241ae102016-11-02 21:57:33 -070035import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.IBinder;
Nancy Zhenge256a182016-11-21 15:46:08 -080037import android.os.RemoteException;
Adrian Roosbcd07652014-10-22 16:57:16 +020038import android.os.ServiceManager;
Jeff Sharkey49ca5292016-05-10 12:54:45 -060039import android.os.ServiceManager.ServiceNotFoundException;
Adrian Roos7374d3a2017-03-31 14:14:53 -070040import android.provider.Settings;
41import android.service.persistentdata.IPersistentDataBlockService;
Jorim Jaggi241ae102016-11-02 21:57:33 -070042import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.view.IOnKeyguardExitResult;
Nancy Zhenge256a182016-11-21 15:46:08 -080044import android.view.IWindowManager;
Jorim Jaggi241ae102016-11-02 21:57:33 -070045import android.view.WindowManager.LayoutParams;
Jeff Brown98365d72012-08-19 20:30:52 -070046import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Jorim Jaggi241ae102016-11-02 21:57:33 -070048import com.android.internal.policy.IKeyguardDismissCallback;
Adrian Roos7374d3a2017-03-31 14:14:53 -070049import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi241ae102016-11-02 21:57:33 -070050
Nancy Zhenge256a182016-11-21 15:46:08 -080051import java.util.List;
52
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053/**
Frank Salimf3b68a62017-05-23 13:02:44 -070054 * Class that can be used to lock and unlock the keyguard. The
55 * actual class to control the keyguard locking is
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 * {@link android.app.KeyguardManager.KeyguardLock}.
57 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060058@SystemService(Context.KEYGUARD_SERVICE)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059public class KeyguardManager {
Jorim Jaggi241ae102016-11-02 21:57:33 -070060
61 private static final String TAG = "KeyguardManager";
62
63 private final Context mContext;
64 private final IWindowManager mWM;
65 private final IActivityManager mAm;
66 private final ITrustManager mTrustManager;
Zimuzob3b9c262018-10-31 11:54:20 +000067 private final INotificationManager mNotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
69 /**
Jim Miller66093a92014-08-13 14:47:47 -070070 * Intent used to prompt user for device credentials.
71 * @hide
72 */
73 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL =
74 "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
75
76 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -080077 * Intent used to prompt user for device credentials.
78 * @hide
79 */
80 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER =
81 "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
82
83 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -070084 * Intent used to prompt user for factory reset credentials.
85 * @hide
86 */
87 public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
88 "android.app.action.CONFIRM_FRP_CREDENTIAL";
89
90 /**
Kevin Chyn1b2137c2019-01-24 16:32:38 -080091 * @hide
92 */
93 public static final String EXTRA_BIOMETRIC_PROMPT_BUNDLE =
94 "android.app.extra.BIOMETRIC_PROMPT_BUNDLE";
95
96 /**
Jim Miller66093a92014-08-13 14:47:47 -070097 * A CharSequence dialog title to show to the user when used with a
98 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
99 * @hide
100 */
101 public static final String EXTRA_TITLE = "android.app.extra.TITLE";
102
103 /**
104 * A CharSequence description to show to the user when used with
105 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
106 * @hide
107 */
108 public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
109
110 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -0700111 * A CharSequence description to show to the user on the alternate button when used with
112 * {@link #ACTION_CONFIRM_FRP_CREDENTIAL}.
113 * @hide
114 */
115 public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
116 "android.app.extra.ALTERNATE_BUTTON_LABEL";
117
118 /**
119 * Result code returned by the activity started by
120 * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
121 * alternate button.
122 *
123 * @hide
124 */
125 public static final int RESULT_ALTERNATE = 1;
126
127 /**
Kevin Chyne64d74e2019-03-04 10:41:03 -0800128 * @deprecated see {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)}
Kevin Chyn1b2137c2019-01-24 16:32:38 -0800129 *
130 * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
131 * if enrolled) for the current user of the device. The caller is expected to launch this
132 * activity using {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
Jim Miller66093a92014-08-13 14:47:47 -0700133 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
134 *
135 * @return the intent for launching the activity or null if no password is required.
136 **/
Kevin Chyn1b2137c2019-01-24 16:32:38 -0800137 @Deprecated
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100138 @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
Kevin Chyn1b2137c2019-01-24 16:32:38 -0800139 public Intent createConfirmDeviceCredentialIntent(CharSequence title,
140 CharSequence description) {
Kevin Chyn6a212172019-01-25 00:06:46 +0000141 if (!isDeviceSecure()) return null;
Jim Miller66093a92014-08-13 14:47:47 -0700142 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
143 intent.putExtra(EXTRA_TITLE, title);
144 intent.putExtra(EXTRA_DESCRIPTION, description);
Nancy Zhenge256a182016-11-21 15:46:08 -0800145
146 // explicitly set the package for security
147 intent.setPackage(getSettingsPackageForIntent(intent));
Jim Miller66093a92014-08-13 14:47:47 -0700148 return intent;
149 }
150
151 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800152 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
153 * for the given user. The caller is expected to launch this activity using
154 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
155 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
156 *
157 * @return the intent for launching the activity or null if no password is required.
158 *
159 * @hide
160 */
161 public Intent createConfirmDeviceCredentialIntent(
162 CharSequence title, CharSequence description, int userId) {
163 if (!isDeviceSecure(userId)) return null;
164 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
165 intent.putExtra(EXTRA_TITLE, title);
166 intent.putExtra(EXTRA_DESCRIPTION, description);
167 intent.putExtra(Intent.EXTRA_USER_ID, userId);
Nancy Zhenge256a182016-11-21 15:46:08 -0800168
169 // explicitly set the package for security
170 intent.setPackage(getSettingsPackageForIntent(intent));
171
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800172 return intent;
173 }
174
Adrian Roos7374d3a2017-03-31 14:14:53 -0700175 /**
176 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
177 * for the previous owner of the device. The caller is expected to launch this activity using
178 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
179 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
180 *
181 * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
182 * clicking this button, the activity returns
183 * {@link #RESULT_ALTERNATE}
184 *
Adrian Roosb2375942018-01-19 22:31:28 +0100185 * @return the intent for launching the activity or null if the previous owner of the device
186 * did not set a credential.
187 * @throws UnsupportedOperationException if the device does not support factory reset
188 * credentials
189 * @throws IllegalStateException if the device has already been provisioned
Adrian Roos7374d3a2017-03-31 14:14:53 -0700190 * @hide
191 */
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100192 @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
Adrian Roos4f3ba352017-12-14 15:12:40 +0100193 @SystemApi
Adrian Roos7374d3a2017-03-31 14:14:53 -0700194 public Intent createConfirmFactoryResetCredentialIntent(
195 CharSequence title, CharSequence description, CharSequence alternateButtonLabel) {
Adrian Roos2adc2632017-09-05 17:01:42 +0200196 if (!LockPatternUtils.frpCredentialEnabled(mContext)) {
Adrian Roos7374d3a2017-03-31 14:14:53 -0700197 Log.w(TAG, "Factory reset credentials not supported.");
Adrian Roosb2375942018-01-19 22:31:28 +0100198 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700199 }
200
201 // Cannot verify credential if the device is provisioned
202 if (Settings.Global.getInt(mContext.getContentResolver(),
203 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
204 Log.e(TAG, "Factory reset credential cannot be verified after provisioning.");
Adrian Roosb2375942018-01-19 22:31:28 +0100205 throw new IllegalStateException("must not be provisioned yet");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700206 }
207
208 // Make sure we have a credential
209 try {
210 IPersistentDataBlockService pdb = IPersistentDataBlockService.Stub.asInterface(
211 ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));
212 if (pdb == null) {
213 Log.e(TAG, "No persistent data block service");
Adrian Roosb2375942018-01-19 22:31:28 +0100214 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700215 }
Adrian Roosb2375942018-01-19 22:31:28 +0100216 // The following will throw an UnsupportedOperationException if the device does not
217 // support factory reset credentials (or something went wrong retrieving it).
Adrian Roos7374d3a2017-03-31 14:14:53 -0700218 if (!pdb.hasFrpCredentialHandle()) {
219 Log.i(TAG, "The persistent data block does not have a factory reset credential.");
220 return null;
221 }
222 } catch (RemoteException e) {
223 throw e.rethrowFromSystemServer();
224 }
225
226 Intent intent = new Intent(ACTION_CONFIRM_FRP_CREDENTIAL);
227 intent.putExtra(EXTRA_TITLE, title);
228 intent.putExtra(EXTRA_DESCRIPTION, description);
229 intent.putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
230
231 // explicitly set the package for security
232 intent.setPackage(getSettingsPackageForIntent(intent));
233
234 return intent;
235 }
236
Zimuzob3b9c262018-10-31 11:54:20 +0000237 /**
238 * Controls whether notifications can be shown atop a securely locked screen in their full
239 * private form (same as when the device is unlocked).
240 *
241 * <p>Other sources like the DevicePolicyManger and Settings app can modify this configuration.
242 * The result is that private notifications are only shown if all sources allow it.
243 *
244 * @param allow secure notifications can be shown if {@code true},
245 * secure notifications cannot be shown if {@code false}
246 * @hide
247 */
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100248 @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
Zimuzob3b9c262018-10-31 11:54:20 +0000249 @RequiresPermission(Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS)
250 @SystemApi
251 public void setPrivateNotificationsAllowed(boolean allow) {
252 try {
253 mNotificationManager.setPrivateNotificationsAllowed(allow);
254 } catch (RemoteException e) {
255 throw e.rethrowFromSystemServer();
256 }
257 }
258
259 /**
260 * Returns whether notifications can be shown atop a securely locked screen in their full
261 * private form (same as when the device is unlocked).
262 *
263 * @return {@code true} if secure notifications can be shown, {@code false} otherwise.
264 * By default, private notifications are allowed.
265 * @hide
266 */
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100267 @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
Zimuzob3b9c262018-10-31 11:54:20 +0000268 @RequiresPermission(Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS)
269 @SystemApi
270 public boolean getPrivateNotificationsAllowed() {
271 try {
272 return mNotificationManager.getPrivateNotificationsAllowed();
273 } catch (RemoteException e) {
274 throw e.rethrowFromSystemServer();
275 }
276 }
277
Nancy Zhenge256a182016-11-21 15:46:08 -0800278 private String getSettingsPackageForIntent(Intent intent) {
279 List<ResolveInfo> resolveInfos = mContext.getPackageManager()
280 .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
281 for (int i = 0; i < resolveInfos.size(); i++) {
282 return resolveInfos.get(i).activityInfo.packageName;
283 }
284
285 return "com.android.settings";
286 }
287
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800288 /**
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100289 * Handle returned by {@link KeyguardManager#newKeyguardLock} that allows
290 * you to disable / reenable the keyguard.
291 *
Jorim Jaggi241ae102016-11-02 21:57:33 -0700292 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
293 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700294 * instead; this allows you to seamlessly hide the keyguard as your application
295 * moves in and out of the foreground and does not require that any special
296 * permissions be requested.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700298 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 public class KeyguardLock {
Kenny Rootd7d2d432014-05-09 10:33:29 -0700300 private final IBinder mToken = new Binder();
301 private final String mTag;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302
303 KeyguardLock(String tag) {
304 mTag = tag;
305 }
306
307 /**
308 * Disable the keyguard from showing. If the keyguard is currently
309 * showing, hide it. The keyguard will be prevented from showing again
310 * until {@link #reenableKeyguard()} is called.
311 *
312 * A good place to call this is from {@link android.app.Activity#onResume()}
313 *
Jim Miller66093a92014-08-13 14:47:47 -0700314 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
Jim Millercb52cb52010-06-07 21:19:16 -0700315 * is enabled that requires a password.
Jim Millerd6b57052010-06-07 17:52:42 -0700316 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 * @see #reenableKeyguard()
318 */
Tor Norbye672055e2015-04-23 17:30:56 -0700319 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 public void disableKeyguard() {
321 try {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100322 mWM.disableKeyguard(mToken, mTag, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 } catch (RemoteException ex) {
324 }
325 }
326
327 /**
328 * Reenable the keyguard. The keyguard will reappear if the previous
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700329 * call to {@link #disableKeyguard()} caused it to be hidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 *
Jim Millerd6b57052010-06-07 17:52:42 -0700331 * A good place to call this is from {@link android.app.Activity#onPause()}
332 *
Jim Millercb52cb52010-06-07 21:19:16 -0700333 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
334 * is enabled that requires a password.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 *
336 * @see #disableKeyguard()
337 */
Tor Norbye672055e2015-04-23 17:30:56 -0700338 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 public void reenableKeyguard() {
340 try {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100341 mWM.reenableKeyguard(mToken, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 } catch (RemoteException ex) {
343 }
344 }
345 }
346
347 /**
348 * Callback passed to {@link KeyguardManager#exitKeyguardSecurely} to notify
349 * caller of result.
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100350 *
351 * @deprecated Use {@link KeyguardDismissCallback}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 */
Jorim Jaggi241ae102016-11-02 21:57:33 -0700353 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 public interface OnKeyguardExitResult {
355
356 /**
357 * @param success True if the user was able to authenticate, false if
358 * not.
359 */
360 void onKeyguardExitResult(boolean success);
361 }
362
Jorim Jaggi241ae102016-11-02 21:57:33 -0700363 /**
Jeff Sharkey67f9d502017-08-05 13:49:13 -0600364 * Callback passed to
365 * {@link KeyguardManager#requestDismissKeyguard(Activity, KeyguardDismissCallback)}
366 * to notify caller of result.
Jorim Jaggi241ae102016-11-02 21:57:33 -0700367 */
368 public static abstract class KeyguardDismissCallback {
369
370 /**
371 * Called when dismissing Keyguard is currently not feasible, i.e. when Keyguard is not
372 * available, not showing or when the activity requesting the Keyguard dismissal isn't
373 * showing or isn't showing behind Keyguard.
374 */
375 public void onDismissError() { }
376
377 /**
378 * Called when dismissing Keyguard has succeeded and the device is now unlocked.
379 */
380 public void onDismissSucceeded() { }
381
382 /**
383 * Called when dismissing Keyguard has been cancelled, i.e. when the user cancelled the
384 * operation or the bouncer was hidden for some other reason.
385 */
386 public void onDismissCancelled() { }
387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388
Nancy Zheng40cd8e42016-11-21 12:58:16 -0800389 KeyguardManager(Context context) throws ServiceNotFoundException {
Nancy Zheng43f166d2016-11-18 18:15:09 -0800390 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700391 mWM = WindowManagerGlobal.getWindowManagerService();
Jorim Jaggi241ae102016-11-02 21:57:33 -0700392 mAm = ActivityManager.getService();
Adrian Roosbcd07652014-10-22 16:57:16 +0200393 mTrustManager = ITrustManager.Stub.asInterface(
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600394 ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE));
Zimuzob3b9c262018-10-31 11:54:20 +0000395 mNotificationManager = INotificationManager.Stub.asInterface(
396 ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 }
398
399 /**
Frank Salimf3b68a62017-05-23 13:02:44 -0700400 * Enables you to lock or unlock the keyguard. Get an instance of this class by
Jim Miller66093a92014-08-13 14:47:47 -0700401 * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}.
403 * @param tag A tag that informally identifies who you are (for debugging who
Frank Salimf3b68a62017-05-23 13:02:44 -0700404 * is disabling the keyguard).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 *
406 * @return A {@link KeyguardLock} handle to use to disable and reenable the
407 * keyguard.
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100408 *
409 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
410 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
411 * instead; this allows you to seamlessly hide the keyguard as your application
412 * moves in and out of the foreground and does not require that any special
413 * permissions be requested.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700415 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 public KeyguardLock newKeyguardLock(String tag) {
417 return new KeyguardLock(tag);
418 }
419
420 /**
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500421 * Return whether the keyguard is currently locked.
422 *
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700423 * @return true if keyguard is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500424 */
425 public boolean isKeyguardLocked() {
426 try {
Mike Lockwood50531242011-02-26 11:23:49 -0500427 return mWM.isKeyguardLocked();
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500428 } catch (RemoteException ex) {
429 return false;
430 }
431 }
432
433 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700434 * Return whether the keyguard is secured by a PIN, pattern or password or a SIM card
435 * is currently locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500436 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700437 * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
438 *
439 * @return true if a PIN, pattern or password is set or a SIM card is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500440 */
441 public boolean isKeyguardSecure() {
442 try {
443 return mWM.isKeyguardSecure();
444 } catch (RemoteException ex) {
445 return false;
446 }
447 }
448
449 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 * If keyguard screen is showing or in restricted key input mode (i.e. in
451 * keyguard password emergency screen). When in such mode, certain keys,
452 * such as the Home key and the right soft keys, don't work.
453 *
454 * @return true if in keyguard restricted input mode.
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100455 * @deprecated Use {@link #isKeyguardLocked()} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 */
457 public boolean inKeyguardRestrictedInputMode() {
Siarhei Vishniakou5f13cf02017-10-12 16:50:06 -0700458 return isKeyguardLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 }
460
461 /**
Adrian Roos50bfeec2014-11-20 16:21:11 +0100462 * Returns whether the device is currently locked and requires a PIN, pattern or
463 * password to unlock.
Adrian Roosbcd07652014-10-22 16:57:16 +0200464 *
Adrian Roos50bfeec2014-11-20 16:21:11 +0100465 * @return true if unlocking the device currently requires a PIN, pattern or
466 * password.
Adrian Roosbcd07652014-10-22 16:57:16 +0200467 */
Adrian Roos50bfeec2014-11-20 16:21:11 +0100468 public boolean isDeviceLocked() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700469 return isDeviceLocked(mContext.getUserId());
Adrian Roosbcd07652014-10-22 16:57:16 +0200470 }
471
472 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700473 * Per-user version of {@link #isDeviceLocked()}.
Adrian Roosbcd07652014-10-22 16:57:16 +0200474 *
Adrian Roosbcd07652014-10-22 16:57:16 +0200475 * @hide
476 */
Mathew Inwood8c854f82018-09-14 12:35:36 +0100477 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adrian Roos50bfeec2014-11-20 16:21:11 +0100478 public boolean isDeviceLocked(int userId) {
Adrian Roosbcd07652014-10-22 16:57:16 +0200479 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700480 return mTrustManager.isDeviceLocked(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200481 } catch (RemoteException e) {
482 return false;
483 }
484 }
485
486 /**
Adrian Roos82893682015-04-02 16:17:46 +0200487 * Returns whether the device is secured with a PIN, pattern or
488 * password.
489 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700490 * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
491 *
Adrian Roos82893682015-04-02 16:17:46 +0200492 * @return true if a PIN, pattern or password was set.
493 */
494 public boolean isDeviceSecure() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700495 return isDeviceSecure(mContext.getUserId());
Adrian Roos82893682015-04-02 16:17:46 +0200496 }
497
498 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700499 * Per-user version of {@link #isDeviceSecure()}.
Adrian Roos82893682015-04-02 16:17:46 +0200500 *
Adrian Roos82893682015-04-02 16:17:46 +0200501 * @hide
502 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100503 @UnsupportedAppUsage
Adrian Roos82893682015-04-02 16:17:46 +0200504 public boolean isDeviceSecure(int userId) {
505 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700506 return mTrustManager.isDeviceSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200507 } catch (RemoteException e) {
508 return false;
509 }
510 }
511
Jeff Sharkey000ce802017-04-29 13:13:27 -0600512 /** @removed */
Jorim Jaggif41e7662017-04-27 14:30:39 +0200513 @Deprecated
Jorim Jaggi241ae102016-11-02 21:57:33 -0700514 public void dismissKeyguard(@NonNull Activity activity,
515 @Nullable KeyguardDismissCallback callback, @Nullable Handler handler) {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200516 requestDismissKeyguard(activity, callback);
517 }
518
519 /**
520 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
521 * be dismissed.
522 * <p>
523 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
524 * method will immediately dismiss the Keyguard without any user interaction.
525 * <p>
526 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
527 * UI so the user can enter their credentials.
chaviw59b98852017-06-13 12:05:44 -0700528 * <p>
529 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
530 * the screen will turn on when the keyguard is dismissed.
Jorim Jaggif41e7662017-04-27 14:30:39 +0200531 *
532 * @param activity The activity requesting the dismissal. The activity must be either visible
533 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
534 * which it would be visible if Keyguard would not be hiding it. If that's not
535 * the case, the request will fail immediately and
536 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
537 * @param callback The callback to be called if the request to dismiss Keyguard was successful
538 * or {@code null} if the caller isn't interested in knowing the result. The
539 * callback will not be invoked if the activity was destroyed before the
540 * callback was received.
541 */
542 public void requestDismissKeyguard(@NonNull Activity activity,
543 @Nullable KeyguardDismissCallback callback) {
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800544 requestDismissKeyguard(activity, null /* message */, callback);
545 }
546
547 /**
548 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
549 * be dismissed.
550 * <p>
551 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
552 * method will immediately dismiss the Keyguard without any user interaction.
553 * <p>
554 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
555 * UI so the user can enter their credentials.
556 * <p>
557 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
558 * the screen will turn on when the keyguard is dismissed.
559 *
560 * @param activity The activity requesting the dismissal. The activity must be either visible
561 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
562 * which it would be visible if Keyguard would not be hiding it. If that's not
563 * the case, the request will fail immediately and
564 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
565 * @param message A message that will be shown in the keyguard explaining why the user
566 * would want to dismiss it.
567 * @param callback The callback to be called if the request to dismiss Keyguard was successful
568 * or {@code null} if the caller isn't interested in knowing the result. The
569 * callback will not be invoked if the activity was destroyed before the
570 * callback was received.
571 * @hide
572 */
573 @RequiresPermission(Manifest.permission.SHOW_KEYGUARD_MESSAGE)
574 @SystemApi
575 public void requestDismissKeyguard(@NonNull Activity activity, @Nullable CharSequence message,
576 @Nullable KeyguardDismissCallback callback) {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700577 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700578 ActivityTaskManager.getService().dismissKeyguard(
579 activity.getActivityToken(), new IKeyguardDismissCallback.Stub() {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700580 @Override
581 public void onDismissError() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200582 if (callback != null && !activity.isDestroyed()) {
583 activity.mHandler.post(callback::onDismissError);
584 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700585 }
586
587 @Override
588 public void onDismissSucceeded() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200589 if (callback != null && !activity.isDestroyed()) {
590 activity.mHandler.post(callback::onDismissSucceeded);
591 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700592 }
593
594 @Override
595 public void onDismissCancelled() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200596 if (callback != null && !activity.isDestroyed()) {
597 activity.mHandler.post(callback::onDismissCancelled);
598 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700599 }
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800600 }, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -0700601 } catch (RemoteException e) {
Lucas Dupinef886542018-01-03 16:03:07 -0800602 throw e.rethrowFromSystemServer();
Clara Bayarri56878a92015-10-29 15:43:55 +0000603 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000604 }
605
Adrian Roos82893682015-04-02 16:17:46 +0200606 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 * Exit the keyguard securely. The use case for this api is that, after
608 * disabling the keyguard, your app, which was granted permission to
609 * disable the keyguard and show a limited amount of information deemed
610 * safe without the user getting past the keyguard, needs to navigate to
611 * something that is not safe to view without getting past the keyguard.
612 *
613 * This will, if the keyguard is secure, bring up the unlock screen of
614 * the keyguard.
615 *
koprivaa1a78482018-10-09 10:09:23 -0700616 * @param callback Lets you know whether the operation was successful and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 * it is safe to launch anything that would normally be considered safe
618 * once the user has gotten past the keyguard.
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100619
620 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
621 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
622 * instead; this allows you to seamlessly hide the keyguard as your application
623 * moves in and out of the foreground and does not require that any special
624 * permissions be requested.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700626 @Deprecated
Tor Norbye672055e2015-04-23 17:30:56 -0700627 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 public void exitKeyguardSecurely(final OnKeyguardExitResult callback) {
629 try {
630 mWM.exitKeyguardSecurely(new IOnKeyguardExitResult.Stub() {
631 public void onKeyguardExitResult(boolean success) throws RemoteException {
Jim Millera999d462013-10-30 13:58:11 -0700632 if (callback != null) {
633 callback.onKeyguardExitResult(success);
634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
636 });
637 } catch (RemoteException e) {
638
639 }
640 }
641}