LoginFilter.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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 17package android.text; 18 19/** 20 * Abstract class for filtering login-related text (user names and passwords) 21 * 22 */ 23public 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 … dend</code> of <code>dest</code> 43 * with the new text from the range <code>start … 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 char[] out = new char[end - start]; // reserve enough space for whole string 53 int outidx = 0; 54 boolean changed = false; 55 56 onStart(); 57 58 // Scan through beginning characters in dest, calling onInvalidCharacter() 59 // for each invalid character. 60 for (int i = 0; i < dstart; i++) { 61 char c = dest.charAt(i); 62 if (!isAllowed(c)) onInvalidCharacter(c); 63 } 64 65 // Scan through changed characters rejecting disallowed chars 66 for (int i = start; i < end; i++) { 67 char c = source.charAt(i); 68 if (isAllowed(c)) { 69 // Character allowed. Add it to the sequence. 70 out[outidx++] = c; 71 } else { 72 if (mAppendInvalid) out[outidx++] = c; 73 else changed = true; // we changed the original string 74 onInvalidCharacter(c); 75 } 76 } 77 78 // Scan through remaining characters in dest, calling onInvalidCharacter() 79 // for each invalid character. 80 for (int i = dend; i < dest.length(); i++) { 81 char c = dest.charAt(i); 82 if (!isAllowed(c)) onInvalidCharacter(c); 83 } 84 85 onStop(); 86 87 if (!changed) { 88 return null; 89 } 90 91 String s = new String(out, 0, outidx); 92 93 if (source instanceof Spanned) { 94 SpannableString sp = new SpannableString(s); 95 TextUtils.copySpansFrom((Spanned) source, 96 start, end, null, sp, 0); 97 return sp; 98 } else { 99 return s; 100 } 101 } 102 103 /** 104 * Called when we start processing filter. 105 */ 106 public void onStart() { 107 108 } 109 110 /** 111 * Called whenever we encounter an invalid character. 112 * @param c the invalid character 113 */ 114 public void onInvalidCharacter(char c) { 115 116 } 117 118 /** 119 * Called when we're done processing filter 120 */ 121 public void onStop() { 122 123 } 124 125 /** 126 * Returns whether or not we allow character c. 127 * Subclasses must override this method. 128 */ 129 public abstract boolean isAllowed(char c); 130 131 /** 132 * This filter rejects characters in the user name that are not compatible with GMail 133 * account creation. It prevents the user from entering user names with characters other than 134 * [a-zA-Z0-9.]. 135 * 136 */ 137 public static class UsernameFilterGMail extends LoginFilter { 138 139 public UsernameFilterGMail() { 140 super(false); 141 } 142 143 public UsernameFilterGMail(boolean appendInvalid) { 144 super(appendInvalid); 145 } 146 147 @Override 148 public boolean isAllowed(char c) { 149 // Allow [a-zA-Z0-9@.] 150 if ('0' <= c && c <= '9') 151 return true; 152 if ('a' <= c && c <= 'z') 153 return true; 154 if ('A' <= c && c <= 'Z') 155 return true; 156 if ('.' == c) 157 return true; 158 return false; 159 } 160 } 161 162 /** 163 * This filter rejects characters in the user name that are not compatible with Google login. 164 * It is slightly less restrictive than the above filter in that it allows [a-zA-Z0-9._-]. 165 * 166 */ 167 public static class UsernameFilterGeneric extends LoginFilter { 168 private static final String mAllowed = "@_-."; // Additional characters 169 170 public UsernameFilterGeneric() { 171 super(false); 172 } 173 174 public UsernameFilterGeneric(boolean appendInvalid) { 175 super(appendInvalid); 176 } 177 178 @Override 179 public boolean isAllowed(char c) { 180 // Allow [a-zA-Z0-9@.] 181 if ('0' <= c && c <= '9') 182 return true; 183 if ('a' <= c && c <= 'z') 184 return true; 185 if ('A' <= c && c <= 'Z') 186 return true; 187 if (mAllowed.indexOf(c) != -1) 188 return true; 189 return false; 190 } 191 } 192 193 /** 194 * This filter is compatible with GMail passwords which restricts characters to 195 * the Latin-1 (ISO8859-1) char set. 196 * 197 */ 198 public static class PasswordFilterGMail extends LoginFilter { 199 200 public PasswordFilterGMail() { 201 super(false); 202 } 203 204 public PasswordFilterGMail(boolean appendInvalid) { 205 super(appendInvalid); 206 } 207 208 // We should reject anything not in the Latin-1 (ISO8859-1) charset 209 @Override 210 public boolean isAllowed(char c) { 211 if (32 <= c && c <= 127) 212 return true; // standard charset 213 // if (128 <= c && c <= 159) return true; // nonstandard (Windows(TM)(R)) charset 214 if (160 <= c && c <= 255) 215 return true; // extended charset 216 return false; 217 } 218 } 219} 220