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 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