Home | History | Annotate | Download | only in app
      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 
     17 package android.app;
     18 
     19 import android.Manifest;
     20 import android.annotation.RequiresPermission;
     21 import android.app.trust.ITrustManager;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.pm.UserInfo;
     25 import android.os.Binder;
     26 import android.os.RemoteException;
     27 import android.os.IBinder;
     28 import android.os.IUserManager;
     29 import android.os.ServiceManager;
     30 import android.os.UserHandle;
     31 import android.os.UserManager;
     32 import android.view.IWindowManager;
     33 import android.view.IOnKeyguardExitResult;
     34 import 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  */
     43 public 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