From 697fa0977ea1d4569064c434bb86e9b9fbfc4b12 Mon Sep 17 00:00:00 2001 From: Yorke Lee Date: Wed, 5 Dec 2012 11:48:58 -0800 Subject: Enable initial matching for Smart Dialling Allow the name matcher function used by smart dialling to perform initial matches of the variety 57 - (J)ohn (S)mith Refactor SmartDialNameMatcher testing method to allow checking multiple match positions. Add tests for initial matches Change-Id: Iadc5e3e8b2f408136c704015d2297e9b520e1065 --- .../dialer/dialpad/SmartDialNameMatcher.java | 42 ++++++++++++++++++++++ .../dialer/dialpad/SmartDialNameMatcherTest.java | 25 +++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java index 53f564275..6f0f35423 100644 --- a/src/com/android/dialer/dialpad/SmartDialNameMatcher.java +++ b/src/com/android/dialer/dialpad/SmartDialNameMatcher.java @@ -44,6 +44,13 @@ public class SmartDialNameMatcher { '9', '9', '9', '9' // W,X,Y,Z -> 9 }; + // Whether or not we allow matches like 57 - (J)ohn (S)mith + private static final boolean ALLOW_INITIAL_MATCH = true; + + // The maximum length of the initial we will match - typically set to 1 to minimize false + // positives + private static final int INITIAL_LENGTH_LIMIT = 1; + /* * The switch statement in this function was generated using the python code: * from unidecode import unidecode @@ -511,6 +518,34 @@ public class SmartDialNameMatcher { matchList.add(new SmartDialMatchPosition( tokenStart, queryLength + tokenStart + seperatorCount)); return true; + } else if (ALLOW_INITIAL_MATCH && queryStart < INITIAL_LENGTH_LIMIT) { + // we matched the first character. + // branch off and see if we can find another match with the remaining + // characters in the query string and the remaining tokens + //find the next space in the query string + int j = nameStart; + while (j < nameLength && displayName.charAt(j) != ' ') { + j++; + } + // this means there is at least one character left after the space + if (j < nameLength - 1) { + final String remainder = displayName.substring(j + 1); + final ArrayList partialTemp = + Lists.newArrayList(); + if (matchesCombination( + remainder, query.substring(queryStart + 1), partialTemp)) { + + // store the list of possible match positions + SmartDialMatchPosition.advanceMatchPositions(partialTemp, j + 1); + partialTemp.add(0, + new SmartDialMatchPosition(nameStart, nameStart + 1)); + + // we found a partial token match, store the data in a + // temp buffer and return it if we end up not finding a full + // token match + partial = partialTemp; + } + } } nameStart++; queryStart++; @@ -532,6 +567,13 @@ public class SmartDialNameMatcher { } } } + // if we have no complete match at this point, then we attempt to fall back to the partial + // token match(if any). If we don't allow initial matching (ALLOW_INITIAL_MATCH = false) + // then partial will always be empty. + if (!partial.isEmpty()) { + matchList.addAll(partial); + return true; + } return false; } diff --git a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java index 492e5b422..8b7ee03f6 100644 --- a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java +++ b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java @@ -66,6 +66,20 @@ public class SmartDialNameMatcherTest extends TestCase { checkMatches("William J Smith", "6576", false, 0, 0); } + + public void testMatches_Initial() { + // wjs matches (W)illiam (J)ohn (S)mith + checkMatches("William John Smith", "957", true, 0, 1, 8, 9, 13, 14); + // wjsmit matches (W)illiam (J)ohn (Smit)h + checkMatches("William John Smith", "957648", true, 0, 1, 8, 9, 13, 17); + // wjohn matches (W)illiam (John) Smith + checkMatches("William John Smith", "95646", true, 0, 1, 8, 12); + // jsmi matches William (J)ohn (Smi)th + checkMatches("William John Smith", "5764", true, 8, 9, 13, 16); + // make sure multiple spaces don't mess things up + checkMatches("William John Smith", "5764", true, 15, 16, 22, 25); + } + // TODO: Do we want to make these pass anymore? @Suppress public void testMatches_repeatedSeparators() { @@ -102,7 +116,7 @@ public class SmartDialNameMatcherTest extends TestCase { } private void checkMatches(String displayName, String query, boolean expectedMatches, - int expectedMatchStart, int expectedMatchEnd) { + int... expectedMatchPositions) { final SmartDialNameMatcher matcher = new SmartDialNameMatcher(query); final ArrayList matchPositions = new ArrayList(); @@ -115,9 +129,14 @@ public class SmartDialNameMatcherTest extends TestCase { + " nfkc=" + Normalizer.normalize(displayName, Normalizer.Form.NFKC) + " matches=" + matches); assertEquals("matches", expectedMatches, matches); + final int length = expectedMatchPositions.length; + assertEquals(length % 2, 0); if (matches) { - assertEquals("start", expectedMatchStart, matchPositions.get(0).start); - assertEquals("end", expectedMatchEnd, matchPositions.get(0).end); + for (int i = 0; i < length/2; i++) { + assertEquals("start", expectedMatchPositions[i * 2], matchPositions.get(i).start); + assertEquals("end", expectedMatchPositions[i * 2 + 1], matchPositions.get(i).end); + } } } + } -- cgit v1.2.3