Skip to content

Commit da8b340

Browse files
Todor KalaydjievAndroid (Google) Code Review
authored andcommitted
Merge "Support auto-complete in PhoneNumberFormattingTextWatcher. Also, simplify logic. Previously, the assumption was that only a deletion or an insertion can happen at a time; but with auto-complete, a deletion and insertion happen at the same time."
2 parents f19d5f0 + 26a9225 commit da8b340

File tree

2 files changed

+86
-48
lines changed

2 files changed

+86
-48
lines changed

telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,6 @@
3939
* The formatting will be restarted once the text is cleared.
4040
*/
4141
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
42-
/**
43-
* One or more characters were removed from the end.
44-
*/
45-
private final static int STATE_REMOVE_LAST = 0;
46-
47-
/**
48-
* One or more characters were appended.
49-
*/
50-
private final static int STATE_APPEND = 1;
51-
52-
/**
53-
* One or more digits were changed in the beginning or the middle of text.
54-
*/
55-
private final static int STATE_MODIFY_DIGITS = 2;
56-
57-
/**
58-
* The changes other than the above.
59-
*/
60-
private final static int STATE_OTHER = 3;
61-
62-
/**
63-
* The state of this change could be one value of the above
64-
*/
65-
private int mState;
6642

6743
/**
6844
* Indicates the change was caused by ourselves.
@@ -97,46 +73,30 @@ public PhoneNumberFormattingTextWatcher(String countryCode) {
9773
mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
9874
}
9975

76+
@Override
10077
public void beforeTextChanged(CharSequence s, int start, int count,
10178
int after) {
10279
if (mSelfChange || mStopFormatting) {
10380
return;
10481
}
105-
if (count == 0 && s.length() == start) {
106-
// Append one or more new chars
107-
mState = STATE_APPEND;
108-
} else if (after == 0 && start + count == s.length() && count > 0) {
109-
// Remove one or more chars from the end of string.
110-
mState = STATE_REMOVE_LAST;
111-
} else if (count > 0 && !hasSeparator(s, start, count)) {
112-
// Remove the dialable chars in the begin or middle of text.
113-
mState = STATE_MODIFY_DIGITS;
114-
} else {
115-
mState = STATE_OTHER;
82+
// If the user manually deleted any non-dialable characters, stop formatting
83+
if (count > 0 && hasSeparator(s, start, count)) {
84+
stopFormatting();
11685
}
11786
}
11887

88+
@Override
11989
public void onTextChanged(CharSequence s, int start, int before, int count) {
12090
if (mSelfChange || mStopFormatting) {
12191
return;
12292
}
123-
if (mState == STATE_OTHER) {
124-
if (count > 0 && !hasSeparator(s, start, count)) {
125-
// User inserted the dialable characters in the middle of text.
126-
mState = STATE_MODIFY_DIGITS;
127-
}
128-
}
129-
// Check whether we should stop formatting.
130-
if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
131-
// User appended the non-dialable character, stop formatting.
132-
stopFormatting();
133-
} else if (mState == STATE_OTHER) {
134-
// User must insert or remove the non-dialable characters in the begin or middle of
135-
// number, stop formatting.
93+
// If the user inserted any non-dialable characters, stop formatting
94+
if (count > 0 && hasSeparator(s, start, count)) {
13695
stopFormatting();
13796
}
13897
}
13998

99+
@Override
140100
public synchronized void afterTextChanged(Editable s) {
141101
if (mStopFormatting) {
142102
// Restart the formatting when all texts were clear.

telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,17 @@ public void testRestartFormatting() {
182182

183183
public void testTextChangedByOtherTextWatcher() {
184184
final TextWatcher cleanupTextWatcher = new TextWatcher() {
185+
@Override
185186
public void afterTextChanged(Editable s) {
186187
s.clear();
187188
}
188189

190+
@Override
189191
public void beforeTextChanged(CharSequence s, int start, int count,
190192
int after) {
191193
}
192194

195+
@Override
193196
public void onTextChanged(CharSequence s, int start, int before,
194197
int count) {
195198
}
@@ -208,6 +211,81 @@ public void onTextChanged(CharSequence s, int start, int before,
208211
assertEquals(expected1, number.toString());
209212
}
210213

214+
/**
215+
* Test the case where some other component is auto-completing what the user is typing
216+
*/
217+
public void testAutoCompleteWithFormattedNumber() {
218+
String init = "650-1";
219+
String expected = "+1-650-123-4567"; // Different formatting than ours
220+
testReplacement(init, expected, expected);
221+
}
222+
223+
/**
224+
* Test the case where some other component is auto-completing what the user is typing
225+
*/
226+
public void testAutoCompleteWithFormattedNameAndNumber() {
227+
String init = "650-1";
228+
String expected = "Test User <650-123-4567>";
229+
testReplacement(init, expected, expected);
230+
}
231+
232+
/**
233+
* Test the case where some other component is auto-completing what the user is typing
234+
*/
235+
public void testAutoCompleteWithNumericNameAndNumber() {
236+
String init = "650";
237+
String expected = "2nd Test User <650-123-4567>";
238+
testReplacement(init, expected, expected);
239+
}
240+
241+
/**
242+
* Test the case where some other component is auto-completing what the user is typing
243+
*/
244+
public void testAutoCompleteWithUnformattedNumber() {
245+
String init = "650-1";
246+
String expected = "6501234567";
247+
testReplacement(init, expected, expected);
248+
}
249+
250+
/**
251+
* Test the case where some other component is auto-completing what the user is typing, where
252+
* the deleted text doesn't have any formatting and neither does the replacement text: in this
253+
* case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
254+
*/
255+
public void testAutoCompleteUnformattedWithUnformattedNumber() {
256+
String init = "650";
257+
String replacement = "6501234567";
258+
String expected = "(650) 123-4567";
259+
testReplacement(init, replacement, expected);
260+
261+
String init2 = "650";
262+
String replacement2 = "16501234567";
263+
String expected2 = "1 650-123-4567";
264+
testReplacement(init2, replacement2, expected2);
265+
}
266+
267+
/**
268+
* Helper method for testing replacing the entire string with another string
269+
* @param init The initial string
270+
* @param expected
271+
*/
272+
private void testReplacement(String init, String replacement, String expected) {
273+
TextWatcher textWatcher = getTextWatcher();
274+
275+
SpannableStringBuilder number = new SpannableStringBuilder(init);
276+
277+
// Replace entire text with the given values
278+
textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
279+
number.replace(0, init.length(), replacement, 0, replacement.length());
280+
Selection.setSelection(number, replacement.length()); // move the cursor to the end
281+
textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
282+
textWatcher.afterTextChanged(number);
283+
284+
assertEquals(expected, number.toString());
285+
// the cursor should be still at the end
286+
assertEquals(expected.length(), Selection.getSelectionEnd(number));
287+
}
288+
211289
private TextWatcher getTextWatcher() {
212290
return new PhoneNumberFormattingTextWatcher("US");
213291
}

0 commit comments

Comments
 (0)