Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.text;
     18 
     19 /**
     20  * Abstract class for filtering login-related text (user names and passwords)
     21  *
     22  */
     23 public abstract class LoginFilter implements InputFilter {
     24     private boolean mAppendInvalid;  // whether to append or ignore invalid characters
     25     /**
     26      * Base constructor for LoginFilter
     27      * @param appendInvalid whether or not to append invalid characters.
     28      */
     29     LoginFilter(boolean appendInvalid) {
     30         mAppendInvalid = appendInvalid;
     31     }
     32 
     33     /**
     34      * Default constructor for LoginFilter doesn't append invalid characters.
     35      */
     36     LoginFilter() {
     37         mAppendInvalid = false;
     38     }
     39 
     40     /**
     41      * This method is called when the buffer is going to replace the
     42      * range <code>dstart &hellip; dend</code> of <code>dest</code>
     43      * with the new text from the range <code>start &hellip; end</code>
     44      * of <code>source</code>.  Returns the CharSequence that we want
     45      * placed there instead, including an empty string
     46      * if appropriate, or <code>null</code> to accept the original
     47      * replacement.  Be careful to not to reject 0-length replacements,
     48      * as this is what happens when you delete text.
     49      */
     50     public CharSequence filter(CharSequence source, int start, int end,
     51             Spanned dest, int dstart, int dend) {
     52         onStart();
     53 
     54         // Scan through beginning characters in dest, calling onInvalidCharacter()
     55         // for each invalid character.
     56         for (int i = 0; i < dstart; i++) {
     57             char c = dest.charAt(i);
     58             if (!isAllowed(c)) onInvalidCharacter(c);
     59         }
     60 
     61         // Scan through changed characters rejecting disallowed chars
     62         SpannableStringBuilder modification = null;
     63         int modoff = 0;
     64 
     65         for (int i = start; i < end; i++) {
     66             char c = source.charAt(i);
     67             if (isAllowed(c)) {
     68                 // Character allowed.
     69                 modoff++;
     70             } else {
     71                 if (mAppendInvalid) {
     72                     modoff++;
     73                 } else {
     74                     if (modification == null) {
     75                         modification = new SpannableStringBuilder(source, start, end);
     76                         modoff = i - start;
     77                     }
     78 
     79                     modification.delete(modoff, modoff + 1);
     80                 }
     81 
     82                 onInvalidCharacter(c);
     83             }
     84         }
     85 
     86         // Scan through remaining characters in dest, calling onInvalidCharacter()
     87         // for each invalid character.
     88         for (int i = dend; i < dest.length(); i++) {
     89             char c = dest.charAt(i);
     90             if (!isAllowed(c)) onInvalidCharacter(c);
     91         }
     92 
     93         onStop();
     94 
     95         // Either returns null if we made no changes,
     96         // or what we wanted to change it to if there were changes.
     97         return modification;
     98     }
     99 
    100     /**
    101      * Called when we start processing filter.
    102      */
    103     public void onStart() {
    104 
    105     }
    106 
    107     /**
    108      * Called whenever we encounter an invalid character.
    109      * @param c the invalid character
    110      */
    111     public void onInvalidCharacter(char c) {
    112 
    113     }
    114 
    115     /**
    116      * Called when we're done processing filter
    117      */
    118     public void onStop() {
    119 
    120     }
    121 
    122     /**
    123      * Returns whether or not we allow character c.
    124      * Subclasses must override this method.
    125      */
    126     public abstract boolean isAllowed(char c);
    127 
    128     /**
    129      * This filter rejects characters in the user name that are not compatible with GMail
    130      * account creation. It prevents the user from entering user names with characters other than
    131      * [a-zA-Z0-9.].
    132      *
    133      */
    134     public static class UsernameFilterGMail extends LoginFilter {
    135 
    136         public UsernameFilterGMail() {
    137             super(false);
    138         }
    139 
    140         public UsernameFilterGMail(boolean appendInvalid) {
    141             super(appendInvalid);
    142         }
    143 
    144         @Override
    145         public boolean isAllowed(char c) {
    146             // Allow [a-zA-Z0-9@.]
    147             if ('0' <= c && c <= '9')
    148                 return true;
    149             if ('a' <= c && c <= 'z')
    150                 return true;
    151             if ('A' <= c && c <= 'Z')
    152                 return true;
    153             if ('.' == c)
    154                 return true;
    155             return false;
    156         }
    157     }
    158 
    159     /**
    160      * This filter rejects characters in the user name that are not compatible with Google login.
    161      * It is slightly less restrictive than the above filter in that it allows [a-zA-Z0-9._-+].
    162      *
    163      */
    164     public static class UsernameFilterGeneric extends LoginFilter {
    165         private static final String mAllowed = "@_-+."; // Additional characters
    166 
    167         public UsernameFilterGeneric() {
    168             super(false);
    169         }
    170 
    171         public UsernameFilterGeneric(boolean appendInvalid) {
    172             super(appendInvalid);
    173         }
    174 
    175         @Override
    176         public boolean isAllowed(char c) {
    177             // Allow [a-zA-Z0-9@.]
    178             if ('0' <= c && c <= '9')
    179                 return true;
    180             if ('a' <= c && c <= 'z')
    181                 return true;
    182             if ('A' <= c && c <= 'Z')
    183                 return true;
    184             if (mAllowed.indexOf(c) != -1)
    185                 return true;
    186             return false;
    187         }
    188     }
    189 
    190     /**
    191      * This filter is compatible with GMail passwords which restricts characters to
    192      * the Latin-1 (ISO8859-1) char set.
    193      *
    194      */
    195     public static class PasswordFilterGMail extends LoginFilter {
    196 
    197         public PasswordFilterGMail() {
    198             super(false);
    199         }
    200 
    201         public PasswordFilterGMail(boolean appendInvalid) {
    202             super(appendInvalid);
    203         }
    204 
    205         // We should reject anything not in the Latin-1 (ISO8859-1) charset
    206         @Override
    207         public boolean isAllowed(char c) {
    208             if (32 <= c && c <= 127)
    209                 return true; // standard charset
    210             // if (128 <= c && c <= 159) return true;  // nonstandard (Windows(TM)(R)) charset
    211             if (160 <= c && c <= 255)
    212                 return true; // extended charset
    213             return false;
    214         }
    215     }
    216 }
    217