Loading java/src/com/android/inputmethod/latin/AutoDictionary.java +4 −10 Original line number Diff line number Diff line Loading @@ -96,11 +96,14 @@ public class AutoDictionary extends ExpandableDictionary { return frequency >= VALIDITY_THRESHOLD; } @Override public void close() { mOpenHelper.close(); super.close(); } private void loadDictionary() { @Override public void loadDictionaryAsync() { // Load the words that correspond to the current input locale Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale }); if (cursor.moveToFirst()) { Loading Loading @@ -183,15 +186,6 @@ public class AutoDictionary extends ExpandableDictionary { return c; } private boolean insert(ContentValues values) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(AUTODICT_TABLE_NAME, Words.WORD, values); if (rowId > 0) { return true; } return false; } private int delete(String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count = db.delete(AUTODICT_TABLE_NAME, where, whereArgs); Loading java/src/com/android/inputmethod/latin/ContactsDictionary.java +12 −61 Original line number Diff line number Diff line Loading @@ -35,15 +35,8 @@ public class ContactsDictionary extends ExpandableDictionary { private ContentObserver mObserver; private boolean mRequiresReload; private long mLastLoadedContacts; private boolean mUpdatingContacts; // Use this lock before touching mUpdatingContacts & mRequiresDownload private Object mUpdatingLock = new Object(); public ContactsDictionary(Context context) { super(context); // Perform a managed query. The Activity will handle closing and requerying the cursor Loading @@ -53,15 +46,10 @@ public class ContactsDictionary extends ExpandableDictionary { cres.registerContentObserver(Contacts.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { synchronized (mUpdatingLock) { mRequiresReload = true; } setRequiresReload(true); } }); synchronized (mUpdatingLock) { loadDictionaryAsyncLocked(); } loadDictionary(); } public synchronized void close() { Loading @@ -69,41 +57,26 @@ public class ContactsDictionary extends ExpandableDictionary { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } super.close(); } private synchronized void loadDictionaryAsyncLocked() { @Override public void startDictionaryLoadingTaskLocked() { long now = SystemClock.uptimeMillis(); if (mLastLoadedContacts == 0 || now - mLastLoadedContacts > 30 * 60 * 1000 /* 30 minutes */) { if (!mUpdatingContacts) { mUpdatingContacts = true; mRequiresReload = false; new LoadContactsTask().execute(); } super.startDictionaryLoadingTaskLocked(); } } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) loadDictionaryAsyncLocked(); // Currently updating contacts, don't return any results. if (mUpdatingContacts) return; } super.getWords(codes, callback, nextLettersFrequencies); } @Override public synchronized boolean isValidWord(CharSequence word) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) loadDictionaryAsyncLocked(); if (mUpdatingContacts) return false; public void loadDictionaryAsync() { Cursor cursor = getContext().getContentResolver() .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); if (cursor != null) { addWords(cursor); } return super.isValidWord(word); mLastLoadedContacts = SystemClock.uptimeMillis(); } private void addWords(Cursor cursor) { Loading Loading @@ -151,26 +124,4 @@ public class ContactsDictionary extends ExpandableDictionary { cursor.close(); } private class LoadContactsTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... v) { Cursor cursor = getContext().getContentResolver() .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); if (cursor != null) { addWords(cursor); } mLastLoadedContacts = SystemClock.uptimeMillis(); return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub synchronized (mUpdatingLock) { mUpdatingContacts = false; } super.onPostExecute(result); } } } java/src/com/android/inputmethod/latin/ExpandableDictionary.java +69 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,11 @@ package com.android.inputmethod.latin; import com.android.inputmethod.latin.Dictionary.WordCallback; import android.content.Context; import android.os.AsyncTask; import android.os.SystemClock; /** * Base class for an in-memory dictionary that can grow dynamically and can Loading @@ -32,6 +36,13 @@ public class ExpandableDictionary extends Dictionary { public static final int MAX_WORD_LENGTH = 32; private static final char QUOTE = '\''; private boolean mRequiresReload; private boolean mUpdatingDictionary; // Use this lock before touching mUpdatingDictionary & mRequiresDownload private Object mUpdatingLock = new Object(); static class Node { char code; int frequency; Loading Loading @@ -70,6 +81,34 @@ public class ExpandableDictionary extends Dictionary { mCodes = new int[MAX_WORD_LENGTH][]; } public void loadDictionary() { synchronized (mUpdatingLock) { startDictionaryLoadingTaskLocked(); } } public void startDictionaryLoadingTaskLocked() { if (!mUpdatingDictionary) { mUpdatingDictionary = true; mRequiresReload = false; new LoadDictionaryTask().execute(); } } public void setRequiresReload(boolean reload) { synchronized (mUpdatingLock) { mRequiresReload = reload; } } public boolean getRequiresReload() { return mRequiresReload; } /** Override to load your dictionary here, on a background thread. */ public void loadDictionaryAsync() { } Context getContext() { return mContext; } Loading Loading @@ -119,6 +158,13 @@ public class ExpandableDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); // Currently updating contacts, don't return any results. if (mUpdatingDictionary) return; } mInputLength = codes.size(); mNextLettersFrequencies = nextLettersFrequencies; if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; Loading @@ -135,6 +181,11 @@ public class ExpandableDictionary extends Dictionary { @Override public synchronized boolean isValidWord(CharSequence word) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); if (mUpdatingDictionary) return false; } final int freq = getWordFrequencyRec(mRoots, word, 0, word.length()); return freq > -1; } Loading Loading @@ -277,6 +328,24 @@ public class ExpandableDictionary extends Dictionary { mRoots = new NodeArray(); } private class LoadDictionaryTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... v) { loadDictionaryAsync(); return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub synchronized (mUpdatingLock) { mUpdatingDictionary = false; } super.onPostExecute(result); } } static char toLowerCase(char c) { if (c < BASE_CHARS.length) { c = BASE_CHARS[c]; Loading java/src/com/android/inputmethod/latin/UserDictionary.java +9 −16 Original line number Diff line number Diff line Loading @@ -16,16 +16,11 @@ package com.android.inputmethod.latin; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.provider.UserDictionary.Words; public class UserDictionary extends ExpandableDictionary { Loading @@ -40,8 +35,6 @@ public class UserDictionary extends ExpandableDictionary { private static final int INDEX_FREQUENCY = 2; private ContentObserver mObserver; private boolean mRequiresReload; private String mLocale; public UserDictionary(Context context, String locale) { Loading @@ -54,7 +47,7 @@ public class UserDictionary extends ExpandableDictionary { cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { mRequiresReload = true; setRequiresReload(true); } }); Loading @@ -66,14 +59,15 @@ public class UserDictionary extends ExpandableDictionary { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } super.close(); } private synchronized void loadDictionary() { @Override public void loadDictionaryAsync() { Cursor cursor = getContext().getContentResolver() .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)", new String[] { mLocale }, null); addWords(cursor); mRequiresReload = false; } /** Loading @@ -86,7 +80,8 @@ public class UserDictionary extends ExpandableDictionary { */ @Override public synchronized void addWord(String word, int frequency) { if (mRequiresReload) loadDictionary(); // Force load the dictionary here synchronously if (getRequiresReload()) loadDictionaryAsync(); // Safeguard against adding long words. Can cause stack overflow. if (word.length() >= getMaxWordLength()) return; Loading @@ -101,19 +96,17 @@ public class UserDictionary extends ExpandableDictionary { getContext().getContentResolver().insert(Words.CONTENT_URI, values); // In case the above does a synchronous callback of the change observer mRequiresReload = false; setRequiresReload(false); } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { if (mRequiresReload) loadDictionary(); super.getWords(codes, callback, nextLettersFrequencies); } @Override public synchronized boolean isValidWord(CharSequence word) { if (mRequiresReload) loadDictionary(); return super.isValidWord(word); } Loading Loading
java/src/com/android/inputmethod/latin/AutoDictionary.java +4 −10 Original line number Diff line number Diff line Loading @@ -96,11 +96,14 @@ public class AutoDictionary extends ExpandableDictionary { return frequency >= VALIDITY_THRESHOLD; } @Override public void close() { mOpenHelper.close(); super.close(); } private void loadDictionary() { @Override public void loadDictionaryAsync() { // Load the words that correspond to the current input locale Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale }); if (cursor.moveToFirst()) { Loading Loading @@ -183,15 +186,6 @@ public class AutoDictionary extends ExpandableDictionary { return c; } private boolean insert(ContentValues values) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(AUTODICT_TABLE_NAME, Words.WORD, values); if (rowId > 0) { return true; } return false; } private int delete(String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count = db.delete(AUTODICT_TABLE_NAME, where, whereArgs); Loading
java/src/com/android/inputmethod/latin/ContactsDictionary.java +12 −61 Original line number Diff line number Diff line Loading @@ -35,15 +35,8 @@ public class ContactsDictionary extends ExpandableDictionary { private ContentObserver mObserver; private boolean mRequiresReload; private long mLastLoadedContacts; private boolean mUpdatingContacts; // Use this lock before touching mUpdatingContacts & mRequiresDownload private Object mUpdatingLock = new Object(); public ContactsDictionary(Context context) { super(context); // Perform a managed query. The Activity will handle closing and requerying the cursor Loading @@ -53,15 +46,10 @@ public class ContactsDictionary extends ExpandableDictionary { cres.registerContentObserver(Contacts.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { synchronized (mUpdatingLock) { mRequiresReload = true; } setRequiresReload(true); } }); synchronized (mUpdatingLock) { loadDictionaryAsyncLocked(); } loadDictionary(); } public synchronized void close() { Loading @@ -69,41 +57,26 @@ public class ContactsDictionary extends ExpandableDictionary { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } super.close(); } private synchronized void loadDictionaryAsyncLocked() { @Override public void startDictionaryLoadingTaskLocked() { long now = SystemClock.uptimeMillis(); if (mLastLoadedContacts == 0 || now - mLastLoadedContacts > 30 * 60 * 1000 /* 30 minutes */) { if (!mUpdatingContacts) { mUpdatingContacts = true; mRequiresReload = false; new LoadContactsTask().execute(); } super.startDictionaryLoadingTaskLocked(); } } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) loadDictionaryAsyncLocked(); // Currently updating contacts, don't return any results. if (mUpdatingContacts) return; } super.getWords(codes, callback, nextLettersFrequencies); } @Override public synchronized boolean isValidWord(CharSequence word) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) loadDictionaryAsyncLocked(); if (mUpdatingContacts) return false; public void loadDictionaryAsync() { Cursor cursor = getContext().getContentResolver() .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); if (cursor != null) { addWords(cursor); } return super.isValidWord(word); mLastLoadedContacts = SystemClock.uptimeMillis(); } private void addWords(Cursor cursor) { Loading Loading @@ -151,26 +124,4 @@ public class ContactsDictionary extends ExpandableDictionary { cursor.close(); } private class LoadContactsTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... v) { Cursor cursor = getContext().getContentResolver() .query(Contacts.CONTENT_URI, PROJECTION, null, null, null); if (cursor != null) { addWords(cursor); } mLastLoadedContacts = SystemClock.uptimeMillis(); return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub synchronized (mUpdatingLock) { mUpdatingContacts = false; } super.onPostExecute(result); } } }
java/src/com/android/inputmethod/latin/ExpandableDictionary.java +69 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,11 @@ package com.android.inputmethod.latin; import com.android.inputmethod.latin.Dictionary.WordCallback; import android.content.Context; import android.os.AsyncTask; import android.os.SystemClock; /** * Base class for an in-memory dictionary that can grow dynamically and can Loading @@ -32,6 +36,13 @@ public class ExpandableDictionary extends Dictionary { public static final int MAX_WORD_LENGTH = 32; private static final char QUOTE = '\''; private boolean mRequiresReload; private boolean mUpdatingDictionary; // Use this lock before touching mUpdatingDictionary & mRequiresDownload private Object mUpdatingLock = new Object(); static class Node { char code; int frequency; Loading Loading @@ -70,6 +81,34 @@ public class ExpandableDictionary extends Dictionary { mCodes = new int[MAX_WORD_LENGTH][]; } public void loadDictionary() { synchronized (mUpdatingLock) { startDictionaryLoadingTaskLocked(); } } public void startDictionaryLoadingTaskLocked() { if (!mUpdatingDictionary) { mUpdatingDictionary = true; mRequiresReload = false; new LoadDictionaryTask().execute(); } } public void setRequiresReload(boolean reload) { synchronized (mUpdatingLock) { mRequiresReload = reload; } } public boolean getRequiresReload() { return mRequiresReload; } /** Override to load your dictionary here, on a background thread. */ public void loadDictionaryAsync() { } Context getContext() { return mContext; } Loading Loading @@ -119,6 +158,13 @@ public class ExpandableDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); // Currently updating contacts, don't return any results. if (mUpdatingDictionary) return; } mInputLength = codes.size(); mNextLettersFrequencies = nextLettersFrequencies; if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; Loading @@ -135,6 +181,11 @@ public class ExpandableDictionary extends Dictionary { @Override public synchronized boolean isValidWord(CharSequence word) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); if (mUpdatingDictionary) return false; } final int freq = getWordFrequencyRec(mRoots, word, 0, word.length()); return freq > -1; } Loading Loading @@ -277,6 +328,24 @@ public class ExpandableDictionary extends Dictionary { mRoots = new NodeArray(); } private class LoadDictionaryTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... v) { loadDictionaryAsync(); return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub synchronized (mUpdatingLock) { mUpdatingDictionary = false; } super.onPostExecute(result); } } static char toLowerCase(char c) { if (c < BASE_CHARS.length) { c = BASE_CHARS[c]; Loading
java/src/com/android/inputmethod/latin/UserDictionary.java +9 −16 Original line number Diff line number Diff line Loading @@ -16,16 +16,11 @@ package com.android.inputmethod.latin; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.provider.UserDictionary.Words; public class UserDictionary extends ExpandableDictionary { Loading @@ -40,8 +35,6 @@ public class UserDictionary extends ExpandableDictionary { private static final int INDEX_FREQUENCY = 2; private ContentObserver mObserver; private boolean mRequiresReload; private String mLocale; public UserDictionary(Context context, String locale) { Loading @@ -54,7 +47,7 @@ public class UserDictionary extends ExpandableDictionary { cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { mRequiresReload = true; setRequiresReload(true); } }); Loading @@ -66,14 +59,15 @@ public class UserDictionary extends ExpandableDictionary { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } super.close(); } private synchronized void loadDictionary() { @Override public void loadDictionaryAsync() { Cursor cursor = getContext().getContentResolver() .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)", new String[] { mLocale }, null); addWords(cursor); mRequiresReload = false; } /** Loading @@ -86,7 +80,8 @@ public class UserDictionary extends ExpandableDictionary { */ @Override public synchronized void addWord(String word, int frequency) { if (mRequiresReload) loadDictionary(); // Force load the dictionary here synchronously if (getRequiresReload()) loadDictionaryAsync(); // Safeguard against adding long words. Can cause stack overflow. if (word.length() >= getMaxWordLength()) return; Loading @@ -101,19 +96,17 @@ public class UserDictionary extends ExpandableDictionary { getContext().getContentResolver().insert(Words.CONTENT_URI, values); // In case the above does a synchronous callback of the change observer mRequiresReload = false; setRequiresReload(false); } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { if (mRequiresReload) loadDictionary(); super.getWords(codes, callback, nextLettersFrequencies); } @Override public synchronized boolean isValidWord(CharSequence word) { if (mRequiresReload) loadDictionary(); return super.isValidWord(word); } Loading