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