Check suggested words whether they are from mainDic or not
- Added counters for suggestions by dictionarys - Added a counter for cancelled suggestions Change-Id: Ia7d3a73855b1e82b60a010f18dba4e1c0fe1c2bbmain
parent
7f96616c75
commit
4ee3676cf3
|
@ -85,8 +85,8 @@ public class AutoDictionary extends ExpandableDictionary {
|
|||
|
||||
private static DatabaseHelper mOpenHelper = null;
|
||||
|
||||
public AutoDictionary(Context context, LatinIME ime, String locale) {
|
||||
super(context);
|
||||
public AutoDictionary(Context context, LatinIME ime, String locale, int dicTypeId) {
|
||||
super(context, dicTypeId);
|
||||
mIme = ime;
|
||||
mLocale = locale;
|
||||
if (mOpenHelper == null) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.nio.channels.Channels;
|
|||
import java.util.Arrays;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +39,7 @@ public class BinaryDictionary extends Dictionary {
|
|||
private static final int TYPED_LETTER_MULTIPLIER = 2;
|
||||
private static final boolean ENABLE_MISSED_CHARACTERS = true;
|
||||
|
||||
private int mDicTypeId;
|
||||
private int mNativeDict;
|
||||
private int mDictLength;
|
||||
private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
|
||||
|
@ -62,10 +62,11 @@ public class BinaryDictionary extends Dictionary {
|
|||
* @param context application context for reading resources
|
||||
* @param resId the resource containing the raw binary dictionary
|
||||
*/
|
||||
public BinaryDictionary(Context context, int resId) {
|
||||
public BinaryDictionary(Context context, int resId, int dicTypeId) {
|
||||
if (resId != 0) {
|
||||
loadDictionary(context, resId);
|
||||
}
|
||||
mDicTypeId = dicTypeId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +74,7 @@ public class BinaryDictionary extends Dictionary {
|
|||
* @param context application context for reading resources
|
||||
* @param resId the resource containing the raw binary dictionary
|
||||
*/
|
||||
public BinaryDictionary(Context context, ByteBuffer byteBuffer) {
|
||||
public BinaryDictionary(Context context, ByteBuffer byteBuffer, int dicTypeId) {
|
||||
if (byteBuffer != null) {
|
||||
if (byteBuffer.isDirect()) {
|
||||
mNativeDictDirectBuffer = byteBuffer;
|
||||
|
@ -86,6 +87,7 @@ public class BinaryDictionary extends Dictionary {
|
|||
mNativeDict = openNative(mNativeDictDirectBuffer,
|
||||
TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER);
|
||||
}
|
||||
mDicTypeId = dicTypeId;
|
||||
}
|
||||
|
||||
private native int openNative(ByteBuffer bb, int typedLetterMultiplier, int fullWordMultiplier);
|
||||
|
@ -166,7 +168,7 @@ public class BinaryDictionary extends Dictionary {
|
|||
len++;
|
||||
}
|
||||
if (len > 0) {
|
||||
callback.addWord(mOutputChars, start, len, mFrequencies[j]);
|
||||
callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.content.ContentResolver;
|
|||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
|
||||
|
@ -37,21 +36,23 @@ public class ContactsDictionary extends ExpandableDictionary {
|
|||
|
||||
private long mLastLoadedContacts;
|
||||
|
||||
public ContactsDictionary(Context context) {
|
||||
super(context);
|
||||
public ContactsDictionary(Context context, int dicTypeId) {
|
||||
super(context, dicTypeId);
|
||||
// Perform a managed query. The Activity will handle closing and requerying the cursor
|
||||
// when needed.
|
||||
ContentResolver cres = context.getContentResolver();
|
||||
|
||||
cres.registerContentObserver(Contacts.CONTENT_URI, true, mObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
public void onChange(boolean self) {
|
||||
setRequiresReload(true);
|
||||
}
|
||||
});
|
||||
cres.registerContentObserver(
|
||||
Contacts.CONTENT_URI, true,mObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
public void onChange(boolean self) {
|
||||
setRequiresReload(true);
|
||||
}
|
||||
});
|
||||
loadDictionary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (mObserver != null) {
|
||||
getContext().getContentResolver().unregisterContentObserver(mObserver);
|
||||
|
|
|
@ -45,9 +45,10 @@ abstract public class Dictionary {
|
|||
* @param wordLength length of valid characters in the character array
|
||||
* @param frequency the frequency of occurence. This is normalized between 1 and 255, but
|
||||
* can exceed those limits
|
||||
* @param dicTypeId of the dictionary where word was from
|
||||
* @return true if the word was added, false if no more words are required
|
||||
*/
|
||||
boolean addWord(char[] word, int wordOffset, int wordLength, int frequency);
|
||||
boolean addWord(char[] word, int wordOffset, int wordLength, int frequency, int dicTypeId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,11 +16,8 @@
|
|||
|
||||
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
|
||||
|
@ -29,6 +26,7 @@ import android.os.SystemClock;
|
|||
public class ExpandableDictionary extends Dictionary {
|
||||
private Context mContext;
|
||||
private char[] mWordBuilder = new char[MAX_WORD_LENGTH];
|
||||
private int mDicTypeId;
|
||||
private int mMaxDepth;
|
||||
private int mInputLength;
|
||||
private int[] mNextLettersFrequencies;
|
||||
|
@ -75,10 +73,11 @@ public class ExpandableDictionary extends Dictionary {
|
|||
|
||||
private int[][] mCodes;
|
||||
|
||||
ExpandableDictionary(Context context) {
|
||||
ExpandableDictionary(Context context, int dicTypeId) {
|
||||
mContext = context;
|
||||
clearDictionary();
|
||||
mCodes = new int[MAX_WORD_LENGTH][];
|
||||
mDicTypeId = dicTypeId;
|
||||
}
|
||||
|
||||
public void loadDictionary() {
|
||||
|
@ -267,7 +266,7 @@ public class ExpandableDictionary extends Dictionary {
|
|||
if (completion) {
|
||||
word[depth] = c;
|
||||
if (terminal) {
|
||||
if (!callback.addWord(word, 0, depth + 1, freq * snr)) {
|
||||
if (!callback.addWord(word, 0, depth + 1, freq * snr, mDicTypeId)) {
|
||||
return;
|
||||
}
|
||||
// Add to frequency of next letters for predictive correction
|
||||
|
@ -305,7 +304,7 @@ public class ExpandableDictionary extends Dictionary {
|
|||
|| !same(word, depth + 1, codes.getTypedWord())) {
|
||||
int finalFreq = freq * snr * addedAttenuation;
|
||||
if (skipPos < 0) finalFreq *= FULL_WORD_FREQ_MULTIPLIER;
|
||||
callback.addWord(word, 0, depth + 1, finalFreq);
|
||||
callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId);
|
||||
}
|
||||
}
|
||||
if (children != null) {
|
||||
|
|
|
@ -99,7 +99,7 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
boolean haveDictionary = false;
|
||||
conf.locale = locale;
|
||||
res.updateConfiguration(conf, res.getDisplayMetrics());
|
||||
BinaryDictionary bd = new BinaryDictionary(this, R.raw.main);
|
||||
BinaryDictionary bd = new BinaryDictionary(this, R.raw.main, Suggest.DIC_MAIN);
|
||||
// Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
|
||||
// 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
|
||||
if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) {
|
||||
|
|
|
@ -331,12 +331,12 @@ public class LatinIME extends InputMethodService
|
|||
if (mUserDictionary != null) mUserDictionary.close();
|
||||
mUserDictionary = new UserDictionary(this, mInputLocale);
|
||||
if (mContactsDictionary == null) {
|
||||
mContactsDictionary = new ContactsDictionary(this);
|
||||
mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS);
|
||||
}
|
||||
if (mAutoDictionary != null) {
|
||||
mAutoDictionary.close();
|
||||
}
|
||||
mAutoDictionary = new AutoDictionary(this, this, mInputLocale);
|
||||
mAutoDictionary = new AutoDictionary(this, this, mInputLocale, Suggest.DIC_AUTO);
|
||||
mSuggest.setUserDictionary(mUserDictionary);
|
||||
mSuggest.setContactsDictionary(mContactsDictionary);
|
||||
mSuggest.setAutoDictionary(mAutoDictionary);
|
||||
|
|
|
@ -29,7 +29,9 @@ import android.util.Log;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String TAG = "LatinIMELogs";
|
||||
|
@ -56,6 +58,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
private static final int ID_SETTING_AUTO_COMPLETE = 8;
|
||||
private static final int ID_VERSION = 9;
|
||||
private static final int ID_EXCEPTION = 10;
|
||||
private static final int ID_SUGGESTIONCOUNT = 11;
|
||||
|
||||
private static final String PREF_ENABLE_LOG = "enable_logging";
|
||||
private static final String PREF_DEBUG_MODE = "debug_mode";
|
||||
|
@ -68,6 +71,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
/* package */ static String sLastAutoSuggestBefore;
|
||||
/* package */ static String sLastAutoSuggestAfter;
|
||||
/* package */ static String sLastAutoSuggestSeparator;
|
||||
private static HashMap<String, Integer> sSuggestDicMap = new HashMap<String, Integer>();
|
||||
|
||||
private ArrayList<LogEntry> mLogBuffer = null;
|
||||
private ArrayList<LogEntry> mPrivacyLogBuffer = null;
|
||||
|
@ -83,6 +87,8 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
private int mDeleteCount;
|
||||
private int mInputCount;
|
||||
private int mWordCount;
|
||||
private int[] mAutoSuggestCountPerDic = new int[Suggest.DIC_TYPE_LAST_ID + 1];
|
||||
private int mAutoCancelledCount;
|
||||
// ActualCharCount includes all characters that were completed.
|
||||
private int mActualCharCount;
|
||||
|
||||
|
@ -119,6 +125,8 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
mInputCount = 0;
|
||||
mWordCount = 0;
|
||||
mActualCharCount = 0;
|
||||
Arrays.fill(mAutoSuggestCountPerDic, 0);
|
||||
mAutoCancelledCount = 0;
|
||||
mLogBuffer = new ArrayList<LogEntry>();
|
||||
mPrivacyLogBuffer = new ArrayList<LogEntry>();
|
||||
mRingCharBuffer = new RingCharBuffer(context);
|
||||
|
@ -138,6 +146,8 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
mInputCount = 0;
|
||||
mWordCount = 0;
|
||||
mActualCharCount = 0;
|
||||
Arrays.fill(mAutoSuggestCountPerDic, 0);
|
||||
mAutoCancelledCount = 0;
|
||||
mLogBuffer.clear();
|
||||
mPrivacyLogBuffer.clear();
|
||||
mRingCharBuffer.reset();
|
||||
|
@ -177,6 +187,18 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
mLastTimeCountEntry = time;
|
||||
}
|
||||
|
||||
private void addSuggestionCountEntry(long time) {
|
||||
if (sLOGPRINT) {
|
||||
Log.d(TAG, "log suggest counts. (1)");
|
||||
}
|
||||
String[] s = new String[mAutoSuggestCountPerDic.length + 1];
|
||||
s[0] = String.valueOf(mAutoCancelledCount);
|
||||
for (int i = 1; i < s.length; ++i) {
|
||||
s[i] = String.valueOf(mAutoSuggestCountPerDic[i - 1]);
|
||||
}
|
||||
mLogBuffer.add(new LogEntry(time, ID_SUGGESTIONCOUNT, s));
|
||||
}
|
||||
|
||||
private void addThemeIdEntry(long time) {
|
||||
if (sLOGPRINT) {
|
||||
Log.d(TAG, "Log theme Id. (1)");
|
||||
|
@ -317,6 +339,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
addThemeIdEntry(now);
|
||||
addSettingsEntry(now);
|
||||
addVersionNameEntry(now);
|
||||
addSuggestionCountEntry(now);
|
||||
String s = LogSerializer.createStringFromEntries(mLogBuffer);
|
||||
if (!TextUtils.isEmpty(s)) {
|
||||
if (sLOGPRINT) {
|
||||
|
@ -406,6 +429,21 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
|
||||
public static void logOnAutoSuggestion(String before, String after) {
|
||||
if (sLogEnabled) {
|
||||
if (!sSuggestDicMap.containsKey(after)) {
|
||||
if (DBG) {
|
||||
Log.e(TAG, "logOnAutoSuggestion was cancelled: came from unknown source.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
int dicId = sSuggestDicMap.get(after);
|
||||
sLatinImeLogger.mAutoSuggestCountPerDic[dicId]++;
|
||||
sSuggestDicMap.clear();
|
||||
if (dicId != Suggest.DIC_MAIN) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, "logOnAutoSuggestion was cancelled: didn't come from main dic.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (before.equals(after)) {
|
||||
before = "";
|
||||
after = "";
|
||||
|
@ -423,6 +461,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
|
||||
public static void logOnAutoSuggestionCanceled() {
|
||||
if (sLogEnabled) {
|
||||
sLatinImeLogger.mAutoCancelledCount++;
|
||||
if (sLastAutoSuggestBefore != null && sLastAutoSuggestAfter != null) {
|
||||
String[] strings = new String[] {
|
||||
sLastAutoSuggestBefore, sLastAutoSuggestAfter, sLastAutoSuggestSeparator};
|
||||
|
@ -471,6 +510,18 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
}
|
||||
|
||||
public static void onStartSuggestion() {
|
||||
if (sLogEnabled) {
|
||||
sSuggestDicMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onAddSuggestedWord(String word, int typeId) {
|
||||
if (sLogEnabled) {
|
||||
sSuggestDicMap.put(word, typeId);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LogSerializer {
|
||||
private static void appendWithLength(StringBuffer sb, String data) {
|
||||
sb.append(data.length());
|
||||
|
|
|
@ -38,6 +38,14 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
public static final int CORRECTION_BASIC = 1;
|
||||
public static final int CORRECTION_FULL = 2;
|
||||
|
||||
public static final int DIC_USER_TYPED = 0;
|
||||
public static final int DIC_MAIN = 1;
|
||||
public static final int DIC_USER = 2;
|
||||
public static final int DIC_AUTO = 3;
|
||||
public static final int DIC_CONTACTS = 4;
|
||||
// If you add a type of dictionary, increment DIC_TYPE_LAST_ID
|
||||
public static final int DIC_TYPE_LAST_ID = 4;
|
||||
|
||||
static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
|
||||
|
||||
private BinaryDictionary mMainDict;
|
||||
|
@ -69,12 +77,12 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
private int mCorrectionMode = CORRECTION_BASIC;
|
||||
|
||||
public Suggest(Context context, int dictionaryResId) {
|
||||
mMainDict = new BinaryDictionary(context, dictionaryResId);
|
||||
mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN);
|
||||
initPool();
|
||||
}
|
||||
|
||||
public Suggest(Context context, ByteBuffer byteBuffer) {
|
||||
mMainDict = new BinaryDictionary(context, byteBuffer);
|
||||
mMainDict = new BinaryDictionary(context, byteBuffer, DIC_MAIN);
|
||||
initPool();
|
||||
}
|
||||
|
||||
|
@ -177,6 +185,7 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
*/
|
||||
public List<CharSequence> getSuggestions(View view, WordComposer wordComposer,
|
||||
boolean includeTypedWordIfValid) {
|
||||
LatinImeLogger.onStartSuggestion();
|
||||
mHaveCorrection = false;
|
||||
mCapitalize = wordComposer.isCapitalized();
|
||||
collectGarbage();
|
||||
|
@ -191,6 +200,7 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
} else {
|
||||
mLowerOriginalWord = "";
|
||||
}
|
||||
LatinImeLogger.onAddSuggestedWord(mOriginalWord.toString(), Suggest.DIC_USER_TYPED);
|
||||
// Search the dictionary only if there are at least 2 characters
|
||||
if (wordComposer.size() > 1) {
|
||||
if (mUserDictionary != null || mContactsDictionary != null) {
|
||||
|
@ -301,7 +311,8 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean addWord(final char[] word, final int offset, final int length, final int freq) {
|
||||
public boolean addWord(final char[] word, final int offset, final int length,
|
||||
final int freq, final int dicTypeId) {
|
||||
int pos = 0;
|
||||
final int[] priorities = mPriorities;
|
||||
final int prefMaxSuggestions = mPrefMaxSuggestions;
|
||||
|
@ -345,6 +356,8 @@ public class Suggest implements Dictionary.WordCallback {
|
|||
if (garbage instanceof StringBuilder) {
|
||||
mStringPool.add(garbage);
|
||||
}
|
||||
} else {
|
||||
LatinImeLogger.onAddSuggestedWord(sb.toString(), dicTypeId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class UserDictionary extends ExpandableDictionary {
|
|||
private String mLocale;
|
||||
|
||||
public UserDictionary(Context context, String locale) {
|
||||
super(context);
|
||||
super(context, Suggest.DIC_USER);
|
||||
mLocale = locale;
|
||||
// Perform a managed query. The Activity will handle closing and requerying the cursor
|
||||
// when needed.
|
||||
|
@ -54,6 +54,7 @@ public class UserDictionary extends ExpandableDictionary {
|
|||
loadDictionary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (mObserver != null) {
|
||||
getContext().getContentResolver().unregisterContentObserver(mObserver);
|
||||
|
|
Loading…
Reference in New Issue