• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
4 import static android.os.Build.VERSION_CODES.M;
5 import static android.os.Build.VERSION_CODES.O;
6 
7 import android.app.Activity;
8 import android.app.KeyguardManager;
9 import android.app.KeyguardManager.KeyguardDismissCallback;
10 import java.util.HashSet;
11 import java.util.Set;
12 import org.robolectric.annotation.Implementation;
13 import org.robolectric.annotation.Implements;
14 import org.robolectric.annotation.RealObject;
15 import org.robolectric.annotation.Resetter;
16 import org.robolectric.shadow.api.Shadow;
17 
18 @Implements(KeyguardManager.class)
19 public class ShadowKeyguardManager {
20   @RealObject private KeyguardManager realKeyguardManager;
21 
22   private static KeyguardManager.KeyguardLock keyguardLock =
23       Shadow.newInstanceOf(KeyguardManager.KeyguardLock.class);
24 
25   private static final Set<Integer> deviceLockedForUsers = new HashSet<Integer>();
26   private static final Set<Integer> deviceSecureForUsers = new HashSet<Integer>();
27   private static boolean inRestrictedInputMode;
28   private static boolean isKeyguardLocked;
29   private static boolean isDeviceLocked;
30   private static boolean isKeyguardSecure;
31   private static boolean isDeviceSecure;
32   private static KeyguardManager.KeyguardDismissCallback callback;
33 
34   /**
35    * For tests, returns the value set via {@link #setinRestrictedInputMode(boolean)}, or `false` by
36    * default.
37    *
38    * @see #setInRestrictedInputMode(boolean)
39    */
40   @Implementation
inKeyguardRestrictedInputMode()41   protected boolean inKeyguardRestrictedInputMode() {
42     return inRestrictedInputMode;
43   }
44 
45   @Implementation(minSdk = O)
requestDismissKeyguard( Activity activity, KeyguardManager.KeyguardDismissCallback callback)46   protected void requestDismissKeyguard(
47       Activity activity, KeyguardManager.KeyguardDismissCallback callback) {
48     if (isKeyguardLocked) {
49       if (this.callback != null) {
50         callback.onDismissError();
51       }
52       this.callback = callback;
53     } else {
54       callback.onDismissError();
55     }
56   }
57 
58   /**
59    * For tests, returns the value set via {@link #setKeyguardLocked(boolean)}, or `false` by
60    * default.
61    *
62    * @see #setKeyguardLocked(boolean)
63    */
64   @Implementation
isKeyguardLocked()65   protected boolean isKeyguardLocked() {
66     return isKeyguardLocked;
67   }
68 
69   /**
70    * Sets whether the device keyguard is locked or not. This affects the value to be returned by
71    * {@link #isKeyguardLocked()} and also invokes callbacks set in
72    *  {@link KeyguardManager#requestDismissKeyguard()}.
73    *
74    *  @param isKeyguardLocked true to lock the keyguard. If a KeyguardDismissCallback is set will
75    *  fire {@link KeyguardDismissCallback#onDismissCancelled()} or false to unlock and dismiss the
76    *  keyguard firing {@link KeyguardDismissCallback#onDismissSucceeded()} if a
77    *  KeyguardDismissCallback is set.
78    *  */
setKeyguardLocked(boolean isKeyguardLocked)79   public void setKeyguardLocked(boolean isKeyguardLocked) {
80     this.isKeyguardLocked = isKeyguardLocked;
81     if (callback != null) {
82       if (isKeyguardLocked) {
83         callback.onDismissCancelled();
84       } else {
85         callback.onDismissSucceeded();
86       }
87       callback = null;
88     }
89   }
90 
91   /**
92    * For tests, returns a {@link ShadowKeyguardLock}.
93    *
94    * @see ShadowKeyguardLock
95    */
96   @Implementation
newKeyguardLock(String tag)97   protected KeyguardManager.KeyguardLock newKeyguardLock(String tag) {
98     return keyguardLock;
99   }
100 
101   /**
102    * Sets the value to be returned by {@link KeyguardManager#inKeyguardRestrictedInputMode()}.
103    *
104    * @see KeyguardManager#inKeyguardRestrictedInputMode()
105    * @deprecated use {@link #setInRestrictedInputMode(boolean)} instead
106    */
107   @Deprecated
setinRestrictedInputMode(boolean restricted)108   public void setinRestrictedInputMode(boolean restricted) {
109     inRestrictedInputMode = restricted;
110   }
111 
112   /**
113    * Sets the value to be returned by {@link KeyguardManager#inKeyguardRestrictedInputMode()}.
114    *
115    * @see KeyguardManager#inKeyguardRestrictedInputMode()
116    */
setInRestrictedInputMode(boolean restricted)117   public void setInRestrictedInputMode(boolean restricted) {
118     inRestrictedInputMode = restricted;
119   }
120 
121   /**
122    * For tests, returns the value set by {@link #setIsKeyguardSecure(boolean)}, or `false` by
123    * default.
124    *
125    * @see #setIsKeyguardSecure(boolean)
126    */
127   @Implementation
isKeyguardSecure()128   protected boolean isKeyguardSecure() {
129     return isKeyguardSecure;
130   }
131 
132   /**
133    * Sets the value to be returned by {@link #isKeyguardSecure()}.
134    *
135    * @see #isKeyguardSecure()
136    */
setIsKeyguardSecure(boolean secure)137   public void setIsKeyguardSecure(boolean secure) {
138     isKeyguardSecure = secure;
139   }
140 
141   /**
142    * For tests on Android >=M, returns the value set by {@link #setIsDeviceSecure(boolean)}, or
143    * `false` by default.
144    *
145    * @see #setIsDeviceSecure(boolean)
146    */
147   @Implementation(minSdk = M)
isDeviceSecure()148   protected boolean isDeviceSecure() {
149     return isDeviceSecure;
150   }
151 
152   /**
153    * For tests on Android >=M, sets the value to be returned by {@link #isDeviceSecure()}.
154    *
155    * @see #isDeviceSecure()
156    */
setIsDeviceSecure(boolean isDeviceSecure)157   public void setIsDeviceSecure(boolean isDeviceSecure) {
158     this.isDeviceSecure = isDeviceSecure;
159   }
160 
161   /**
162    * For tests on Android >=M, returns the value set by {@link #setIsDeviceSecure(int, boolean)}, or
163    * `false` by default.
164    *
165    * @see #setIsDeviceSecure(int, boolean)
166    */
167   @Implementation(minSdk = M)
isDeviceSecure(int userId)168   protected boolean isDeviceSecure(int userId) {
169     return deviceSecureForUsers.contains(userId);
170   }
171 
172   /**
173    * For tests on Android >=M, sets the value to be returned by {@link #isDeviceSecure(int)}.
174    *
175    * @see #isDeviceSecure(int)
176    */
setIsDeviceSecure(int userId, boolean isDeviceSecure)177   public void setIsDeviceSecure(int userId, boolean isDeviceSecure) {
178     if (isDeviceSecure) {
179       deviceSecureForUsers.add(userId);
180     } else {
181       deviceSecureForUsers.remove(userId);
182     }
183   }
184 
185   /**
186    * For tests on Android >=L MR1, sets the value to be returned by {@link #isDeviceLocked()}.
187    *
188    * @see #isDeviceLocked()
189    */
setIsDeviceLocked(boolean isDeviceLocked)190   public void setIsDeviceLocked(boolean isDeviceLocked) {
191     this.isDeviceLocked = isDeviceLocked;
192   }
193 
194   /**
195    * @return `false` by default, or the value passed to {@link #setIsDeviceLocked(boolean)}.
196    * @see #isDeviceLocked()
197    */
198   @Implementation(minSdk = LOLLIPOP_MR1)
isDeviceLocked()199   protected boolean isDeviceLocked() {
200     return isDeviceLocked;
201   }
202 
203   /**
204    * For tests on Android >= L MR1, sets the value to be returned by {@link #isDeviceLocked(int)}.
205    *
206    * @see #isDeviceLocked(int)
207    */
setIsDeviceLocked(int userId, boolean isLocked)208   public void setIsDeviceLocked(int userId, boolean isLocked) {
209     if (isLocked) {
210       deviceLockedForUsers.add(userId);
211     } else {
212       deviceLockedForUsers.remove(userId);
213     }
214   }
215 
216   @Implementation(minSdk = LOLLIPOP_MR1)
isDeviceLocked(int userId)217   protected boolean isDeviceLocked(int userId) {
218     return deviceLockedForUsers.contains(userId);
219   }
220 
221   /** An implementation of {@link KeyguardManager#KeyguardLock}, for use in tests. */
222   @Implements(KeyguardManager.KeyguardLock.class)
223   public static class ShadowKeyguardLock {
224     private boolean keyguardEnabled = true;
225 
226     /**
227      * Sets the value to be returned by {@link #isEnabled()} to false.
228      *
229      * @see #isEnabled()
230      */
231     @Implementation
disableKeyguard()232     protected void disableKeyguard() {
233       keyguardEnabled = false;
234     }
235 
236     /**
237      * Sets the value to be returned by {@link #isEnabled()} to true.
238      *
239      * @see #isEnabled()
240      */
241     @Implementation
reenableKeyguard()242     protected void reenableKeyguard() {
243       keyguardEnabled = true;
244     }
245 
246     /**
247      * For tests, returns the value set via {@link #disableKeyguard()} or {@link reenableKeyguard},
248      * or `true` by default.
249      *
250      * @see #setKeyguardLocked(boolean)
251      */
isEnabled()252     public boolean isEnabled() {
253       return keyguardEnabled;
254     }
255   }
256 
257   @Resetter
reset()258   public static void reset() {
259     // Static because the state is Global but Context.getSystemService() returns a new instance
260     // on each call.
261     keyguardLock = Shadow.newInstanceOf(KeyguardManager.KeyguardLock.class);
262 
263     deviceLockedForUsers.clear();
264     deviceSecureForUsers.clear();
265     inRestrictedInputMode = false;
266     isKeyguardLocked = false;
267     isDeviceLocked = false;
268     isKeyguardSecure = false;
269     isDeviceSecure = false;
270     callback = null;
271   }
272 }
273