1 package com.android.internal.widget; 2 3 import android.os.AsyncTask; 4 5 import com.android.internal.widget.LockPatternUtils.RequestThrottledException; 6 7 /** 8 * Helper class to check/verify PIN/Password/Pattern asynchronously. 9 */ 10 public final class LockPatternChecker { 11 /** 12 * Interface for a callback to be invoked after security check. 13 */ 14 public interface OnCheckCallback { 15 16 /** 17 * Invoked as soon as possible we know that the credentials match. This will be called 18 * earlier than {@link #onChecked} but only if the credentials match. 19 */ onEarlyMatched()20 default void onEarlyMatched() {} 21 22 /** 23 * Invoked when a security check is finished. 24 * 25 * @param matched Whether the PIN/Password/Pattern matches the stored one. 26 * @param throttleTimeoutMs The amount of time in ms to wait before reattempting 27 * the call. Only non-0 if matched is false. 28 */ onChecked(boolean matched, int throttleTimeoutMs)29 void onChecked(boolean matched, int throttleTimeoutMs); 30 31 /** 32 * Called when the underlying AsyncTask was cancelled. 33 */ onCancelled()34 default void onCancelled() {} 35 } 36 37 /** 38 * Interface for a callback to be invoked after security verification. 39 */ 40 public interface OnVerifyCallback { 41 /** 42 * Invoked when a security verification is finished. 43 * 44 * @param attestation The attestation that the challenge was verified, or null. 45 * @param throttleTimeoutMs The amount of time in ms to wait before reattempting 46 * the call. Only non-0 if attestation is null. 47 */ onVerified(byte[] attestation, int throttleTimeoutMs)48 void onVerified(byte[] attestation, int throttleTimeoutMs); 49 } 50 51 /** 52 * Verify a lockscreen credential asynchronously. 53 * 54 * @param utils The LockPatternUtils instance to use. 55 * @param credential The credential to check. 56 * @param challenge The challenge to verify against the credential. 57 * @param userId The user to check against the credential. 58 * @param callback The callback to be invoked with the verification result. 59 */ verifyCredential(final LockPatternUtils utils, final LockscreenCredential credential, final long challenge, final int userId, final OnVerifyCallback callback)60 public static AsyncTask<?, ?, ?> verifyCredential(final LockPatternUtils utils, 61 final LockscreenCredential credential, 62 final long challenge, 63 final int userId, 64 final OnVerifyCallback callback) { 65 // Create a copy of the credential since checking credential is asynchrounous. 66 final LockscreenCredential credentialCopy = credential.duplicate(); 67 AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() { 68 private int mThrottleTimeout; 69 70 @Override 71 protected byte[] doInBackground(Void... args) { 72 try { 73 return utils.verifyCredential(credentialCopy, challenge, userId); 74 } catch (RequestThrottledException ex) { 75 mThrottleTimeout = ex.getTimeoutMs(); 76 return null; 77 } 78 } 79 80 @Override 81 protected void onPostExecute(byte[] result) { 82 callback.onVerified(result, mThrottleTimeout); 83 credentialCopy.zeroize(); 84 } 85 86 @Override 87 protected void onCancelled() { 88 credentialCopy.zeroize(); 89 } 90 }; 91 task.execute(); 92 return task; 93 } 94 95 /** 96 * Checks a lockscreen credential asynchronously. 97 * 98 * @param utils The LockPatternUtils instance to use. 99 * @param credential The credential to check. 100 * @param userId The user to check against the credential. 101 * @param callback The callback to be invoked with the check result. 102 */ checkCredential(final LockPatternUtils utils, final LockscreenCredential credential, final int userId, final OnCheckCallback callback)103 public static AsyncTask<?, ?, ?> checkCredential(final LockPatternUtils utils, 104 final LockscreenCredential credential, 105 final int userId, 106 final OnCheckCallback callback) { 107 // Create a copy of the credential since checking credential is asynchrounous. 108 final LockscreenCredential credentialCopy = credential.duplicate(); 109 AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() { 110 private int mThrottleTimeout; 111 112 @Override 113 protected Boolean doInBackground(Void... args) { 114 try { 115 return utils.checkCredential(credentialCopy, userId, callback::onEarlyMatched); 116 } catch (RequestThrottledException ex) { 117 mThrottleTimeout = ex.getTimeoutMs(); 118 return false; 119 } 120 } 121 122 @Override 123 protected void onPostExecute(Boolean result) { 124 callback.onChecked(result, mThrottleTimeout); 125 credentialCopy.zeroize(); 126 } 127 128 @Override 129 protected void onCancelled() { 130 callback.onCancelled(); 131 credentialCopy.zeroize(); 132 } 133 }; 134 task.execute(); 135 return task; 136 } 137 138 /** 139 * Perform a lockscreen credential verification explicitly on a managed profile with unified 140 * challenge, using the parent user's credential. 141 * 142 * @param utils The LockPatternUtils instance to use. 143 * @param credential The credential to check. 144 * @param challenge The challenge to verify against the credential. 145 * @param userId The user to check against the credential. 146 * @param callback The callback to be invoked with the verification result. 147 */ verifyTiedProfileChallenge(final LockPatternUtils utils, final LockscreenCredential credential, final long challenge, final int userId, final OnVerifyCallback callback)148 public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils, 149 final LockscreenCredential credential, 150 final long challenge, 151 final int userId, 152 final OnVerifyCallback callback) { 153 // Create a copy of the credential since checking credential is asynchrounous. 154 final LockscreenCredential credentialCopy = credential.duplicate(); 155 AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() { 156 private int mThrottleTimeout; 157 158 @Override 159 protected byte[] doInBackground(Void... args) { 160 try { 161 return utils.verifyTiedProfileChallenge(credentialCopy, challenge, userId); 162 } catch (RequestThrottledException ex) { 163 mThrottleTimeout = ex.getTimeoutMs(); 164 return null; 165 } 166 } 167 168 @Override 169 protected void onPostExecute(byte[] result) { 170 callback.onVerified(result, mThrottleTimeout); 171 credentialCopy.zeroize(); 172 } 173 174 @Override 175 protected void onCancelled() { 176 credentialCopy.zeroize(); 177 } 178 }; 179 task.execute(); 180 return task; 181 } 182 } 183