Home | History | Annotate | Download | only in widget
      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          */
     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          */
     32         void onChecked(boolean matched, int throttleTimeoutMs);
     33 
     34         /**
     35          * Called when the underlying AsyncTask was cancelled.
     36          */
     37         default void onCancelled() {}
     38     }
     39 
     40     /**
     41      * Interface for a callback to be invoked after security verification.
     42      */
     43     public interface OnVerifyCallback {
     44         /**
     45          * Invoked when a security verification is finished.
     46          *
     47          * @param attestation The attestation that the challenge was verified, or null.
     48          * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
     49          * the call. Only non-0 if attestation is null.
     50          */
     51         void onVerified(byte[] attestation, int throttleTimeoutMs);
     52     }
     53 
     54     /**
     55      * Verify a pattern asynchronously.
     56      *
     57      * @param utils The LockPatternUtils instance to use.
     58      * @param pattern The pattern to check.
     59      * @param challenge The challenge to verify against the pattern.
     60      * @param userId The user to check against the pattern.
     61      * @param callback The callback to be invoked with the verification result.
     62      */
     63     public static AsyncTask<?, ?, ?> verifyPattern(final LockPatternUtils utils,
     64             final List<LockPatternView.Cell> pattern,
     65             final long challenge,
     66             final int userId,
     67             final OnVerifyCallback callback) {
     68         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
     69             private int mThrottleTimeout;
     70             private List<LockPatternView.Cell> patternCopy;
     71 
     72             @Override
     73             protected void onPreExecute() {
     74                 // Make a copy of the pattern to prevent race conditions.
     75                 // No need to clone the individual cells because they are immutable.
     76                 patternCopy = new ArrayList(pattern);
     77             }
     78 
     79             @Override
     80             protected byte[] doInBackground(Void... args) {
     81                 try {
     82                     return utils.verifyPattern(patternCopy, challenge, userId);
     83                 } catch (RequestThrottledException ex) {
     84                     mThrottleTimeout = ex.getTimeoutMs();
     85                     return null;
     86                 }
     87             }
     88 
     89             @Override
     90             protected void onPostExecute(byte[] result) {
     91                 callback.onVerified(result, mThrottleTimeout);
     92             }
     93         };
     94         task.execute();
     95         return task;
     96     }
     97 
     98     /**
     99      * Checks a pattern asynchronously.
    100      *
    101      * @param utils The LockPatternUtils instance to use.
    102      * @param pattern The pattern to check.
    103      * @param userId The user to check against the pattern.
    104      * @param callback The callback to be invoked with the check result.
    105      */
    106     public static AsyncTask<?, ?, ?> checkPattern(final LockPatternUtils utils,
    107             final List<LockPatternView.Cell> pattern,
    108             final int userId,
    109             final OnCheckCallback callback) {
    110         AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
    111             private int mThrottleTimeout;
    112             private List<LockPatternView.Cell> patternCopy;
    113 
    114             @Override
    115             protected void onPreExecute() {
    116                 // Make a copy of the pattern to prevent race conditions.
    117                 // No need to clone the individual cells because they are immutable.
    118                 patternCopy = new ArrayList(pattern);
    119             }
    120 
    121             @Override
    122             protected Boolean doInBackground(Void... args) {
    123                 try {
    124                     return utils.checkPattern(patternCopy, userId, callback::onEarlyMatched);
    125                 } catch (RequestThrottledException ex) {
    126                     mThrottleTimeout = ex.getTimeoutMs();
    127                     return false;
    128                 }
    129             }
    130 
    131             @Override
    132             protected void onPostExecute(Boolean result) {
    133                 callback.onChecked(result, mThrottleTimeout);
    134             }
    135 
    136             @Override
    137             protected void onCancelled() {
    138                 callback.onCancelled();
    139             }
    140         };
    141         task.execute();
    142         return task;
    143     }
    144 
    145     /**
    146      * Verify a password asynchronously.
    147      *
    148      * @param utils The LockPatternUtils instance to use.
    149      * @param password The password to check.
    150      * @param challenge The challenge to verify against the pattern.
    151      * @param userId The user to check against the pattern.
    152      * @param callback The callback to be invoked with the verification result.
    153      */
    154     public static AsyncTask<?, ?, ?> verifyPassword(final LockPatternUtils utils,
    155             final String password,
    156             final long challenge,
    157             final int userId,
    158             final OnVerifyCallback callback) {
    159         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
    160             private int mThrottleTimeout;
    161 
    162             @Override
    163             protected byte[] doInBackground(Void... args) {
    164                 try {
    165                     return utils.verifyPassword(password, challenge, userId);
    166                 } catch (RequestThrottledException ex) {
    167                     mThrottleTimeout = ex.getTimeoutMs();
    168                     return null;
    169                 }
    170             }
    171 
    172             @Override
    173             protected void onPostExecute(byte[] result) {
    174                 callback.onVerified(result, mThrottleTimeout);
    175             }
    176         };
    177         task.execute();
    178         return task;
    179     }
    180 
    181     /**
    182      * Verify a password asynchronously.
    183      *
    184      * @param utils The LockPatternUtils instance to use.
    185      * @param password The password to check.
    186      * @param challenge The challenge to verify against the pattern.
    187      * @param userId The user to check against the pattern.
    188      * @param callback The callback to be invoked with the verification result.
    189      */
    190     public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils,
    191             final String password,
    192             final boolean isPattern,
    193             final long challenge,
    194             final int userId,
    195             final OnVerifyCallback callback) {
    196         AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
    197             private int mThrottleTimeout;
    198 
    199             @Override
    200             protected byte[] doInBackground(Void... args) {
    201                 try {
    202                     return utils.verifyTiedProfileChallenge(password, isPattern, challenge, userId);
    203                 } catch (RequestThrottledException ex) {
    204                     mThrottleTimeout = ex.getTimeoutMs();
    205                     return null;
    206                 }
    207             }
    208 
    209             @Override
    210             protected void onPostExecute(byte[] result) {
    211                 callback.onVerified(result, mThrottleTimeout);
    212             }
    213         };
    214         task.execute();
    215         return task;
    216     }
    217 
    218     /**
    219      * Checks a password asynchronously.
    220      *
    221      * @param utils The LockPatternUtils instance to use.
    222      * @param password The password to check.
    223      * @param userId The user to check against the pattern.
    224      * @param callback The callback to be invoked with the check result.
    225      */
    226     public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils,
    227             final String password,
    228             final int userId,
    229             final OnCheckCallback callback) {
    230         AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
    231             private int mThrottleTimeout;
    232 
    233             @Override
    234             protected Boolean doInBackground(Void... args) {
    235                 try {
    236                     return utils.checkPassword(password, userId, callback::onEarlyMatched);
    237                 } catch (RequestThrottledException ex) {
    238                     mThrottleTimeout = ex.getTimeoutMs();
    239                     return false;
    240                 }
    241             }
    242 
    243             @Override
    244             protected void onPostExecute(Boolean result) {
    245                 callback.onChecked(result, mThrottleTimeout);
    246             }
    247 
    248             @Override
    249             protected void onCancelled() {
    250                 callback.onCancelled();
    251             }
    252         };
    253         task.execute();
    254         return task;
    255     }
    256 }
    257