blob: fb933bd980c72b90aa9a5680f71449a877faa9e3 [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 Roos7374d3a2017-03-31 14:14:53 -070038import android.provider.Settings;
39import android.service.persistentdata.IPersistentDataBlockService;
Jorim Jaggi241ae102016-11-02 21:57:33 -070040import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.view.IOnKeyguardExitResult;
Nancy Zhenge256a182016-11-21 15:46:08 -080042import android.view.IWindowManager;
Jorim Jaggi241ae102016-11-02 21:57:33 -070043import android.view.WindowManager.LayoutParams;
Jeff Brown98365d72012-08-19 20:30:52 -070044import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
Jorim Jaggi241ae102016-11-02 21:57:33 -070046import com.android.internal.policy.IKeyguardDismissCallback;
Adrian Roos7374d3a2017-03-31 14:14:53 -070047import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi241ae102016-11-02 21:57:33 -070048
Nancy Zhenge256a182016-11-21 15:46:08 -080049import java.util.List;
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051/**
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060052 * Class that can be used to lock and unlock the keyboard. The
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -070053 * actual class to control the keyboard locking is
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 * {@link android.app.KeyguardManager.KeyguardLock}.
55 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060056@SystemService(Context.KEYGUARD_SERVICE)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057public class KeyguardManager {
Jorim Jaggi241ae102016-11-02 21:57:33 -070058
59 private static final String TAG = "KeyguardManager";
60
61 private final Context mContext;
62 private final IWindowManager mWM;
63 private final IActivityManager mAm;
64 private final ITrustManager mTrustManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
66 /**
Jim Miller66093a92014-08-13 14:47:47 -070067 * Intent used to prompt user for device credentials.
68 * @hide
69 */
70 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL =
71 "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
72
73 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -080074 * Intent used to prompt user for device credentials.
75 * @hide
76 */
77 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER =
78 "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
79
80 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -070081 * Intent used to prompt user for factory reset credentials.
82 * @hide
83 */
84 public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
85 "android.app.action.CONFIRM_FRP_CREDENTIAL";
86
87 /**
Jim Miller66093a92014-08-13 14:47:47 -070088 * A CharSequence dialog title to show to the user when used with a
89 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
90 * @hide
91 */
92 public static final String EXTRA_TITLE = "android.app.extra.TITLE";
93
94 /**
95 * A CharSequence description to show to the user when used with
96 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
97 * @hide
98 */
99 public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
100
101 /**
Adrian Roos7374d3a2017-03-31 14:14:53 -0700102 * A CharSequence description to show to the user on the alternate button when used with
103 * {@link #ACTION_CONFIRM_FRP_CREDENTIAL}.
104 * @hide
105 */
106 public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
107 "android.app.extra.ALTERNATE_BUTTON_LABEL";
108
109 /**
110 * Result code returned by the activity started by
111 * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
112 * alternate button.
113 *
114 * @hide
115 */
116 public static final int RESULT_ALTERNATE = 1;
117
118 /**
Jim Miller66093a92014-08-13 14:47:47 -0700119 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
120 * for the current user of the device. The caller is expected to launch this activity using
121 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
122 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
123 *
124 * @return the intent for launching the activity or null if no password is required.
125 **/
Jim Millerbde3d182014-08-26 19:53:17 -0700126 public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800127 if (!isDeviceSecure()) return null;
Jim Miller66093a92014-08-13 14:47:47 -0700128 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
129 intent.putExtra(EXTRA_TITLE, title);
130 intent.putExtra(EXTRA_DESCRIPTION, description);
Nancy Zhenge256a182016-11-21 15:46:08 -0800131
132 // explicitly set the package for security
133 intent.setPackage(getSettingsPackageForIntent(intent));
Jim Miller66093a92014-08-13 14:47:47 -0700134 return intent;
135 }
136
137 /**
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800138 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
139 * for the given user. The caller is expected to launch this activity using
140 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
141 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
142 *
143 * @return the intent for launching the activity or null if no password is required.
144 *
145 * @hide
146 */
147 public Intent createConfirmDeviceCredentialIntent(
148 CharSequence title, CharSequence description, int userId) {
149 if (!isDeviceSecure(userId)) return null;
150 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
151 intent.putExtra(EXTRA_TITLE, title);
152 intent.putExtra(EXTRA_DESCRIPTION, description);
153 intent.putExtra(Intent.EXTRA_USER_ID, userId);
Nancy Zhenge256a182016-11-21 15:46:08 -0800154
155 // explicitly set the package for security
156 intent.setPackage(getSettingsPackageForIntent(intent));
157
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800158 return intent;
159 }
160
Adrian Roos7374d3a2017-03-31 14:14:53 -0700161 /**
162 * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
163 * for the previous owner of the device. The caller is expected to launch this activity using
164 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
165 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
166 *
167 * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
168 * clicking this button, the activity returns
169 * {@link #RESULT_ALTERNATE}
170 *
Adrian Roosb2375942018-01-19 22:31:28 +0100171 * @return the intent for launching the activity or null if the previous owner of the device
172 * did not set a credential.
173 * @throws UnsupportedOperationException if the device does not support factory reset
174 * credentials
175 * @throws IllegalStateException if the device has already been provisioned
Adrian Roos7374d3a2017-03-31 14:14:53 -0700176 * @hide
177 */
Adrian Roos4f3ba352017-12-14 15:12:40 +0100178 @SystemApi
Adrian Roos7374d3a2017-03-31 14:14:53 -0700179 public Intent createConfirmFactoryResetCredentialIntent(
180 CharSequence title, CharSequence description, CharSequence alternateButtonLabel) {
Adrian Roos2adc2632017-09-05 17:01:42 +0200181 if (!LockPatternUtils.frpCredentialEnabled(mContext)) {
Adrian Roos7374d3a2017-03-31 14:14:53 -0700182 Log.w(TAG, "Factory reset credentials not supported.");
Adrian Roosb2375942018-01-19 22:31:28 +0100183 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700184 }
185
186 // Cannot verify credential if the device is provisioned
187 if (Settings.Global.getInt(mContext.getContentResolver(),
188 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
189 Log.e(TAG, "Factory reset credential cannot be verified after provisioning.");
Adrian Roosb2375942018-01-19 22:31:28 +0100190 throw new IllegalStateException("must not be provisioned yet");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700191 }
192
193 // Make sure we have a credential
194 try {
195 IPersistentDataBlockService pdb = IPersistentDataBlockService.Stub.asInterface(
196 ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));
197 if (pdb == null) {
198 Log.e(TAG, "No persistent data block service");
Adrian Roosb2375942018-01-19 22:31:28 +0100199 throw new UnsupportedOperationException("not supported on this device");
Adrian Roos7374d3a2017-03-31 14:14:53 -0700200 }
Adrian Roosb2375942018-01-19 22:31:28 +0100201 // The following will throw an UnsupportedOperationException if the device does not
202 // support factory reset credentials (or something went wrong retrieving it).
Adrian Roos7374d3a2017-03-31 14:14:53 -0700203 if (!pdb.hasFrpCredentialHandle()) {
204 Log.i(TAG, "The persistent data block does not have a factory reset credential.");
205 return null;
206 }
207 } catch (RemoteException e) {
208 throw e.rethrowFromSystemServer();
209 }
210
211 Intent intent = new Intent(ACTION_CONFIRM_FRP_CREDENTIAL);
212 intent.putExtra(EXTRA_TITLE, title);
213 intent.putExtra(EXTRA_DESCRIPTION, description);
214 intent.putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
215
216 // explicitly set the package for security
217 intent.setPackage(getSettingsPackageForIntent(intent));
218
219 return intent;
220 }
221
Nancy Zhenge256a182016-11-21 15:46:08 -0800222 private String getSettingsPackageForIntent(Intent intent) {
223 List<ResolveInfo> resolveInfos = mContext.getPackageManager()
224 .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
225 for (int i = 0; i < resolveInfos.size(); i++) {
226 return resolveInfos.get(i).activityInfo.packageName;
227 }
228
229 return "com.android.settings";
230 }
231
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800232 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700233 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
234 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700235 * instead; this allows you to seamlessly hide the keyguard as your application
236 * moves in and out of the foreground and does not require that any special
237 * permissions be requested.
238 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 * Handle returned by {@link KeyguardManager#newKeyguardLock} that allows
240 * you to disable / reenable the keyguard.
241 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700242 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 public class KeyguardLock {
Kenny Rootd7d2d432014-05-09 10:33:29 -0700244 private final IBinder mToken = new Binder();
245 private final String mTag;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246
247 KeyguardLock(String tag) {
248 mTag = tag;
249 }
250
251 /**
252 * Disable the keyguard from showing. If the keyguard is currently
253 * showing, hide it. The keyguard will be prevented from showing again
254 * until {@link #reenableKeyguard()} is called.
255 *
256 * A good place to call this is from {@link android.app.Activity#onResume()}
257 *
Jim Miller66093a92014-08-13 14:47:47 -0700258 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
Jim Millercb52cb52010-06-07 21:19:16 -0700259 * is enabled that requires a password.
Jim Millerd6b57052010-06-07 17:52:42 -0700260 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 * @see #reenableKeyguard()
262 */
Tor Norbye672055e2015-04-23 17:30:56 -0700263 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 public void disableKeyguard() {
265 try {
266 mWM.disableKeyguard(mToken, mTag);
267 } catch (RemoteException ex) {
268 }
269 }
270
271 /**
272 * Reenable the keyguard. The keyguard will reappear if the previous
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700273 * call to {@link #disableKeyguard()} caused it to be hidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 *
Jim Millerd6b57052010-06-07 17:52:42 -0700275 * A good place to call this is from {@link android.app.Activity#onPause()}
276 *
Jim Millercb52cb52010-06-07 21:19:16 -0700277 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
278 * is enabled that requires a password.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 *
280 * @see #disableKeyguard()
281 */
Tor Norbye672055e2015-04-23 17:30:56 -0700282 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 public void reenableKeyguard() {
284 try {
285 mWM.reenableKeyguard(mToken);
286 } catch (RemoteException ex) {
287 }
288 }
289 }
290
291 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700292 * @deprecated Use {@link KeyguardDismissCallback}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 * Callback passed to {@link KeyguardManager#exitKeyguardSecurely} to notify
294 * caller of result.
295 */
Jorim Jaggi241ae102016-11-02 21:57:33 -0700296 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 public interface OnKeyguardExitResult {
298
299 /**
300 * @param success True if the user was able to authenticate, false if
301 * not.
302 */
303 void onKeyguardExitResult(boolean success);
304 }
305
Jorim Jaggi241ae102016-11-02 21:57:33 -0700306 /**
Jeff Sharkey67f9d502017-08-05 13:49:13 -0600307 * Callback passed to
308 * {@link KeyguardManager#requestDismissKeyguard(Activity, KeyguardDismissCallback)}
309 * to notify caller of result.
Jorim Jaggi241ae102016-11-02 21:57:33 -0700310 */
311 public static abstract class KeyguardDismissCallback {
312
313 /**
314 * Called when dismissing Keyguard is currently not feasible, i.e. when Keyguard is not
315 * available, not showing or when the activity requesting the Keyguard dismissal isn't
316 * showing or isn't showing behind Keyguard.
317 */
318 public void onDismissError() { }
319
320 /**
321 * Called when dismissing Keyguard has succeeded and the device is now unlocked.
322 */
323 public void onDismissSucceeded() { }
324
325 /**
326 * Called when dismissing Keyguard has been cancelled, i.e. when the user cancelled the
327 * operation or the bouncer was hidden for some other reason.
328 */
329 public void onDismissCancelled() { }
330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331
Nancy Zheng40cd8e42016-11-21 12:58:16 -0800332 KeyguardManager(Context context) throws ServiceNotFoundException {
Nancy Zheng43f166d2016-11-18 18:15:09 -0800333 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700334 mWM = WindowManagerGlobal.getWindowManagerService();
Jorim Jaggi241ae102016-11-02 21:57:33 -0700335 mAm = ActivityManager.getService();
Adrian Roosbcd07652014-10-22 16:57:16 +0200336 mTrustManager = ITrustManager.Stub.asInterface(
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600337 ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339
340 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700341 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
342 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700343 * instead; this allows you to seamlessly hide the keyguard as your application
344 * moves in and out of the foreground and does not require that any special
345 * permissions be requested.
346 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 * Enables you to lock or unlock the keyboard. Get an instance of this class by
Jim Miller66093a92014-08-13 14:47:47 -0700348 * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}.
350 * @param tag A tag that informally identifies who you are (for debugging who
351 * is disabling he keyguard).
352 *
353 * @return A {@link KeyguardLock} handle to use to disable and reenable the
354 * keyguard.
355 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700356 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 public KeyguardLock newKeyguardLock(String tag) {
358 return new KeyguardLock(tag);
359 }
360
361 /**
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500362 * Return whether the keyguard is currently locked.
363 *
Jean-Michel Trivi37fde0a2012-05-24 17:13:06 -0700364 * @return true if keyguard is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500365 */
366 public boolean isKeyguardLocked() {
367 try {
Mike Lockwood50531242011-02-26 11:23:49 -0500368 return mWM.isKeyguardLocked();
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500369 } catch (RemoteException ex) {
370 return false;
371 }
372 }
373
374 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700375 * Return whether the keyguard is secured by a PIN, pattern or password or a SIM card
376 * is currently locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500377 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700378 * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
379 *
380 * @return true if a PIN, pattern or password is set or a SIM card is locked.
Mike Lockwood520d8bc2011-02-18 13:23:13 -0500381 */
382 public boolean isKeyguardSecure() {
383 try {
384 return mWM.isKeyguardSecure();
385 } catch (RemoteException ex) {
386 return false;
387 }
388 }
389
390 /**
Siarhei Vishniakou5f13cf02017-10-12 16:50:06 -0700391 * @deprecated Use {@link #isKeyguardLocked()} instead.
392 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 * If keyguard screen is showing or in restricted key input mode (i.e. in
394 * keyguard password emergency screen). When in such mode, certain keys,
395 * such as the Home key and the right soft keys, don't work.
396 *
397 * @return true if in keyguard restricted input mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 */
399 public boolean inKeyguardRestrictedInputMode() {
Siarhei Vishniakou5f13cf02017-10-12 16:50:06 -0700400 return isKeyguardLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 }
402
403 /**
Adrian Roos50bfeec2014-11-20 16:21:11 +0100404 * Returns whether the device is currently locked and requires a PIN, pattern or
405 * password to unlock.
Adrian Roosbcd07652014-10-22 16:57:16 +0200406 *
Adrian Roos50bfeec2014-11-20 16:21:11 +0100407 * @return true if unlocking the device currently requires a PIN, pattern or
408 * password.
Adrian Roosbcd07652014-10-22 16:57:16 +0200409 */
Adrian Roos50bfeec2014-11-20 16:21:11 +0100410 public boolean isDeviceLocked() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700411 return isDeviceLocked(mContext.getUserId());
Adrian Roosbcd07652014-10-22 16:57:16 +0200412 }
413
414 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700415 * Per-user version of {@link #isDeviceLocked()}.
Adrian Roosbcd07652014-10-22 16:57:16 +0200416 *
Adrian Roosbcd07652014-10-22 16:57:16 +0200417 * @hide
418 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100419 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adrian Roos50bfeec2014-11-20 16:21:11 +0100420 public boolean isDeviceLocked(int userId) {
Adrian Roosbcd07652014-10-22 16:57:16 +0200421 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700422 return mTrustManager.isDeviceLocked(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200423 } catch (RemoteException e) {
424 return false;
425 }
426 }
427
428 /**
Adrian Roos82893682015-04-02 16:17:46 +0200429 * Returns whether the device is secured with a PIN, pattern or
430 * password.
431 *
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700432 * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
433 *
Adrian Roos82893682015-04-02 16:17:46 +0200434 * @return true if a PIN, pattern or password was set.
435 */
436 public boolean isDeviceSecure() {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700437 return isDeviceSecure(mContext.getUserId());
Adrian Roos82893682015-04-02 16:17:46 +0200438 }
439
440 /**
Adrian Roosc39b4fc2015-04-28 15:48:00 -0700441 * Per-user version of {@link #isDeviceSecure()}.
Adrian Roos82893682015-04-02 16:17:46 +0200442 *
Adrian Roos82893682015-04-02 16:17:46 +0200443 * @hide
444 */
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100445 @UnsupportedAppUsage
Adrian Roos82893682015-04-02 16:17:46 +0200446 public boolean isDeviceSecure(int userId) {
447 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700448 return mTrustManager.isDeviceSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200449 } catch (RemoteException e) {
450 return false;
451 }
452 }
453
Jeff Sharkey000ce802017-04-29 13:13:27 -0600454 /** @removed */
Jorim Jaggif41e7662017-04-27 14:30:39 +0200455 @Deprecated
Jorim Jaggi241ae102016-11-02 21:57:33 -0700456 public void dismissKeyguard(@NonNull Activity activity,
457 @Nullable KeyguardDismissCallback callback, @Nullable Handler handler) {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200458 requestDismissKeyguard(activity, callback);
459 }
460
461 /**
462 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
463 * be dismissed.
464 * <p>
465 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
466 * method will immediately dismiss the Keyguard without any user interaction.
467 * <p>
468 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
469 * UI so the user can enter their credentials.
chaviw59b98852017-06-13 12:05:44 -0700470 * <p>
471 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
472 * the screen will turn on when the keyguard is dismissed.
Jorim Jaggif41e7662017-04-27 14:30:39 +0200473 *
474 * @param activity The activity requesting the dismissal. The activity must be either visible
475 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
476 * which it would be visible if Keyguard would not be hiding it. If that's not
477 * the case, the request will fail immediately and
478 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
479 * @param callback The callback to be called if the request to dismiss Keyguard was successful
480 * or {@code null} if the caller isn't interested in knowing the result. The
481 * callback will not be invoked if the activity was destroyed before the
482 * callback was received.
483 */
484 public void requestDismissKeyguard(@NonNull Activity activity,
485 @Nullable KeyguardDismissCallback callback) {
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800486 requestDismissKeyguard(activity, null /* message */, callback);
487 }
488
489 /**
490 * If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
491 * be dismissed.
492 * <p>
493 * If the Keyguard is not secure or the device is currently in a trusted state, calling this
494 * method will immediately dismiss the Keyguard without any user interaction.
495 * <p>
496 * If the Keyguard is secure and the device is not in a trusted state, this will bring up the
497 * UI so the user can enter their credentials.
498 * <p>
499 * If the value set for the {@link Activity} attr {@link android.R.attr#turnScreenOn} is true,
500 * the screen will turn on when the keyguard is dismissed.
501 *
502 * @param activity The activity requesting the dismissal. The activity must be either visible
503 * by using {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} or must be in a state in
504 * which it would be visible if Keyguard would not be hiding it. If that's not
505 * the case, the request will fail immediately and
506 * {@link KeyguardDismissCallback#onDismissError} will be invoked.
507 * @param message A message that will be shown in the keyguard explaining why the user
508 * would want to dismiss it.
509 * @param callback The callback to be called if the request to dismiss Keyguard was successful
510 * or {@code null} if the caller isn't interested in knowing the result. The
511 * callback will not be invoked if the activity was destroyed before the
512 * callback was received.
513 * @hide
514 */
515 @RequiresPermission(Manifest.permission.SHOW_KEYGUARD_MESSAGE)
516 @SystemApi
517 public void requestDismissKeyguard(@NonNull Activity activity, @Nullable CharSequence message,
518 @Nullable KeyguardDismissCallback callback) {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700519 try {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700520 mAm.dismissKeyguard(activity.getActivityToken(), new IKeyguardDismissCallback.Stub() {
521 @Override
522 public void onDismissError() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200523 if (callback != null && !activity.isDestroyed()) {
524 activity.mHandler.post(callback::onDismissError);
525 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700526 }
527
528 @Override
529 public void onDismissSucceeded() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200530 if (callback != null && !activity.isDestroyed()) {
531 activity.mHandler.post(callback::onDismissSucceeded);
532 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700533 }
534
535 @Override
536 public void onDismissCancelled() throws RemoteException {
Jorim Jaggif41e7662017-04-27 14:30:39 +0200537 if (callback != null && !activity.isDestroyed()) {
538 activity.mHandler.post(callback::onDismissCancelled);
539 }
Jorim Jaggi241ae102016-11-02 21:57:33 -0700540 }
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800541 }, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -0700542 } catch (RemoteException e) {
Lucas Dupinef886542018-01-03 16:03:07 -0800543 throw e.rethrowFromSystemServer();
Clara Bayarri56878a92015-10-29 15:43:55 +0000544 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000545 }
546
Adrian Roos82893682015-04-02 16:17:46 +0200547 /**
Jorim Jaggi241ae102016-11-02 21:57:33 -0700548 * @deprecated Use {@link LayoutParams#FLAG_DISMISS_KEYGUARD}
549 * and/or {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED}
Dianne Hackborn9567a662011-04-19 18:44:03 -0700550 * instead; this allows you to seamlessly hide the keyguard as your application
551 * moves in and out of the foreground and does not require that any special
552 * permissions be requested.
553 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 * Exit the keyguard securely. The use case for this api is that, after
555 * disabling the keyguard, your app, which was granted permission to
556 * disable the keyguard and show a limited amount of information deemed
557 * safe without the user getting past the keyguard, needs to navigate to
558 * something that is not safe to view without getting past the keyguard.
559 *
560 * This will, if the keyguard is secure, bring up the unlock screen of
561 * the keyguard.
562 *
koprivaa1a78482018-10-09 10:09:23 -0700563 * @param callback Lets you know whether the operation was successful and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 * it is safe to launch anything that would normally be considered safe
565 * once the user has gotten past the keyguard.
566 */
Dianne Hackborn9567a662011-04-19 18:44:03 -0700567 @Deprecated
Tor Norbye672055e2015-04-23 17:30:56 -0700568 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 public void exitKeyguardSecurely(final OnKeyguardExitResult callback) {
570 try {
571 mWM.exitKeyguardSecurely(new IOnKeyguardExitResult.Stub() {
572 public void onKeyguardExitResult(boolean success) throws RemoteException {
Jim Millera999d462013-10-30 13:58:11 -0700573 if (callback != null) {
574 callback.onKeyguardExitResult(success);
575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 }
577 });
578 } catch (RemoteException e) {
579
580 }
581 }
582}