diff options
Diffstat (limited to 'java/src')
11 files changed, 198 insertions, 154 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index a5205d8ba..43baf6172 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -117,9 +117,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack PointerTracker.DrawingProxy, MoreKeysPanel.Controller { private static final String TAG = MainKeyboardView.class.getSimpleName(); - // TODO: Kill process when the usability study mode was changed. - private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; - /** Listener for {@link KeyboardActionListener}. */ private KeyboardActionListener mKeyboardActionListener; @@ -1069,8 +1066,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack final int y = (int)me.getY(index); // TODO: This might be moved to the tracker.processMotionEvent() call below. - if (ENABLE_USABILITY_STUDY_LOG && action != MotionEvent.ACTION_MOVE) { - writeUsabilityStudyLog(me, action, eventTime, index, id, x, y); + if (LatinImeLogger.sUsabilityStudy) { + UsabilityStudyLogUtils.writeMotionEvent(me); } // TODO: This should be moved to the tracker.processMotionEvent() call below. // Currently the same "move" event is being logged twice. @@ -1131,15 +1128,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack final int px = (int)me.getX(i); final int py = (int)me.getY(i); tracker.onMoveEvent(px, py, eventTime, me); - if (ENABLE_USABILITY_STUDY_LOG) { - writeUsabilityStudyLog(me, action, eventTime, i, pointerId, px, py); - } - // TODO: This seems to be no longer necessary, and confusing because it leads to - // duplicate MotionEvents being recorded. - // if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - // ResearchLogger.mainKeyboardView_processMotionEvent( - // me, action, eventTime, i, pointerId, px, py); - // } } } else { final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); @@ -1149,35 +1137,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack return true; } - private static void writeUsabilityStudyLog(final MotionEvent me, final int action, - final long eventTime, final int index, final int id, final int x, final int y) { - final String eventTag; - switch (action) { - case MotionEvent.ACTION_UP: - eventTag = "[Up]"; - break; - case MotionEvent.ACTION_DOWN: - eventTag = "[Down]"; - break; - case MotionEvent.ACTION_POINTER_UP: - eventTag = "[PointerUp]"; - break; - case MotionEvent.ACTION_POINTER_DOWN: - eventTag = "[PointerDown]"; - break; - case MotionEvent.ACTION_MOVE: - eventTag = "[Move]"; - break; - default: - eventTag = "[Action" + action + "]"; - break; - } - final float size = me.getSize(index); - final float pressure = me.getPressure(index); - UsabilityStudyLogUtils.getInstance().write( - eventTag + eventTime + "," + id + "," + x + "," + y + "," + size + "," + pressure); - } - public void cancelAllOngoingEvents() { mKeyTimerHandler.cancelAllMessages(); mDrawingHandler.cancelAllMessages(); @@ -1370,4 +1329,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack drawIcon(canvas, mSpaceIcon, x, y, iconWidth, iconHeight); } } + + public void deallocateMemory() { + mGestureTrailsPreview.deallocateMemory(); + } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java index dff5177ce..d4c25941c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java @@ -104,7 +104,12 @@ public final class GestureTrailsPreview extends AbstractDrawingPreview { freeOffscreenBuffer(); } + public void deallocateMemory() { + freeOffscreenBuffer(); + } + private void freeOffscreenBuffer() { + mOffscreenCanvas.setBitmap(null); if (mOffscreenBuffer != null) { mOffscreenBuffer.recycle(); mOffscreenBuffer = null; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1211ea5ad..614c14308 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -76,7 +76,7 @@ import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.personalization.PersonalizationDictionaryHelper; -import com.android.inputmethod.latin.personalization.UserHistoryDictionary; +import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsActivity; import com.android.inputmethod.latin.settings.SettingsValues; @@ -169,7 +169,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private boolean mIsMainDictionaryAvailable; private UserBinaryDictionary mUserDictionary; - private UserHistoryDictionary mUserHistoryDictionary; + private UserHistoryPredictionDictionary mUserHistoryPredictionDictionary; private boolean mIsUserDictionaryAvailable; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; @@ -539,35 +539,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); final String localeStr = subtypeLocale.toString(); - final ContactsBinaryDictionary oldContactsDictionary; - if (mSuggest != null) { - oldContactsDictionary = mSuggest.getContactsDictionary(); - mSuggest.close(); - } else { - oldContactsDictionary = null; - } - mSuggest = new Suggest(this /* Context */, subtypeLocale, + final Suggest newSuggest = new Suggest(this /* Context */, subtypeLocale, this /* SuggestInitializationListener */); final SettingsValues settingsValues = mSettings.getCurrent(); if (settingsValues.mCorrectionEnabled) { - mSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); + newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); } mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - ResearchLogger.getInstance().initSuggest(mSuggest); + ResearchLogger.getInstance().initSuggest(newSuggest); } mUserDictionary = new UserBinaryDictionary(this, localeStr); mIsUserDictionaryAvailable = mUserDictionary.isEnabled(); - mSuggest.setUserDictionary(mUserDictionary); - - resetContactsDictionary(oldContactsDictionary); + newSuggest.setUserDictionary(mUserDictionary); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - mUserHistoryDictionary = - PersonalizationDictionaryHelper.getUserHistoryDictionary(this, localeStr, prefs); - mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); + + mUserHistoryPredictionDictionary = PersonalizationDictionaryHelper + .getUserHistoryPredictionDictionary(this, localeStr, prefs); + newSuggest.setUserHistoryPredictionDictionary(mUserHistoryPredictionDictionary); + + final Suggest oldSuggest = mSuggest; + resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null); + mSuggest = newSuggest; + if (oldSuggest != null) oldSuggest.close(); } /** @@ -579,8 +576,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen * @param oldContactsDictionary an optional dictionary to use, or null */ private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary) { + final Suggest suggest = mSuggest; final boolean shouldSetDictionary = - (null != mSuggest && mSettings.getCurrent().mUseContactsDict); + (null != suggest && mSettings.getCurrent().mUseContactsDict); final ContactsBinaryDictionary dictionaryToUse; if (!shouldSetDictionary) { @@ -607,8 +605,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - if (null != mSuggest) { - mSuggest.setContactsDictionary(dictionaryToUse); + if (null != suggest) { + suggest.setContactsDictionary(dictionaryToUse); } } @@ -620,8 +618,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onDestroy() { - if (mSuggest != null) { - mSuggest.close(); + final Suggest suggest = mSuggest; + if (suggest != null) { + suggest.close(); mSuggest = null; } mSettings.onDestroy(); @@ -795,7 +794,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Note: the following does a round-trip IPC on the main thread: be careful final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); - if (null != mSuggest && null != currentLocale && !currentLocale.equals(mSuggest.mLocale)) { + final Suggest suggest = mSuggest; + if (null != suggest && null != currentLocale && !currentLocale.equals(suggest.mLocale)) { initSuggest(); } if (mSuggestionStripView != null) { @@ -813,8 +813,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen loadSettings(); currentSettingsValues = mSettings.getCurrent(); - if (mSuggest != null && currentSettingsValues.mCorrectionEnabled) { - mSuggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); + if (suggest != null && currentSettingsValues.mCorrectionEnabled) { + suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); } switcher.loadKeyboard(editorInfo, currentSettingsValues); @@ -894,6 +894,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); if (mainKeyboardView != null) { mainKeyboardView.cancelAllOngoingEvents(); + mainKeyboardView.deallocateMemory(); } // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestionStrip(); @@ -2447,12 +2448,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // AND it's in none of our current dictionaries (main, user or otherwise). // Please note that if mSuggest is null, it means that everything is off: suggestion // and correction, so we shouldn't try to show the hint + final Suggest suggest = mSuggest; final boolean showingAddToDictionaryHint = (SuggestedWordInfo.KIND_TYPED == suggestionInfo.mKind || SuggestedWordInfo.KIND_OOV_CORRECTION == suggestionInfo.mKind) - && mSuggest != null + && suggest != null // If the suggestion is not in the dictionary, the hint should be shown. - && !AutoCorrectionUtils.isValidWord(mSuggest, suggestion, true); + && !AutoCorrectionUtils.isValidWord(suggest, suggestion, true); if (currentSettings.mIsInternal) { LatinImeLoggerUtils.onSeparator((char)Constants.CODE_SPACE, @@ -2498,7 +2500,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private String addToUserHistoryDictionary(final String suggestion) { if (TextUtils.isEmpty(suggestion)) return null; - if (mSuggest == null) return null; + final Suggest suggest = mSuggest; + if (suggest == null) return null; // If correction is not enabled, we don't add words to the user history dictionary. // That's to avoid unintended additions in some sensitive fields, or fields that @@ -2506,12 +2509,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SettingsValues currentSettings = mSettings.getCurrent(); if (!currentSettings.mCorrectionEnabled) return null; - final Suggest suggest = mSuggest; - final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary; - if (suggest == null || userHistoryDictionary == null) { - // Avoid concurrent issue - return null; - } + final UserHistoryPredictionDictionary userHistoryDictionary = + mUserHistoryPredictionDictionary; + if (userHistoryDictionary == null) return null; + final String prevWord = mConnection.getNthPreviousWord(currentSettings.mWordSeparators, 2); final String secondWord; if (mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps()) { @@ -2657,7 +2658,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mConnection.deleteSurroundingText(deleteLength, 0); if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) { - mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); + mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord); } mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1); if (mSettings.isInternal()) { diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 647c6f6e1..6b016675a 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -22,7 +22,7 @@ import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.personalization.UserHistoryDictionary; +import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary; import com.android.inputmethod.latin.utils.AutoCorrectionUtils; import com.android.inputmethod.latin.utils.BoundedTreeSet; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -168,8 +168,10 @@ public final class Suggest { addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary); } - public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) { - addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); + public void setUserHistoryPredictionDictionary( + final UserHistoryPredictionDictionary userHistoryPredictionDictionary) { + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, + userHistoryPredictionDictionary); } public void setAutoCorrectionThreshold(float threshold) { diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java index c76dea0bb..9d041f4eb 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableDictionary; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -47,16 +46,17 @@ import java.util.ArrayList; import java.util.concurrent.locks.ReentrantLock; /** - * Locally gathers stats about the words user types and various other signals like auto-correction - * cancellation or manual picks. This allows the keyboard to adapt to the typist over time. + * This class is a base class of a dictionary for the personalized prediction language model. */ -public class UserHistoryDictionary extends ExpandableDictionary { - private static final String TAG = UserHistoryDictionary.class.getSimpleName(); - private static final String NAME = UserHistoryDictionary.class.getSimpleName(); +public abstract class DynamicPredictionDictionaryBase extends ExpandableDictionary { + public static void registerUpdateListener(PersonalizationDictionaryUpdateListener listener) { + // TODO: Implement + } + + private static final String TAG = DynamicPredictionDictionaryBase.class.getSimpleName(); public static final boolean DBG_SAVE_RESTORE = false; - public static final boolean DBG_STRESS_TEST = false; - public static final boolean DBG_ALWAYS_WRITE = false; - public static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG; + private static final boolean DBG_STRESS_TEST = false; + private static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG; private static final FormatOptions VERSION3 = new FormatOptions(3, true /* supportsDynamicUpdate */); @@ -65,14 +65,7 @@ public class UserHistoryDictionary extends ExpandableDictionary { private static final int FREQUENCY_FOR_TYPED = 2; /** Maximum number of pairs. Pruning will start when databases goes above this number. */ - public static final int MAX_HISTORY_BIGRAMS = 10000; - - /** - * When it hits maximum bigram pair, it will delete until you are left with - * only (sMaxHistoryBigrams - sDeleteHistoryBigrams) pairs. - * Do not keep this number small to avoid deleting too often. - */ - public static final int DELETE_HISTORY_BIGRAMS = 1000; + private static final int MAX_HISTORY_BIGRAMS = 10000; /** Locale for which this user history dictionary is storing words */ private final String mLocale; @@ -85,9 +78,9 @@ public class UserHistoryDictionary extends ExpandableDictionary { // Should always be false except when we use this class for test @UsedForTesting boolean isTest = false; - /* package */ UserHistoryDictionary(final Context context, final String locale, - final SharedPreferences sp) { - super(context, Dictionary.TYPE_USER_HISTORY); + /* package */ DynamicPredictionDictionaryBase(final Context context, final String locale, + final SharedPreferences sp, final String dictionaryType) { + super(context, dictionaryType); mLocale = locale; mPrefs = sp; if (mLocale != null && mLocale.length() > 1) { @@ -102,8 +95,8 @@ public class UserHistoryDictionary extends ExpandableDictionary { // Also, the database is written to somewhat frequently, so it needs to be kept alive // throughout the life of the process. // mOpenHelper.close(); - // Ignore close because we cache UserHistoryDictionary for each language. See getInstance() - // above. + // Ignore close because we cache PersonalizationPredictionDictionary for each language. + // See getInstance() above. // super.close(); } @@ -184,7 +177,7 @@ public class UserHistoryDictionary extends ExpandableDictionary { } @Override - public void loadDictionaryAsync() { + public final void loadDictionaryAsync() { // This must be run on non-main thread mBigramListLock.lock(); try { @@ -194,48 +187,47 @@ public class UserHistoryDictionary extends ExpandableDictionary { } } - private int profTotal; - private void loadDictionaryAsyncLocked() { + final int[] profTotalCount = { 0 }; + final String locale = getLocale(); if (DBG_STRESS_TEST) { try { - Log.w(TAG, "Start stress in loading: " + mLocale); + Log.w(TAG, "Start stress in loading: " + locale); Thread.sleep(15000); Log.w(TAG, "End stress in loading"); } catch (InterruptedException e) { } } - final long last = Settings.readLastUserHistoryWriteTime(mPrefs, mLocale); + final long last = Settings.readLastUserHistoryWriteTime(mPrefs, locale); final boolean initializing = last == 0; final long now = System.currentTimeMillis(); - profTotal = 0; - final String fileName = NAME + "." + mLocale + ".dict"; + final String fileName = getDictionaryFileName(); final ExpandableDictionary dictionary = this; final OnAddWordListener listener = new OnAddWordListener() { @Override public void setUnigram(final String word, final String shortcutTarget, final int frequency) { - profTotal++; if (DBG_SAVE_RESTORE) { Log.d(TAG, "load unigram: " + word + "," + frequency); } dictionary.addWord(word, shortcutTarget, frequency); - mBigramList.addBigram(null, word, (byte)frequency); + ++profTotalCount[0]; + addToBigramListLocked(null, word, (byte)frequency); } @Override public void setBigram(final String word1, final String word2, final int frequency) { if (word1.length() < Constants.DICTIONARY_MAX_WORD_LENGTH && word2.length() < Constants.DICTIONARY_MAX_WORD_LENGTH) { - profTotal++; if (DBG_SAVE_RESTORE) { Log.d(TAG, "load bigram: " + word1 + "," + word2 + "," + frequency); } + ++profTotalCount[0]; dictionary.setBigramAndGetFrequency( word1, word2, initializing ? new ForgettingCurveParams(true) : new ForgettingCurveParams(frequency, now, last)); } - mBigramList.addBigram(word1, word2, (byte)frequency); + addToBigramListLocked(word1, word2, (byte)frequency); } }; @@ -264,11 +256,21 @@ public class UserHistoryDictionary extends ExpandableDictionary { if (PROFILE_SAVE_RESTORE) { final long diff = System.currentTimeMillis() - now; Log.d(TAG, "PROF: Load UserHistoryDictionary: " - + mLocale + ", " + diff + "ms. load " + profTotal + "entries."); + + locale + ", " + diff + "ms. load " + profTotalCount[0] + "entries."); } } } + protected abstract String getDictionaryFileName(); + + protected String getLocale() { + return mLocale; + } + + private void addToBigramListLocked(String word0, String word1, byte fcValue) { + mBigramList.addBigram(word0, word1, fcValue); + } + /** * Async task to write pending words to the binarydicts. */ @@ -277,16 +279,16 @@ public class UserHistoryDictionary extends ExpandableDictionary { private final UserHistoryDictionaryBigramList mBigramList; private final boolean mAddLevel0Bigrams; private final String mLocale; - private final UserHistoryDictionary mUserHistoryDictionary; + private final DynamicPredictionDictionaryBase mDynamicPredictionDictionary; private final SharedPreferences mPrefs; private final Context mContext; public UpdateBinaryTask(final UserHistoryDictionaryBigramList pendingWrites, - final String locale, final UserHistoryDictionary dict, + final String locale, final DynamicPredictionDictionaryBase dict, final SharedPreferences prefs, final Context context) { mBigramList = pendingWrites; mLocale = locale; - mUserHistoryDictionary = dict; + mDynamicPredictionDictionary = dict; mPrefs = prefs; mContext = context; mAddLevel0Bigrams = mBigramList.size() <= MAX_HISTORY_BIGRAMS; @@ -294,19 +296,19 @@ public class UserHistoryDictionary extends ExpandableDictionary { @Override protected Void doInBackground(final Void... v) { - if (mUserHistoryDictionary.isTest) { + if (mDynamicPredictionDictionary.isTest) { // If isTest == true, wait until the lock is released. - mUserHistoryDictionary.mBigramListLock.lock(); + mDynamicPredictionDictionary.mBigramListLock.lock(); try { doWriteTaskLocked(); } finally { - mUserHistoryDictionary.mBigramListLock.unlock(); + mDynamicPredictionDictionary.mBigramListLock.unlock(); } - } else if (mUserHistoryDictionary.mBigramListLock.tryLock()) { + } else if (mDynamicPredictionDictionary.mBigramListLock.tryLock()) { try { doWriteTaskLocked(); } finally { - mUserHistoryDictionary.mBigramListLock.unlock(); + mDynamicPredictionDictionary.mBigramListLock.unlock(); } } return null; @@ -324,7 +326,8 @@ public class UserHistoryDictionary extends ExpandableDictionary { } final long now = PROFILE_SAVE_RESTORE ? System.currentTimeMillis() : 0; - final String fileName = NAME + "." + mLocale + ".dict"; + final String fileName = + mDynamicPredictionDictionary.getDictionaryFileName(); final File file = new File(mContext.getFilesDir(), fileName); FileOutputStream out = null; @@ -360,7 +363,8 @@ public class UserHistoryDictionary extends ExpandableDictionary { freq = FREQUENCY_FOR_TYPED; final byte prevFc = mBigramList.getBigrams(word1).get(word2); } else { // bigram - final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2); + final NextWord nw = + mDynamicPredictionDictionary.getBigramWord(word1, word2); if (nw != null) { final ForgettingCurveParams fcp = nw.getFcParams(); final byte prevFc = mBigramList.getBigrams(word1).get(word2); diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java index e09e834bf..f5dae99ef 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java @@ -29,15 +29,16 @@ public class PersonalizationDictionaryHelper { private static final String TAG = PersonalizationDictionaryHelper.class.getSimpleName(); private static final boolean DEBUG = false; - private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>> + private static final ConcurrentHashMap<String, SoftReference<UserHistoryPredictionDictionary>> sLangDictCache = CollectionUtils.newConcurrentHashMap(); - public static UserHistoryDictionary getUserHistoryDictionary( + public static UserHistoryPredictionDictionary getUserHistoryPredictionDictionary( final Context context, final String locale, final SharedPreferences sp) { synchronized (sLangDictCache) { if (sLangDictCache.containsKey(locale)) { - final SoftReference<UserHistoryDictionary> ref = sLangDictCache.get(locale); - final UserHistoryDictionary dict = ref == null ? null : ref.get(); + final SoftReference<UserHistoryPredictionDictionary> ref = + sLangDictCache.get(locale); + final UserHistoryPredictionDictionary dict = ref == null ? null : ref.get(); if (dict != null) { if (DEBUG) { Log.w(TAG, "Use cached UserHistoryDictionary for " + locale); @@ -45,8 +46,9 @@ public class PersonalizationDictionaryHelper { return dict; } } - final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale, sp); - sLangDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict)); + final UserHistoryPredictionDictionary dict = + new UserHistoryPredictionDictionary(context, locale, sp); + sLangDictCache.put(locale, new SoftReference<UserHistoryPredictionDictionary>(dict)); return dict; } } diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java index 2ec0dc00c..c78e5a95b 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateListener.java @@ -16,6 +16,6 @@ package com.android.inputmethod.latin.personalization; -public class PersonalizationDictionaryUpdateListener { +public interface PersonalizationDictionaryUpdateListener { // TODO: Implement } diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java index 7bce97978..955bd2762 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java @@ -17,30 +17,20 @@ package com.android.inputmethod.latin.personalization; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.ExpandableDictionary; import android.content.Context; import android.content.SharedPreferences; -/** - * This class is a dictionary for the personalized prediction language model implemented in Java. - */ -public class PersonalizationPredictionDictionary extends ExpandableDictionary { - public static void registerUpdateListener(PersonalizationDictionaryUpdateListener listener) { - // TODO: Implement - } +public class PersonalizationPredictionDictionary extends DynamicPredictionDictionaryBase { + private static final String NAME = PersonalizationPredictionDictionary.class.getSimpleName(); - /** Locale for which this user history dictionary is storing words */ - private final String mLocale; - private final SharedPreferences mPrefs; - - // Singleton - private PersonalizationPredictionDictionary(final Context context, final String locale, + /* package */ PersonalizationPredictionDictionary(final Context context, final String locale, final SharedPreferences sp) { - super(context, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA); - mLocale = locale; - mPrefs = sp; + super(context, locale, sp, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA); } - // TODO: Implement + @Override + protected String getDictionaryFileName() { + return NAME + "." + getLocale() + ".dict"; + } } diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java index b93630a18..f21db25a6 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java @@ -53,7 +53,7 @@ public final class UserHistoryDictionaryBigramList { * Called when loaded from the SQL DB. */ public void addBigram(String word1, String word2, byte fcValue) { - if (UserHistoryDictionary.DBG_SAVE_RESTORE) { + if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) { Log.d(TAG, "--- add bigram: " + word1 + ", " + word2 + ", " + fcValue); } final HashMap<String, Byte> map; @@ -73,7 +73,7 @@ public final class UserHistoryDictionaryBigramList { * Called when inserted to the SQL DB. */ public void updateBigram(String word1, String word2, byte fcValue) { - if (UserHistoryDictionary.DBG_SAVE_RESTORE) { + if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) { Log.d(TAG, "--- update bigram: " + word1 + ", " + word2 + ", " + fcValue); } final HashMap<String, Byte> map; diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java new file mode 100644 index 000000000..d11784454 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.personalization; + +import com.android.inputmethod.latin.Dictionary; + +import android.content.Context; +import android.content.SharedPreferences; + +/** + * Locally gathers stats about the words user types and various other signals like auto-correction + * cancellation or manual picks. This allows the keyboard to adapt to the typist over time. + */ +public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase { + private static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName(); + /* package */ UserHistoryPredictionDictionary(final Context context, final String locale, + final SharedPreferences sp) { + super(context, locale, sp, Dictionary.TYPE_USER_HISTORY); + } + + @Override + protected String getDictionaryFileName() { + return NAME + "." + getLocale() + ".dict"; + } +} diff --git a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java b/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java index 729a8723d..06826dac0 100644 --- a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Process; import android.util.Log; +import android.view.MotionEvent; import com.android.inputmethod.latin.LatinImeLogger; @@ -109,6 +110,43 @@ public final class UsabilityStudyLogUtils { LatinImeLogger.onPrintAllUsabilityStudyLogs(); } + public static void writeMotionEvent(final MotionEvent me) { + final int action = me.getActionMasked(); + final long eventTime = me.getEventTime(); + final int pointerCount = me.getPointerCount(); + for (int index = 0; index < pointerCount; index++) { + final int id = me.getPointerId(index); + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); + final float size = me.getSize(index); + final float pressure = me.getPressure(index); + + final String eventTag; + switch (action) { + case MotionEvent.ACTION_UP: + eventTag = "[Up]"; + break; + case MotionEvent.ACTION_DOWN: + eventTag = "[Down]"; + break; + case MotionEvent.ACTION_POINTER_UP: + eventTag = "[PointerUp]"; + break; + case MotionEvent.ACTION_POINTER_DOWN: + eventTag = "[PointerDown]"; + break; + case MotionEvent.ACTION_MOVE: + eventTag = "[Move]"; + break; + default: + eventTag = "[Action" + action + "]"; + break; + } + getInstance().write(eventTag + eventTime + "," + id + "," + x + "," + y + "," + size + + "," + pressure); + } + } + public void write(final String log) { mLoggingHandler.post(new Runnable() { @Override |