Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b79b25f authored by Jatin Matani's avatar Jatin Matani Committed by Android Git Automerger
Browse files

am bf732e70: Merge "Store raw strings for personal dictionary"

* commit 'bf732e70':
  Store raw strings for personal dictionary
parents 70f0c721 bf732e70
Loading
Loading
Loading
Loading
+28 −26
Original line number Diff line number Diff line
@@ -40,9 +40,9 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -196,11 +196,10 @@ public class PersonalDictionaryLookup implements Closeable {
    private AtomicBoolean mIsClosed = new AtomicBoolean(false);

    /**
     * We store a map from a dictionary word to the set of locales it belongs
     * in. We then iterate over the set of locales to find a match using
     * LocaleUtils.
     * We store a map from a dictionary word to the set of locales & raw string(as it appears)
     * We then iterate over the set of locales to find a match using LocaleUtils.
     */
    private volatile HashMap<String, ArrayList<Locale>> mDictWords;
    private volatile HashMap<String, HashMap<Locale, String>> mDictWords;

    /**
     * We store a map from a shortcut to a word for each locale.
@@ -317,7 +316,7 @@ public class PersonalDictionaryLookup implements Closeable {
     * @return set of words that apply to the given locale.
     */
    public Set<String> getWordsForLocale(@Nonnull final Locale inputLocale) {
        final HashMap<String, ArrayList<Locale>> dictWords = mDictWords;
        final HashMap<String, HashMap<Locale, String>> dictWords = mDictWords;
        if (CollectionUtils.isNullOrEmpty(dictWords)) {
            return Collections.emptySet();
        }
@@ -325,11 +324,14 @@ public class PersonalDictionaryLookup implements Closeable {
        final Set<String> words = new HashSet<>();
        final String inputLocaleString = inputLocale.toString();
        for (String word : dictWords.keySet()) {
            for (Locale wordLocale : dictWords.get(word)) {
            HashMap<Locale, String> localeStringMap = dictWords.get(word);
                if (!CollectionUtils.isNullOrEmpty(localeStringMap)) {
                    for (Locale wordLocale : localeStringMap.keySet()) {
                        final String wordLocaleString = wordLocale.toString();
                        final int match = LocaleUtils.getMatchLevel(wordLocaleString, inputLocaleString);
                        if (LocaleUtils.isMatch(match)) {
                    words.add(word);
                            words.add(localeStringMap.get(wordLocale));
                        }
                    }
            }
        }
@@ -399,29 +401,29 @@ public class PersonalDictionaryLookup implements Closeable {
            return false;
        }

        // Atomically obtain the current copy of mDictWords;
        final HashMap<String, ArrayList<Locale>> dictWords = mDictWords;

        if (DebugFlags.DEBUG_ENABLED) {
            Log.d(mTag, "isValidWord() : Word [" + word + "] in Locale [" + inputLocale + "]");
        }
        // Atomically obtain the current copy of mDictWords;
        final HashMap<String, HashMap<Locale, String>> dictWords = mDictWords;
        // Lowercase the word using the given locale. Note, that dictionary
        // words are lowercased using their locale, and theoretically the
        // lowercasing between two matching locales may differ. For simplicity
        // we ignore that possibility.
        final String lowercased = word.toLowerCase(inputLocale);
        final ArrayList<Locale> dictLocales = dictWords.get(lowercased);
        if (null == dictLocales) {
        final HashMap<Locale, String> dictLocales = dictWords.get(lowercased);

        if (CollectionUtils.isNullOrEmpty(dictLocales)) {
            if (DebugFlags.DEBUG_ENABLED) {
                Log.d(mTag, "isValidWord() : No entry for lowercased word [" + lowercased + "]");
                Log.d(mTag, "isValidWord() : No entry for word [" + word + "]");
            }
            return false;
        } else {
            if (DebugFlags.DEBUG_ENABLED) {
                Log.d(mTag, "isValidWord() : Found entry for lowercased word [" + lowercased + "]");
                Log.d(mTag, "isValidWord() : Found entry for word [" + word + "]");
            }
            // Iterate over the locales this word is in.
            for (final Locale dictLocale : dictLocales) {
            for (final Locale dictLocale : dictLocales.keySet()) {
                final int matchLevel = LocaleUtils.getMatchLevel(dictLocale.toString(),
                        inputLocale.toString());
                if (DebugFlags.DEBUG_ENABLED) {
@@ -529,7 +531,7 @@ public class PersonalDictionaryLookup implements Closeable {
            return;
        }
        Log.i(mTag, "loadPersonalDictionary() : Start Loading");
        HashMap<String, ArrayList<Locale>> dictWords = new HashMap<>();
        HashMap<String, HashMap<Locale, String>> dictWords = new HashMap<>();
        HashMap<Locale, HashMap<String, String>> shortcutsPerLocale = new HashMap<>();
        // Load the dictionary.  Items are returned in the default sort order (by frequency).
        Cursor cursor = mResolver.query(UserDictionary.Words.CONTENT_URI,
@@ -581,21 +583,21 @@ public class PersonalDictionaryLookup implements Closeable {
                final String dictWord = rawDictWord.toLowerCase(dictLocale);
                if (DebugFlags.DEBUG_ENABLED) {
                    Log.d(mTag, "loadPersonalDictionary() : Adding word [" + dictWord
                            + "] for locale " + dictLocale);
                            + "] for locale " + dictLocale + "with value" + rawDictWord);
                }
                // Check if there is an existing entry for this word.
                ArrayList<Locale> dictLocales = dictWords.get(dictWord);
                if (null == dictLocales) {
                HashMap<Locale, String> dictLocales = dictWords.get(dictWord);
                if (CollectionUtils.isNullOrEmpty(dictLocales)) {
                    // If there is no entry for this word, create one.
                    if (DebugFlags.DEBUG_ENABLED) {
                        Log.d(mTag, "loadPersonalDictionary() : Word [" + dictWord +
                                "] not seen for other locales, creating new entry");
                    }
                    dictLocales = new ArrayList<>();
                    dictLocales = new HashMap<>();
                    dictWords.put(dictWord, dictLocales);
                }
                // Append the locale to the list of locales this word is in.
                dictLocales.add(dictLocale);
                dictLocales.put(dictLocale, rawDictWord);

                // If there is no column for a shortcut, we're done.
                final int shortcutIndex = cursor.getColumnIndex(UserDictionary.Words.SHORTCUT);
+39 −1
Original line number Diff line number Diff line
@@ -289,7 +289,8 @@ public class PersonalDictionaryLookupTest extends AndroidTestCase {
        addWord("fOo", Locale.FRENCH, 17, null);

        // Create the PersonalDictionaryLookup and wait until it's loaded.
        PersonalDictionaryLookup lookup = new PersonalDictionaryLookup(mContext, ExecutorUtils.SPELLING);
        PersonalDictionaryLookup lookup = new PersonalDictionaryLookup(mContext,
                ExecutorUtils.SPELLING);
        lookup.open();

        // Both en_CA and en_US match.
@@ -304,6 +305,43 @@ public class PersonalDictionaryLookupTest extends AndroidTestCase {
        lookup.close();
    }


    public void testCaseMatchingForWordsAndShortcuts() {
        Log.d(TAG, "testCaseMatchingForWordsAndShortcuts");
        addWord("Foo", Locale.US, 17, "f");
        addWord("bokabu", Locale.US, 17, "Bu");

        // Create the PersonalDictionaryLookup and wait until it's loaded.
        PersonalDictionaryLookup lookup = new PersonalDictionaryLookup(mContext,
                ExecutorUtils.SPELLING);
        lookup.open();

        // Valid, inspite of capitalization in US but not in other
        // locales.
        assertTrue(lookup.isValidWord("Foo", Locale.US));
        assertTrue(lookup.isValidWord("foo", Locale.US));
        assertFalse(lookup.isValidWord("Foo", Locale.UK));
        assertFalse(lookup.isValidWord("foo", Locale.UK));

        // Valid in all forms in US.
        assertTrue(lookup.isValidWord("bokabu", Locale.US));
        assertTrue(lookup.isValidWord("BOKABU", Locale.US));
        assertTrue(lookup.isValidWord("BokaBU", Locale.US));

        // Correct capitalization; sensitive to shortcut casing & locale.
        assertEquals("Foo", lookup.expandShortcut("f", Locale.US));
        assertNull(lookup.expandShortcut("f", Locale.UK));

        // Correct capitalization; sensitive to shortcut casing & locale.
        assertEquals("bokabu", lookup.expandShortcut("Bu", Locale.US));
        assertNull(lookup.expandShortcut("Bu", Locale.UK));
        assertNull(lookup.expandShortcut("bu", Locale.US));

        // Verify that raw strings are retained for #getWordsForLocale.
        verifyWordExists(lookup.getWordsForLocale(Locale.US), "Foo");
        verifyWordDoesNotExist(lookup.getWordsForLocale(Locale.US), "foo");
    }

    public void testManageListeners() {
        Log.d(TAG, "testManageListeners");