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