1/* 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 19import android.Manifest; 20import android.annotation.RequiresPermission; 21import android.app.trust.ITrustManager; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.UserInfo; 25import android.os.Binder; 26import android.os.RemoteException; 27import android.os.IBinder; 28import android.os.IUserManager; 29import android.os.ServiceManager; 30import android.os.UserHandle; 31import android.os.UserManager; 32import android.view.IWindowManager; 33import android.view.IOnKeyguardExitResult; 34import android.view.WindowManagerGlobal; 35 36/** 37 * Class that can be used to lock and unlock the keyboard. Get an instance of this 38 * class by calling {@link android.content.Context#getSystemService(java.lang.String)} 39 * with argument {@link android.content.Context#KEYGUARD_SERVICE}. The 40 * actual class to control the keyboard locking is 41 * {@link android.app.KeyguardManager.KeyguardLock}. 42 */ 43public class KeyguardManager { 44 private IWindowManager mWM; 45 private ITrustManager mTrustManager; 46 private IUserManager mUserManager; 47 48 /** 49 * Intent used to prompt user for device credentials. 50 * @hide 51 */ 52 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL = 53 "android.app.action.CONFIRM_DEVICE_CREDENTIAL"; 54 55 /** 56 * Intent used to prompt user for device credentials. 57 * @hide 58 */ 59 public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER = 60 "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER"; 61 62 /** 63 * A CharSequence dialog title to show to the user when used with a 64 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. 65 * @hide 66 */ 67 public static final String EXTRA_TITLE = "android.app.extra.TITLE"; 68 69 /** 70 * A CharSequence description to show to the user when used with 71 * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}. 72 * @hide 73 */ 74 public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION"; 75 76 /** 77 * Get an intent to prompt the user to confirm credentials (pin, pattern or password) 78 * for the current user of the device. The caller is expected to launch this activity using 79 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for 80 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge. 81 * 82 * @return the intent for launching the activity or null if no password is required. 83 **/ 84 public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) { 85 if (!isDeviceSecure()) return null; 86 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL); 87 intent.putExtra(EXTRA_TITLE, title); 88 intent.putExtra(EXTRA_DESCRIPTION, description); 89 // For security reasons, only allow this to come from system settings. 90 intent.setPackage("com.android.settings"); 91 return intent; 92 } 93 94 /** 95 * Get an intent to prompt the user to confirm credentials (pin, pattern or password) 96 * for the given user. The caller is expected to launch this activity using 97 * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for 98 * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge. 99 * 100 * @return the intent for launching the activity or null if no password is required. 101 * 102 * @hide 103 */ 104 public Intent createConfirmDeviceCredentialIntent( 105 CharSequence title, CharSequence description, int userId) { 106 if (!isDeviceSecure(userId)) return null; 107 Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER); 108 intent.putExtra(EXTRA_TITLE, title); 109 intent.putExtra(EXTRA_DESCRIPTION, description); 110 intent.putExtra(Intent.EXTRA_USER_ID, userId); 111 // For security reasons, only allow this to come from system settings. 112 intent.setPackage("com.android.settings"); 113 return intent; 114 } 115 116 /** 117 * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} 118 * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} 119 * instead; this allows you to seamlessly hide the keyguard as your application 120 * moves in and out of the foreground and does not require that any special 121 * permissions be requested. 122 * 123 * Handle returned by {@link KeyguardManager#newKeyguardLock} that allows 124 * you to disable / reenable the keyguard. 125 */ 126 public class KeyguardLock { 127 private final IBinder mToken = new Binder(); 128 private final String mTag; 129 130 KeyguardLock(String tag) { 131 mTag = tag; 132 } 133 134 /** 135 * Disable the keyguard from showing. If the keyguard is currently 136 * showing, hide it. The keyguard will be prevented from showing again 137 * until {@link #reenableKeyguard()} is called. 138 * 139 * A good place to call this is from {@link android.app.Activity#onResume()} 140 * 141 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager} 142 * is enabled that requires a password. 143 * 144 * <p>This method requires the caller to hold the permission 145 * {@link android.Manifest.permission#DISABLE_KEYGUARD}. 146 * 147 * @see #reenableKeyguard() 148 */ 149 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD) 150 public void disableKeyguard() { 151 try { 152 mWM.disableKeyguard(mToken, mTag); 153 } catch (RemoteException ex) { 154 } 155 } 156 157 /** 158 * Reenable the keyguard. The keyguard will reappear if the previous 159 * call to {@link #disableKeyguard()} caused it to be hidden. 160 * 161 * A good place to call this is from {@link android.app.Activity#onPause()} 162 * 163 * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager} 164 * is enabled that requires a password. 165 * 166 * <p>This method requires the caller to hold the permission 167 * {@link android.Manifest.permission#DISABLE_KEYGUARD}. 168 * 169 * @see #disableKeyguard() 170 */ 171 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD) 172 public void reenableKeyguard() { 173 try { 174 mWM.reenableKeyguard(mToken); 175 } catch (RemoteException ex) { 176 } 177 } 178 } 179 180 /** 181 * Callback passed to {@link KeyguardManager#exitKeyguardSecurely} to notify 182 * caller of result. 183 */ 184 public interface OnKeyguardExitResult { 185 186 /** 187 * @param success True if the user was able to authenticate, false if 188 * not. 189 */ 190 void onKeyguardExitResult(boolean success); 191 } 192 193 194 KeyguardManager() { 195 mWM = WindowManagerGlobal.getWindowManagerService(); 196 mTrustManager = ITrustManager.Stub.asInterface( 197 ServiceManager.getService(Context.TRUST_SERVICE)); 198 mUserManager = IUserManager.Stub.asInterface( 199 ServiceManager.getService(Context.USER_SERVICE)); 200 } 201 202 /** 203 * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} 204 * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} 205 * instead; this allows you to seamlessly hide the keyguard as your application 206 * moves in and out of the foreground and does not require that any special 207 * permissions be requested. 208 * 209 * Enables you to lock or unlock the keyboard. Get an instance of this class by 210 * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. 211 * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}. 212 * @param tag A tag that informally identifies who you are (for debugging who 213 * is disabling he keyguard). 214 * 215 * @return A {@link KeyguardLock} handle to use to disable and reenable the 216 * keyguard. 217 */ 218 @Deprecated 219 public KeyguardLock newKeyguardLock(String tag) { 220 return new KeyguardLock(tag); 221 } 222 223 /** 224 * Return whether the keyguard is currently locked. 225 * 226 * @return true if keyguard is locked. 227 */ 228 public boolean isKeyguardLocked() { 229 try { 230 return mWM.isKeyguardLocked(); 231 } catch (RemoteException ex) { 232 return false; 233 } 234 } 235 236 /** 237 * Return whether the keyguard is secured by a PIN, pattern or password or a SIM card 238 * is currently locked. 239 * 240 * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states. 241 * 242 * @return true if a PIN, pattern or password is set or a SIM card is locked. 243 */ 244 public boolean isKeyguardSecure() { 245 try { 246 return mWM.isKeyguardSecure(); 247 } catch (RemoteException ex) { 248 return false; 249 } 250 } 251 252 /** 253 * If keyguard screen is showing or in restricted key input mode (i.e. in 254 * keyguard password emergency screen). When in such mode, certain keys, 255 * such as the Home key and the right soft keys, don't work. 256 * 257 * @return true if in keyguard restricted input mode. 258 * 259 * @see android.view.WindowManagerPolicy#inKeyguardRestrictedKeyInputMode 260 */ 261 public boolean inKeyguardRestrictedInputMode() { 262 try { 263 return mWM.inKeyguardRestrictedInputMode(); 264 } catch (RemoteException ex) { 265 return false; 266 } 267 } 268 269 /** 270 * Returns whether the device is currently locked and requires a PIN, pattern or 271 * password to unlock. 272 * 273 * @return true if unlocking the device currently requires a PIN, pattern or 274 * password. 275 */ 276 public boolean isDeviceLocked() { 277 return isDeviceLocked(UserHandle.getCallingUserId()); 278 } 279 280 /** 281 * Per-user version of {@link #isDeviceLocked()}. 282 * 283 * @hide 284 */ 285 public boolean isDeviceLocked(int userId) { 286 ITrustManager trustManager = getTrustManager(); 287 try { 288 return trustManager.isDeviceLocked(userId); 289 } catch (RemoteException e) { 290 return false; 291 } 292 } 293 294 /** 295 * Returns whether the device is secured with a PIN, pattern or 296 * password. 297 * 298 * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure. 299 * 300 * @return true if a PIN, pattern or password was set. 301 */ 302 public boolean isDeviceSecure() { 303 return isDeviceSecure(UserHandle.getCallingUserId()); 304 } 305 306 /** 307 * Per-user version of {@link #isDeviceSecure()}. 308 * 309 * @hide 310 */ 311 public boolean isDeviceSecure(int userId) { 312 ITrustManager trustManager = getTrustManager(); 313 try { 314 return trustManager.isDeviceSecure(userId); 315 } catch (RemoteException e) { 316 return false; 317 } 318 } 319 320 private synchronized ITrustManager getTrustManager() { 321 if (mTrustManager == null) { 322 mTrustManager = ITrustManager.Stub.asInterface( 323 ServiceManager.getService(Context.TRUST_SERVICE)); 324 } 325 return mTrustManager; 326 } 327 328 /** 329 * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} 330 * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} 331 * instead; this allows you to seamlessly hide the keyguard as your application 332 * moves in and out of the foreground and does not require that any special 333 * permissions be requested. 334 * 335 * Exit the keyguard securely. The use case for this api is that, after 336 * disabling the keyguard, your app, which was granted permission to 337 * disable the keyguard and show a limited amount of information deemed 338 * safe without the user getting past the keyguard, needs to navigate to 339 * something that is not safe to view without getting past the keyguard. 340 * 341 * This will, if the keyguard is secure, bring up the unlock screen of 342 * the keyguard. 343 * 344 * <p>This method requires the caller to hold the permission 345 * {@link android.Manifest.permission#DISABLE_KEYGUARD}. 346 * 347 * @param callback Let's you know whether the operation was succesful and 348 * it is safe to launch anything that would normally be considered safe 349 * once the user has gotten past the keyguard. 350 */ 351 @Deprecated 352 @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD) 353 public void exitKeyguardSecurely(final OnKeyguardExitResult callback) { 354 try { 355 mWM.exitKeyguardSecurely(new IOnKeyguardExitResult.Stub() { 356 public void onKeyguardExitResult(boolean success) throws RemoteException { 357 if (callback != null) { 358 callback.onKeyguardExitResult(success); 359 } 360 } 361 }); 362 } catch (RemoteException e) { 363 364 } 365 } 366} 367