blob: 1db111af0b105847f42af264746a579349e227a9 [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;
Tor Norbye672055e2015-04-23 17:30:56 -070022import android.annotation.RequiresPermission;
Adrian Roos4f3ba352017-12-14 15:12:40 +010023import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060024import android.annotation.SystemService;
Mathew Inwood4fb17d12018-08-14 14:25:44 +010025import android.annotation.UnsupportedAppUsage;
Adrian Roosbcd07652014-10-22 16:57:16 +020026import android.app.trust.ITrustManager;
27import android.content.Context;
Jim Miller66093a92014-08-13 14:47:47 -070028import android.content.Intent;
Nancy Zheng43f166d2016-11-18 18:15:09 -080029import android.content.pm.PackageManager;
Nancy Zhenge256a182016-11-21 15:46:08 -080030import android.content.pm.ResolveInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.Binder;
Mathew Inwood45d2c252018-09-14 12:35:36 +010032import android.os.Build;
Jorim Jaggi241ae102016-11-02 21:57:33 -070033import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.IBinder;
Nancy Zhenge256a182016-11-21 15:46:08 -080035import android.os.RemoteException;
Adrian Roosbcd07652014-10-22 16:57:16 +020036import android.os.ServiceManager;
Jeff Sharkey49ca5292016-05-10 12:54:45 -060037import android.os.ServiceManager.ServiceNotFoundException;
Adrian Roosbcd07652014-10-22 16:57:16 +020038import android.os.UserHandle;
Adrian Roos7374d3a2017-03-31 14:14:53 -070039import android.provider.Settings;
40import android.service.persistentdata.IPersistentDataBlockService;
Jorim Jaggi241ae102016-11-02 21:57:33 -070041import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.view.IOnKeyguardExitResult;
Nancy Zhenge256a182016-11-21 15:46:08 -080043import android.view.IWindowManager;
Jorim Jaggi241ae102016-11-02 21:57:33 -070044import android.view.WindowManager.LayoutParams;
Jeff Brown98365d72012-08-19 20:30:52 -070045import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
Jorim Jaggi241ae102016-11-02 21:57:33 -070047import com.android.internal.policy.IKeyguardDismissCallback;
Adrian Roos7374d3a2017-03-31 14:14:53 -070048import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi241ae102016-11-02 21:57:33 -070049
Nancy Zhenge256a182016-11-21 15:46:08 -080050import java.util.List;
51
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052/**
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060053 * Class that can be used to lock and unlock the keyboard. The
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -070054 * actual class to control the keyboard locking is
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 * {@link android.app.KeyguardManager.KeyguardLock}.
56 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060057@SystemService(Context.KEYGUARD_SERVICE)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058public class KeyguardManager {
Jorim Jaggi241ae102016-11-02 21:57:33 -070059
60 private static final String TAG = "KeyguardManager";
61
62 private final Context mContext;
63 private final IWindowManager mWM;
64 private final IActivityManager mAm;
65 private final ITrustManager mTrustManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
67 /**
Jim Miller66093a92014-08-13 14:47:47 -070068 * Intent used to prompt user for device credentials.
69 * @hide
70 */
71 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL =
72 "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
73
74 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -080075 * Intent used to prompt user for device credentials.
76 * @hide
77 */
78 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER =
79 "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
80
81 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -070082 * Intent used to prompt user for factory reset credentials.
83 * @hide
84 */
85 public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
86 "android.app.action.CONFIRM_FRP_CREDENTIAL";
87
88 /**
Jim Miller66093a92014-08-13 14:47:47 -070089 * A CharSequence dialog title to show to the user when used with a
90 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
91 * @hide
92 */
93 public static final String EXTRA_TITLE = "android.app.extra.TITLE";
94
95 /**
96 * A CharSequence description to show to the user when used with
97 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
98 * @hide
99 */
100 public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
101
102 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -0700103 * A CharSequence description to show to the user on the alternate button when used with
104 * {@link #ACTION_CONFIRM_FRP_CREDENTIAL}.
105 * @hide
106 */
107 public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
108 "android.app.extra.ALTERNATE_BUTTON_LABEL";
109
110 /**
111 * Result code returned by the activity started by
112 * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
113 * alternate button.
114 *
115 * @hide
116 */
117 public static final int RESULT_ALTERNATE = 1;
118
119 /**
Jim Miller66093a92014-08-13 14:47:47 -0700120 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
121 * for the current user of the device. The caller is expected to launch this activity using
122 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
123 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
124 *
125 * @return the intent for launching the activity or null if no password is required.
126 **/
Jim Millerbde3d182014-08-26 19:53:17 -0700127 public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800128 if (!isDeviceSecure()) return null;
Jim Miller66093a92014-08-13 14:47:47 -0700129 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
130 intent.putExtra(EXTRA_TITLE, title);
131 intent.putExtra(EXTRA_DESCRIPTION, description);
Nancy Zhenge256a182016-11-21 15:46:08 -0800132
133 // explicitly set the package for security
134 intent.setPackage(getSettingsPackageForIntent(intent));
Jim Miller66093a92014-08-13 14:47:47 -0700135 return intent;
136 }
137
138 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800139 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
140 * for the given user. The caller is expected to launch this activity using
141 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
142 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
143 *
144 * @return the intent for launching the activity or null if no password is required.
145 *
146 * @hide
147 */
148 public Intent createConfirmDeviceCredentialIntent(
149 CharSequence title, CharSequence description, int userId) {
150 if (!isDeviceSecure(userId)) return null;
151 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
152 intent.putExtra(EXTRA_TITLE, title);
153 intent.putExtra(EXTRA_DESCRIPTION, description);
154 intent.putExtra(Intent.EXTRA_USER_ID, userId);
Nancy Zhenge256a182016-11-21 15:46:08 -0800155
156 // explicitly set the package for security
157 intent.setPackage(getSettingsPackageForIntent(intent));
158
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800159 return intent;
160 }
161
Adrian Roos7374d3a2017-03-31 14:14:53 -0700162 /**
163 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
164 * for the previous owner of the device. The caller is expected to launch this activity using
165 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
166 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
167 *
168 * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
169 * clicking this button, the activity returns
170 * {@link #RESULT_ALTERNATE}
171 *
Adrian Roosb2375942018-01-19 22:31:28 +0100172 * @return the intent for launching the activity or null if the previous owner of the device
173 * did not set a credential.
174 * @throws UnsupportedOperationException if the device does not support factory reset
175 * credentials
176 * @throws IllegalStateException if the device has already been provisioned
Adrian Roos7374d3a2017-03-31 14:14:53 -0700177 * @hide
178 */
Adrian Roos4f3ba352017-12-14 15:12:40 +0100179 @SystemApi
Adrian Roos7374d3a2017-03-31 14:14:53 -0700180 public Intent createConfirmFactoryResetCredentialIntent(
181 CharSequence title, CharSequence description, CharSequence alternateButtonLabel) {
Adrian Roos2adc2632017-09-05 17:01:42 +0200182 if (!LockPatternUtils.frpCredentialEnabled(mContext)) {
Adrian Roos7374d3a2017-03-31 14:14:53 -0700183 Log.w(TAG, "Factory reset credentials not supported.");
Adrian Roosb2375942018-01-19 22:31:28 +0100184 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700185 }
186
187 // Cannot verify credential if the device is provisioned
188 if (Settings.Global.getInt(mContext.getContentResolver(),
189 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
190 Log.e(TAG, "Factory reset credential cannot be verified after provisioning.");
Adrian Roosb2375942018-01-19 22:31:28 +0100191 throw new IllegalStateException("must not be provisioned yet");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700192 }
193
194 // Make sure we have a credential
195 try {
196 IPersistentDataBlockService pdb = IPersistentDataBlockService.Stub.asInterface(
197 ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));
198 if (pdb == null) {
199 Log.e(TAG, "No persistent data block service");
Adrian Roosb2375942018-01-19 22:31:28 +0100200 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700201 }
Adrian Roosb2375942018-01-19 22:31:28 +0100202 // The following will throw an UnsupportedOperationException if the device does not
203 // support factory reset credentials (or something went wrong retrieving it).
Adrian Roos7374d3a2017-03-31 14:14:53 -0700204 if (!pdb.hasFrpCredentialHandle()) {
205 Log.i(TAG, "The persistent data block does not have a factory reset credential.");
206 return null;
207 }
208 } catch (RemoteException e) {
209 throw e.rethrowFromSystemServer();
210 }
211
212 Intent intent = new Intent(ACTION_CONFIRM_FRP_CREDENTIAL);
213 intent.putExtra(EXTRA_TITLE, title);
214 intent.putExtra(EXTRA_DESCRIPTION, description);
215 intent.putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
216
217 // explicitly set the package for security
218 intent.setPackage(getSettingsPackageForIntent(intent));
219
220 return intent;
221 }
222
Nancy Zhenge256a182016-11-21 15:46:08 -0800223 private String getSettingsPackageForIntent(Intent intent) {
224 List<ResolveInfo> resolveInfos = mContext.getPackageManager()
225 .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
226 for (int i = 0; i < resolveInfos.size(); i++) {
227 return resolveInfos.get(i).activityInfo.packageName;
228 }
229
230 return "com.android.settings";
231 }
232
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800233 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700234 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
235 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700236 * instead; this allows you to seamlessly hide the keyguard as your application
237 * moves in and out of the foreground and does not require that any special
238 * permissions be requested.
239 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 * Handle returned by {@link KeyguardManager#newKeyguardLock} that allows
241 * you to disable / reenable the keyguard.
242 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700243 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 public class KeyguardLock {
Kenny Rootd7d2d432014-05-09 10:33:29 -0700245 private final IBinder mToken = new Binder();
246 private final String mTag;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 KeyguardLock(String tag) {
249 mTag = tag;
250 }
251
252 /**
253 * Disable the keyguard from showing. If the keyguard is currently
254 * showing, hide it. The keyguard will be prevented from showing again
255 * until {@link #reenableKeyguard()} is called.
256 *
257 * A good place to call this is from {@link android.app.Activity#onResume()}
258 *
Jim Miller66093a92014-08-13 14:47:47 -0700259 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
Jim Millercb52cb52010-06-07 21:19:16 -0700260 * is enabled that requires a password.
Jim Millerd6b57052010-06-07 17:52:42 -0700261 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 * @see #reenableKeyguard()
263 */
Tor Norbye672055e2015-04-23 17:30:56 -0700264 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 public void disableKeyguard() {
266 try {
267 mWM.disableKeyguard(mToken, mTag);
268 } catch (RemoteException ex) {
269 }
270 }
271
272 /**
273 * Reenable the keyguard. The keyguard will reappear if the previous
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700274 * call to {@link #disableKeyguard()} caused it to be hidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 *
Jim Millerd6b57052010-06-07 17:52:42 -0700276 * A good place to call this is from {@link android.app.Activity#onPause()}
277 *
Jim Millercb52cb52010-06-07 21:19:16 -0700278 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
279 * is enabled that requires a password.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 *
281 * @see #disableKeyguard()
282 */
Tor Norbye672055e2015-04-23 17:30:56 -0700283 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 public void reenableKeyguard() {
285 try {
286 mWM.reenableKeyguard(mToken);
287 } catch (RemoteException ex) {
288 }
289 }
290 }
291
292 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700293 * @deprecated Use {@link KeyguardDismissCallback}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 * Callback passed to {@link KeyguardManager#exitKeyguardSecurely} to notify
295 * caller of result.
296 */
Jorim Jaggi241ae102016-11-02 21:57:33 -0700297 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 public interface OnKeyguardExitResult {
299
300 /**
301 * @param success True if the user was able to authenticate, false if
302 * not.
303 */
304 void onKeyguardExitResult(boolean success);
305 }
306
Jorim Jaggi241ae102016-11-02 21:57:33 -0700307 /**
Jeff Sharkey67f9d502017-08-05 13:49:13 -0600308 * Callback passed to
309 * {@link KeyguardManager#requestDismissKeyguard(Activity, KeyguardDismissCallback)}
310 * to notify caller of result.
Jorim Jaggi241ae102016-11-02 21:57:33 -0700311 */
312 public static abstract class KeyguardDismissCallback {
313
314 /**
315 * Called when dismissing Keyguard is currently not feasible, i.e. when Keyguard is not
316 * available, not showing or when the activity requesting the Keyguard dismissal isn't
317 * showing or isn't showing behind Keyguard.
318 */
319 public void onDismissError() { }
320
321 /**
322 * Called when dismissing Keyguard has succeeded and the device is now unlocked.
323 */
324 public void onDismissSucceeded() { }
325
326 /**
327 * Called when dismissing Keyguard has been cancelled, i.e. when the user cancelled the
328 * operation or the bouncer was hidden for some other reason.
329 */
330 public void onDismissCancelled() { }
331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332
Nancy Zheng40cd8e42016-11-21 12:58:16 -0800333 KeyguardManager(Context context) throws ServiceNotFoundException {
Nancy Zheng43f166d2016-11-18 18:15:09 -0800334 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700335 mWM = WindowManagerGlobal.getWindowManagerService();
Jorim Jaggi241ae102016-11-02 21:57:33 -0700336 mAm = ActivityManager.getService();
Adrian Roosbcd07652014-10-22 16:57:16 +0200337 mTrustManager = ITrustManager.Stub.asInterface(
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600338 ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 }
340
341 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700342 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
343 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700344 * instead; this allows you to seamlessly hide the keyguard as your application
345 * moves in and out of the foreground and does not require that any special
346 * permissions be requested.
347 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 * Enables you to lock or unlock the keyboard. Get an instance of this class by
Jim Miller66093a92014-08-13 14:47:47 -0700349 * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}.
351 * @param tag A tag that informally identifies who you are (for debugging who
352 * is disabling he keyguard).
353 *
354 * @return A {@link KeyguardLock} handle to use to disable and reenable the
355 * keyguard.
356 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700357 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 public KeyguardLock newKeyguardLock(String tag) {
359 return new KeyguardLock(tag);
360 }
361
362 /**
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500363 * Return whether the keyguard is currently locked.
364 *
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700365 * @return true if keyguard is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500366 */
367 public boolean isKeyguardLocked() {
368 try {
Mike Lockwood50531242011-02-26 11:23:49 -0500369 return mWM.isKeyguardLocked();
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500370 } catch (RemoteException ex) {
371 return false;
372 }
373 }
374
375 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700376 * Return whether the keyguard is secured by a PIN, pattern or password or a SIM card
377 * is currently locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500378 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700379 * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
380 *
381 * @return true if a PIN, pattern or password is set or a SIM card is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500382 */
383 public boolean isKeyguardSecure() {
384 try {
385 return mWM.isKeyguardSecure();
386 } catch (RemoteException ex) {
387 return false;
388 }
389 }
390
391 /**
Siarhei Vishniakou5f13cf02017-10-12 16:50:06 -0700392 * @deprecated Use {@link #isKeyguardLocked()} instead.
393 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 * If keyguard screen is showing or in restricted key input mode (i.e. in
395 * keyguard password emergency screen). When in such mode, certain keys,
396 * such as the Home key and the right soft keys, don't work.
397 *
398 * @return true if in keyguard restricted input mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 */
400 public boolean inKeyguardRestrictedInputMode() {
Siarhei Vishniakou5f13cf02017-10-12 16:50:06 -0700401 return isKeyguardLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 }
403
404 /**
Adrian Roos50bfeec2014-11-20 16:21:11 +0100405 * Returns whether the device is currently locked and requires a PIN, pattern or
406 * password to unlock.
Adrian Roosbcd07652014-10-22 16:57:16 +0200407 *
Adrian Roos50bfeec2014-11-20 16:21:11 +0100408 * @return true if unlocking the device currently requires a PIN, pattern or
409 * password.
Adrian Roosbcd07652014-10-22 16:57:16 +0200410 */
Adrian Roos50bfeec2014-11-20 16:21:11 +0100411 public boolean isDeviceLocked() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700412 return isDeviceLocked(mContext.getUserId());
Adrian Roosbcd07652014-10-22 16:57:16 +0200413 }
414
415 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700416 * Per-user version of {@link #isDeviceLocked()}.
Adrian Roosbcd07652014-10-22 16:57:16 +0200417 *
Adrian Roosbcd07652014-10-22 16:57:16 +0200418 * @hide
419 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100420 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adrian Roos50bfeec2014-11-20 16:21:11 +0100421 public boolean isDeviceLocked(int userId) {
Adrian Roosbcd07652014-10-22 16:57:16 +0200422 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700423 return mTrustManager.isDeviceLocked(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200424 } catch (RemoteException e) {
425 return false;
426 }
427 }
428
429 /**
Adrian Roos82893682015-04-02 16:17:46 +0200430 * Returns whether the device is secured with a PIN, pattern or
431 * password.
432 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700433 * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
434 *
Adrian Roos82893682015-04-02 16:17:46 +0200435 * @return true if a PIN, pattern or password was set.
436 */
437 public boolean isDeviceSecure() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700438 return isDeviceSecure(mContext.getUserId());
Adrian Roos82893682015-04-02 16:17:46 +0200439 }
440
441 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700442 * Per-user version of {@link #isDeviceSecure()}.
Adrian Roos82893682015-04-02 16:17:46 +0200443 *
Adrian Roos82893682015-04-02 16:17:46 +0200444 * @hide
445 */
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100446 @UnsupportedAppUsage
Adrian Roos82893682015-04-02 16:17:46 +0200447 public boolean isDeviceSecure(int userId) {
448 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700449 return mTrustManager.isDeviceSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200450 } catch (RemoteException e) {
451 return false;
452 }
453 }
454
Jeff Sharkey000ce802017-04-29 13:13:27 -0600455 /** @removed */
Jorim Jaggif41e7662017-04-27 14:30:39 +0200456 @Deprecated
Jorim Jaggi241ae102016-11-02 21:57:33 -0700457 public void dismissKeyguard(@NonNull Activity activity,
458 @Nullable KeyguardDismissCallback callback, @Nullable Handler handler) {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200459 requestDismissKeyguard(activity, callback);
460 }
461
462 /**
463 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
464 * be dismissed.
465 * <p>
466 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
467 * method will immediately dismiss the Keyguard without any user interaction.
468 * <p>
469 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
470 * UI so the user can enter their credentials.
chaviw59b98852017-06-13 12:05:44 -0700471 * <p>
472 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
473 * the screen will turn on when the keyguard is dismissed.
Jorim Jaggif41e7662017-04-27 14:30:39 +0200474 *
475 * @param activity The activity requesting the dismissal. The activity must be either visible
476 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
477 * which it would be visible if Keyguard would not be hiding it. If that's not
478 * the case, the request will fail immediately and
479 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
480 * @param callback The callback to be called if the request to dismiss Keyguard was successful
481 * or {@code null} if the caller isn't interested in knowing the result. The
482 * callback will not be invoked if the activity was destroyed before the
483 * callback was received.
484 */
485 public void requestDismissKeyguard(@NonNull Activity activity,
486 @Nullable KeyguardDismissCallback callback) {
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800487 requestDismissKeyguard(activity, null /* message */, callback);
488 }
489
490 /**
491 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
492 * be dismissed.
493 * <p>
494 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
495 * method will immediately dismiss the Keyguard without any user interaction.
496 * <p>
497 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
498 * UI so the user can enter their credentials.
499 * <p>
500 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
501 * the screen will turn on when the keyguard is dismissed.
502 *
503 * @param activity The activity requesting the dismissal. The activity must be either visible
504 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
505 * which it would be visible if Keyguard would not be hiding it. If that's not
506 * the case, the request will fail immediately and
507 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
508 * @param message A message that will be shown in the keyguard explaining why the user
509 * would want to dismiss it.
510 * @param callback The callback to be called if the request to dismiss Keyguard was successful
511 * or {@code null} if the caller isn't interested in knowing the result. The
512 * callback will not be invoked if the activity was destroyed before the
513 * callback was received.
514 * @hide
515 */
516 @RequiresPermission(Manifest.permission.SHOW_KEYGUARD_MESSAGE)
517 @SystemApi
518 public void requestDismissKeyguard(@NonNull Activity activity, @Nullable CharSequence message,
519 @Nullable KeyguardDismissCallback callback) {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700520 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700521 mAm.dismissKeyguard(activity.getActivityToken(), new IKeyguardDismissCallback.Stub() {
522 @Override
523 public void onDismissError() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200524 if (callback != null && !activity.isDestroyed()) {
525 activity.mHandler.post(callback::onDismissError);
526 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700527 }
528
529 @Override
530 public void onDismissSucceeded() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200531 if (callback != null && !activity.isDestroyed()) {
532 activity.mHandler.post(callback::onDismissSucceeded);
533 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700534 }
535
536 @Override
537 public void onDismissCancelled() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200538 if (callback != null && !activity.isDestroyed()) {
539 activity.mHandler.post(callback::onDismissCancelled);
540 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700541 }
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800542 }, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -0700543 } catch (RemoteException e) {
Lucas Dupinef886542018-01-03 16:03:07 -0800544 throw e.rethrowFromSystemServer();
Clara Bayarri56878a92015-10-29 15:43:55 +0000545 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000546 }
547
Adrian Roos82893682015-04-02 16:17:46 +0200548 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700549 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
550 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700551 * instead; this allows you to seamlessly hide the keyguard as your application
552 * moves in and out of the foreground and does not require that any special
553 * permissions be requested.
554 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 * Exit the keyguard securely. The use case for this api is that, after
556 * disabling the keyguard, your app, which was granted permission to
557 * disable the keyguard and show a limited amount of information deemed
558 * safe without the user getting past the keyguard, needs to navigate to
559 * something that is not safe to view without getting past the keyguard.
560 *
561 * This will, if the keyguard is secure, bring up the unlock screen of
562 * the keyguard.
563 *
564 * @param callback Let's you know whether the operation was succesful and
565 * it is safe to launch anything that would normally be considered safe
566 * once the user has gotten past the keyguard.
567 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700568 @Deprecated
Tor Norbye672055e2015-04-23 17:30:56 -0700569 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 public void exitKeyguardSecurely(final OnKeyguardExitResult callback) {
571 try {
572 mWM.exitKeyguardSecurely(new IOnKeyguardExitResult.Stub() {
573 public void onKeyguardExitResult(boolean success) throws RemoteException {
Jim Millera999d462013-10-30 13:58:11 -0700574 if (callback != null) {
575 callback.onKeyguardExitResult(success);
576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 }
578 });
579 } catch (RemoteException e) {
580
581 }
582 }
583}