• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.internal.widget;
2 
3 import android.os.AsyncTask;
4 
5 import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
6 
7 import java.util.ArrayList;
8 import java.util.List;
9 
10 /**
11  * Helper class to check/verify PIN/Password/Pattern asynchronously.
12  */
13 public final class LockPatternChecker {
14     /**
15      * Interface for a callback to be invoked after security check.
16      */
17     public interface OnCheckCallback {
18 
19         /**
20          * Invoked as soon as possible we know that the credentials match. This will be called
21          * earlier than {@link #onChecked} but only if the credentials match.
22          */
onEarlyMatched()23         default void onEarlyMatched() {}
24 
25         /**
26          * Invoked when a security check is finished.
27          *
28          * @param matched Whether the PIN/Password/Pattern matches the stored one.
29          * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
30          * the call. Only non-0 if matched is false.
31          */
onChecked(boolean matched, int throttleTimeoutMs)32         void onChecked(boolean matched, int throttleTimeoutMs);
33     }
34 
35     /**
36      * Interface for a callback to be invoked after security verification.
37      */
38     public interface OnVerifyCallback {
39         /**
40          * Invoked when a security verification is finished.
41          *
42          * @param attestation The attestation that the challenge was verified, or null.
43          * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
44          * the call. Only non-0 if attestation is null.
45          */
onVerified(byte[] attestation, int throttleTimeoutMs)46         void onVerified(byte[] attestation, int throttleTimeoutMs);
47     }
48 
49     /**
50      * Verify a pattern asynchronously.
51      *
52      * @param utils The LockPatternUtils instance to use.
53      * @param pattern The pattern to check.
54      * @param challenge The challenge to verify against the pattern.
55      * @param userId The user to check against the pattern.
56      * @param callback The callback to be invoked with the verification result.
57      */
verifyPattern(final LockPatternUtils utils, final List<LockPatternView.Cell> pattern, final long challenge, final int userId, final OnVerifyCallback callback)58     public static AsyncTask<?, ?, ?> verifyPattern(final LockPatternUtils utils,
59             final List<LockPatternView.Cell> pattern,
60             final long challenge,
61             final int userId,
62             final OnVerifyCallback callback) {
63         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
64             private int mThrottleTimeout;
65             private List<LockPatternView.Cell> patternCopy;
66 
67             @Override
68             protected void onPreExecute() {
69                 // Make a copy of the pattern to prevent race conditions.
70                 // No need to clone the individual cells because they are immutable.
71                 patternCopy = new ArrayList(pattern);
72             }
73 
74             @Override
75             protected byte[] doInBackground(Void... args) {
76                 try {
77                     return utils.verifyPattern(patternCopy, challenge, userId);
78                 } catch (RequestThrottledException ex) {
79                     mThrottleTimeout = ex.getTimeoutMs();
80                     return null;
81                 }
82             }
83 
84             @Override
85             protected void onPostExecute(byte[] result) {
86                 callback.onVerified(result, mThrottleTimeout);
87             }
88         };
89         task.execute();
90         return task;
91     }
92 
93     /**
94      * Checks a pattern asynchronously.
95      *
96      * @param utils The LockPatternUtils instance to use.
97      * @param pattern The pattern to check.
98      * @param userId The user to check against the pattern.
99      * @param callback The callback to be invoked with the check result.
100      */
checkPattern(final LockPatternUtils utils, final List<LockPatternView.Cell> pattern, final int userId, final OnCheckCallback callback)101     public static AsyncTask<?, ?, ?> checkPattern(final LockPatternUtils utils,
102             final List<LockPatternView.Cell> pattern,
103             final int userId,
104             final OnCheckCallback callback) {
105         AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
106             private int mThrottleTimeout;
107             private List<LockPatternView.Cell> patternCopy;
108 
109             @Override
110             protected void onPreExecute() {
111                 // Make a copy of the pattern to prevent race conditions.
112                 // No need to clone the individual cells because they are immutable.
113                 patternCopy = new ArrayList(pattern);
114             }
115 
116             @Override
117             protected Boolean doInBackground(Void... args) {
118                 try {
119                     return utils.checkPattern(patternCopy, userId, callback::onEarlyMatched);
120                 } catch (RequestThrottledException ex) {
121                     mThrottleTimeout = ex.getTimeoutMs();
122                     return false;
123                 }
124             }
125 
126             @Override
127             protected void onPostExecute(Boolean result) {
128                 callback.onChecked(result, mThrottleTimeout);
129             }
130         };
131         task.execute();
132         return task;
133     }
134 
135     /**
136      * Verify a password asynchronously.
137      *
138      * @param utils The LockPatternUtils instance to use.
139      * @param password The password to check.
140      * @param challenge The challenge to verify against the pattern.
141      * @param userId The user to check against the pattern.
142      * @param callback The callback to be invoked with the verification result.
143      */
verifyPassword(final LockPatternUtils utils, final String password, final long challenge, final int userId, final OnVerifyCallback callback)144     public static AsyncTask<?, ?, ?> verifyPassword(final LockPatternUtils utils,
145             final String password,
146             final long challenge,
147             final int userId,
148             final OnVerifyCallback callback) {
149         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
150             private int mThrottleTimeout;
151 
152             @Override
153             protected byte[] doInBackground(Void... args) {
154                 try {
155                     return utils.verifyPassword(password, challenge, userId);
156                 } catch (RequestThrottledException ex) {
157                     mThrottleTimeout = ex.getTimeoutMs();
158                     return null;
159                 }
160             }
161 
162             @Override
163             protected void onPostExecute(byte[] result) {
164                 callback.onVerified(result, mThrottleTimeout);
165             }
166         };
167         task.execute();
168         return task;
169     }
170 
171     /**
172      * Verify a password asynchronously.
173      *
174      * @param utils The LockPatternUtils instance to use.
175      * @param password The password to check.
176      * @param challenge The challenge to verify against the pattern.
177      * @param userId The user to check against the pattern.
178      * @param callback The callback to be invoked with the verification result.
179      */
verifyTiedProfileChallenge(final LockPatternUtils utils, final String password, final boolean isPattern, final long challenge, final int userId, final OnVerifyCallback callback)180     public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils,
181             final String password,
182             final boolean isPattern,
183             final long challenge,
184             final int userId,
185             final OnVerifyCallback callback) {
186         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
187             private int mThrottleTimeout;
188 
189             @Override
190             protected byte[] doInBackground(Void... args) {
191                 try {
192                     return utils.verifyTiedProfileChallenge(password, isPattern, challenge, userId);
193                 } catch (RequestThrottledException ex) {
194                     mThrottleTimeout = ex.getTimeoutMs();
195                     return null;
196                 }
197             }
198 
199             @Override
200             protected void onPostExecute(byte[] result) {
201                 callback.onVerified(result, mThrottleTimeout);
202             }
203         };
204         task.execute();
205         return task;
206     }
207 
208     /**
209      * Checks a password asynchronously.
210      *
211      * @param utils The LockPatternUtils instance to use.
212      * @param password The password to check.
213      * @param userId The user to check against the pattern.
214      * @param callback The callback to be invoked with the check result.
215      */
checkPassword(final LockPatternUtils utils, final String password, final int userId, final OnCheckCallback callback)216     public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils,
217             final String password,
218             final int userId,
219             final OnCheckCallback callback) {
220         AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
221             private int mThrottleTimeout;
222 
223             @Override
224             protected Boolean doInBackground(Void... args) {
225                 try {
226                     return utils.checkPassword(password, userId, callback::onEarlyMatched);
227                 } catch (RequestThrottledException ex) {
228                     mThrottleTimeout = ex.getTimeoutMs();
229                     return false;
230                 }
231             }
232 
233             @Override
234             protected void onPostExecute(Boolean result) {
235                 callback.onChecked(result, mThrottleTimeout);
236             }
237         };
238         task.execute();
239         return task;
240     }
241 }
242