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