summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoremancebo <emancebo@cyngn.com>2014-07-25 17:37:28 -0700
committerEd Mancebo <emancebo@cyngn.com>2015-01-06 21:41:26 +0000
commit86c9b695c49037c031a47637fa975136555c6287 (patch)
tree417eb43fe8d2c27cc658395868a3fbaf6d03ff48
parent1f62ee2c3335c501c42aa5060b56efdbd9681534 (diff)
downloadandroid_packages_apps_Dialer-86c9b695c49037c031a47637fa975136555c6287.tar.gz
android_packages_apps_Dialer-86c9b695c49037c031a47637fa975136555c6287.tar.bz2
android_packages_apps_Dialer-86c9b695c49037c031a47637fa975136555c6287.zip
Return match positions to enable highlighting for CN smart dial
Change-Id: I9255c582708c2fbfe22e7a2bf3ad971da692e2a9
-rw-r--r--src/com/android/dialer/dialpad/ChineseSmartDialMap.java61
-rw-r--r--src/com/android/dialer/dialpad/SmartDialPrefix.java6
-rw-r--r--tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java35
3 files changed, 88 insertions, 14 deletions
diff --git a/src/com/android/dialer/dialpad/ChineseSmartDialMap.java b/src/com/android/dialer/dialpad/ChineseSmartDialMap.java
index 3e2c13cca..5e63f8857 100644
--- a/src/com/android/dialer/dialpad/ChineseSmartDialMap.java
+++ b/src/com/android/dialer/dialpad/ChineseSmartDialMap.java
@@ -5,6 +5,8 @@ import com.android.providers.contacts.HanziToPinyin;
import android.text.TextUtils;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
public class ChineseSmartDialMap implements SmartDialMap {
@@ -439,28 +441,63 @@ public class ChineseSmartDialMap implements SmartDialMap {
}
/*
- * Since the dialpad is matching off the generated pinyin, the
- * Chinese characters can't be highlighted. Just return true if
- * there is a match without highlighting a character position.
+ * Uses the default matching logic on the pinyin name and attempts to map the match positions
+ * back to the original display name
*/
@Override
public boolean matchesCombination(SmartDialNameMatcher smartDialNameMatcher,
String displayName, String query, ArrayList<SmartDialMatchPosition> matchList) {
+
String pinyinName = tokenizeToPinyins(displayName);
- if (displayName.equals(pinyinName)) {
- return smartDialNameMatcher.matchesCombination(displayName, query, matchList);
- }
- final int nameLength = pinyinName.length();
- final int queryLength = query.length();
- if (nameLength < queryLength) {
+ ArrayList<SmartDialMatchPosition> computedMatchList = new ArrayList<SmartDialMatchPosition>();
+ boolean matches = smartDialNameMatcher.matchesCombination(pinyinName, query, computedMatchList);
+ if (!matches)
return false;
- }
- if (queryLength == 0) {
- return false;
+ // name was translated to pinyin before matching. attempt to map the match positions
+ // back to the original display string
+ if (!displayName.equals(pinyinName)) {
+
+ // construct an array that maps each character of the pinyin name back to the index of
+ // the hanzi token from which it came
+ // For example, if:
+ // displayName = 红霞李
+ // pinyinName = "hong xia li"
+ // then:
+ // pinyinMapping = 0,0,0,0,-1,1,1,1,-1,2,2
+ int[] pinyinMapping = new int[pinyinName.length()];
+ int curToken = 0;
+ for (int i=0; i < pinyinName.length(); ++i) {
+ char c = pinyinName.charAt(i);
+ if (c == ' ') {
+ ++curToken;
+ pinyinMapping[i] = -1;
+ }
+ else {
+ pinyinMapping[i] = curToken;
+ }
+ }
+
+ // calculate unique hanzi characters that are matched
+ Set<Integer> positionsToHighlight = new HashSet<Integer>();
+ for (SmartDialMatchPosition matchPosition : computedMatchList) {
+ for (int pos = matchPosition.start; pos < matchPosition.end; ++pos) {
+ int mappedPos = pinyinMapping[pos];
+ if (mappedPos >= 0)
+ positionsToHighlight.add(mappedPos);
+ }
+ }
+
+ // reset computed matches
+ computedMatchList = new ArrayList<SmartDialMatchPosition>();
+ for (int matchPos : positionsToHighlight) {
+ // use one object per position for simplicity
+ computedMatchList.add(new SmartDialMatchPosition(matchPos, matchPos+1));
+ }
}
+ matchList.addAll(computedMatchList);
return true;
}
diff --git a/src/com/android/dialer/dialpad/SmartDialPrefix.java b/src/com/android/dialer/dialpad/SmartDialPrefix.java
index e80e133e3..1026ebb60 100644
--- a/src/com/android/dialer/dialpad/SmartDialPrefix.java
+++ b/src/com/android/dialer/dialpad/SmartDialPrefix.java
@@ -127,6 +127,12 @@ public class SmartDialPrefix {
sNanpInitialized = true;
}
+ // for testing only
+ @VisibleForTesting
+ static void setSmartDialMap(SmartDialMap map) {
+ mMap = map;
+ }
+
/**
* Explicitly setting the user Nanp to the given boolean
*/
diff --git a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
index b0dc91d2c..0c910670c 100644
--- a/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
+++ b/tests/src/com/android/dialer/dialpad/SmartDialNameMatcherTest.java
@@ -33,6 +33,12 @@ import junit.framework.TestCase;
public class SmartDialNameMatcherTest extends AndroidTestCase {
private static final String TAG = "SmartDialNameMatcherTest";
+ @Override
+ public void setUp() {
+ SmartDialPrefix.setSmartDialMap(new LatinSmartDialMap());
+ SmartDialPrefix.setUserInNanpRegion(true);
+ }
+
public void testMatches() {
// Test to ensure that all alphabetic characters are covered
checkMatches("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
@@ -162,6 +168,30 @@ public class SmartDialNameMatcherTest extends AndroidTestCase {
fail("Cyrillic letters aren't supported yet.");
}
+ public void testMatches_chinese() {
+ SmartDialPrefix.setSmartDialMap(new ChineseSmartDialMap());
+
+ // basic cases
+ checkMatches("红霞李", "46", true, 0, 1);
+ checkMatches("红霞李", "46649", true, 0, 1, 1, 2);
+ checkMatches("红霞李", "5", true, 2, 3);
+ checkMatches("红霞李", "466494254", true, 0, 1, 1, 2, 2, 3);
+
+ // test with spaces
+ checkMatches("红霞 李", "466494254", true, 0, 1, 1, 2, 2, 3);
+ checkMatches(" 红 霞 李", "466494254", true, 0, 1, 1, 2, 2, 3);
+
+ // when character sets are mixed, match english only
+ checkMatches("Hongxia 李", "46", true, 0, 2);
+ checkMatches("Hongxia 李", "5", false);
+
+ // make sure regular english cases still work
+ checkMatches("Meow Face", "63", true, 0, 2);
+ checkMatches("Meow Face", "32", true, 5, 7);
+ checkMatches("Meow Face", "632", true, 0, 1, 5, 7);
+
+ SmartDialPrefix.setSmartDialMap(new LatinSmartDialMap());
+ }
public void testMatches_NumberBasic() {
// Simple basic examples that start the match from the start of the number
@@ -199,6 +229,7 @@ public class SmartDialNameMatcherTest extends AndroidTestCase {
public void testMatches_NumberNANP() {
SmartDialPrefix.setUserInNanpRegion(true);
+
// An 11 digit number prefixed with 1 should be matched by the 10 digit number, as well as
// the 7 digit number (without area code)
checkMatchesNumber("1-510-333-7596", "5103337596", true, true, 2, 14);
@@ -253,8 +284,8 @@ public class SmartDialNameMatcherTest extends AndroidTestCase {
final SmartDialNameMatcher matcher = new SmartDialNameMatcher(query, getContext());
final ArrayList<SmartDialMatchPosition> matchPositions =
new ArrayList<SmartDialMatchPosition>();
- final boolean matches = matcher.matchesCombination(
- displayName, query, matchPositions);
+ final boolean matches =
+ SmartDialPrefix.getMap().matchesCombination(matcher, displayName, query, matchPositions);
Log.d(TAG, "query=" + query + " text=" + displayName
+ " nfd=" + Normalizer.normalize(displayName, Normalizer.Form.NFD)
+ " nfc=" + Normalizer.normalize(displayName, Normalizer.Form.NFC)