Check suggested words whether they are from mainDic or not

- Added counters for suggestions by dictionarys
- Added a counter for cancelled suggestions

Change-Id: Ia7d3a73855b1e82b60a010f18dba4e1c0fe1c2bb
main
satok 2010-06-02 18:30:27 +09:00
parent 7f96616c75
commit 4ee3676cf3
10 changed files with 98 additions and 30 deletions

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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());

View File

@ -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;
}

View File

@ -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);