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