Merge "Fix some compiler warnings"

This commit is contained in:
Tadashi G. Takaoka 2014-10-21 15:06:54 +00:00 committed by Android (Google) Code Review
commit 46a007261f
115 changed files with 913 additions and 920 deletions

View file

@ -346,7 +346,8 @@ final class KeyCodeDescriptionMapper {
} }
// TODO: Remove this method once TTS supports emoticon verbalization. // TODO: Remove this method once TTS supports emoticon verbalization.
private String getSpokenEmoticonDescription(final Context context, final String outputText) { private static String getSpokenEmoticonDescription(final Context context,
final String outputText) {
final StringBuilder sb = new StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX); final StringBuilder sb = new StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX);
final int textLength = outputText.length(); final int textLength = outputText.length();
for (int index = 0; index < textLength; index = outputText.offsetByCodePoints(index, 1)) { for (int index = 0; index < textLength; index = outputText.offsetByCodePoints(index, 1)) {

View file

@ -329,9 +329,8 @@ final class KeyboardAccessibilityNodeProvider<KV extends KeyboardView>
if (currentSettings.isWordSeparator(key.getCode())) { if (currentSettings.isWordSeparator(key.getCode())) {
return mAccessibilityUtils.getAutoCorrectionDescription( return mAccessibilityUtils.getAutoCorrectionDescription(
keyCodeDescription, shouldObscure); keyCodeDescription, shouldObscure);
} else {
return keyCodeDescription;
} }
return keyCodeDescription;
} }
/** /**

View file

@ -144,7 +144,7 @@ public final class CompatUtils {
public <T> ToObjectMethodWrapper<T> getMethod(final String name, public <T> ToObjectMethodWrapper<T> getMethod(final String name,
final T defaultValue, final Class<?>... parameterTypes) { final T defaultValue, final Class<?>... parameterTypes) {
return new ToObjectMethodWrapper<T>(CompatUtils.getMethod(mClass, name, parameterTypes), return new ToObjectMethodWrapper<>(CompatUtils.getMethod(mClass, name, parameterTypes),
defaultValue); defaultValue);
} }

View file

@ -46,7 +46,7 @@ public class CursorAnchorInfoCompatWrapper {
*/ */
public static final int FLAG_IS_RTL = 0x04; public static final int FLAG_IS_RTL = 0x04;
private CursorAnchorInfoCompatWrapper() { CursorAnchorInfoCompatWrapper() {
// This class is not publicly instantiable. // This class is not publicly instantiable.
} }

View file

@ -17,6 +17,7 @@
package com.android.inputmethod.compat; package com.android.inputmethod.compat;
import android.text.Spannable; import android.text.Spannable;
import android.text.Spanned;
import android.text.style.LocaleSpan; import android.text.style.LocaleSpan;
import android.util.Log; import android.util.Log;
@ -127,13 +128,13 @@ public final class LocaleSpanCompatUtils {
final int spanFlag = spannable.getSpanFlags(existingLocaleSpan); final int spanFlag = spannable.getSpanFlags(existingLocaleSpan);
if (spanStart < newStart) { if (spanStart < newStart) {
newStart = spanStart; newStart = spanStart;
isStartExclusive = ((spanFlag & Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) == isStartExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
if (newEnd < spanEnd) { if (newEnd < spanEnd) {
newEnd = spanEnd; newEnd = spanEnd;
isEndExclusive = ((spanFlag & Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) == isEndExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
existingLocaleSpansToBeMerged.add(existingLocaleSpan); existingLocaleSpansToBeMerged.add(existingLocaleSpan);
} }
@ -201,24 +202,17 @@ public final class LocaleSpanCompatUtils {
private static int getSpanFlag(final int originalFlag, private static int getSpanFlag(final int originalFlag,
final boolean isStartExclusive, final boolean isEndExclusive) { final boolean isStartExclusive, final boolean isEndExclusive) {
return (originalFlag & ~Spannable.SPAN_POINT_MARK_MASK) | return (originalFlag & ~Spanned.SPAN_POINT_MARK_MASK) |
getSpanPointMarkFlag(isStartExclusive, isEndExclusive); getSpanPointMarkFlag(isStartExclusive, isEndExclusive);
} }
private static int getSpanPointMarkFlag(final boolean isStartExclusive, private static int getSpanPointMarkFlag(final boolean isStartExclusive,
final boolean isEndExclusive) { final boolean isEndExclusive) {
if (isStartExclusive) { if (isStartExclusive) {
if (isEndExclusive) { return isEndExclusive ? Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
return Spannable.SPAN_EXCLUSIVE_EXCLUSIVE; : Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
} else {
return Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
}
} else {
if (isEndExclusive) {
return Spannable.SPAN_INCLUSIVE_EXCLUSIVE;
} else {
return Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
} }
return isEndExclusive ? Spanned.SPAN_INCLUSIVE_EXCLUSIVE
: Spanned.SPAN_INCLUSIVE_INCLUSIVE;
} }
} }

View file

@ -71,13 +71,13 @@ public class NotificationCompatUtils {
CompatUtils.invoke(builder, null, METHOD_setPriority, PRIORITY_LOW); CompatUtils.invoke(builder, null, METHOD_setPriority, PRIORITY_LOW);
} }
@SuppressWarnings("deprecation")
public static Notification build(final Notification.Builder builder) { public static Notification build(final Notification.Builder builder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// #build was added in API level 16, JELLY_BEAN // #build was added in API level 16, JELLY_BEAN
return (Notification) CompatUtils.invoke(builder, null, METHOD_build); return (Notification) CompatUtils.invoke(builder, null, METHOD_build);
} else {
// #getNotification was deprecated in API level 16, JELLY_BEAN
return builder.getNotification();
} }
// #getNotification was deprecated in API level 16, JELLY_BEAN
return builder.getNotification();
} }
} }

View file

@ -122,19 +122,23 @@ public class ButtonSwitcher extends FrameLayout {
mDeleteButton.setTranslationX(STATUS_DELETE == status ? 0 : width); mDeleteButton.setTranslationX(STATUS_DELETE == status ? 0 : width);
} }
// The helper method for {@link AnimatorListenerAdapter}.
void animateButtonIfStatusIsEqual(final View newButton, final int newStatus) {
if (newStatus != mStatus) return;
animateButton(newButton, ANIMATION_IN);
}
private void animateButtonPosition(final int oldStatus, final int newStatus) { private void animateButtonPosition(final int oldStatus, final int newStatus) {
final View oldButton = getButton(oldStatus); final View oldButton = getButton(oldStatus);
final View newButton = getButton(newStatus); final View newButton = getButton(newStatus);
if (null != oldButton && null != newButton) { if (null != oldButton && null != newButton) {
// Transition between two buttons : animate out, then in // Transition between two buttons : animate out, then in
animateButton(oldButton, ANIMATION_OUT).setListener( animateButton(oldButton, ANIMATION_OUT).setListener(new AnimatorListenerAdapter() {
new AnimatorListenerAdapter() { @Override
@Override public void onAnimationEnd(final Animator animation) {
public void onAnimationEnd(final Animator animation) { animateButtonIfStatusIsEqual(newButton, newStatus);
if (newStatus != mStatus) return; }
animateButton(newButton, ANIMATION_IN); });
}
});
} else if (null != oldButton) { } else if (null != oldButton) {
animateButton(oldButton, ANIMATION_OUT); animateButton(oldButton, ANIMATION_OUT);
} else if (null != newButton) { } else if (null != newButton) {
@ -159,9 +163,8 @@ public class ButtonSwitcher extends FrameLayout {
if (ANIMATION_IN == direction) { if (ANIMATION_IN == direction) {
button.setClickable(true); button.setClickable(true);
return button.animate().translationX(0); return button.animate().translationX(0);
} else {
button.setClickable(false);
return button.animate().translationX(outerX - innerX);
} }
button.setClickable(false);
return button.animate().translationX(outerX - innerX);
} }
} }

View file

@ -148,7 +148,7 @@ public class DictionaryDownloadProgressBar extends ProgressBar {
} }
} }
private class UpdateHelper implements Runnable { class UpdateHelper implements Runnable {
private int mProgress; private int mProgress;
@Override @Override
public void run() { public void run() {

View file

@ -32,7 +32,7 @@ import java.util.HashMap;
* in case some dictionaries appeared, disappeared, changed states etc. * in case some dictionaries appeared, disappeared, changed states etc.
*/ */
public class DictionaryListInterfaceState { public class DictionaryListInterfaceState {
private static class State { static class State {
public boolean mOpen = false; public boolean mOpen = false;
public int mStatus = MetadataDbHelper.STATUS_UNKNOWN; public int mStatus = MetadataDbHelper.STATUS_UNKNOWN;
} }

View file

@ -255,10 +255,9 @@ public final class DictionaryProvider extends ContentProvider {
if (null != dictFiles && dictFiles.size() > 0) { if (null != dictFiles && dictFiles.size() > 0) {
PrivateLog.log("Returned " + dictFiles.size() + " files"); PrivateLog.log("Returned " + dictFiles.size() + " files");
return new ResourcePathCursor(dictFiles); return new ResourcePathCursor(dictFiles);
} else {
PrivateLog.log("No dictionary files for this URL");
return new ResourcePathCursor(Collections.<WordListInfo>emptyList());
} }
PrivateLog.log("No dictionary files for this URL");
return new ResourcePathCursor(Collections.<WordListInfo>emptyList());
// V2_METADATA and V2_DATAFILE are not supported for query() // V2_METADATA and V2_DATAFILE are not supported for query()
default: default:
return null; return null;
@ -319,14 +318,13 @@ public final class DictionaryProvider extends ContentProvider {
final AssetFileDescriptor afd = getContext().getResources().openRawResourceFd( final AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(
R.raw.empty); R.raw.empty);
return afd; return afd;
} else {
final String localFilename =
wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
final File f = getContext().getFileStreamPath(localFilename);
final ParcelFileDescriptor pfd =
ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
return new AssetFileDescriptor(pfd, 0, pfd.getStatSize());
} }
final String localFilename =
wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
final File f = getContext().getFileStreamPath(localFilename);
final ParcelFileDescriptor pfd =
ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
return new AssetFileDescriptor(pfd, 0, pfd.getStatSize());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
// No file : fall through and return null // No file : fall through and return null
} }
@ -461,13 +459,16 @@ public final class DictionaryProvider extends ContentProvider {
final String wordlistId = uri.getLastPathSegment(); final String wordlistId = uri.getLastPathSegment();
final String clientId = getClientId(uri); final String clientId = getClientId(uri);
final ContentValues wordList = getWordlistMetadataForWordlistId(clientId, wordlistId); final ContentValues wordList = getWordlistMetadataForWordlistId(clientId, wordlistId);
if (null == wordList) return 0; if (null == wordList) {
return 0;
}
final int status = wordList.getAsInteger(MetadataDbHelper.STATUS_COLUMN); final int status = wordList.getAsInteger(MetadataDbHelper.STATUS_COLUMN);
final int version = wordList.getAsInteger(MetadataDbHelper.VERSION_COLUMN); final int version = wordList.getAsInteger(MetadataDbHelper.VERSION_COLUMN);
if (MetadataDbHelper.STATUS_DELETING == status) { if (MetadataDbHelper.STATUS_DELETING == status) {
UpdateHandler.markAsDeleted(getContext(), clientId, wordlistId, version, status); UpdateHandler.markAsDeleted(getContext(), clientId, wordlistId, version, status);
return 1; return 1;
} else if (MetadataDbHelper.STATUS_INSTALLED == status) { }
if (MetadataDbHelper.STATUS_INSTALLED == status) {
final String result = uri.getQueryParameter(QUERY_PARAMETER_DELETE_RESULT); final String result = uri.getQueryParameter(QUERY_PARAMETER_DELETE_RESULT);
if (QUERY_PARAMETER_FAILURE.equals(result)) { if (QUERY_PARAMETER_FAILURE.equals(result)) {
if (DEBUG) { if (DEBUG) {
@ -480,15 +481,10 @@ public final class DictionaryProvider extends ContentProvider {
wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN); wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
final File f = getContext().getFileStreamPath(localFilename); final File f = getContext().getFileStreamPath(localFilename);
// f.delete() returns true if the file was successfully deleted, false otherwise // f.delete() returns true if the file was successfully deleted, false otherwise
if (f.delete()) { return f.delete() ? 1 : 0;
return 1;
} else {
return 0;
}
} else {
Log.e(TAG, "Attempt to delete a file whose status is " + status);
return 0;
} }
Log.e(TAG, "Attempt to delete a file whose status is " + status);
return 0;
} }
/** /**

View file

@ -179,7 +179,7 @@ public final class DictionaryService extends Service {
return Service.START_REDELIVER_INTENT; return Service.START_REDELIVER_INTENT;
} }
private static void dispatchBroadcast(final Context context, final Intent intent) { static void dispatchBroadcast(final Context context, final Intent intent) {
if (DATE_CHANGED_INTENT_ACTION.equals(intent.getAction())) { if (DATE_CHANGED_INTENT_ACTION.equals(intent.getAction())) {
// This happens when the date of the device changes. This normally happens // This happens when the date of the device changes. This normally happens
// at midnight local time, but it may happen if the user changes the date // at midnight local time, but it may happen if the user changes the date

View file

@ -31,7 +31,6 @@ import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -203,25 +202,19 @@ public final class DictionarySettingsFragment extends PreferenceFragment
@Override @Override
public void updateCycleCompleted() {} public void updateCycleCompleted() {}
private void refreshNetworkState() { void refreshNetworkState() {
NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
boolean isConnected = null == info ? false : info.isConnected(); boolean isConnected = null == info ? false : info.isConnected();
if (null != mUpdateNowMenu) mUpdateNowMenu.setEnabled(isConnected); if (null != mUpdateNowMenu) mUpdateNowMenu.setEnabled(isConnected);
} }
private void refreshInterface() { void refreshInterface() {
final Activity activity = getActivity(); final Activity activity = getActivity();
if (null == activity) return; if (null == activity) return;
final long lastUpdateDate =
MetadataDbHelper.getLastUpdateDateForClient(getActivity(), mClientId);
final PreferenceGroup prefScreen = getPreferenceScreen(); final PreferenceGroup prefScreen = getPreferenceScreen();
final Collection<? extends Preference> prefList = final Collection<? extends Preference> prefList =
createInstalledDictSettingsCollection(mClientId); createInstalledDictSettingsCollection(mClientId);
final String updateNowSummary = getString(R.string.last_update) + " "
+ DateUtils.formatDateTime(activity, lastUpdateDate,
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -239,14 +232,14 @@ public final class DictionarySettingsFragment extends PreferenceFragment
}); });
} }
private Preference createErrorMessage(final Activity activity, final int messageResource) { private static Preference createErrorMessage(final Activity activity, final int messageResource) {
final Preference message = new Preference(activity); final Preference message = new Preference(activity);
message.setTitle(messageResource); message.setTitle(messageResource);
message.setEnabled(false); message.setEnabled(false);
return message; return message;
} }
private void removeAnyDictSettings(final PreferenceGroup prefGroup) { static void removeAnyDictSettings(final PreferenceGroup prefGroup) {
for (int i = prefGroup.getPreferenceCount() - 1; i >= 0; --i) { for (int i = prefGroup.getPreferenceCount() - 1; i >= 0; --i) {
prefGroup.removePreference(prefGroup.getPreference(i)); prefGroup.removePreference(prefGroup.getPreference(i));
} }
@ -276,7 +269,7 @@ public final class DictionarySettingsFragment extends PreferenceFragment
.appendQueryParameter(DictionaryProvider.QUERY_PARAMETER_PROTOCOL_VERSION, "2") .appendQueryParameter(DictionaryProvider.QUERY_PARAMETER_PROTOCOL_VERSION, "2")
.build(); .build();
final Activity activity = getActivity(); final Activity activity = getActivity();
final Cursor cursor = null == activity ? null final Cursor cursor = (null == activity) ? null
: activity.getContentResolver().query(contentUri, null, null, null, null); : activity.getContentResolver().query(contentUri, null, null, null, null);
if (null == cursor) { if (null == cursor) {
@ -289,61 +282,57 @@ public final class DictionarySettingsFragment extends PreferenceFragment
final ArrayList<Preference> result = new ArrayList<>(); final ArrayList<Preference> result = new ArrayList<>();
result.add(createErrorMessage(activity, R.string.no_dictionaries_available)); result.add(createErrorMessage(activity, R.string.no_dictionaries_available));
return result; return result;
} else {
final String systemLocaleString = Locale.getDefault().toString();
final TreeMap<String, WordListPreference> prefMap = new TreeMap<>();
final int idIndex = cursor.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
final int versionIndex = cursor.getColumnIndex(MetadataDbHelper.VERSION_COLUMN);
final int localeIndex = cursor.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
final int descriptionIndex =
cursor.getColumnIndex(MetadataDbHelper.DESCRIPTION_COLUMN);
final int statusIndex = cursor.getColumnIndex(MetadataDbHelper.STATUS_COLUMN);
final int filesizeIndex = cursor.getColumnIndex(MetadataDbHelper.FILESIZE_COLUMN);
do {
final String wordlistId = cursor.getString(idIndex);
final int version = cursor.getInt(versionIndex);
final String localeString = cursor.getString(localeIndex);
final Locale locale = new Locale(localeString);
final String description = cursor.getString(descriptionIndex);
final int status = cursor.getInt(statusIndex);
final int matchLevel =
LocaleUtils.getMatchLevel(systemLocaleString, localeString);
final String matchLevelString =
LocaleUtils.getMatchLevelSortedString(matchLevel);
final int filesize = cursor.getInt(filesizeIndex);
// The key is sorted in lexicographic order, according to the match level, then
// the description.
final String key = matchLevelString + "." + description + "." + wordlistId;
final WordListPreference existingPref = prefMap.get(key);
if (null == existingPref || existingPref.hasPriorityOver(status)) {
final WordListPreference oldPreference = mCurrentPreferenceMap.get(key);
final WordListPreference pref;
if (null != oldPreference
&& oldPreference.mVersion == version
&& oldPreference.hasStatus(status)
&& oldPreference.mLocale.equals(locale)) {
// If the old preference has all the new attributes, reuse it. Ideally,
// we should reuse the old pref even if its status is different and call
// setStatus here, but setStatus calls Preference#setSummary() which
// needs to be done on the UI thread and we're not on the UI thread
// here. We could do all this work on the UI thread, but in this case
// it's probably lighter to stay on a background thread and throw this
// old preference out.
pref = oldPreference;
} else {
// Otherwise, discard it and create a new one instead.
// TODO: when the status is different from the old one, we need to
// animate the old one out before animating the new one in.
pref = new WordListPreference(activity, mDictionaryListInterfaceState,
mClientId, wordlistId, version, locale, description, status,
filesize);
}
prefMap.put(key, pref);
}
} while (cursor.moveToNext());
mCurrentPreferenceMap = prefMap;
return prefMap.values();
} }
final String systemLocaleString = Locale.getDefault().toString();
final TreeMap<String, WordListPreference> prefMap = new TreeMap<>();
final int idIndex = cursor.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
final int versionIndex = cursor.getColumnIndex(MetadataDbHelper.VERSION_COLUMN);
final int localeIndex = cursor.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
final int descriptionIndex = cursor.getColumnIndex(MetadataDbHelper.DESCRIPTION_COLUMN);
final int statusIndex = cursor.getColumnIndex(MetadataDbHelper.STATUS_COLUMN);
final int filesizeIndex = cursor.getColumnIndex(MetadataDbHelper.FILESIZE_COLUMN);
do {
final String wordlistId = cursor.getString(idIndex);
final int version = cursor.getInt(versionIndex);
final String localeString = cursor.getString(localeIndex);
final Locale locale = new Locale(localeString);
final String description = cursor.getString(descriptionIndex);
final int status = cursor.getInt(statusIndex);
final int matchLevel = LocaleUtils.getMatchLevel(systemLocaleString, localeString);
final String matchLevelString = LocaleUtils.getMatchLevelSortedString(matchLevel);
final int filesize = cursor.getInt(filesizeIndex);
// The key is sorted in lexicographic order, according to the match level, then
// the description.
final String key = matchLevelString + "." + description + "." + wordlistId;
final WordListPreference existingPref = prefMap.get(key);
if (null == existingPref || existingPref.hasPriorityOver(status)) {
final WordListPreference oldPreference = mCurrentPreferenceMap.get(key);
final WordListPreference pref;
if (null != oldPreference
&& oldPreference.mVersion == version
&& oldPreference.hasStatus(status)
&& oldPreference.mLocale.equals(locale)) {
// If the old preference has all the new attributes, reuse it. Ideally,
// we should reuse the old pref even if its status is different and call
// setStatus here, but setStatus calls Preference#setSummary() which
// needs to be done on the UI thread and we're not on the UI thread
// here. We could do all this work on the UI thread, but in this case
// it's probably lighter to stay on a background thread and throw this
// old preference out.
pref = oldPreference;
} else {
// Otherwise, discard it and create a new one instead.
// TODO: when the status is different from the old one, we need to
// animate the old one out before animating the new one in.
pref = new WordListPreference(activity, mDictionaryListInterfaceState,
mClientId, wordlistId, version, locale, description, status,
filesize);
}
prefMap.put(key, pref);
}
} while (cursor.moveToNext());
mCurrentPreferenceMap = prefMap;
return prefMap.values();
} finally { } finally {
cursor.close(); cursor.close();
} }
@ -396,26 +385,28 @@ public final class DictionarySettingsFragment extends PreferenceFragment
if (null != mUpdateNowMenu) mUpdateNowMenu.setTitle(R.string.cancel); if (null != mUpdateNowMenu) mUpdateNowMenu.setTitle(R.string.cancel);
} }
private void stopLoadingAnimation() { void stopLoadingAnimation() {
final View preferenceView = getView(); final View preferenceView = getView();
final Activity activity = getActivity(); final Activity activity = getActivity();
if (null == activity) return; if (null == activity) return;
final View loadingView = mLoadingView;
final MenuItem updateNowMenu = mUpdateNowMenu;
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
mLoadingView.setVisibility(View.GONE); loadingView.setVisibility(View.GONE);
preferenceView.setVisibility(View.VISIBLE); preferenceView.setVisibility(View.VISIBLE);
mLoadingView.startAnimation(AnimationUtils.loadAnimation( loadingView.startAnimation(AnimationUtils.loadAnimation(
getActivity(), android.R.anim.fade_out)); activity, android.R.anim.fade_out));
preferenceView.startAnimation(AnimationUtils.loadAnimation( preferenceView.startAnimation(AnimationUtils.loadAnimation(
getActivity(), android.R.anim.fade_in)); activity, android.R.anim.fade_in));
// The menu is created by the framework asynchronously after the activity, // The menu is created by the framework asynchronously after the activity,
// which means it's possible to have the activity running but the menu not // which means it's possible to have the activity running but the menu not
// created yet - hence the necessity for a null check here. // created yet - hence the necessity for a null check here.
if (null != mUpdateNowMenu) { if (null != updateNowMenu) {
mUpdateNowMenu.setTitle(R.string.check_for_updates_now); updateNowMenu.setTitle(R.string.check_for_updates_now);
}
} }
}); }
});
} }
} }

View file

@ -226,7 +226,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
createClientTable(db); createClientTable(db);
} }
private void addRawChecksumColumnUnlessPresent(final SQLiteDatabase db) { private static void addRawChecksumColumnUnlessPresent(final SQLiteDatabase db) {
try { try {
db.execSQL("SELECT " + RAW_CHECKSUM_COLUMN + " FROM " db.execSQL("SELECT " + RAW_CHECKSUM_COLUMN + " FROM "
+ METADATA_TABLE_NAME + " LIMIT 0;"); + METADATA_TABLE_NAME + " LIMIT 0;");
@ -237,7 +237,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
} }
} }
private void addRetryCountColumnUnlessPresent(final SQLiteDatabase db) { private static void addRetryCountColumnUnlessPresent(final SQLiteDatabase db) {
try { try {
db.execSQL("SELECT " + RETRY_COUNT_COLUMN + " FROM " db.execSQL("SELECT " + RETRY_COUNT_COLUMN + " FROM "
+ METADATA_TABLE_NAME + " LIMIT 0;"); + METADATA_TABLE_NAME + " LIMIT 0;");

View file

@ -30,9 +30,6 @@ import java.util.List;
* Helper class to easy up manipulation of dictionary pack metadata. * Helper class to easy up manipulation of dictionary pack metadata.
*/ */
public class MetadataHandler { public class MetadataHandler {
@SuppressWarnings("unused")
private static final String TAG = "DictionaryProvider:" + MetadataHandler.class.getSimpleName();
// The canonical file name for metadata. This is not the name of a real file on the // The canonical file name for metadata. This is not the name of a real file on the
// device, but a symbolic name used in the database and in metadata handling. It is never // device, but a symbolic name used in the database and in metadata handling. It is never
// tested against, only used for human-readability as the file name for the metadata. // tested against, only used for human-readability as the file name for the metadata.

View file

@ -43,8 +43,8 @@ public class PrivateLog {
+ COLUMN_DATE + " TEXT," + COLUMN_DATE + " TEXT,"
+ COLUMN_EVENT + " TEXT);"; + COLUMN_EVENT + " TEXT);";
private static final SimpleDateFormat sDateFormat = static final SimpleDateFormat sDateFormat = new SimpleDateFormat(
new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US); "yyyy/MM/dd HH:mm:ss", Locale.ROOT);
private static PrivateLog sInstance = new PrivateLog(); private static PrivateLog sInstance = new PrivateLog();
private static DebugHelper sDebugHelper = null; private static DebugHelper sDebugHelper = null;
@ -62,9 +62,9 @@ public class PrivateLog {
} }
} }
private static class DebugHelper extends SQLiteOpenHelper { static class DebugHelper extends SQLiteOpenHelper {
private DebugHelper(final Context context) { DebugHelper(final Context context) {
super(context, LOG_DATABASE_NAME, null, LOG_DATABASE_VERSION); super(context, LOG_DATABASE_NAME, null, LOG_DATABASE_VERSION);
} }
@ -84,7 +84,7 @@ public class PrivateLog {
insert(db, "Upgrade finished"); insert(db, "Upgrade finished");
} }
private static void insert(SQLiteDatabase db, String event) { static void insert(SQLiteDatabase db, String event) {
if (!DEBUG) return; if (!DEBUG) return;
final ContentValues c = new ContentValues(2); final ContentValues c = new ContentValues(2);
c.put(COLUMN_DATE, sDateFormat.format(new Date(System.currentTimeMillis()))); c.put(COLUMN_DATE, sDateFormat.format(new Date(System.currentTimeMillis())));

View file

@ -59,6 +59,8 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import javax.annotation.Nullable;
/** /**
* Handler for the update process. * Handler for the update process.
* *
@ -750,19 +752,22 @@ public final class UpdateHandler {
* @return an ordered list of runnables to be called to upgrade. * @return an ordered list of runnables to be called to upgrade.
*/ */
private static ActionBatch compareMetadataForUpgrade(final Context context, private static ActionBatch compareMetadataForUpgrade(final Context context,
final String clientId, List<WordListMetadata> from, List<WordListMetadata> to) { final String clientId, @Nullable final List<WordListMetadata> from,
@Nullable final List<WordListMetadata> to) {
final ActionBatch actions = new ActionBatch(); final ActionBatch actions = new ActionBatch();
// Upgrade existing word lists // Upgrade existing word lists
DebugLogUtils.l("Comparing dictionaries"); DebugLogUtils.l("Comparing dictionaries");
final Set<String> wordListIds = new TreeSet<>(); final Set<String> wordListIds = new TreeSet<>();
// TODO: Can these be null? // TODO: Can these be null?
if (null == from) from = new ArrayList<>(); final List<WordListMetadata> fromList = (from == null) ? new ArrayList<WordListMetadata>()
if (null == to) to = new ArrayList<>(); : from;
for (WordListMetadata wlData : from) wordListIds.add(wlData.mId); final List<WordListMetadata> toList = (to == null) ? new ArrayList<WordListMetadata>()
for (WordListMetadata wlData : to) wordListIds.add(wlData.mId); : to;
for (WordListMetadata wlData : fromList) wordListIds.add(wlData.mId);
for (WordListMetadata wlData : toList) wordListIds.add(wlData.mId);
for (String id : wordListIds) { for (String id : wordListIds) {
final WordListMetadata currentInfo = MetadataHandler.findWordListById(from, id); final WordListMetadata currentInfo = MetadataHandler.findWordListById(fromList, id);
final WordListMetadata metadataInfo = MetadataHandler.findWordListById(to, id); final WordListMetadata metadataInfo = MetadataHandler.findWordListById(toList, id);
// TODO: Remove the following unnecessary check, since we are now doing the filtering // TODO: Remove the following unnecessary check, since we are now doing the filtering
// inside findWordListById. // inside findWordListById.
final WordListMetadata newInfo = null == metadataInfo final WordListMetadata newInfo = null == metadataInfo

View file

@ -38,45 +38,39 @@ import java.util.Locale;
* enable or delete it as appropriate for the current state of the word list. * enable or delete it as appropriate for the current state of the word list.
*/ */
public final class WordListPreference extends Preference { public final class WordListPreference extends Preference {
static final private String TAG = WordListPreference.class.getSimpleName(); private static final String TAG = WordListPreference.class.getSimpleName();
// What to display in the "status" field when we receive unknown data as a status from // What to display in the "status" field when we receive unknown data as a status from
// the content provider. Empty string sounds sensible. // the content provider. Empty string sounds sensible.
static final private String NO_STATUS_MESSAGE = ""; private static final String NO_STATUS_MESSAGE = "";
/// Actions /// Actions
static final private int ACTION_UNKNOWN = 0; private static final int ACTION_UNKNOWN = 0;
static final private int ACTION_ENABLE_DICT = 1; private static final int ACTION_ENABLE_DICT = 1;
static final private int ACTION_DISABLE_DICT = 2; private static final int ACTION_DISABLE_DICT = 2;
static final private int ACTION_DELETE_DICT = 3; private static final int ACTION_DELETE_DICT = 3;
// Members // Members
// The context to get resources
final Context mContext;
// The id of the client for which this preference is.
final String mClientId;
// The metadata word list id and version of this word list. // The metadata word list id and version of this word list.
public final String mWordlistId; public final String mWordlistId;
public final int mVersion; public final int mVersion;
public final Locale mLocale; public final Locale mLocale;
public final String mDescription; public final String mDescription;
// The id of the client for which this preference is.
private final String mClientId;
// The status // The status
private int mStatus; private int mStatus;
// The size of the dictionary file // The size of the dictionary file
private final int mFilesize; private final int mFilesize;
private final DictionaryListInterfaceState mInterfaceState; private final DictionaryListInterfaceState mInterfaceState;
private final OnWordListPreferenceClick mPreferenceClickHandler =
new OnWordListPreferenceClick();
private final OnActionButtonClick mActionButtonClickHandler =
new OnActionButtonClick();
public WordListPreference(final Context context, public WordListPreference(final Context context,
final DictionaryListInterfaceState dictionaryListInterfaceState, final String clientId, final DictionaryListInterfaceState dictionaryListInterfaceState, final String clientId,
final String wordlistId, final int version, final Locale locale, final String wordlistId, final int version, final Locale locale,
final String description, final int status, final int filesize) { final String description, final int status, final int filesize) {
super(context, null); super(context, null);
mContext = context;
mInterfaceState = dictionaryListInterfaceState; mInterfaceState = dictionaryListInterfaceState;
mClientId = clientId; mClientId = clientId;
mVersion = version; mVersion = version;
@ -116,22 +110,23 @@ public final class WordListPreference extends Preference {
} }
private String getSummary(final int status) { private String getSummary(final int status) {
final Context context = getContext();
switch (status) { switch (status) {
// If we are deleting the word list, for the user it's like it's already deleted. // If we are deleting the word list, for the user it's like it's already deleted.
// It should be reinstallable. Exposing to the user the whole complexity of // It should be reinstallable. Exposing to the user the whole complexity of
// the delayed deletion process between the dictionary pack and Android Keyboard // the delayed deletion process between the dictionary pack and Android Keyboard
// would only be confusing. // would only be confusing.
case MetadataDbHelper.STATUS_DELETING: case MetadataDbHelper.STATUS_DELETING:
case MetadataDbHelper.STATUS_AVAILABLE: case MetadataDbHelper.STATUS_AVAILABLE:
return mContext.getString(R.string.dictionary_available); return context.getString(R.string.dictionary_available);
case MetadataDbHelper.STATUS_DOWNLOADING: case MetadataDbHelper.STATUS_DOWNLOADING:
return mContext.getString(R.string.dictionary_downloading); return context.getString(R.string.dictionary_downloading);
case MetadataDbHelper.STATUS_INSTALLED: case MetadataDbHelper.STATUS_INSTALLED:
return mContext.getString(R.string.dictionary_installed); return context.getString(R.string.dictionary_installed);
case MetadataDbHelper.STATUS_DISABLED: case MetadataDbHelper.STATUS_DISABLED:
return mContext.getString(R.string.dictionary_disabled); return context.getString(R.string.dictionary_disabled);
default: default:
return NO_STATUS_MESSAGE; return NO_STATUS_MESSAGE;
} }
} }
@ -154,7 +149,7 @@ public final class WordListPreference extends Preference {
{ ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT } { ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT }
}; };
private int getButtonSwitcherStatus(final int status) { static int getButtonSwitcherStatus(final int status) {
if (status >= sStatusActionList.length) { if (status >= sStatusActionList.length) {
Log.e(TAG, "Unknown status " + status); Log.e(TAG, "Unknown status " + status);
return ButtonSwitcher.STATUS_NO_BUTTON; return ButtonSwitcher.STATUS_NO_BUTTON;
@ -162,7 +157,7 @@ public final class WordListPreference extends Preference {
return sStatusActionList[status][0]; return sStatusActionList[status][0];
} }
private static int getActionIdFromStatusAndMenuEntry(final int status) { static int getActionIdFromStatusAndMenuEntry(final int status) {
if (status >= sStatusActionList.length) { if (status >= sStatusActionList.length) {
Log.e(TAG, "Unknown status " + status); Log.e(TAG, "Unknown status " + status);
return ACTION_UNKNOWN; return ACTION_UNKNOWN;
@ -171,9 +166,10 @@ public final class WordListPreference extends Preference {
} }
private void disableDict() { private void disableDict() {
SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext); final Context context = getContext();
final SharedPreferences prefs = CommonPreferences.getCommonPreferences(context);
CommonPreferences.disable(prefs, mWordlistId); CommonPreferences.disable(prefs, mWordlistId);
UpdateHandler.markAsUnused(mContext, mClientId, mWordlistId, mVersion, mStatus); UpdateHandler.markAsUnused(context, mClientId, mWordlistId, mVersion, mStatus);
if (MetadataDbHelper.STATUS_DOWNLOADING == mStatus) { if (MetadataDbHelper.STATUS_DOWNLOADING == mStatus) {
setStatus(MetadataDbHelper.STATUS_AVAILABLE); setStatus(MetadataDbHelper.STATUS_AVAILABLE);
} else if (MetadataDbHelper.STATUS_INSTALLED == mStatus) { } else if (MetadataDbHelper.STATUS_INSTALLED == mStatus) {
@ -184,11 +180,13 @@ public final class WordListPreference extends Preference {
Log.e(TAG, "Unexpected state of the word list for disabling " + mStatus); Log.e(TAG, "Unexpected state of the word list for disabling " + mStatus);
} }
} }
private void enableDict() { private void enableDict() {
SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext); final Context context = getContext();
final SharedPreferences prefs = CommonPreferences.getCommonPreferences(context);
CommonPreferences.enable(prefs, mWordlistId); CommonPreferences.enable(prefs, mWordlistId);
// Explicit enabling by the user : allow downloading on metered data connection. // Explicit enabling by the user : allow downloading on metered data connection.
UpdateHandler.markAsUsed(mContext, mClientId, mWordlistId, mVersion, mStatus, true); UpdateHandler.markAsUsed(context, mClientId, mWordlistId, mVersion, mStatus, true);
if (MetadataDbHelper.STATUS_AVAILABLE == mStatus) { if (MetadataDbHelper.STATUS_AVAILABLE == mStatus) {
setStatus(MetadataDbHelper.STATUS_DOWNLOADING); setStatus(MetadataDbHelper.STATUS_DOWNLOADING);
} else if (MetadataDbHelper.STATUS_DISABLED == mStatus } else if (MetadataDbHelper.STATUS_DISABLED == mStatus
@ -203,11 +201,13 @@ public final class WordListPreference extends Preference {
Log.e(TAG, "Unexpected state of the word list for enabling " + mStatus); Log.e(TAG, "Unexpected state of the word list for enabling " + mStatus);
} }
} }
private void deleteDict() { private void deleteDict() {
SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext); final Context context = getContext();
final SharedPreferences prefs = CommonPreferences.getCommonPreferences(context);
CommonPreferences.disable(prefs, mWordlistId); CommonPreferences.disable(prefs, mWordlistId);
setStatus(MetadataDbHelper.STATUS_DELETING); setStatus(MetadataDbHelper.STATUS_DELETING);
UpdateHandler.markAsDeleting(mContext, mClientId, mWordlistId, mVersion, mStatus); UpdateHandler.markAsDeleting(context, mClientId, mWordlistId, mVersion, mStatus);
} }
@Override @Override
@ -225,8 +225,8 @@ public final class WordListPreference extends Preference {
status.setVisibility(showProgressBar ? View.INVISIBLE : View.VISIBLE); status.setVisibility(showProgressBar ? View.INVISIBLE : View.VISIBLE);
progressBar.setVisibility(showProgressBar ? View.VISIBLE : View.INVISIBLE); progressBar.setVisibility(showProgressBar ? View.VISIBLE : View.INVISIBLE);
final ButtonSwitcher buttonSwitcher = final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)view.findViewById(
(ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher); R.id.wordlist_button_switcher);
// We need to clear the state of the button switcher, because we reuse views; if we didn't // We need to clear the state of the button switcher, because we reuse views; if we didn't
// reset it would animate from whatever its old state was. // reset it would animate from whatever its old state was.
buttonSwitcher.reset(mInterfaceState); buttonSwitcher.reset(mInterfaceState);
@ -244,63 +244,67 @@ public final class WordListPreference extends Preference {
// The button is closed. // The button is closed.
buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON); buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
} }
buttonSwitcher.setInternalOnClickListener(mActionButtonClickHandler); buttonSwitcher.setInternalOnClickListener(new View.OnClickListener() {
view.setOnClickListener(mPreferenceClickHandler); @Override
public void onClick(final View v) {
onActionButtonClicked();
}
});
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
onWordListClicked(v);
}
});
} }
private class OnWordListPreferenceClick implements View.OnClickListener { void onWordListClicked(final View v) {
@Override // Note : v is the preference view
public void onClick(final View v) { final ViewParent parent = v.getParent();
// Note : v is the preference view // Just in case something changed in the framework, test for the concrete class
final ViewParent parent = v.getParent(); if (!(parent instanceof ListView)) return;
// Just in case something changed in the framework, test for the concrete class final ListView listView = (ListView)parent;
if (!(parent instanceof ListView)) return; final int indexToOpen;
final ListView listView = (ListView)parent; // Close all first, we'll open back any item that needs to be open.
final int indexToOpen; final boolean wasOpen = mInterfaceState.isOpen(mWordlistId);
// Close all first, we'll open back any item that needs to be open. mInterfaceState.closeAll();
final boolean wasOpen = mInterfaceState.isOpen(mWordlistId); if (wasOpen) {
mInterfaceState.closeAll(); // This button being shown. Take note that we don't want to open any button in the
if (wasOpen) { // loop below.
// This button being shown. Take note that we don't want to open any button in the indexToOpen = -1;
// loop below. } else {
indexToOpen = -1; // This button was not being shown. Open it, and remember the index of this
// child as the one to open in the following loop.
mInterfaceState.setOpen(mWordlistId, mStatus);
indexToOpen = listView.indexOfChild(v);
}
final int lastDisplayedIndex =
listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();
// The "lastDisplayedIndex" is actually displayed, hence the <=
for (int i = 0; i <= lastDisplayedIndex; ++i) {
final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i)
.findViewById(R.id.wordlist_button_switcher);
if (i == indexToOpen) {
buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(mStatus));
} else { } else {
// This button was not being shown. Open it, and remember the index of this buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
// child as the one to open in the following loop.
mInterfaceState.setOpen(mWordlistId, mStatus);
indexToOpen = listView.indexOfChild(v);
}
final int lastDisplayedIndex =
listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();
// The "lastDisplayedIndex" is actually displayed, hence the <=
for (int i = 0; i <= lastDisplayedIndex; ++i) {
final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i)
.findViewById(R.id.wordlist_button_switcher);
if (i == indexToOpen) {
buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(mStatus));
} else {
buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
}
} }
} }
} }
private class OnActionButtonClick implements View.OnClickListener { void onActionButtonClicked() {
@Override switch (getActionIdFromStatusAndMenuEntry(mStatus)) {
public void onClick(final View v) { case ACTION_ENABLE_DICT:
switch (getActionIdFromStatusAndMenuEntry(mStatus)) { enableDict();
case ACTION_ENABLE_DICT: break;
enableDict(); case ACTION_DISABLE_DICT:
break; disableDict();
case ACTION_DISABLE_DICT: break;
disableDict(); case ACTION_DELETE_DICT:
break; deleteDict();
case ACTION_DELETE_DICT: break;
deleteDict(); default:
break; Log.e(TAG, "Unknown menu item pressed");
default:
Log.e(TAG, "Unknown menu item pressed");
}
} }
} }
} }

View file

@ -18,7 +18,6 @@ package com.android.inputmethod.event;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.view.KeyCharacterMap;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
@ -70,8 +69,8 @@ public class DeadKeyCombiner implements Combiner {
/** /**
* Maps Unicode combining diacritical to display-form dead key. * Maps Unicode combining diacritical to display-form dead key.
*/ */
private static final SparseIntArray sCombiningToAccent = new SparseIntArray(); static final SparseIntArray sCombiningToAccent = new SparseIntArray();
private static final SparseIntArray sAccentToCombining = new SparseIntArray(); static final SparseIntArray sAccentToCombining = new SparseIntArray();
static { static {
// U+0300: COMBINING GRAVE ACCENT // U+0300: COMBINING GRAVE ACCENT
addCombining('\u0300', ACCENT_GRAVE); addCombining('\u0300', ACCENT_GRAVE);
@ -217,21 +216,20 @@ public class DeadKeyCombiner implements Combiner {
final StringBuilder mDeadSequence = new StringBuilder(); final StringBuilder mDeadSequence = new StringBuilder();
@Nonnull @Nonnull
private Event createEventChainFromSequence(final @Nonnull CharSequence text, private static Event createEventChainFromSequence(final @Nonnull CharSequence text,
final Event originalEvent) { final Event originalEvent) {
if (text.length() <= 0) { if (text.length() <= 0) {
return originalEvent; return originalEvent;
} else {
Event lastEvent = null;
int codePoint = 0;
for (int i = text.length(); i > 0; i -= Character.charCount(codePoint)) {
codePoint = Character.codePointBefore(text, i);
final Event thisEvent = Event.createHardwareKeypressEvent(codePoint,
originalEvent.mKeyCode, lastEvent, false /* isKeyRepeat */);
lastEvent = thisEvent;
}
return lastEvent;
} }
Event lastEvent = null;
int codePoint = 0;
for (int i = text.length(); i > 0; i -= Character.charCount(codePoint)) {
codePoint = Character.codePointBefore(text, i);
final Event thisEvent = Event.createHardwareKeypressEvent(codePoint,
originalEvent.mKeyCode, lastEvent, false /* isKeyRepeat */);
lastEvent = thisEvent;
}
return lastEvent;
} }
@Override @Override
@ -248,51 +246,49 @@ public class DeadKeyCombiner implements Combiner {
// no dead keys at all in the current input, so this combiner has nothing to do and // no dead keys at all in the current input, so this combiner has nothing to do and
// simply returns the event as is. The majority of events will go through this path. // simply returns the event as is. The majority of events will go through this path.
return event; return event;
} else {
if (Character.isWhitespace(event.mCodePoint)
|| event.mCodePoint == mDeadSequence.codePointBefore(mDeadSequence.length())) {
// When whitespace or twice the same dead key, we should output the dead sequence
// as is.
final Event resultEvent = createEventChainFromSequence(mDeadSequence.toString(),
event);
mDeadSequence.setLength(0);
return resultEvent;
} else if (event.isFunctionalKeyEvent()) {
if (Constants.CODE_DELETE == event.mKeyCode) {
// Remove the last code point
final int trimIndex = mDeadSequence.length() - Character.charCount(
mDeadSequence.codePointBefore(mDeadSequence.length()));
mDeadSequence.setLength(trimIndex);
return Event.createConsumedEvent(event);
} else {
return event;
}
} else if (event.isDead()) {
mDeadSequence.appendCodePoint(event.mCodePoint);
return Event.createConsumedEvent(event);
} else {
// Combine normally.
final StringBuilder sb = new StringBuilder();
sb.appendCodePoint(event.mCodePoint);
int codePointIndex = 0;
while (codePointIndex < mDeadSequence.length()) {
final int deadCodePoint = mDeadSequence.codePointAt(codePointIndex);
final char replacementSpacingChar =
Data.getNonstandardCombination(deadCodePoint, event.mCodePoint);
if (Data.NOT_A_CHAR != replacementSpacingChar) {
sb.setCharAt(0, replacementSpacingChar);
} else {
final int combining = Data.sAccentToCombining.get(deadCodePoint);
sb.appendCodePoint(0 == combining ? deadCodePoint : combining);
}
codePointIndex += Character.isSupplementaryCodePoint(deadCodePoint) ? 2 : 1;
}
final String normalizedString = Normalizer.normalize(sb, Normalizer.Form.NFC);
final Event resultEvent = createEventChainFromSequence(normalizedString, event);
mDeadSequence.setLength(0);
return resultEvent;
}
} }
if (Character.isWhitespace(event.mCodePoint)
|| event.mCodePoint == mDeadSequence.codePointBefore(mDeadSequence.length())) {
// When whitespace or twice the same dead key, we should output the dead sequence as is.
final Event resultEvent = createEventChainFromSequence(mDeadSequence.toString(),
event);
mDeadSequence.setLength(0);
return resultEvent;
}
if (event.isFunctionalKeyEvent()) {
if (Constants.CODE_DELETE == event.mKeyCode) {
// Remove the last code point
final int trimIndex = mDeadSequence.length() - Character.charCount(
mDeadSequence.codePointBefore(mDeadSequence.length()));
mDeadSequence.setLength(trimIndex);
return Event.createConsumedEvent(event);
}
return event;
}
if (event.isDead()) {
mDeadSequence.appendCodePoint(event.mCodePoint);
return Event.createConsumedEvent(event);
}
// Combine normally.
final StringBuilder sb = new StringBuilder();
sb.appendCodePoint(event.mCodePoint);
int codePointIndex = 0;
while (codePointIndex < mDeadSequence.length()) {
final int deadCodePoint = mDeadSequence.codePointAt(codePointIndex);
final char replacementSpacingChar =
Data.getNonstandardCombination(deadCodePoint, event.mCodePoint);
if (Data.NOT_A_CHAR != replacementSpacingChar) {
sb.setCharAt(0, replacementSpacingChar);
} else {
final int combining = Data.sAccentToCombining.get(deadCodePoint);
sb.appendCodePoint(0 == combining ? deadCodePoint : combining);
}
codePointIndex += Character.isSupplementaryCodePoint(deadCodePoint) ? 2 : 1;
}
final String normalizedString = Normalizer.normalize(sb, Normalizer.Form.NFC);
final Event resultEvent = createEventChainFromSequence(normalizedString, event);
mDeadSequence.setLength(0);
return resultEvent;
} }
@Override @Override

View file

@ -21,6 +21,8 @@ import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
import javax.annotation.Nonnull;
/** /**
* Class representing a generic input event as handled by Latin IME. * Class representing a generic input event as handled by Latin IME.
* *
@ -134,12 +136,14 @@ public class Event {
} }
} }
@Nonnull
public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode, public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode,
final int x, final int y, final boolean isKeyRepeat) { final int x, final int y, final boolean isKeyRepeat) {
return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, x, y, return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, x, y,
null /* suggestedWordInfo */, isKeyRepeat ? FLAG_REPEAT : FLAG_NONE, null); null /* suggestedWordInfo */, isKeyRepeat ? FLAG_REPEAT : FLAG_NONE, null);
} }
@Nonnull
public static Event createHardwareKeypressEvent(final int codePoint, final int keyCode, public static Event createHardwareKeypressEvent(final int codePoint, final int keyCode,
final Event next, final boolean isKeyRepeat) { final Event next, final boolean isKeyRepeat) {
return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode,
@ -149,6 +153,7 @@ public class Event {
// This creates an input event for a dead character. @see {@link #FLAG_DEAD} // This creates an input event for a dead character. @see {@link #FLAG_DEAD}
@ExternallyReferenced @ExternallyReferenced
@Nonnull
public static Event createDeadEvent(final int codePoint, final int keyCode, final Event next) { public static Event createDeadEvent(final int codePoint, final int keyCode, final Event next) {
// TODO: add an argument or something if we ever create a software layout with dead keys. // TODO: add an argument or something if we ever create a software layout with dead keys.
return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode,
@ -163,6 +168,7 @@ public class Event {
* @param codePoint the code point. * @param codePoint the code point.
* @return an event for this code point. * @return an event for this code point.
*/ */
@Nonnull
public static Event createEventForCodePointFromUnknownSource(final int codePoint) { public static Event createEventForCodePointFromUnknownSource(final int codePoint) {
// TODO: should we have a different type of event for this? After all, it's not a key press. // TODO: should we have a different type of event for this? After all, it's not a key press.
return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE,
@ -178,6 +184,7 @@ public class Event {
* @param y the Y coordinate. * @param y the Y coordinate.
* @return an event for this code point and coordinates. * @return an event for this code point and coordinates.
*/ */
@Nonnull
public static Event createEventForCodePointFromAlreadyTypedText(final int codePoint, public static Event createEventForCodePointFromAlreadyTypedText(final int codePoint,
final int x, final int y) { final int x, final int y) {
// TODO: should we have a different type of event for this? After all, it's not a key press. // TODO: should we have a different type of event for this? After all, it's not a key press.
@ -189,6 +196,7 @@ public class Event {
* Creates an input event representing the manual pick of a suggestion. * Creates an input event representing the manual pick of a suggestion.
* @return an event for this suggestion pick. * @return an event for this suggestion pick.
*/ */
@Nonnull
public static Event createSuggestionPickedEvent(final SuggestedWordInfo suggestedWordInfo) { public static Event createSuggestionPickedEvent(final SuggestedWordInfo suggestedWordInfo) {
return new Event(EVENT_TYPE_SUGGESTION_PICKED, suggestedWordInfo.mWord, return new Event(EVENT_TYPE_SUGGESTION_PICKED, suggestedWordInfo.mWord,
NOT_A_CODE_POINT, NOT_A_KEY_CODE, NOT_A_CODE_POINT, NOT_A_KEY_CODE,
@ -204,6 +212,7 @@ public class Event {
* @param keyCode the key code, or NOT_A_KEYCODE if not applicable. * @param keyCode the key code, or NOT_A_KEYCODE if not applicable.
* @return an event for this text. * @return an event for this text.
*/ */
@Nonnull
public static Event createSoftwareTextEvent(final CharSequence text, final int keyCode) { public static Event createSoftwareTextEvent(final CharSequence text, final int keyCode) {
return new Event(EVENT_TYPE_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode, return new Event(EVENT_TYPE_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
@ -228,6 +237,7 @@ public class Event {
* @param source the event to copy the properties of. * @param source the event to copy the properties of.
* @return an identical event marked as consumed. * @return an identical event marked as consumed.
*/ */
@Nonnull
public static Event createConsumedEvent(final Event source) { public static Event createConsumedEvent(final Event source) {
// A consumed event should not input any text at all, so we pass the empty string as text. // A consumed event should not input any text at all, so we pass the empty string as text.
return new Event(source.mEventType, source.mText, source.mCodePoint, source.mKeyCode, return new Event(source.mEventType, source.mText, source.mCodePoint, source.mKeyCode,
@ -235,6 +245,7 @@ public class Event {
source.mNextEvent); source.mNextEvent);
} }
@Nonnull
public static Event createNotHandledEvent() { public static Event createNotHandledEvent() {
return new Event(EVENT_TYPE_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE, return new Event(EVENT_TYPE_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,

View file

@ -67,10 +67,9 @@ public class HardwareKeyboardEventDecoder implements HardwareEventDecoder {
if (keyEvent.isShiftPressed()) { if (keyEvent.isShiftPressed()) {
return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT,
Constants.CODE_SHIFT_ENTER, null /* next */, isKeyRepeat); Constants.CODE_SHIFT_ENTER, null /* next */, isKeyRepeat);
} else {
return Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
null /* next */, isKeyRepeat);
} }
return Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
null /* next */, isKeyRepeat);
} }
// If not Enter, then this is just a regular keypress event for a normal character // If not Enter, then this is just a regular keypress event for a normal character
// that can be committed right away, taking into account the current state. // that can be committed right away, taking into account the current state.

View file

@ -115,6 +115,7 @@ public class MyanmarReordering implements Combiner {
* @param newEvent the new event to add to the stream. null if none. * @param newEvent the new event to add to the stream. null if none.
* @return the resulting software text event. Never null. * @return the resulting software text event. Never null.
*/ */
@Nonnull
private Event clearAndGetResultingEvent(final Event newEvent) { private Event clearAndGetResultingEvent(final Event newEvent) {
final CharSequence combinedText; final CharSequence combinedText;
if (mCurrentEvents.size() > 0) { if (mCurrentEvents.size() > 0) {
@ -139,7 +140,8 @@ public class MyanmarReordering implements Combiner {
if (null == lastEvent) { if (null == lastEvent) {
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
return Event.createConsumedEvent(newEvent); return Event.createConsumedEvent(newEvent);
} else if (isConsonantOrMedial(lastEvent.mCodePoint)) { }
if (isConsonantOrMedial(lastEvent.mCodePoint)) {
final Event resultingEvent = clearAndGetResultingEvent(null); final Event resultingEvent = clearAndGetResultingEvent(null);
mCurrentEvents.add(Event.createSoftwareKeypressEvent(ZERO_WIDTH_NON_JOINER, mCurrentEvents.add(Event.createSoftwareKeypressEvent(ZERO_WIDTH_NON_JOINER,
Event.NOT_A_KEY_CODE, Event.NOT_A_KEY_CODE,
@ -147,15 +149,17 @@ public class MyanmarReordering implements Combiner {
false /* isKeyRepeat */)); false /* isKeyRepeat */));
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
return resultingEvent; return resultingEvent;
} else { // VOWEL_E == lastCodePoint. But if that was anything else this is correct too.
return clearAndGetResultingEvent(newEvent);
} }
} if (isConsonant(codePoint)) { // VOWEL_E == lastCodePoint. But if that was anything else this is correct too.
return clearAndGetResultingEvent(newEvent);
}
if (isConsonant(codePoint)) {
final Event lastEvent = getLastEvent(); final Event lastEvent = getLastEvent();
if (null == lastEvent) { if (null == lastEvent) {
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
return Event.createConsumedEvent(newEvent); return Event.createConsumedEvent(newEvent);
} else if (VOWEL_E == lastEvent.mCodePoint) { }
if (VOWEL_E == lastEvent.mCodePoint) {
final int eventSize = mCurrentEvents.size(); final int eventSize = mCurrentEvents.size();
if (eventSize >= 2 if (eventSize >= 2
&& mCurrentEvents.get(eventSize - 2).mCodePoint == ZERO_WIDTH_NON_JOINER) { && mCurrentEvents.get(eventSize - 2).mCodePoint == ZERO_WIDTH_NON_JOINER) {
@ -178,15 +182,17 @@ public class MyanmarReordering implements Combiner {
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
mCurrentEvents.add(lastEvent); mCurrentEvents.add(lastEvent);
return Event.createConsumedEvent(newEvent); return Event.createConsumedEvent(newEvent);
} else { // lastCodePoint is a consonant/medial. But if it's something else it's fine
return clearAndGetResultingEvent(newEvent);
} }
} else if (isMedial(codePoint)) { // lastCodePoint is a consonant/medial. But if it's something else it's fine
return clearAndGetResultingEvent(newEvent);
}
if (isMedial(codePoint)) {
final Event lastEvent = getLastEvent(); final Event lastEvent = getLastEvent();
if (null == lastEvent) { if (null == lastEvent) {
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
return Event.createConsumedEvent(newEvent); return Event.createConsumedEvent(newEvent);
} else if (VOWEL_E == lastEvent.mCodePoint) { }
if (VOWEL_E == lastEvent.mCodePoint) {
final int eventSize = mCurrentEvents.size(); final int eventSize = mCurrentEvents.size();
// If there is already a consonant, then we are in the middle of a syllable, and we // If there is already a consonant, then we are in the middle of a syllable, and we
// need to reorder. // need to reorder.
@ -205,37 +211,36 @@ public class MyanmarReordering implements Combiner {
} }
// Otherwise, we just commit everything. // Otherwise, we just commit everything.
return clearAndGetResultingEvent(null); return clearAndGetResultingEvent(null);
} else { // lastCodePoint is a consonant/medial. But if it's something else it's fine
return clearAndGetResultingEvent(newEvent);
} }
} else if (Constants.CODE_DELETE == newEvent.mKeyCode) { // lastCodePoint is a consonant/medial. But if it's something else it's fine
final Event lastEvent = getLastEvent(); return clearAndGetResultingEvent(newEvent);
}
final Event lastEvent = getLastEvent();
if (Constants.CODE_DELETE == newEvent.mKeyCode && null != lastEvent) {
final int eventSize = mCurrentEvents.size(); final int eventSize = mCurrentEvents.size();
if (null != lastEvent) { if (VOWEL_E == lastEvent.mCodePoint) {
if (VOWEL_E == lastEvent.mCodePoint) { // We have a VOWEL_E at the end. There are four cases.
// We have a VOWEL_E at the end. There are four cases. // - The vowel is the only code point in the buffer. Remove it.
// - The vowel is the only code point in the buffer. Remove it. // - The vowel is preceded by a ZWNJ. Remove both vowel E and ZWNJ.
// - The vowel is preceded by a ZWNJ. Remove both vowel E and ZWNJ. // - The vowel is preceded by a consonant/medial, remove the consonant/medial.
// - The vowel is preceded by a consonant/medial, remove the consonant/medial. // - In all other cases, it's strange, so just remove the last code point.
// - In all other cases, it's strange, so just remove the last code point. if (eventSize <= 1) {
if (eventSize <= 1) { mCurrentEvents.clear();
mCurrentEvents.clear(); } else { // eventSize >= 2
} else { // eventSize >= 2 final int previousCodePoint = mCurrentEvents.get(eventSize - 2).mCodePoint;
final int previousCodePoint = mCurrentEvents.get(eventSize - 2).mCodePoint; if (previousCodePoint == ZERO_WIDTH_NON_JOINER) {
if (previousCodePoint == ZERO_WIDTH_NON_JOINER) { mCurrentEvents.remove(eventSize - 1);
mCurrentEvents.remove(eventSize - 1); mCurrentEvents.remove(eventSize - 2);
mCurrentEvents.remove(eventSize - 2); } else if (isConsonantOrMedial(previousCodePoint)) {
} else if (isConsonantOrMedial(previousCodePoint)) { mCurrentEvents.remove(eventSize - 2);
mCurrentEvents.remove(eventSize - 2); } else {
} else { mCurrentEvents.remove(eventSize - 1);
mCurrentEvents.remove(eventSize - 1);
}
} }
return Event.createConsumedEvent(newEvent);
} else if (eventSize > 0) {
mCurrentEvents.remove(eventSize - 1);
return Event.createConsumedEvent(newEvent);
} }
return Event.createConsumedEvent(newEvent);
} else if (eventSize > 0) {
mCurrentEvents.remove(eventSize - 1);
return Event.createConsumedEvent(newEvent);
} }
} }
// This character is not part of the combining scheme, so we should reset everything. // This character is not part of the combining scheme, so we should reset everything.
@ -243,10 +248,9 @@ public class MyanmarReordering implements Combiner {
// If we have events in flight, then add the new event and return the resulting event. // If we have events in flight, then add the new event and return the resulting event.
mCurrentEvents.add(newEvent); mCurrentEvents.add(newEvent);
return clearAndGetResultingEvent(null); return clearAndGetResultingEvent(null);
} else {
// If we don't have any events in flight, then just pass this one through.
return newEvent;
} }
// If we don't have any events in flight, then just pass this one through.
return newEvent;
} }
@Override @Override

View file

@ -25,7 +25,6 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;

View file

@ -40,7 +40,6 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.define.DebugFlags; import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.utils.DebugLogUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.ScriptUtils; import com.android.inputmethod.latin.utils.ScriptUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@ -424,9 +423,8 @@ public final class KeyboardLayoutSet {
final String tag = parser.getName(); final String tag = parser.getName();
if (TAG_KEYBOARD_SET.equals(tag)) { if (TAG_KEYBOARD_SET.equals(tag)) {
break; break;
} else {
throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_KEYBOARD_SET);
} }
throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_KEYBOARD_SET);
} }
} }
} }

View file

@ -273,6 +273,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
} }
// Future method for requesting an updating to the shift state. // Future method for requesting an updating to the shift state.
@Override
public void requestUpdatingShiftState(final int currentAutoCapsState, public void requestUpdatingShiftState(final int currentAutoCapsState,
final int currentRecapitalizeState) { final int currentRecapitalizeState) {
mState.onUpdateShiftState(currentAutoCapsState, currentRecapitalizeState); mState.onUpdateShiftState(currentAutoCapsState, currentRecapitalizeState);

View file

@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard;
import android.graphics.Rect; import android.graphics.Rect;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.android.inputmethod.keyboard.internal.TouchPositionCorrection; import com.android.inputmethod.keyboard.internal.TouchPositionCorrection;

View file

@ -181,7 +181,7 @@ public class TextDecorator {
layoutMain(); layoutMain();
} }
private void layoutMain() { void layoutMain() {
final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper; final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper;
if (info == null) { if (info == null) {
@ -289,7 +289,7 @@ public class TextDecorator {
mHasRtlCharsInLastComposingText); mHasRtlCharsInLastComposingText);
} }
private void onClickIndicator() { void onClickIndicator() {
if (mMode != MODE_SHOWING_INDICATOR) { if (mMode != MODE_SHOWING_INDICATOR) {
return; return;
} }

View file

@ -147,7 +147,7 @@ final class EmojiCategory {
mShownCategories.add(properties); mShownCategories.add(properties);
} }
public String getCategoryName(final int categoryId, final int categoryPageId) { public static String getCategoryName(final int categoryId, final int categoryPageId) {
return sCategoryName[categoryId] + "-" + categoryPageId; return sCategoryName[categoryId] + "-" + categoryPageId;
} }

View file

@ -138,6 +138,21 @@ final class EmojiPageKeyboardView extends KeyboardView implements
return mKeyDetector.detectHitKey(x, y); return mKeyDetector.detectHitKey(x, y);
} }
void callListenerOnReleaseKey(final Key releasedKey, final boolean withKeyRegistering) {
releasedKey.onReleased();
invalidateKey(releasedKey);
if (withKeyRegistering) {
mListener.onReleaseKey(releasedKey);
}
}
void callListenerOnPressKey(final Key pressedKey) {
mPendingKeyDown = null;
pressedKey.onReleased();
invalidateKey(pressedKey);
mListener.onPressKey(pressedKey);
}
public void releaseCurrentKey(final boolean withKeyRegistering) { public void releaseCurrentKey(final boolean withKeyRegistering) {
mHandler.removeCallbacks(mPendingKeyDown); mHandler.removeCallbacks(mPendingKeyDown);
mPendingKeyDown = null; mPendingKeyDown = null;
@ -145,11 +160,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements
if (currentKey == null) { if (currentKey == null) {
return; return;
} }
currentKey.onReleased(); callListenerOnReleaseKey(currentKey, withKeyRegistering);
invalidateKey(currentKey);
if (withKeyRegistering) {
mListener.onReleaseKey(currentKey);
}
mCurrentKey = null; mCurrentKey = null;
} }
@ -165,10 +176,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mPendingKeyDown = new Runnable() { mPendingKeyDown = new Runnable() {
@Override @Override
public void run() { public void run() {
mPendingKeyDown = null; callListenerOnPressKey(key);
key.onPressed();
invalidateKey(key);
mListener.onPressKey(key);
} }
}; };
mHandler.postDelayed(mPendingKeyDown, KEY_PRESS_DELAY_TIME); mHandler.postDelayed(mPendingKeyDown, KEY_PRESS_DELAY_TIME);
@ -195,15 +203,11 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mHandler.postDelayed(new Runnable() { mHandler.postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
key.onReleased(); callListenerOnReleaseKey(key, true /* withRegistering */);
invalidateKey(key);
mListener.onReleaseKey(key);
} }
}, KEY_RELEASE_DELAY_TIME); }, KEY_RELEASE_DELAY_TIME);
} else { } else {
key.onReleased(); callListenerOnReleaseKey(key, true /* withRegistering */);
invalidateKey(key);
mListener.onReleaseKey(key);
} }
return true; return true;
} }

View file

@ -149,7 +149,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
} }
private void addTab(final TabHost host, final int categoryId) { private void addTab(final TabHost host, final int categoryId) {
final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */); final String tabId = EmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */);
final TabHost.TabSpec tspec = host.newTabSpec(tabId); final TabHost.TabSpec tspec = host.newTabSpec(tabId);
tspec.setContent(R.id.emoji_keyboard_dummy); tspec.setContent(R.id.emoji_keyboard_dummy);
final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate( final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(

View file

@ -148,7 +148,7 @@ public final class KeyPreviewChoreographer {
keyPreviewView.setPivotY(previewHeight); keyPreviewView.setPivotY(previewHeight);
} }
private void showKeyPreview(final Key key, final KeyPreviewView keyPreviewView, void showKeyPreview(final Key key, final KeyPreviewView keyPreviewView,
final boolean withAnimation) { final boolean withAnimation) {
if (!withAnimation) { if (!withAnimation) {
keyPreviewView.setVisibility(View.VISIBLE); keyPreviewView.setVisibility(View.VISIBLE);
@ -166,25 +166,25 @@ public final class KeyPreviewChoreographer {
} }
public Animator createShowUpAnimator(final Key key, final KeyPreviewView keyPreviewView) { public Animator createShowUpAnimator(final Key key, final KeyPreviewView keyPreviewView) {
final Animator animator = mParams.createShowUpAnimator(keyPreviewView); final Animator showUpAnimator = mParams.createShowUpAnimator(keyPreviewView);
animator.addListener(new AnimatorListenerAdapter() { showUpAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationStart(final Animator animator) { public void onAnimationStart(final Animator animator) {
showKeyPreview(key, keyPreviewView, false /* withAnimation */); showKeyPreview(key, keyPreviewView, false /* withAnimation */);
} }
}); });
return animator; return showUpAnimator;
} }
private Animator createDismissAnimator(final Key key, final KeyPreviewView keyPreviewView) { private Animator createDismissAnimator(final Key key, final KeyPreviewView keyPreviewView) {
final Animator animator = mParams.createDismissAnimator(keyPreviewView); final Animator dismissAnimator = mParams.createDismissAnimator(keyPreviewView);
animator.addListener(new AnimatorListenerAdapter() { dismissAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(final Animator animator) { public void onAnimationEnd(final Animator animator) {
dismissKeyPreview(key, false /* withAnimation */); dismissKeyPreview(key, false /* withAnimation */);
} }
}); });
return animator; return dismissAnimator;
} }
private static class KeyPreviewAnimators extends AnimatorListenerAdapter { private static class KeyPreviewAnimators extends AnimatorListenerAdapter {

View file

@ -733,18 +733,18 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
} }
} }
private boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) { private static boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) {
// TODO: adujst this for multilingual input // TODO: adujst this for multilingual input
return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString()); return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString());
} }
private boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) { private static boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) {
// TODO: adujst this for multilingual input // TODO: adujst this for multilingual input
return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode,
locales[0].getLanguage()); locales[0].getLanguage());
} }
private boolean matchCountryCodes(TypedArray caseAttr, Locale[] locales) { private static boolean matchCountryCodes(TypedArray caseAttr, Locale[] locales) {
// TODO: adujst this for multilingual input // TODO: adujst this for multilingual input
return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode, return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode,
locales[0].getCountry()); locales[0].getCountry());

View file

@ -28,7 +28,8 @@ import java.util.Arrays;
*/ */
@UsedForTesting @UsedForTesting
public class MatrixUtils { public class MatrixUtils {
private static final String TAG = MatrixUtils.class.getSimpleName(); static final String TAG = MatrixUtils.class.getSimpleName();
public static class MatrixOperationFailedException extends Exception { public static class MatrixOperationFailedException extends Exception {
private static final long serialVersionUID = 4384485606788583829L; private static final long serialVersionUID = 4384485606788583829L;

View file

@ -108,9 +108,8 @@ public final class MoreKeySpec {
: Constants.printableCode(mCode)); : Constants.printableCode(mCode));
if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) { if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {
return output; return output;
} else {
return label + "|" + output;
} }
return label + "|" + output;
} }
public static class LettersOnBaseLayout { public static class LettersOnBaseLayout {

View file

@ -80,6 +80,7 @@ public final class TouchPositionCorrection {
return mRadii.length; return mRadii.length;
} }
@SuppressWarnings("static-method")
public float getX(final int row) { public float getX(final int row) {
return 0.0f; return 0.0f;
// Touch position correction data for X coordinate is obsolete. // Touch position correction data for X coordinate is obsolete.

View file

@ -121,12 +121,11 @@ final public class BinaryDictionaryGetter {
// reason some dictionaries have been installed BUT the dictionary pack can't be // reason some dictionaries have been installed BUT the dictionary pack can't be
// found anymore it's safer to actually supply installed dictionaries. // found anymore it's safer to actually supply installed dictionaries.
return true; return true;
} else {
// The default is true here for the same reasons as above. We got the dictionary
// pack but if we don't have any settings for it it means the user has never been
// to the settings yet. So by default, the main dictionaries should be on.
return mDictPreferences.getBoolean(dictId, true);
} }
// The default is true here for the same reasons as above. We got the dictionary
// pack but if we don't have any settings for it it means the user has never been
// to the settings yet. So by default, the main dictionaries should be on.
return mDictPreferences.getBoolean(dictId, true);
} }
} }

View file

@ -26,7 +26,6 @@ import android.os.SystemClock;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
@ -164,7 +163,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
} }
} }
private boolean useFirstLastBigramsForLocale(final Locale locale) { private static boolean useFirstLastBigramsForLocale(final Locale locale) {
// TODO: Add firstname/lastname bigram rules for other languages. // TODO: Add firstname/lastname bigram rules for other languages.
if (locale != null && locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) { if (locale != null && locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
return true; return true;
@ -269,7 +268,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return end; return end;
} }
private boolean haveContentsChanged() { boolean haveContentsChanged() {
final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis();
final int contactCount = getContactCount(); final int contactCount = getContactCount();
if (contactCount > MAX_CONTACT_COUNT) { if (contactCount > MAX_CONTACT_COUNT) {

View file

@ -70,7 +70,7 @@ public final class DicTraverseSession {
mNativeDicTraverseSession, dictionary, previousWord, previousWordLength); mNativeDicTraverseSession, dictionary, previousWord, previousWordLength);
} }
private final long createNativeDicTraverseSession(String locale, long dictSize) { private static long createNativeDicTraverseSession(String locale, long dictSize) {
return setDicTraverseSessionNative(locale, dictSize); return setDicTraverseSessionNative(locale, dictSize);
} }

View file

@ -72,9 +72,13 @@ public abstract class Dictionary {
* Set out of the dictionary types listed above that are based on data specific to the user, * Set out of the dictionary types listed above that are based on data specific to the user,
* e.g., the user's contacts. * e.g., the user's contacts.
*/ */
private static final HashSet<String> sUserSpecificDictionaryTypes = private static final HashSet<String> sUserSpecificDictionaryTypes = new HashSet<>(Arrays.asList(
new HashSet(Arrays.asList(new String[] { TYPE_USER_TYPED, TYPE_USER, TYPE_CONTACTS, TYPE_USER_TYPED,
TYPE_USER_HISTORY, TYPE_PERSONALIZATION, TYPE_CONTEXTUAL })); TYPE_USER,
TYPE_CONTACTS,
TYPE_USER_HISTORY,
TYPE_PERSONALIZATION,
TYPE_CONTEXTUAL));
public Dictionary(final String dictType, final Locale locale) { public Dictionary(final String dictType, final Locale locale) {
mDictType = dictType; mDictType = dictType;

View file

@ -172,9 +172,8 @@ public class DictionaryFacilitator {
public Dictionary getDict(final String dictType) { public Dictionary getDict(final String dictType) {
if (Dictionary.TYPE_MAIN.equals(dictType)) { if (Dictionary.TYPE_MAIN.equals(dictType)) {
return mMainDict; return mMainDict;
} else {
return getSubDict(dictType);
} }
return getSubDict(dictType);
} }
public ExpandableBinaryDictionary getSubDict(final String dictType) { public ExpandableBinaryDictionary getSubDict(final String dictType) {
@ -184,9 +183,8 @@ public class DictionaryFacilitator {
public boolean hasDict(final String dictType) { public boolean hasDict(final String dictType) {
if (Dictionary.TYPE_MAIN.equals(dictType)) { if (Dictionary.TYPE_MAIN.equals(dictType)) {
return mMainDict != null; return mMainDict != null;
} else {
return mSubDictMap.containsKey(dictType);
} }
return mSubDictMap.containsKey(dictType);
} }
public void closeDict(final String dictType) { public void closeDict(final String dictType) {
@ -305,7 +303,7 @@ public class DictionaryFacilitator {
usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */); usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */);
} }
private DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups, static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
final Locale locale) { final Locale locale) {
for (int i = 0; i < dictionaryGroups.length; ++i) { for (int i = 0; i < dictionaryGroups.length; ++i) {
if (locale.equals(dictionaryGroups[i].mLocale)) { if (locale.equals(dictionaryGroups[i].mLocale)) {
@ -422,34 +420,41 @@ public class DictionaryFacilitator {
ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() { ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
@Override @Override
public void run() { public void run() {
for (final Locale locale : locales) { doReloadUninitializedMainDictionaries(
final DictionaryGroup dictionaryGroup = context, locales, listener, latchForWaitingLoadingMainDictionary);
findDictionaryGroupWithLocale(mDictionaryGroups, locale);
if (null == dictionaryGroup) {
// This should never happen, but better safe than crashy
Log.w(TAG, "Expected a dictionary group for " + locale + " but none found");
continue;
}
final Dictionary mainDict =
DictionaryFactory.createMainDictionaryFromManager(context, locale);
synchronized (mLock) {
if (locale.equals(dictionaryGroup.mLocale)) {
dictionaryGroup.setMainDict(mainDict);
} else {
// Dictionary facilitator has been reset for another locale.
mainDict.close();
}
}
}
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(
hasAtLeastOneInitializedMainDictionary());
}
latchForWaitingLoadingMainDictionary.countDown();
} }
}); });
} }
void doReloadUninitializedMainDictionaries(final Context context, final Locale[] locales,
final DictionaryInitializationListener listener,
final CountDownLatch latchForWaitingLoadingMainDictionary) {
for (final Locale locale : locales) {
final DictionaryGroup dictionaryGroup =
findDictionaryGroupWithLocale(mDictionaryGroups, locale);
if (null == dictionaryGroup) {
// This should never happen, but better safe than crashy
Log.w(TAG, "Expected a dictionary group for " + locale + " but none found");
continue;
}
final Dictionary mainDict =
DictionaryFactory.createMainDictionaryFromManager(context, locale);
synchronized (mLock) {
if (locale.equals(dictionaryGroup.mLocale)) {
dictionaryGroup.setMainDict(mainDict);
} else {
// Dictionary facilitator has been reset for another locale.
mainDict.close();
}
}
}
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(
hasAtLeastOneInitializedMainDictionary());
}
latchForWaitingLoadingMainDictionary.countDown();
}
@UsedForTesting @UsedForTesting
public void resetDictionariesForTesting(final Context context, final Locale[] locales, public void resetDictionariesForTesting(final Context context, final Locale[] locales,
final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,

View file

@ -31,7 +31,7 @@ import android.util.LruCache;
* This class automatically creates and releases facilitator instances using LRU policy. * This class automatically creates and releases facilitator instances using LRU policy.
*/ */
public class DictionaryFacilitatorLruCache { public class DictionaryFacilitatorLruCache {
private static final String TAG = DictionaryFacilitatorLruCache.class.getSimpleName(); static final String TAG = DictionaryFacilitatorLruCache.class.getSimpleName();
private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000; private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000;
private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5; private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5;
@ -81,7 +81,8 @@ public class DictionaryFacilitatorLruCache {
mDictionaryNamePrefix = dictionaryNamePrefix; mDictionaryNamePrefix = dictionaryNamePrefix;
} }
private void waitForLoadingMainDictionary(final DictionaryFacilitator dictionaryFacilitator) { private static void waitForLoadingMainDictionary(
final DictionaryFacilitator dictionaryFacilitator) {
for (int i = 0; i < MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT; i++) { for (int i = 0; i < MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT; i++) {
try { try {
dictionaryFacilitator.waitForLoadingMainDictionaries( dictionaryFacilitator.waitForLoadingMainDictionaries(

View file

@ -21,11 +21,11 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils;
@ -47,6 +47,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* Abstract base class for an expandable dictionary that can be created and updated dynamically * Abstract base class for an expandable dictionary that can be created and updated dynamically
@ -107,11 +108,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/ */
protected abstract void loadInitialContentsLocked(); protected abstract void loadInitialContentsLocked();
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) { static boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
return formatVersion == FormatSpec.VERSION4; return formatVersion == FormatSpec.VERSION4;
} }
private boolean needsToMigrateDictionary(final int formatVersion) { private static boolean needsToMigrateDictionary(final int formatVersion) {
// When we bump up the dictionary format version, the old version should be added to here // When we bump up the dictionary format version, the old version should be added to here
// for supporting migration. Note that native code has to support reading such formats. // for supporting migration. Note that native code has to support reading such formats.
return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING; return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING;
@ -159,7 +160,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithLock(mLock.writeLock(), mDictName /* executorName */, task); asyncExecuteTaskWithLock(mLock.writeLock(), mDictName /* executorName */, task);
} }
private void asyncExecuteTaskWithLock(final Lock lock, final String executorName, private static void asyncExecuteTaskWithLock(final Lock lock, final String executorName,
final Runnable task) { final Runnable task) {
asyncPreCheckAndExecuteTaskWithLock(lock, null /* preCheckTask */, executorName, task); asyncPreCheckAndExecuteTaskWithLock(lock, null /* preCheckTask */, executorName, task);
} }
@ -172,8 +173,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
// Execute task with lock when the result of preCheckTask is true or preCheckTask is null. // Execute task with lock when the result of preCheckTask is true or preCheckTask is null.
private void asyncPreCheckAndExecuteTaskWithLock(final Lock lock, private static void asyncPreCheckAndExecuteTaskWithLock(final Lock lock,
final Callable<Boolean> preCheckTask, final String executorName, final Runnable task) { final Callable<Boolean> preCheckTask, final String executorName, final Runnable task) {
final String tag = TAG;
ExecutorUtils.getExecutor(executorName).execute(new Runnable() { ExecutorUtils.getExecutor(executorName).execute(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -183,7 +185,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return; return;
} }
} catch (final Exception e) { } catch (final Exception e) {
Log.e(TAG, "The pre check task throws an exception.", e); Log.e(tag, "The pre check task throws an exception.", e);
return; return;
} }
} }
@ -197,6 +199,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}); });
} }
@Nullable
BinaryDictionary getBinaryDictionary() {
return mBinaryDictionary;
}
void closeBinaryDictionary() {
if (mBinaryDictionary != null) {
mBinaryDictionary.close();
mBinaryDictionary = null;
}
}
/** /**
* Closes and cleans up the binary dictionary. * Closes and cleans up the binary dictionary.
*/ */
@ -205,10 +219,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary != null) { closeBinaryDictionary();
mBinaryDictionary.close();
mBinaryDictionary = null;
}
} }
}); });
} }
@ -234,14 +245,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}); });
} }
private void removeBinaryDictionaryLocked() { void removeBinaryDictionaryLocked() {
if (mBinaryDictionary != null) { closeBinaryDictionary();
mBinaryDictionary.close();
}
if (mDictFile.exists() && !FileUtils.deleteRecursively(mDictFile)) { if (mDictFile.exists() && !FileUtils.deleteRecursively(mDictFile)) {
Log.e(TAG, "Can't remove a file: " + mDictFile.getName()); Log.e(TAG, "Can't remove a file: " + mDictFile.getName());
} }
mBinaryDictionary = null;
} }
private void openBinaryDictionaryLocked() { private void openBinaryDictionaryLocked() {
@ -250,7 +258,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
true /* useFullEditDistance */, mLocale, mDictType, true /* isUpdatable */); true /* useFullEditDistance */, mLocale, mDictType, true /* isUpdatable */);
} }
private void createOnMemoryBinaryDictionaryLocked() { void createOnMemoryBinaryDictionaryLocked() {
mBinaryDictionary = new BinaryDictionary( mBinaryDictionary = new BinaryDictionary(
mDictFile.getAbsolutePath(), true /* useFullEditDistance */, mLocale, mDictType, mDictFile.getAbsolutePath(), true /* useFullEditDistance */, mLocale, mDictType,
DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap()); DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap());
@ -273,7 +281,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { if (getBinaryDictionary() == null) {
return; return;
} }
runGCIfRequiredLocked(mindsBlockByGC); runGCIfRequiredLocked(mindsBlockByGC);
@ -291,24 +299,24 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Nonnull final Runnable updateTask, @Nonnull final Runnable updateTask,
@Nonnull final String word, @Nonnull final DistracterFilter distracterFilter) { @Nonnull final String word, @Nonnull final DistracterFilter distracterFilter) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncPreCheckAndExecuteTaskWithWriteLock( final Callable<Boolean> preCheckTask = new Callable<Boolean>() {
new Callable<Boolean>() { @Override
@Override public Boolean call() throws Exception {
public Boolean call() throws Exception { return !distracterFilter.isDistracterToWordsInDictionaries(
return !distracterFilter.isDistracterToWordsInDictionaries( NgramContext.EMPTY_PREV_WORDS_INFO, word, mLocale);
NgramContext.EMPTY_PREV_WORDS_INFO, word, mLocale); }
} };
}, final Runnable task = new Runnable() {
new Runnable() { @Override
@Override public void run() {
public void run() { if (getBinaryDictionary() == null) {
if (mBinaryDictionary == null) { return;
return; }
} runGCIfRequiredLocked(true /* mindsBlockByGC */);
runGCIfRequiredLocked(true /* mindsBlockByGC */); updateTask.run();
updateTask.run(); }
} };
}); asyncPreCheckAndExecuteTaskWithWriteLock(preCheckTask, task);
} }
/** /**
@ -344,11 +352,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
if (!mBinaryDictionary.removeUnigramEntry(word)) { if (!binaryDictionary.removeUnigramEntry(word)) {
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "Cannot remove unigram entry: " + word); Log.i(TAG, "Cannot remove unigram entry: " + word);
} }
@ -366,7 +375,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { if (getBinaryDictionary() == null) {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
@ -395,11 +404,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
if (!mBinaryDictionary.removeNgramEntry(ngramContext, word)) { if (!binaryDictionary.removeNgramEntry(ngramContext, word)) {
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "Cannot remove n-gram entry."); Log.i(TAG, "Cannot remove n-gram entry.");
Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word); Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word);
@ -418,7 +428,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
updateDictionaryWithWriteLockIfWordIsNotADistracter(new Runnable() { updateDictionaryWithWriteLockIfWordIsNotADistracter(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!mBinaryDictionary.updateEntriesForWordWithNgramContext(ngramContext, word, final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return;
}
if (!binaryDictionary.updateEntriesForWordWithNgramContext(ngramContext, word,
isValidWord, count, timestamp)) { isValidWord, count, timestamp)) {
if (DEBUG) { if (DEBUG) {
Log.e(TAG, "Cannot update counter. word: " + word Log.e(TAG, "Cannot update counter. word: " + word
@ -444,10 +458,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override @Override
public void run() { public void run() {
try { try {
if (mBinaryDictionary == null) { final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return; return;
} }
mBinaryDictionary.addMultipleDictionaryEntries( binaryDictionary.addMultipleDictionaryEntries(
languageModelParams.toArray( languageModelParams.toArray(
new LanguageModelParam[languageModelParams.size()])); new LanguageModelParam[languageModelParams.size()]));
} finally { } finally {
@ -555,7 +570,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Loads the current binary dictionary from internal storage. Assumes the dictionary file * Loads the current binary dictionary from internal storage. Assumes the dictionary file
* exists. * exists.
*/ */
private void loadBinaryDictionaryLocked() { void loadBinaryDictionaryLocked() {
if (DBG_STRESS_TEST) { if (DBG_STRESS_TEST) {
// Test if this class does not cause problems when it takes long time to load binary // Test if this class does not cause problems when it takes long time to load binary
// dictionary. // dictionary.
@ -583,7 +598,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** /**
* Create a new binary dictionary and load initial contents. * Create a new binary dictionary and load initial contents.
*/ */
private void createNewDictionaryLocked() { void createNewDictionaryLocked() {
removeBinaryDictionaryLocked(); removeBinaryDictionaryLocked();
createOnMemoryBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked();
loadInitialContentsLocked(); loadInitialContentsLocked();
@ -599,6 +614,14 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mNeedsToRecreate = true; mNeedsToRecreate = true;
} }
void clearNeedsToRecreate() {
mNeedsToRecreate = false;
}
boolean isNeededToRecreate() {
return mNeedsToRecreate;
}
/** /**
* Load the current binary dictionary from internal storage. If the dictionary file doesn't * Load the current binary dictionary from internal storage. If the dictionary file doesn't
* exists or needs to be regenerated, the new dictionary file will be asynchronously generated. * exists or needs to be regenerated, the new dictionary file will be asynchronously generated.
@ -621,35 +644,39 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Reloads the dictionary. Access is controlled on a per dictionary file basis. * Reloads the dictionary. Access is controlled on a per dictionary file basis.
*/ */
private final void asyncReloadDictionary() { private final void asyncReloadDictionary() {
if (mIsReloading.compareAndSet(false, true)) { final AtomicBoolean isReloading = mIsReloading;
asyncExecuteTaskWithWriteLock(new Runnable() { if (!isReloading.compareAndSet(false, true)) {
@Override return;
public void run() {
try {
if (!mDictFile.exists() || mNeedsToRecreate) {
// If the dictionary file does not exist or contents have been updated,
// generate a new one.
createNewDictionaryLocked();
} else if (mBinaryDictionary == null) {
// Otherwise, load the existing dictionary.
loadBinaryDictionaryLocked();
if (mBinaryDictionary != null && !(isValidDictionaryLocked()
// TODO: remove the check below
&& matchesExpectedBinaryDictFormatVersionForThisType(
mBinaryDictionary.getFormatVersion()))) {
// Binary dictionary or its format version is not valid. Regenerate
// the dictionary file. createNewDictionaryLocked will remove the
// existing files if appropriate.
createNewDictionaryLocked();
}
}
mNeedsToRecreate = false;
} finally {
mIsReloading.set(false);
}
}
});
} }
final File dictFile = mDictFile;
asyncExecuteTaskWithWriteLock(new Runnable() {
@Override
public void run() {
try {
if (!dictFile.exists() || isNeededToRecreate()) {
// If the dictionary file does not exist or contents have been updated,
// generate a new one.
createNewDictionaryLocked();
} else if (getBinaryDictionary() == null) {
// Otherwise, load the existing dictionary.
loadBinaryDictionaryLocked();
final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary != null && !(isValidDictionaryLocked()
// TODO: remove the check below
&& matchesExpectedBinaryDictFormatVersionForThisType(
binaryDictionary.getFormatVersion()))) {
// Binary dictionary or its format version is not valid. Regenerate
// the dictionary file. createNewDictionaryLocked will remove the
// existing files if appropriate.
createNewDictionaryLocked();
}
}
clearNeedsToRecreate();
} finally {
isReloading.set(false);
}
}
});
} }
/** /**
@ -659,19 +686,20 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return; return;
} }
if (mBinaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) { if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
mBinaryDictionary.flushWithGC(); binaryDictionary.flushWithGC();
} else { } else {
mBinaryDictionary.flush(); binaryDictionary.flush();
} }
} }
}); });
} }
private static int parseEntryCount(final String entryCountStr) { static int parseEntryCount(final String entryCountStr) {
int entryCount; int entryCount;
try { try {
entryCount = Integer.parseInt(entryCountStr); entryCount = Integer.parseInt(entryCountStr);
@ -683,23 +711,27 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public DictionaryStats getDictionaryStats() { public DictionaryStats getDictionaryStats() {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
final String dictName = mDictName;
final File dictFile = mDictFile;
final AsyncResultHolder<DictionaryStats> result = new AsyncResultHolder<>(); final AsyncResultHolder<DictionaryStats> result = new AsyncResultHolder<>();
asyncExecuteTaskWithLock(mLock.readLock(), mDictName /* executorName */, new Runnable() { asyncExecuteTaskWithLock(mLock.readLock(), dictName /* executorName */, new Runnable() {
@Override @Override
public void run() { public void run() {
if (mBinaryDictionary == null) { final BinaryDictionary binaryDictionary = getBinaryDictionary();
result.set(new DictionaryStats(mLocale, mDictName, mDictFile, if (binaryDictionary == null) {
result.set(new DictionaryStats(mLocale, dictName, dictFile,
DictionaryStats.NOT_AN_ENTRY_COUNT, DictionaryStats.NOT_AN_ENTRY_COUNT,
DictionaryStats.NOT_AN_ENTRY_COUNT)); DictionaryStats.NOT_AN_ENTRY_COUNT));
return;
} }
final int unigramCount = parseEntryCount( final int unigramCount = parseEntryCount(
mBinaryDictionary.getPropertyForGettingStats( binaryDictionary.getPropertyForGettingStats(
BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY)); BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
// TODO: Get dedicated entry counts for bigram, trigram, and so on. // TODO: Get dedicated entry counts for bigram, trigram, and so on.
final int ngramCount = parseEntryCount(mBinaryDictionary.getPropertyForGettingStats( final int ngramCount = parseEntryCount(binaryDictionary.getPropertyForGettingStats(
BinaryDictionary.MAX_BIGRAM_COUNT_QUERY)); BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
// TODO: Get more information from dictionary. // TODO: Get more information from dictionary.
result.set(new DictionaryStats(mLocale, mDictName, mDictFile, unigramCount, result.set(new DictionaryStats(mLocale, dictName, dictFile, unigramCount,
ngramCount)); ngramCount));
} }
}); });
@ -731,28 +763,34 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void dumpAllWordsForDebug() { public void dumpAllWordsForDebug() {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
final String tag = TAG;
final String dictName = mDictName;
asyncExecuteTaskWithLock(mLock.readLock(), "dumpAllWordsForDebug", new Runnable() { asyncExecuteTaskWithLock(mLock.readLock(), "dumpAllWordsForDebug", new Runnable() {
@Override @Override
public void run() { public void run() {
Log.d(TAG, "Dump dictionary: " + mDictName + " for " + mLocale); Log.d(tag, "Dump dictionary: " + dictName + " for " + mLocale);
final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) {
return;
}
try { try {
final DictionaryHeader header = mBinaryDictionary.getHeader(); final DictionaryHeader header = binaryDictionary.getHeader();
Log.d(TAG, "Format version: " + mBinaryDictionary.getFormatVersion()); Log.d(tag, "Format version: " + binaryDictionary.getFormatVersion());
Log.d(TAG, CombinedFormatUtils.formatAttributeMap( Log.d(tag, CombinedFormatUtils.formatAttributeMap(
header.mDictionaryOptions.mAttributes)); header.mDictionaryOptions.mAttributes));
} catch (final UnsupportedFormatException e) { } catch (final UnsupportedFormatException e) {
Log.d(TAG, "Cannot fetch header information.", e); Log.d(tag, "Cannot fetch header information.", e);
} }
int token = 0; int token = 0;
do { do {
final BinaryDictionary.GetNextWordPropertyResult result = final BinaryDictionary.GetNextWordPropertyResult result =
mBinaryDictionary.getNextWordProperty(token); binaryDictionary.getNextWordProperty(token);
final WordProperty wordProperty = result.mWordProperty; final WordProperty wordProperty = result.mWordProperty;
if (wordProperty == null) { if (wordProperty == null) {
Log.d(TAG, " dictionary is empty."); Log.d(tag, " dictionary is empty.");
break; break;
} }
Log.d(TAG, wordProperty.toString()); Log.d(tag, wordProperty.toString());
token = result.mNextToken; token = result.mNextToken;
} while (token != 0); } while (token != 0);
} }

View file

@ -119,15 +119,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
SuggestionStripView.Listener, SuggestionStripViewAccessor, SuggestionStripView.Listener, SuggestionStripViewAccessor,
DictionaryFacilitator.DictionaryInitializationListener, DictionaryFacilitator.DictionaryInitializationListener,
ImportantNoticeDialog.ImportantNoticeDialogListener { ImportantNoticeDialog.ImportantNoticeDialogListener {
private static final String TAG = LatinIME.class.getSimpleName(); static final String TAG = LatinIME.class.getSimpleName();
private static final boolean TRACE = false; private static final boolean TRACE = false;
private static boolean DEBUG = false; private static boolean DEBUG = false;
private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100;
private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2; private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2;
private static final int PENDING_IMS_CALLBACK_DURATION_MILLIS = 800; private static final int PENDING_IMS_CALLBACK_DURATION_MILLIS = 800;
private static final long DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS = TimeUnit.SECONDS.toMillis(2); static final long DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS = TimeUnit.SECONDS.toMillis(2);
private static final long DELAY_DEALLOCATE_MEMORY_MILLIS = TimeUnit.SECONDS.toMillis(10); static final long DELAY_DEALLOCATE_MEMORY_MILLIS = TimeUnit.SECONDS.toMillis(10);
/** /**
* The name of the scheme used by the Package Manager to warn of a new package installation, * The name of the scheme used by the Package Manager to warn of a new package installation,
@ -135,7 +135,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/ */
private static final String SCHEME_PACKAGE = "package"; private static final String SCHEME_PACKAGE = "package";
private final Settings mSettings; final Settings mSettings;
private final DictionaryFacilitator mDictionaryFacilitator = private final DictionaryFacilitator mDictionaryFacilitator =
new DictionaryFacilitator(this /* context */); new DictionaryFacilitator(this /* context */);
// TODO: Move from LatinIME. // TODO: Move from LatinIME.
@ -149,7 +149,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE); mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
} }
}); });
private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */, final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
this /* SuggestionStripViewAccessor */, mDictionaryFacilitator); this /* SuggestionStripViewAccessor */, mDictionaryFacilitator);
// We expect to have only one decoder in almost all cases, hence the default capacity of 1. // We expect to have only one decoder in almost all cases, hence the default capacity of 1.
// If it turns out we need several, it will get grown seamlessly. // If it turns out we need several, it will get grown seamlessly.
@ -163,7 +163,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private RichInputMethodManager mRichImm; private RichInputMethodManager mRichImm;
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher; final SubtypeSwitcher mSubtypeSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState(); private final SubtypeState mSubtypeState = new SubtypeState();
private final SpecialKeyDetector mSpecialKeyDetector; private final SpecialKeyDetector mSpecialKeyDetector;
private StatsUtilsManager mStatsUtilsManager; private StatsUtilsManager mStatsUtilsManager;
@ -204,7 +204,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2; private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2;
private static final int ARG2_UNUSED = 0; private static final int ARG2_UNUSED = 0;
private static final int ARG1_FALSE = 0;
private static final int ARG1_TRUE = 1; private static final int ARG1_TRUE = 1;
private int mDelayInMillisecondsToUpdateSuggestions; private int mDelayInMillisecondsToUpdateSuggestions;
@ -654,7 +653,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
private void resetDictionaryFacilitatorIfNecessary() { void resetDictionaryFacilitatorIfNecessary() {
final Locale[] subtypeSwitcherLocales = mSubtypeSwitcher.getCurrentSubtypeLocales(); final Locale[] subtypeSwitcherLocales = mSubtypeSwitcher.getCurrentSubtypeLocales();
if (mDictionaryFacilitator.isForLocales(subtypeSwitcherLocales)) { if (mDictionaryFacilitator.isForLocales(subtypeSwitcherLocales)) {
return; return;
@ -791,17 +790,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
void updateCursorAnchorInfo() {
// CursorAnchorInfo is used on L and later.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isFullscreenMode() && mExtractEditText != null) {
mInputLogic.onUpdateCursorAnchorInfo(
CursorAnchorInfoUtils.extractFromTextView(mExtractEditText));
}
}
}
private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener = private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener =
new ViewTreeObserver.OnPreDrawListener() { new ViewTreeObserver.OnPreDrawListener() {
@Override @Override
public boolean onPreDraw() { public boolean onPreDraw() {
// CursorAnchorInfo is used on L and later. updateCursorAnchorInfo();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (isFullscreenMode() && mExtractEditText != null) {
mInputLogic.onUpdateCursorAnchorInfo(
CursorAnchorInfoUtils.extractFromTextView(mExtractEditText));
}
}
return true; return true;
} }
}; };
@ -846,12 +849,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
loadKeyboard(); loadKeyboard();
} }
private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInput(editorInfo, restarting); super.onStartInput(editorInfo, restarting);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInputView(editorInfo, restarting); super.onStartInputView(editorInfo, restarting);
// Switch to the null consumer to handle cases leading to early exit below, for which we // Switch to the null consumer to handle cases leading to early exit below, for which we
// also wouldn't be consuming gesture data. // also wouldn't be consuming gesture data.
@ -1034,7 +1037,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
private void onFinishInputInternal() { void onFinishInputInternal() {
super.onFinishInput(); super.onFinishInput();
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@ -1043,7 +1046,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
private void onFinishInputViewInternal(final boolean finishingInput) { void onFinishInputViewInternal(final boolean finishingInput) {
super.onFinishInputView(finishingInput); super.onFinishInputView(finishingInput);
cleanupInternalStateForFinishInput(); cleanupInternalStateForFinishInput();
} }
@ -1295,11 +1298,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
private int getCurrentAutoCapsState() { int getCurrentAutoCapsState() {
return mInputLogic.getCurrentAutoCapsState(mSettings.getCurrent()); return mInputLogic.getCurrentAutoCapsState(mSettings.getCurrent());
} }
private int getCurrentRecapitalizeState() { int getCurrentRecapitalizeState() {
return mInputLogic.getCurrentRecapitalizeState(); return mInputLogic.getCurrentRecapitalizeState();
} }
@ -1389,12 +1392,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard(); final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard();
if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
return codePoint; return codePoint;
} else {
return Constants.CODE_SYMBOL_SHIFT;
} }
} else { return Constants.CODE_SYMBOL_SHIFT;
return codePoint;
} }
return codePoint;
} }
// Implementation of {@link KeyboardActionListener}. // Implementation of {@link KeyboardActionListener}.
@ -1496,7 +1497,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
// This method must run on the UI Thread. // This method must run on the UI Thread.
private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords, void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
final boolean dismissGestureFloatingPreviewText) { final boolean dismissGestureFloatingPreviewText) {
showSuggestionStrip(suggestedWords); showSuggestionStrip(suggestedWords);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@ -1812,7 +1813,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
}; };
private void launchSettings() { void launchSettings() {
mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR); mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
requestHideSelf(0); requestHideSelf(0);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@ -1836,6 +1837,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
languageSelectionTitle, languageSelectionTitle,
getString(ApplicationUtils.getActivityTitleResId(this, SettingsActivity.class)) getString(ApplicationUtils.getActivityTitleResId(this, SettingsActivity.class))
}; };
final String imeId = mRichImm.getInputMethodIdOfThisIme();
final OnClickListener listener = new OnClickListener() { final OnClickListener listener = new OnClickListener() {
@Override @Override
public void onClick(DialogInterface di, int position) { public void onClick(DialogInterface di, int position) {
@ -1843,7 +1845,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switch (position) { switch (position) {
case 0: case 0:
final Intent intent = IntentUtils.getInputLanguageSelectionIntent( final Intent intent = IntentUtils.getInputLanguageSelectionIntent(
mRichImm.getInputMethodIdOfThisIme(), imeId,
Intent.FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP); | Intent.FLAG_ACTIVITY_CLEAR_TOP);

View file

@ -31,14 +31,14 @@ public class NgramContext {
public static final NgramContext EMPTY_PREV_WORDS_INFO = public static final NgramContext EMPTY_PREV_WORDS_INFO =
new NgramContext(WordInfo.EMPTY_WORD_INFO); new NgramContext(WordInfo.EMPTY_WORD_INFO);
public static final NgramContext BEGINNING_OF_SENTENCE = public static final NgramContext BEGINNING_OF_SENTENCE =
new NgramContext(WordInfo.BEGINNING_OF_SENTENCE); new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO);
/** /**
* Word information used to represent previous words information. * Word information used to represent previous words information.
*/ */
public static class WordInfo { public static class WordInfo {
public static final WordInfo EMPTY_WORD_INFO = new WordInfo(null); public static final WordInfo EMPTY_WORD_INFO = new WordInfo(null);
public static final WordInfo BEGINNING_OF_SENTENCE = new WordInfo(); public static final WordInfo BEGINNING_OF_SENTENCE_WORD_INFO = new WordInfo();
// This is an empty char sequence when mIsBeginningOfSentence is true. // This is an empty char sequence when mIsBeginningOfSentence is true.
public final CharSequence mWord; public final CharSequence mWord;
@ -48,7 +48,7 @@ public class NgramContext {
public final boolean mIsBeginningOfSentence; public final boolean mIsBeginningOfSentence;
// Beginning of sentence. // Beginning of sentence.
public WordInfo() { private WordInfo() {
mWord = ""; mWord = "";
mIsBeginningOfSentence = true; mIsBeginningOfSentence = true;
} }
@ -96,18 +96,6 @@ public class NgramContext {
mPrevWordsCount = prevWordsInfo.length; mPrevWordsCount = prevWordsInfo.length;
} }
// Construct from WordInfo array and size. The caller shouldn't change prevWordsInfo after
// calling this method.
private NgramContext(final NgramContext ngramContext, final int prevWordsCount) {
if (ngramContext.mPrevWordsCount < prevWordsCount) {
throw new IndexOutOfBoundsException("ngramContext.mPrevWordsCount ("
+ ngramContext.mPrevWordsCount + ") is smaller than prevWordsCount ("
+ prevWordsCount + ")");
}
mPrevWordsInfo = ngramContext.mPrevWordsInfo;
mPrevWordsCount = prevWordsCount;
}
// Create next prevWordsInfo using current prevWordsInfo. // Create next prevWordsInfo using current prevWordsInfo.
public NgramContext getNextNgramContext(final WordInfo wordInfo) { public NgramContext getNextNgramContext(final WordInfo wordInfo) {
final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM,

View file

@ -44,8 +44,6 @@ import com.android.inputmethod.latin.utils.SpannableStringUtils;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.TextRange; import com.android.inputmethod.latin.utils.TextRange;
import java.util.Arrays;
/** /**
* Enrichment class for InputConnection to simplify interaction and add functionality. * Enrichment class for InputConnection to simplify interaction and add functionality.
* *
@ -91,7 +89,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
/** /**
* This variable is a temporary object used in * This variable is a temporary object used in
* {@link #commitTextWithBackgroundColor(CharSequence, int, int)} to avoid object creation. * {@link #commitTextWithBackgroundColor(CharSequence,int,int,int)} to avoid object creation.
*/ */
private SpannableStringBuilder mTempObjectForCommitText = new SpannableStringBuilder(); private SpannableStringBuilder mTempObjectForCommitText = new SpannableStringBuilder();
/** /**
@ -151,9 +149,8 @@ public final class RichInputConnection implements PrivateCommandPerformer {
} else { } else {
if (DBG) { if (DBG) {
throw new RuntimeException("Nest level too deep"); throw new RuntimeException("Nest level too deep");
} else {
Log.e(TAG, "Nest level too deep : " + mNestLevel);
} }
Log.e(TAG, "Nest level too deep : " + mNestLevel);
} }
if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -351,10 +348,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
// If we have some composing text and a space before, then we should have // If we have some composing text and a space before, then we should have
// MODE_CHARACTERS and MODE_WORDS on. // MODE_CHARACTERS and MODE_WORDS on.
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & inputType; return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & inputType;
} else {
// We have some composing text - we should be in MODE_CHARACTERS only.
return TextUtils.CAP_MODE_CHARACTERS & inputType;
} }
// We have some composing text - we should be in MODE_CHARACTERS only.
return TextUtils.CAP_MODE_CHARACTERS & inputType;
} }
// TODO: this will generally work, but there may be cases where the buffer contains SOME // TODO: this will generally work, but there may be cases where the buffer contains SOME
// information but not enough to determine the caps mode accurately. This may happen after // information but not enough to determine the caps mode accurately. This may happen after
@ -624,10 +620,6 @@ public final class RichInputConnection implements PrivateCommandPerformer {
prev, spacingAndPunctuations, n); prev, spacingAndPunctuations, n);
} }
private static boolean isSeparator(final int code, final int[] sortedSeparators) {
return Arrays.binarySearch(sortedSeparators, code) >= 0;
}
private static boolean isPartOfCompositionForScript(final int codePoint, private static boolean isPartOfCompositionForScript(final int codePoint,
final SpacingAndPunctuations spacingAndPunctuations, final int scriptId) { final SpacingAndPunctuations spacingAndPunctuations, final int scriptId) {
// We always consider word connectors part of compositions. // We always consider word connectors part of compositions.
@ -977,7 +969,8 @@ public final class RichInputConnection implements PrivateCommandPerformer {
/** /**
* @return {@code true} if the application reported that the monitor mode of * @return {@code true} if the application reported that the monitor mode of
* {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is currently enabled. * {@link InputMethodService#onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo)}
* is currently enabled.
*/ */
public boolean isCursorAnchorInfoMonitorEnabled() { public boolean isCursorAnchorInfoMonitorEnabled() {
return mCursorAnchorInfoMonitorEnabled; return mCursorAnchorInfoMonitorEnabled;

View file

@ -20,7 +20,6 @@ import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;

View file

@ -291,8 +291,9 @@ public final class SubtypeSwitcher {
} }
private static RichInputMethodSubtype sForcedSubtypeForTesting = null; private static RichInputMethodSubtype sForcedSubtypeForTesting = null;
@UsedForTesting @UsedForTesting
void forceSubtype(final InputMethodSubtype subtype) { static void forceSubtype(final InputMethodSubtype subtype) {
sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype); sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype);
} }

View file

@ -328,7 +328,7 @@ public final class Suggest {
* @param info the suggestion info * @param info the suggestion info
* @return whether it's fine to auto-correct to this. * @return whether it's fine to auto-correct to this.
*/ */
private boolean isAllowedByAutoCorrectionWithSpaceFilter(final SuggestedWordInfo info) { private static boolean isAllowedByAutoCorrectionWithSpaceFilter(final SuggestedWordInfo info) {
final Locale locale = info.mSourceDict.mLocale; final Locale locale = info.mSourceDict.mLocale;
if (null == locale) { if (null == locale) {
return true; return true;

View file

@ -365,9 +365,8 @@ public class SuggestedWords {
public String toString() { public String toString() {
if (TextUtils.isEmpty(mDebugString)) { if (TextUtils.isEmpty(mDebugString)) {
return mWord; return mWord;
} else {
return mWord + " (" + mDebugString + ")";
} }
return mWord + " (" + mDebugString + ")";
} }
// This will always remove the higher index if a duplicate is found. // This will always remove the higher index if a duplicate is found.

View file

@ -64,7 +64,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
private static final String NAME = "userunigram"; private static final String NAME = "userunigram";
private ContentObserver mObserver; private ContentObserver mObserver;
final private String mLocale; final private String mLocaleString;
final private boolean mAlsoUseMoreRestrictiveLocales; final private boolean mAlsoUseMoreRestrictiveLocales;
protected UserBinaryDictionary(final Context context, final Locale locale, protected UserBinaryDictionary(final Context context, final Locale locale,
@ -74,9 +74,9 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
final String localeStr = locale.toString(); final String localeStr = locale.toString();
if (SubtypeLocaleUtils.NO_LANGUAGE.equals(localeStr)) { if (SubtypeLocaleUtils.NO_LANGUAGE.equals(localeStr)) {
// If we don't have a locale, insert into the "all locales" user dictionary. // If we don't have a locale, insert into the "all locales" user dictionary.
mLocale = USER_DICTIONARY_ALL_LANGUAGES; mLocaleString = USER_DICTIONARY_ALL_LANGUAGES;
} else { } else {
mLocale = localeStr; mLocaleString = localeStr;
} }
mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales; mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales;
ContentResolver cres = context.getContentResolver(); ContentResolver cres = context.getContentResolver();
@ -124,7 +124,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// This is correct for locale processing. // This is correct for locale processing.
// For this example, we'll look at the "en_US_POSIX" case. // For this example, we'll look at the "en_US_POSIX" case.
final String[] localeElements = final String[] localeElements =
TextUtils.isEmpty(mLocale) ? new String[] {} : mLocale.split("_", 3); TextUtils.isEmpty(mLocaleString) ? new String[] {} : mLocaleString.split("_", 3);
final int length = localeElements.length; final int length = localeElements.length;
final StringBuilder request = new StringBuilder("(locale is NULL)"); final StringBuilder request = new StringBuilder("(locale is NULL)");
@ -207,9 +207,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
if (client != null) { if (client != null) {
client.release(); client.release();
return true; return true;
} else {
return false;
} }
return false;
} }
/** /**
@ -227,17 +226,16 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY, null, locale); HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY, null, locale);
} }
private int scaleFrequencyFromDefaultToLatinIme(final int defaultFrequency) { private static int scaleFrequencyFromDefaultToLatinIme(final int defaultFrequency) {
// The default frequency for the user dictionary is 250 for historical reasons. // The default frequency for the user dictionary is 250 for historical reasons.
// Latin IME considers a good value for the default user dictionary frequency // Latin IME considers a good value for the default user dictionary frequency
// is about 160 considering the scale we use. So we are scaling down the values. // is about 160 considering the scale we use. So we are scaling down the values.
if (defaultFrequency > Integer.MAX_VALUE / LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY) { if (defaultFrequency > Integer.MAX_VALUE / LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY) {
return (defaultFrequency / HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY) return (defaultFrequency / HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY)
* LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY; * LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY;
} else {
return (defaultFrequency * LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY)
/ HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY;
} }
return (defaultFrequency * LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY)
/ HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY;
} }
private void addWordsLocked(final Cursor cursor) { private void addWordsLocked(final Cursor cursor) {

View file

@ -353,9 +353,8 @@ public final class WordComposer {
if (size() <= 1) { if (size() <= 1) {
return mCapitalizedMode == CAPS_MODE_AUTO_SHIFT_LOCKED return mCapitalizedMode == CAPS_MODE_AUTO_SHIFT_LOCKED
|| mCapitalizedMode == CAPS_MODE_MANUAL_SHIFT_LOCKED; || mCapitalizedMode == CAPS_MODE_MANUAL_SHIFT_LOCKED;
} else {
return mCapsCount == size();
} }
return mCapsCount == size();
} }
public boolean wasShiftedNoLock() { public boolean wasShiftedNoLock() {

View file

@ -44,7 +44,7 @@ import java.util.Locale;
* A class to read a local file as a dictionary for debugging purposes. * A class to read a local file as a dictionary for debugging purposes.
*/ */
public class ExternalDictionaryGetterForDebug { public class ExternalDictionaryGetterForDebug {
private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
+ "/Download"; + "/Download";
private static String[] findDictionariesInTheDownloadedFolder() { private static String[] findDictionariesInTheDownloadedFolder() {
@ -142,8 +142,7 @@ public class ExternalDictionaryGetterForDebug {
}).create().show(); }).create().show();
} }
private static void installFile(final Context context, final File file, static void installFile(final Context context, final File file, final DictionaryHeader header) {
final DictionaryHeader header) {
BufferedOutputStream outputStream = null; BufferedOutputStream outputStream = null;
File tempFile = null; File tempFile = null;
try { try {

View file

@ -75,7 +75,7 @@ public final class InputLogic {
private static final String TAG = InputLogic.class.getSimpleName(); private static final String TAG = InputLogic.class.getSimpleName();
// TODO : Remove this member when we can. // TODO : Remove this member when we can.
private final LatinIME mLatinIME; final LatinIME mLatinIME;
private final SuggestionStripViewAccessor mSuggestionStripViewAccessor; private final SuggestionStripViewAccessor mSuggestionStripViewAccessor;
// Never null. // Never null.
@ -1512,12 +1512,6 @@ public final class InputLogic {
} }
} }
final int[] codePoints = StringUtils.toCodePointArray(typedWord); final int[] codePoints = StringUtils.toCodePointArray(typedWord);
// We want the context of preceding words for suggestion. If we have chars in the word
// before the cursor, then we want the word before that, hence 2; otherwise,
// we want the word immediately before the cursor, hence 1.
final NgramContext ngramContext = getNgramContextFromNthPreviousWordForSuggestion(
settingsValues.mSpacingAndPunctuations,
0 == numberOfCharsInWordBeforeCursor ? 1 : 2);
mWordComposer.setComposingWord(codePoints, mWordComposer.setComposingWord(codePoints,
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
mWordComposer.setCursorPositionWithinWord( mWordComposer.setCursorPositionWithinWord(
@ -1533,8 +1527,7 @@ public final class InputLogic {
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() { SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override @Override
public void onGetSuggestedWords(final SuggestedWords suggestedWords) { public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
mIsAutoCorrectionIndicatorOn = false; doShowSuggestionsAndClearAutoCorrectionIndicator(suggestedWords);
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
}}); }});
} else { } else {
// We found suggestion spans in the word. We'll create the SuggestedWords out of // We found suggestion spans in the word. We'll create the SuggestedWords out of
@ -1545,11 +1538,15 @@ public final class InputLogic {
null /* rawSuggestions */, typedWord, false /* typedWordValid */, null /* rawSuggestions */, typedWord, false /* typedWordValid */,
false /* willAutoCorrect */, false /* isObsoleteSuggestions */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */,
SuggestedWords.INPUT_STYLE_RECORRECTION, SuggestedWords.NOT_A_SEQUENCE_NUMBER); SuggestedWords.INPUT_STYLE_RECORRECTION, SuggestedWords.NOT_A_SEQUENCE_NUMBER);
mIsAutoCorrectionIndicatorOn = false; doShowSuggestionsAndClearAutoCorrectionIndicator(suggestedWords);
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
} }
} }
void doShowSuggestionsAndClearAutoCorrectionIndicator(final SuggestedWords suggestedWords) {
mIsAutoCorrectionIndicatorOn = false;
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
}
/** /**
* Reverts a previous commit with auto-correction. * Reverts a previous commit with auto-correction.
* *
@ -1761,12 +1758,12 @@ public final class InputLogic {
// word information from textview. // word information from textview.
return mConnection.getNgramContextFromNthPreviousWord( return mConnection.getNgramContextFromNthPreviousWord(
spacingAndPunctuations, nthPreviousWord); spacingAndPunctuations, nthPreviousWord);
} else {
return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ?
NgramContext.BEGINNING_OF_SENTENCE :
new NgramContext(new NgramContext.WordInfo(
mLastComposedWord.mCommittedWord.toString()));
} }
if (LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord) {
return NgramContext.BEGINNING_OF_SENTENCE;
}
return new NgramContext(new NgramContext.WordInfo(
mLastComposedWord.mCommittedWord.toString()));
} }
/** /**
@ -1819,9 +1816,8 @@ public final class InputLogic {
// If no code point, #getCodePointBeforeCursor returns NOT_A_CODE_POINT. // If no code point, #getCodePointBeforeCursor returns NOT_A_CODE_POINT.
if (Constants.CODE_PERIOD == codePointBeforeCursor) { if (Constants.CODE_PERIOD == codePointBeforeCursor) {
return text.substring(1); return text.substring(1);
} else {
return text;
} }
return text;
} }
/** /**
@ -1877,7 +1873,7 @@ public final class InputLogic {
* @param previousSuggestedWords The previously suggested words. * @param previousSuggestedWords The previously suggested words.
* @return Obsolete suggestions with the newly typed word. * @return Obsolete suggestions with the newly typed word.
*/ */
private SuggestedWords retrieveOlderSuggestions(final String typedWord, static SuggestedWords retrieveOlderSuggestions(final String typedWord,
final SuggestedWords previousSuggestedWords) { final SuggestedWords previousSuggestedWords) {
final SuggestedWords oldSuggestedWords = previousSuggestedWords.isPunctuationSuggestions() final SuggestedWords oldSuggestedWords = previousSuggestedWords.isPunctuationSuggestions()
? SuggestedWords.getEmptyInstance() : previousSuggestedWords; ? SuggestedWords.getEmptyInstance() : previousSuggestedWords;

View file

@ -23,7 +23,6 @@ import android.os.Message;
import com.android.inputmethod.compat.LooperCompatUtils; import com.android.inputmethod.compat.LooperCompatUtils;
import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
@ -62,7 +61,7 @@ class InputLogicHandler implements Handler.Callback {
final OnGetSuggestedWordsCallback callback) {} final OnGetSuggestedWordsCallback callback) {}
}; };
private InputLogicHandler() { InputLogicHandler() {
mNonUIThreadHandler = null; mNonUIThreadHandler = null;
mLatinIME = null; mLatinIME = null;
mInputLogic = null; mInputLogic = null;
@ -134,30 +133,38 @@ class InputLogicHandler implements Handler.Callback {
return; return;
} }
mInputLogic.mWordComposer.setBatchInputPointers(batchPointers); mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
showGestureSuggestionsWithPreviewVisuals(suggestedWords, isTailBatchInput);
}
};
getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH
: SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber, : SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber, callback);
new OnGetSuggestedWordsCallback() { }
@Override }
public void onGetSuggestedWords(SuggestedWords suggestedWords) {
// We're now inside the callback. This always runs on the Non-UI thread, void showGestureSuggestionsWithPreviewVisuals(final SuggestedWords suggestedWordsForBatchInput,
// no matter what thread updateBatchInput was originally called on. final boolean isTailBatchInput) {
if (suggestedWords.isEmpty()) { final SuggestedWords suggestedWordsToShowSuggestions;
// Use old suggestions if we don't have any new ones. // We're now inside the callback. This always runs on the Non-UI thread,
// Previous suggestions are found in InputLogic#mSuggestedWords. // no matter what thread updateBatchInput was originally called on.
// Since these are the most recent ones and we just recomputed if (suggestedWordsForBatchInput.isEmpty()) {
// new ones to update them, then the previous ones are there. // Use old suggestions if we don't have any new ones.
suggestedWords = mInputLogic.mSuggestedWords; // Previous suggestions are found in InputLogic#mSuggestedWords.
} // Since these are the most recent ones and we just recomputed
mLatinIME.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWords, // new ones to update them, then the previous ones are there.
isTailBatchInput /* dismissGestureFloatingPreviewText */); suggestedWordsToShowSuggestions = mInputLogic.mSuggestedWords;
if (isTailBatchInput) { } else {
mInBatchInput = false; suggestedWordsToShowSuggestions = suggestedWordsForBatchInput;
// The following call schedules onEndBatchInputInternal }
// to be called on the UI thread. mLatinIME.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWordsToShowSuggestions,
mLatinIME.mHandler.showTailBatchInputResult(suggestedWords); isTailBatchInput /* dismissGestureFloatingPreviewText */);
} if (isTailBatchInput) {
} mInBatchInput = false;
}); // The following call schedules onEndBatchInputInternal
// to be called on the UI thread.
mLatinIME.mHandler.showTailBatchInputResult(suggestedWordsToShowSuggestions);
} }
} }

View file

@ -40,11 +40,8 @@ public final class ProbabilityInfo {
if (probabilityInfo2 == null) { if (probabilityInfo2 == null) {
return probabilityInfo1; return probabilityInfo1;
} }
if (probabilityInfo1.mProbability > probabilityInfo2.mProbability) { return (probabilityInfo1.mProbability > probabilityInfo2.mProbability) ? probabilityInfo1
return probabilityInfo1; : probabilityInfo2;
} else {
return probabilityInfo2;
}
} }
public ProbabilityInfo(final int probability) { public ProbabilityInfo(final int probability) {
@ -67,9 +64,8 @@ public final class ProbabilityInfo {
public int hashCode() { public int hashCode() {
if (hasHistoricalInfo()) { if (hasHistoricalInfo()) {
return Arrays.hashCode(new Object[] { mProbability, mTimestamp, mLevel, mCount }); return Arrays.hashCode(new Object[] { mProbability, mTimestamp, mLevel, mCount });
} else {
return Arrays.hashCode(new Object[] { mProbability });
} }
return Arrays.hashCode(new Object[] { mProbability });
} }
@Override @Override

View file

@ -18,6 +18,7 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.NgramContext.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils;
@ -61,10 +62,8 @@ public final class WordProperty implements Comparable<WordProperty> {
} else { } else {
mNgrams = new ArrayList<>(); mNgrams = new ArrayList<>();
final NgramContext ngramContext = new NgramContext(new WordInfo(mWord)); final NgramContext ngramContext = new NgramContext(new WordInfo(mWord));
if (bigrams != null) { for (final WeightedString bigramTarget : bigrams) {
for (final WeightedString bigramTarget : bigrams) { mNgrams.add(new NgramProperty(bigramTarget, ngramContext));
mNgrams.add(new NgramProperty(bigramTarget, ngramContext));
}
} }
} }
mIsBeginningOfSentence = false; mIsBeginningOfSentence = false;
@ -104,7 +103,8 @@ public final class WordProperty implements Comparable<WordProperty> {
final int relatedNgramCount = ngramTargets.size(); final int relatedNgramCount = ngramTargets.size();
final WordInfo currentWordInfo = final WordInfo currentWordInfo =
mIsBeginningOfSentence ? WordInfo.BEGINNING_OF_SENTENCE : new WordInfo(mWord); mIsBeginningOfSentence ? WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO
: new WordInfo(mWord);
final NgramContext ngramContext = new NgramContext(currentWordInfo); final NgramContext ngramContext = new NgramContext(currentWordInfo);
for (int i = 0; i < relatedNgramCount; i++) { for (int i = 0; i < relatedNgramCount; i++) {
final String ngramTargetString = final String ngramTargetString =
@ -202,7 +202,7 @@ public final class WordProperty implements Comparable<WordProperty> {
@UsedForTesting @UsedForTesting
public boolean isValid() { public boolean isValid() {
return getProbability() != BinaryDictionary.NOT_A_PROBABILITY; return getProbability() != Dictionary.NOT_A_PROBABILITY;
} }
@Override @Override

View file

@ -85,12 +85,11 @@ public class BlockingHttpClient {
throw new AuthException(mConnection.getResponseMessage()); throw new AuthException(mConnection.getResponseMessage());
} }
throw new HttpException(responseCode); throw new HttpException(responseCode);
} else {
if (DEBUG) {
Log.d(TAG, "request executed successfully");
}
return responseProcessor.onSuccess(mConnection.getInputStream());
} }
if (DEBUG) {
Log.d(TAG, "request executed successfully");
}
return responseProcessor.onSuccess(mConnection.getInputStream());
} finally { } finally {
mConnection.disconnect(); mConnection.disconnect();
} }

View file

@ -39,14 +39,10 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
public static final int FREQUENCY_FOR_WORDS_IN_DICTS = FREQUENCY_FOR_TYPED; public static final int FREQUENCY_FOR_WORDS_IN_DICTS = FREQUENCY_FOR_TYPED;
public static final int FREQUENCY_FOR_WORDS_NOT_IN_DICTS = Dictionary.NOT_A_PROBABILITY; public static final int FREQUENCY_FOR_WORDS_NOT_IN_DICTS = Dictionary.NOT_A_PROBABILITY;
/** The locale for this dictionary. */
public final Locale mLocale;
protected DecayingExpandableBinaryDictionaryBase(final Context context, protected DecayingExpandableBinaryDictionaryBase(final Context context,
final String dictName, final Locale locale, final String dictionaryType, final String dictName, final Locale locale, final String dictionaryType,
final File dictFile) { final File dictFile) {
super(context, dictName, locale, dictionaryType, dictFile); super(context, dictName, locale, dictionaryType, dictFile);
mLocale = locale;
if (mLocale != null && mLocale.toString().length() > 1) { if (mLocale != null && mLocale.toString().length() > 1) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
} }

View file

@ -17,7 +17,6 @@
package com.android.inputmethod.latin.personalization; package com.android.inputmethod.latin.personalization;
import android.content.Context; import android.content.Context;
import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
@ -35,7 +34,6 @@ import java.util.Locale;
*/ */
public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase { public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase {
/* package */ static final String NAME = UserHistoryDictionary.class.getSimpleName(); /* package */ static final String NAME = UserHistoryDictionary.class.getSimpleName();
private final static int SUPPORTED_NGRAM = 2; // TODO: 3
// TODO: Make this constructor private // TODO: Make this constructor private
/* package */ UserHistoryDictionary(final Context context, final Locale locale) { /* package */ UserHistoryDictionary(final Context context, final Locale locale) {

View file

@ -259,6 +259,7 @@ final class CustomInputStylePreference extends DialogPreference
mSubtype = (InputMethodSubtype)source.readParcelable(null); mSubtype = (InputMethodSubtype)source.readParcelable(null);
} }
@SuppressWarnings("hiding")
public static final Parcelable.Creator<SavedState> CREATOR = public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() { new Parcelable.Creator<SavedState>() {
@Override @Override

View file

@ -16,7 +16,6 @@
package com.android.inputmethod.latin.settings; package com.android.inputmethod.latin.settings;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;

View file

@ -20,8 +20,6 @@ import android.os.Bundle;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import java.util.ArrayList;
/** /**
* "Multilingual options" settings sub screen. * "Multilingual options" settings sub screen.
* *

View file

@ -43,9 +43,7 @@ public class RadioButtonPreference extends Preference {
private final View.OnClickListener mClickListener = new View.OnClickListener() { private final View.OnClickListener mClickListener = new View.OnClickListener() {
@Override @Override
public void onClick(final View v) { public void onClick(final View v) {
if (mListener != null) { callListenerOnRadioButtonClicked();
mListener.onRadioButtonClicked(RadioButtonPreference.this);
}
} }
}; };
@ -67,6 +65,12 @@ public class RadioButtonPreference extends Preference {
mListener = listener; mListener = listener;
} }
void callListenerOnRadioButtonClicked() {
if (mListener != null) {
mListener.onRadioButtonClicked(this);
}
}
@Override @Override
protected void onBindView(final View view) { protected void onBindView(final View view) {
super.onBindView(view); super.onBindView(view);

View file

@ -273,9 +273,8 @@ public class SettingsValues {
final RichInputMethodManager imm = RichInputMethodManager.getInstance(); final RichInputMethodManager imm = RichInputMethodManager.getInstance();
if (mIncludesOtherImesInLanguageSwitchList) { if (mIncludesOtherImesInLanguageSwitchList) {
return imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */); return imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */);
} else {
return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
} }
return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
} }
public boolean isSameInputType(final EditorInfo editorInfo) { public boolean isSameInputType(final EditorInfo editorInfo) {

View file

@ -50,9 +50,6 @@ import java.util.concurrent.Semaphore;
*/ */
public final class AndroidSpellCheckerService extends SpellCheckerService public final class AndroidSpellCheckerService extends SpellCheckerService
implements SharedPreferences.OnSharedPreferenceChangeListener { implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
private static final boolean DBG = false;
public static final String PREF_USE_CONTACTS_KEY = "pref_spellcheck_use_contacts"; public static final String PREF_USE_CONTACTS_KEY = "pref_spellcheck_use_contacts";
private static final int SPELLCHECKER_DUMMY_KEYBOARD_WIDTH = 480; private static final int SPELLCHECKER_DUMMY_KEYBOARD_WIDTH = 480;

View file

@ -312,11 +312,10 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
// Don't kill the keyboard if there is a bug in the spell checker // Don't kill the keyboard if there is a bug in the spell checker
if (DBG) { if (DBG) {
throw e; throw e;
} else {
Log.e(TAG, "Exception while spellcheking", e);
return AndroidSpellCheckerService.getNotInDictEmptySuggestions(
false /* reportAsTypo */);
} }
Log.e(TAG, "Exception while spellcheking", e);
return AndroidSpellCheckerService.getNotInDictEmptySuggestions(
false /* reportAsTypo */);
} }
} }

View file

@ -16,7 +16,9 @@
package com.android.inputmethod.latin.spellcheck; package com.android.inputmethod.latin.spellcheck;
import android.annotation.TargetApi;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build;
import android.view.textservice.SentenceSuggestionsInfo; import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo; import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo; import android.view.textservice.TextInfo;
@ -76,19 +78,19 @@ public class SentenceLevelAdapter {
private static class WordIterator { private static class WordIterator {
private final SpacingAndPunctuations mSpacingAndPunctuations; private final SpacingAndPunctuations mSpacingAndPunctuations;
public WordIterator(final Resources res, final Locale locale) { public WordIterator(final Resources res, final Locale locale) {
final RunInLocale<SpacingAndPunctuations> job final RunInLocale<SpacingAndPunctuations> job =
= new RunInLocale<SpacingAndPunctuations>() { new RunInLocale<SpacingAndPunctuations>() {
@Override @Override
protected SpacingAndPunctuations job(final Resources res) { protected SpacingAndPunctuations job(final Resources r) {
return new SpacingAndPunctuations(res); return new SpacingAndPunctuations(r);
} }
}; };
mSpacingAndPunctuations = job.runInLocale(res, locale); mSpacingAndPunctuations = job.runInLocale(res, locale);
} }
public int getEndOfWord(final CharSequence sequence, int index) { public int getEndOfWord(final CharSequence sequence, final int fromIndex) {
final int length = sequence.length(); final int length = sequence.length();
index = index < 0 ? 0 : Character.offsetByCodePoints(sequence, index, 1); int index = fromIndex < 0 ? 0 : Character.offsetByCodePoints(sequence, fromIndex, 1);
while (index < length) { while (index < length) {
final int codePoint = Character.codePointAt(sequence, index); final int codePoint = Character.codePointAt(sequence, index);
if (mSpacingAndPunctuations.isWordSeparator(codePoint)) { if (mSpacingAndPunctuations.isWordSeparator(codePoint)) {
@ -111,12 +113,12 @@ public class SentenceLevelAdapter {
return index; return index;
} }
public int getBeginningOfNextWord(final CharSequence sequence, int index) { public int getBeginningOfNextWord(final CharSequence sequence, final int fromIndex) {
final int length = sequence.length(); final int length = sequence.length();
if (index >= length) { if (fromIndex >= length) {
return -1; return -1;
} }
index = index < 0 ? 0 : Character.offsetByCodePoints(sequence, index, 1); int index = fromIndex < 0 ? 0 : Character.offsetByCodePoints(sequence, fromIndex, 1);
while (index < length) { while (index < length) {
final int codePoint = Character.codePointAt(sequence, index); final int codePoint = Character.codePointAt(sequence, index);
if (!mSpacingAndPunctuations.isWordSeparator(codePoint)) { if (!mSpacingAndPunctuations.isWordSeparator(codePoint)) {
@ -140,7 +142,7 @@ public class SentenceLevelAdapter {
final int cookie = originalTextInfo.getCookie(); final int cookie = originalTextInfo.getCookie();
final int start = -1; final int start = -1;
final int end = originalText.length(); final int end = originalText.length();
final ArrayList<SentenceWordItem> wordItems = new ArrayList<SentenceWordItem>(); final ArrayList<SentenceWordItem> wordItems = new ArrayList<>();
int wordStart = wordIterator.getBeginningOfNextWord(originalText, start); int wordStart = wordIterator.getBeginningOfNextWord(originalText, start);
int wordEnd = wordIterator.getEndOfWord(originalText, wordStart); int wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
while (wordStart <= end && wordEnd != -1 && wordStart != -1) { while (wordStart <= end && wordEnd != -1 && wordStart != -1) {
@ -158,6 +160,7 @@ public class SentenceLevelAdapter {
return new SentenceTextInfoParams(originalTextInfo, wordItems); return new SentenceTextInfoParams(originalTextInfo, wordItems);
} }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static SentenceSuggestionsInfo reconstructSuggestions( public static SentenceSuggestionsInfo reconstructSuggestions(
SentenceTextInfoParams originalTextInfoParams, SuggestionsInfo[] results) { SentenceTextInfoParams originalTextInfoParams, SuggestionsInfo[] results) {
if (results == null || results.length == 0) { if (results == null || results.length == 0) {

View file

@ -50,10 +50,8 @@ import com.android.inputmethod.latin.PunctuationSuggestions;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import com.android.inputmethod.latin.utils.ViewLayoutUtils; import com.android.inputmethod.latin.utils.ViewLayoutUtils;
@ -380,6 +378,7 @@ final class SuggestionStripLayoutHelper {
final int countInStrip = mSuggestionsCountInStrip; final int countInStrip = mSuggestionsCountInStrip;
mMoreSuggestionsAvailable = (wordCountToShow > countInStrip); mMoreSuggestionsAvailable = (wordCountToShow > countInStrip);
@SuppressWarnings("unused")
int x = 0; int x = 0;
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) { for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
if (positionInStrip != 0) { if (positionInStrip != 0) {

View file

@ -177,12 +177,11 @@ public class UserDictionarySettings extends ListFragment {
return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
QUERY_SELECTION_ALL_LOCALES, null, QUERY_SELECTION_ALL_LOCALES, null,
"UPPER(" + UserDictionary.Words.WORD + ")"); "UPPER(" + UserDictionary.Words.WORD + ")");
} else {
final String queryLocale = null != locale ? locale : Locale.getDefault().toString();
return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
QUERY_SELECTION, new String[] { queryLocale },
"UPPER(" + UserDictionary.Words.WORD + ")");
} }
final String queryLocale = null != locale ? locale : Locale.getDefault().toString();
return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
QUERY_SELECTION, new String[] { queryLocale },
"UPPER(" + UserDictionary.Words.WORD + ")");
} }
private ListAdapter createAdapter() { private ListAdapter createAdapter() {

View file

@ -59,11 +59,7 @@ public class AsyncResultHolder<E> {
*/ */
public E get(final E defaultValue, final long timeOut) { public E get(final E defaultValue, final long timeOut) {
try { try {
if (mLatch.await(timeOut, TimeUnit.MILLISECONDS)) { return mLatch.await(timeOut, TimeUnit.MILLISECONDS) ? mResult : defaultValue;
return mResult;
} else {
return defaultValue;
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
return defaultValue; return defaultValue;
} }

View file

@ -24,7 +24,6 @@ import com.android.inputmethod.latin.define.DebugFlags;
public final class AutoCorrectionUtils { public final class AutoCorrectionUtils {
private static final boolean DBG = DebugFlags.DEBUG_ENABLED; private static final boolean DBG = DebugFlags.DEBUG_ENABLED;
private static final String TAG = AutoCorrectionUtils.class.getSimpleName(); private static final String TAG = AutoCorrectionUtils.class.getSimpleName();
private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4;
private AutoCorrectionUtils() { private AutoCorrectionUtils() {
// Purely static class: can't instantiate. // Purely static class: can't instantiate.

View file

@ -18,9 +18,6 @@ package com.android.inputmethod.latin.utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public final class CollectionUtils { public final class CollectionUtils {
private CollectionUtils() { private CollectionUtils() {
@ -47,7 +44,7 @@ public final class CollectionUtils {
* @param c Collection to test. * @param c Collection to test.
* @return Whether c contains no elements. * @return Whether c contains no elements.
*/ */
public static boolean isNullOrEmpty(final Collection c) { public static boolean isNullOrEmpty(final Collection<?> c) {
return c == null || c.isEmpty(); return c == null || c.isEmpty();
} }
} }

View file

@ -24,6 +24,7 @@ import android.inputmethodservice.InputMethodService;
import android.os.Build; import android.os.Build;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable; import android.text.Spannable;
import android.text.Spanned;
import android.view.View; import android.view.View;
import android.view.ViewParent; import android.view.ViewParent;
import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.CursorAnchorInfo;
@ -149,7 +150,7 @@ public final class CursorAnchorInfoUtils {
final Object[] spans = spannable.getSpans(0, text.length(), Object.class); final Object[] spans = spannable.getSpans(0, text.length(), Object.class);
for (Object span : spans) { for (Object span : spans) {
final int spanFlag = spannable.getSpanFlags(span); final int spanFlag = spannable.getSpanFlags(span);
if ((spanFlag & Spannable.SPAN_COMPOSING) != 0) { if ((spanFlag & Spanned.SPAN_COMPOSING) != 0) {
composingTextStart = Math.min(composingTextStart, composingTextStart = Math.min(composingTextStart,
spannable.getSpanStart(span)); spannable.getSpanStart(span));
composingTextEnd = Math.max(composingTextEnd, spannable.getSpanEnd(span)); composingTextEnd = Math.max(composingTextEnd, spannable.getSpanEnd(span));

View file

@ -41,10 +41,9 @@ public class DistracterFilterCheckingIsInDictionary implements DistracterFilter
// This filter treats entries that are already in the dictionary as non-distracters // This filter treats entries that are already in the dictionary as non-distracters
// because they have passed the filtering in the past. // because they have passed the filtering in the past.
return false; return false;
} else {
return mDistracterFilter.isDistracterToWordsInDictionaries(
ngramContext, testedWord, locale);
} }
return mDistracterFilter.isDistracterToWordsInDictionaries(
ngramContext, testedWord, locale);
} }
@Override @Override

View file

@ -27,7 +27,7 @@ import java.util.concurrent.ThreadFactory;
* Utilities to manage executors. * Utilities to manage executors.
*/ */
public class ExecutorUtils { public class ExecutorUtils {
private static final ConcurrentHashMap<String, ExecutorService> sExecutorMap = static final ConcurrentHashMap<String, ExecutorService> sExecutorMap =
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();
private static class ThreadFactoryWithId implements ThreadFactory { private static class ThreadFactoryWithId implements ThreadFactory {
@ -49,7 +49,7 @@ public class ExecutorUtils {
public static ExecutorService getExecutor(final String id) { public static ExecutorService getExecutor(final String id) {
ExecutorService executor = sExecutorMap.get(id); ExecutorService executor = sExecutorMap.get(id);
if (executor == null) { if (executor == null) {
synchronized(sExecutorMap) { synchronized (sExecutorMap) {
executor = sExecutorMap.get(id); executor = sExecutorMap.get(id);
if (executor == null) { if (executor == null) {
executor = Executors.newSingleThreadExecutor(new ThreadFactoryWithId(id)); executor = Executors.newSingleThreadExecutor(new ThreadFactoryWithId(id));
@ -65,7 +65,7 @@ public class ExecutorUtils {
*/ */
@UsedForTesting @UsedForTesting
public static void shutdownAllExecutors() { public static void shutdownAllExecutors() {
synchronized(sExecutorMap) { synchronized (sExecutorMap) {
for (final ExecutorService executor : sExecutorMap.values()) { for (final ExecutorService executor : sExecutorMap.values()) {
executor.execute(new Runnable() { executor.execute(new Runnable() {
@Override @Override

View file

@ -20,7 +20,6 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType; import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType;

View file

@ -74,20 +74,20 @@ public final class NgramContextUtils {
} }
// If we can't find (n + i) words, the context is beginning-of-sentence. // If we can't find (n + i) words, the context is beginning-of-sentence.
if (focusedWordIndex < 0) { if (focusedWordIndex < 0) {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE; prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break; break;
} }
final String focusedWord = w[focusedWordIndex]; final String focusedWord = w[focusedWordIndex];
// If the word is, the context is beginning-of-sentence. // If the word is, the context is beginning-of-sentence.
final int length = focusedWord.length(); final int length = focusedWord.length();
if (length <= 0) { if (length <= 0) {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE; prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break; break;
} }
// If ends in a sentence separator, the context is beginning-of-sentence. // If ends in a sentence separator, the context is beginning-of-sentence.
final char lastChar = focusedWord.charAt(length - 1); final char lastChar = focusedWord.charAt(length - 1);
if (spacingAndPunctuations.isSentenceSeparator(lastChar)) { if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE; prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break; break;
} }
// If ends in a word separator or connector, the context is unclear. // If ends in a word separator or connector, the context is unclear.

View file

@ -51,7 +51,7 @@ public final class SpannableStringUtils {
// of a word. But the spans have been split into two by the getText{Before,After}Cursor // of a word. But the spans have been split into two by the getText{Before,After}Cursor
// methods, so after concatenation they may end in the middle of a word. // methods, so after concatenation they may end in the middle of a word.
// Since we don't use them, we can just remove them and avoid crashing. // Since we don't use them, we can just remove them and avoid crashing.
fl &= ~Spannable.SPAN_PARAGRAPH; fl &= ~Spanned.SPAN_PARAGRAPH;
int st = source.getSpanStart(spans[i]); int st = source.getSpanStart(spans[i]);
int en = source.getSpanEnd(spans[i]); int en = source.getSpanEnd(spans[i]);

View file

@ -39,7 +39,7 @@ import java.util.Locale;
*/ */
// TODO: consolidate this into RichInputMethodSubtype // TODO: consolidate this into RichInputMethodSubtype
public final class SubtypeLocaleUtils { public final class SubtypeLocaleUtils {
private static final String TAG = SubtypeLocaleUtils.class.getSimpleName(); static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
// This reference class {@link Constants} must be located in the same package as LatinIME.java. // This reference class {@link Constants} must be located in the same package as LatinIME.java.
private static final String RESOURCE_PACKAGE_NAME = Constants.class.getPackage().getName(); private static final String RESOURCE_PACKAGE_NAME = Constants.class.getPackage().getName();
@ -245,9 +245,8 @@ public final class SubtypeLocaleUtils {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
&& subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) { && subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) {
return subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME); return subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME);
} else {
return getSubtypeLocaleDisplayNameInternal(subtype.getLocale(), displayLocale);
} }
return getSubtypeLocaleDisplayNameInternal(subtype.getLocale(), displayLocale);
} }
public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) { public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) {

View file

@ -66,8 +66,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
return super.addAll(e); return super.addAll(e);
} }
private static final class SuggestedWordInfoComparator static final class SuggestedWordInfoComparator implements Comparator<SuggestedWordInfo> {
implements Comparator<SuggestedWordInfo> {
// This comparator ranks the word info with the higher frequency first. That's because // This comparator ranks the word info with the higher frequency first. That's because
// that's the order we want our elements in. // that's the order we want our elements in.
@Override @Override

View file

@ -20,7 +20,6 @@ import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
@ -72,141 +71,141 @@ public class LocaleSpanCompatUtilsTests extends AndroidTestCase {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if only LocaleSpans are updated. // Test if only LocaleSpans are updated.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
text.setSpan(styleSpan, 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(styleSpan, 0, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
assertSpanCount(2, text); assertSpanCount(2, text);
assertSpanEquals(styleSpan, text, 0); assertSpanEquals(styleSpan, text, 0);
assertLocaleSpan(text, 1, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 1, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if two jointed spans are merged into one span. // Test if two jointed spans are merged into one span.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if two overlapped spans are merged into one span. // Test if two overlapped spans are merged into one span.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if three overlapped spans are merged into one span. // Test if three overlapped spans are merged into one span.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 8, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 8, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 8, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if disjoint spans remain disjoint. // Test if disjoint spans remain disjoint.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 8, 9, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 8, 9, Locale.JAPANESE);
assertSpanCount(3, text); assertSpanCount(3, text);
assertLocaleSpan(text, 0, 1, 3, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 3, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 1, 5, 6, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 1, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 2, 8, 9, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 2, 8, 9, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if existing span flags are preserved during merge. // Test if existing span flags are preserved during merge.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5,
Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 4, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 4, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE,
Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
} }
// Test if existing span flags are preserved even when partially overlapped (leading edge). // Test if existing span flags are preserved even when partially overlapped (leading edge).
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5,
Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 7, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 7, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_INCLUSIVE_EXCLUSIVE | Spanned.SPAN_INTERMEDIATE);
} }
// Test if existing span flags are preserved even when partially overlapped (trailing edge). // Test if existing span flags are preserved even when partially overlapped (trailing edge).
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 3, 7, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 3, 7,
Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE,
Spannable.SPAN_EXCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); Spanned.SPAN_EXCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
} }
// Test if existing locale span will be removed when the locale doesn't match. // Test if existing locale span will be removed when the locale doesn't match.
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 5, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 5,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 7, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 7, Locale.JAPANESE);
assertSpanCount(1, text); assertSpanCount(1, text);
assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if existing locale span will be removed when the locale doesn't match. (case 2) // Test if existing locale span will be removed when the locale doesn't match. (case 2)
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 6, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 6, Locale.JAPANESE);
assertSpanCount(3, text); assertSpanCount(3, text);
assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 1, 6, 7, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 1, 6, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 2, 5, 6, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 2, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if existing locale span will be removed when the locale doesn't match. (case 3) // Test if existing locale span will be removed when the locale doesn't match. (case 3)
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 5, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 5, Locale.JAPANESE);
assertSpanCount(2, text); assertSpanCount(2, text);
assertLocaleSpan(text, 0, 5, 7, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 5, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 1, 2, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 1, 2, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
// Test if existing locale span will be removed when the locale doesn't match. (case 3) // Test if existing locale span will be removed when the locale doesn't match. (case 3)
{ {
final SpannableString text = new SpannableString("0123456789"); final SpannableString text = new SpannableString("0123456789");
text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 8, Locale.JAPANESE); LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 8, Locale.JAPANESE);
assertSpanCount(2, text); assertSpanCount(2, text);
assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertLocaleSpan(text, 1, 5, 8, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); assertLocaleSpan(text, 1, 5, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
} }
} }

View file

@ -78,6 +78,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase {
assertArrayEquals(message, expected, actual); assertArrayEquals(message, expected, actual);
} }
@SuppressWarnings("static-method")
public void testEmptyEntry() { public void testEmptyEntry() {
assertInsertAdditionalMoreKeys("null more keys and null additons", assertInsertAdditionalMoreKeys("null more keys and null additons",
null, null,
@ -106,6 +107,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase {
new String[] { "a", "A", "b", "B", "c", "d" }); new String[] { "a", "A", "b", "B", "c", "d" });
} }
@SuppressWarnings("static-method")
public void testInsertAdditionalMoreKeys() { public void testInsertAdditionalMoreKeys() {
// Escaped marker. // Escaped marker.
assertInsertAdditionalMoreKeys("escaped marker", assertInsertAdditionalMoreKeys("escaped marker",
@ -306,6 +308,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase {
assertArrayEquals(message, expected, actual); assertArrayEquals(message, expected, actual);
} }
@SuppressWarnings("static-method")
public void testGetBooleanValue() { public void testGetBooleanValue() {
assertGetBooleanValue("Has label", HAS_LABEL, assertGetBooleanValue("Has label", HAS_LABEL,
new String[] { HAS_LABEL, "a", "b", "c" }, new String[] { HAS_LABEL, "a", "b", "c" },
@ -345,6 +348,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase {
assertArrayEquals(message, expected, actual); assertArrayEquals(message, expected, actual);
} }
@SuppressWarnings("static-method")
public void testGetIntValue() { public void testGetIntValue() {
assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1, assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1,
new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" },

View file

@ -174,13 +174,12 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion, if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion,
LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) { LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) {
return file; return file;
} else {
throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ " cannot be created. Foramt version: " + formatVersion);
} }
throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ " cannot be created. Foramt version: " + formatVersion);
} }
private BinaryDictionary getBinaryDictionary(final File dictFile) { private static BinaryDictionary getBinaryDictionary(final File dictFile) {
return new BinaryDictionary(dictFile.getAbsolutePath(), return new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */, 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
@ -683,7 +682,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile);
binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, "" /* shortcutTarget */, binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, "" /* shortcutTarget */,
BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, Dictionary.NOT_A_PROBABILITY /* shortcutProbability */,
true /* isBeginningOfSentence */, true /* isNotAWord */, true /* isBeginningOfSentence */, true /* isNotAWord */,
false /* isPossiblyOffensive */, mCurrentTime); false /* isPossiblyOffensive */, mCurrentTime);
final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE; final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE;

View file

@ -111,13 +111,12 @@ public class BinaryDictionaryTests extends AndroidTestCase {
if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion, if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion,
Locale.ENGLISH, attributeMap)) { Locale.ENGLISH, attributeMap)) {
return file; return file;
} else {
throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ " cannot be created. Format version: " + formatVersion);
} }
throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ " cannot be created. Format version: " + formatVersion);
} }
private BinaryDictionary getBinaryDictionary(final File dictFile) { private static BinaryDictionary getBinaryDictionary(final File dictFile) {
return new BinaryDictionary(dictFile.getAbsolutePath(), return new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */, 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
@ -211,15 +210,14 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(probability, binaryDictionary.getFrequency("aaa")); assertEquals(probability, binaryDictionary.getFrequency("aaa"));
assertEquals(updatedProbability, binaryDictionary.getFrequency(validLongWord)); assertEquals(updatedProbability, binaryDictionary.getFrequency(validLongWord));
assertEquals(BinaryDictionary.NOT_A_PROBABILITY, assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency(invalidLongWord));
binaryDictionary.getFrequency(invalidLongWord));
assertEquals(updatedProbability, binaryDictionary.getFrequency("abc")); assertEquals(updatedProbability, binaryDictionary.getFrequency("abc"));
} }
private static void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, private static void addUnigramWord(final BinaryDictionary binaryDictionary, final String word,
final int probability) { final int probability) {
binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */, binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */,
BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, Dictionary.NOT_A_PROBABILITY /* shortcutProbability */,
false /* isBeginningOfSentence */, false /* isNotAWord */, false /* isBeginningOfSentence */, false /* isNotAWord */,
false /* isPossiblyOffensive */, false /* isPossiblyOffensive */,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
@ -975,7 +973,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final boolean isPossiblyOffensive = random.nextBoolean(); final boolean isPossiblyOffensive = random.nextBoolean();
// TODO: Add tests for historical info. // TODO: Add tests for historical info.
binaryDictionary.addUnigramEntry(word, unigramProbability, binaryDictionary.addUnigramEntry(word, unigramProbability,
null /* shortcutTarget */, BinaryDictionary.NOT_A_PROBABILITY, null /* shortcutTarget */, Dictionary.NOT_A_PROBABILITY,
false /* isBeginningOfSentence */, isNotAWord, isPossiblyOffensive, false /* isBeginningOfSentence */, isNotAWord, isPossiblyOffensive,
BinaryDictionary.NOT_A_VALID_TIMESTAMP); BinaryDictionary.NOT_A_VALID_TIMESTAMP);
if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) { if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {

View file

@ -61,7 +61,6 @@ public class BlueUnderlineTests extends InputTestsBase {
public void testBlueUnderlineOnBackspace() { public void testBlueUnderlineOnBackspace() {
final String STRING_TO_TYPE = "tgis"; final String STRING_TO_TYPE = "tgis";
final int typedLength = STRING_TO_TYPE.length(); final int typedLength = STRING_TO_TYPE.length();
final int EXPECTED_SUGGESTION_SPAN_START = -1;
final int EXPECTED_UNDERLINE_SPAN_START = 0; final int EXPECTED_UNDERLINE_SPAN_START = 0;
final int EXPECTED_UNDERLINE_SPAN_END = 3; final int EXPECTED_UNDERLINE_SPAN_END = 3;
type(STRING_TO_TYPE); type(STRING_TO_TYPE);

View file

@ -47,7 +47,7 @@ public class DictionaryFacilitatorLruCacheTests extends AndroidTestCase {
getContext(), MAX_CACHE_SIZE_LARGE, "")); getContext(), MAX_CACHE_SIZE_LARGE, ""));
} }
private void testGetFacilitator(final DictionaryFacilitatorLruCache cache) { private static void testGetFacilitator(final DictionaryFacilitatorLruCache cache) {
final DictionaryFacilitator dictionaryFacilitatorEnUs = cache.get(Locale.US); final DictionaryFacilitator dictionaryFacilitatorEnUs = cache.get(Locale.US);
assertNotNull(dictionaryFacilitatorEnUs); assertNotNull(dictionaryFacilitatorEnUs);
assertTrue(dictionaryFacilitatorEnUs.isForLocales(new Locale[] { Locale.US })); assertTrue(dictionaryFacilitatorEnUs.isForLocales(new Locale[] { Locale.US }));
@ -68,7 +68,7 @@ public class DictionaryFacilitatorLruCacheTests extends AndroidTestCase {
getContext(), MAX_CACHE_SIZE_LARGE, "")); getContext(), MAX_CACHE_SIZE_LARGE, ""));
} }
private void testSetUseContactsDictionary(final DictionaryFacilitatorLruCache cache) { private static void testSetUseContactsDictionary(final DictionaryFacilitatorLruCache cache) {
assertNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS)); assertNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS));
cache.setUseContactsDictionary(true /* useContactsDictionary */); cache.setUseContactsDictionary(true /* useContactsDictionary */);
assertNotNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS)); assertNotNull(cache.get(Locale.US).getSubDictForTesting(Dictionary.TYPE_CONTACTS));

View file

@ -25,7 +25,7 @@ import java.util.ArrayList;
@LargeTest @LargeTest
public class InputLogicTestsDeadKeys extends InputTestsBase { public class InputLogicTestsDeadKeys extends InputTestsBase {
// A helper class for readability // A helper class for readability
private static class EventList extends ArrayList<Event> { static class EventList extends ArrayList<Event> {
public EventList addCodePoint(final int codePoint, final boolean isDead) { public EventList addCodePoint(final int codePoint, final boolean isDead) {
final Event event; final Event event;
if (isDead) { if (isDead) {

View file

@ -80,7 +80,6 @@ import android.util.Pair;
@LargeTest @LargeTest
// These tests are inactive until the combining code for Myanmar Reordering is sorted out. // These tests are inactive until the combining code for Myanmar Reordering is sorted out.
@Suppress @Suppress
@SuppressWarnings("rawtypes")
public class InputLogicTestsReorderingMyanmar extends InputTestsBase { public class InputLogicTestsReorderingMyanmar extends InputTestsBase {
// The tests are formatted as follows. // The tests are formatted as follows.
// Each test is an entry in the array of Pair arrays. // Each test is an entry in the array of Pair arrays.
@ -90,7 +89,7 @@ public class InputLogicTestsReorderingMyanmar extends InputTestsBase {
// member is stored the string that should be in the text view after this // member is stored the string that should be in the text view after this
// key press. // key press.
private static final Pair[][] TESTS = { private static final Pair<?, ?>[][] TESTS = {
// Tests for U+1031 MYANMAR VOWEL SIGN E : // Tests for U+1031 MYANMAR VOWEL SIGN E :
new Pair[] { // Type : U+1031 U+1000 U+101F က new Pair[] { // Type : U+1031 U+1000 U+101F က
@ -206,13 +205,12 @@ public class InputLogicTestsReorderingMyanmar extends InputTestsBase {
*/ */
}; };
@SuppressWarnings("unchecked") private void doMyanmarTest(final int testNumber, final Pair<?, ?>[] test) {
private void doMyanmarTest(final int testNumber, final Pair[] test) {
int stepNumber = 0; int stepNumber = 0;
for (final Pair<int[], String> step : test) { for (final Pair<?, ?> step : test) {
++stepNumber; ++stepNumber;
final int[] input = step.first; final int[] input = (int[]) step.first;
final String expectedResult = step.second; final String expectedResult = (String) step.second;
if (input.length > 1) { if (input.length > 1) {
mLatinIME.onTextInput(new String(input, 0, input.length)); mLatinIME.onTextInput(new String(input, 0, input.length));
} else { } else {
@ -226,7 +224,7 @@ public class InputLogicTestsReorderingMyanmar extends InputTestsBase {
public void testMyanmarReordering() { public void testMyanmarReordering() {
int testNumber = 0; int testNumber = 0;
changeLanguage("my_MM", "CombiningRules=MyanmarReordering"); changeLanguage("my_MM", "CombiningRules=MyanmarReordering");
for (final Pair[] test : TESTS) { for (final Pair<?, ?>[] test : TESTS) {
// Small trick to reset LatinIME : setText("") and send updateSelection with values // Small trick to reset LatinIME : setText("") and send updateSelection with values
// LatinIME has never seen, and cursor pos 0,0. // LatinIME has never seen, and cursor pos 0,0.
mEditText.setText(""); mEditText.setText("");

View file

@ -40,7 +40,6 @@ import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
import com.android.inputmethod.event.Event; import com.android.inputmethod.event.Event;
import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.Dictionary.PhonyDictionary; import com.android.inputmethod.latin.Dictionary.PhonyDictionary;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.settings.DebugSettings; import com.android.inputmethod.latin.settings.DebugSettings;
@ -250,7 +249,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
// Now, Looper#loop() never exits in normal operation unless the Looper#quit() method // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method
// is called, which has a lot of bad side effects. We can however just throw an exception // is called, which has a lot of bad side effects. We can however just throw an exception
// in the runnable which will unwind the stack and allow us to exit. // in the runnable which will unwind the stack and allow us to exit.
private final class InterruptRunMessagesException extends RuntimeException { final class InterruptRunMessagesException extends RuntimeException {
// Empty class // Empty class
} }
protected void runMessages() { protected void runMessages() {
@ -284,7 +283,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
} else { } else {
final int x = key.getX() + key.getWidth() / 2; final int x = key.getX() + key.getWidth() / 2;
final int y = key.getY() + key.getHeight() / 2; final int y = key.getY() + key.getHeight() / 2;
event = mLatinIME.createSoftwareKeypressEvent(codePoint, x, y, isKeyRepeat); event = LatinIME.createSoftwareKeypressEvent(codePoint, x, y, isKeyRepeat);
} }
mLatinIME.onEvent(event); mLatinIME.onEvent(event);
// Also see the comment at the top of this function about onReleaseKey // Also see the comment at the top of this function about onReleaseKey
@ -309,9 +308,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
final Key key = mKeyboard.getKey(codePoint); final Key key = mKeyboard.getKey(codePoint);
if (key == null) { if (key == null) {
throw new RuntimeException("Code point not on the keyboard"); throw new RuntimeException("Code point not on the keyboard");
} else {
return new Point(key.getX() + key.getWidth() / 2, key.getY() + key.getHeight() / 2);
} }
return new Point(key.getX() + key.getWidth() / 2, key.getY() + key.getHeight() / 2);
} }
protected void gesture(final String stringToGesture) { protected void gesture(final String stringToGesture) {
@ -386,7 +384,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
false /* isAuxiliary */, false /* isAuxiliary */,
false /* overridesImplicitlyEnabledSubtype */, false /* overridesImplicitlyEnabledSubtype */,
0 /* id */); 0 /* id */);
SubtypeSwitcher.getInstance().forceSubtype(subtype); SubtypeSwitcher.forceSubtype(subtype);
mLatinIME.onCurrentInputMethodSubtypeChanged(subtype); mLatinIME.onCurrentInputMethodSubtypeChanged(subtype);
runMessages(); runMessages();
mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard(); mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();

View file

@ -25,8 +25,8 @@ import android.test.suitebuilder.annotation.SmallTest;
public class NgramContextTests extends AndroidTestCase { public class NgramContextTests extends AndroidTestCase {
public void testConstruct() { public void testConstruct() {
assertEquals(new NgramContext(new WordInfo("a")), new NgramContext(new WordInfo("a"))); assertEquals(new NgramContext(new WordInfo("a")), new NgramContext(new WordInfo("a")));
assertEquals(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE), assertEquals(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO),
new NgramContext(WordInfo.BEGINNING_OF_SENTENCE)); new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO));
assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO), assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO),
new NgramContext(WordInfo.EMPTY_WORD_INFO)); new NgramContext(WordInfo.EMPTY_WORD_INFO));
assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO), assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO),
@ -35,17 +35,18 @@ public class NgramContextTests extends AndroidTestCase {
public void testIsBeginningOfSentenceContext() { public void testIsBeginningOfSentenceContext() {
assertFalse(new NgramContext().isBeginningOfSentenceContext()); assertFalse(new NgramContext().isBeginningOfSentenceContext());
assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE) assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO)
.isBeginningOfSentenceContext()); .isBeginningOfSentenceContext());
assertTrue(NgramContext.BEGINNING_OF_SENTENCE.isBeginningOfSentenceContext()); assertTrue(NgramContext.BEGINNING_OF_SENTENCE.isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("a")).isBeginningOfSentenceContext()); assertFalse(new NgramContext(new WordInfo("a")).isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("")).isBeginningOfSentenceContext()); assertFalse(new NgramContext(new WordInfo("")).isBeginningOfSentenceContext());
assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO).isBeginningOfSentenceContext()); assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO).isBeginningOfSentenceContext());
assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE, new WordInfo("a")) assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO, new WordInfo("a"))
.isBeginningOfSentenceContext()); .isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("a"), WordInfo.BEGINNING_OF_SENTENCE) assertFalse(new NgramContext(new WordInfo("a"), WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO)
.isBeginningOfSentenceContext()); .isBeginningOfSentenceContext());
assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO, WordInfo.BEGINNING_OF_SENTENCE) assertFalse(new NgramContext(
WordInfo.EMPTY_WORD_INFO, WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO)
.isBeginningOfSentenceContext()); .isBeginningOfSentenceContext());
} }
@ -56,7 +57,7 @@ public class NgramContextTests extends AndroidTestCase {
assertEquals("b", ngramContext_b_a.getNthPrevWord(1)); assertEquals("b", ngramContext_b_a.getNthPrevWord(1));
assertEquals("a", ngramContext_b_a.getNthPrevWord(2)); assertEquals("a", ngramContext_b_a.getNthPrevWord(2));
final NgramContext ngramContext_bos_b = final NgramContext ngramContext_bos_b =
ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE); ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO);
assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext()); assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext());
assertEquals("b", ngramContext_bos_b.getNthPrevWord(2)); assertEquals("b", ngramContext_bos_b.getNthPrevWord(2));
final NgramContext ngramContext_c_bos = final NgramContext ngramContext_c_bos =

View file

@ -136,7 +136,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
} }
} }
private class MockInputMethodService extends InputMethodService { static class MockInputMethodService extends InputMethodService {
private MockConnection mMockConnection; private MockConnection mMockConnection;
public void setInputConnection(final MockConnection mockConnection) { public void setInputConnection(final MockConnection mockConnection) {
mMockConnection = mockConnection; mMockConnection = mockConnection;
@ -221,7 +221,6 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE }); mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE });
final SpacingAndPunctuations TAB = new SpacingAndPunctuations( final SpacingAndPunctuations TAB = new SpacingAndPunctuations(
mSpacingAndPunctuations, new int[] { Constants.CODE_TAB }); mSpacingAndPunctuations, new int[] { Constants.CODE_TAB });
final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t");
// A character that needs surrogate pair to represent its code point (U+2008A). // A character that needs surrogate pair to represent its code point (U+2008A).
final String SUPPLEMENTARY_CHAR_STRING = "\uD840\uDC8A"; final String SUPPLEMENTARY_CHAR_STRING = "\uD840\uDC8A";
final SpacingAndPunctuations SUPPLEMENTARY_CHAR = new SpacingAndPunctuations( final SpacingAndPunctuations SUPPLEMENTARY_CHAR = new SpacingAndPunctuations(

View file

@ -16,14 +16,10 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import android.os.Build;
import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.LargeTest;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.WordComposer;
@LargeTest @LargeTest
public class ShiftModeTests extends InputTestsBase { public class ShiftModeTests extends InputTestsBase {

View file

@ -60,7 +60,7 @@ public class SuggestedWordsTests extends AndroidTestCase {
} }
// Helper for testGetTransformedWordInfo // Helper for testGetTransformedWordInfo
private SuggestedWordInfo transformWordInfo(final String info, private static SuggestedWordInfo transformWordInfo(final String info,
final int trailingSingleQuotesCount) { final int trailingSingleQuotesCount) {
final SuggestedWordInfo suggestedWordInfo = createTypedWordInfo(info); final SuggestedWordInfo suggestedWordInfo = createTypedWordInfo(info);
final SuggestedWordInfo returnedWordInfo = final SuggestedWordInfo returnedWordInfo =

View file

@ -117,7 +117,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
super.tearDown(); super.tearDown();
} }
private void generateWords(final int number, final Random random) { private static void generateWords(final int number, final Random random) {
final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE, final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE,
random); random);
final Set<String> wordSet = new HashSet<>(); final Set<String> wordSet = new HashSet<>();
@ -138,7 +138,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
/** /**
* Adds unigrams to the dictionary. * Adds unigrams to the dictionary.
*/ */
private void addUnigrams(final int number, final FusionDictionary dict, private static void addUnigrams(final int number, final FusionDictionary dict,
final List<String> words, final HashMap<String, List<String>> shortcutMap) { final List<String> words, final HashMap<String, List<String>> shortcutMap) {
for (int i = 0; i < number; ++i) { for (int i = 0; i < number; ++i) {
final String word = words.get(i); final String word = words.get(i);
@ -154,7 +154,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
} }
} }
private void addBigrams(final FusionDictionary dict, private static void addBigrams(final FusionDictionary dict,
final List<String> words, final List<String> words,
final SparseArray<List<Integer>> bigrams) { final SparseArray<List<Integer>> bigrams) {
for (int i = 0; i < bigrams.size(); ++i) { for (int i = 0; i < bigrams.size(); ++i) {
@ -173,7 +173,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
// new java.io.FileWriter(new File(filename)), dict); // new java.io.FileWriter(new File(filename)), dict);
// } // }
private long timeWritingDictToFile(final File file, final FusionDictionary dict, private static long timeWritingDictToFile(final File file, final FusionDictionary dict,
final FormatSpec.FormatOptions formatOptions) { final FormatSpec.FormatOptions formatOptions) {
long now = -1, diff = -1; long now = -1, diff = -1;
@ -196,7 +196,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
return diff; return diff;
} }
private void checkDictionary(final FusionDictionary dict, final List<String> words, private static void checkDictionary(final FusionDictionary dict, final List<String> words,
final SparseArray<List<Integer>> bigrams, final SparseArray<List<Integer>> bigrams,
final HashMap<String, List<String>> shortcutMap) { final HashMap<String, List<String>> shortcutMap) {
assertNotNull(dict); assertNotNull(dict);
@ -231,16 +231,16 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
} }
} }
private String outputOptions(final int bufferType, private static String outputOptions(final int bufferType,
final FormatSpec.FormatOptions formatOptions) { final FormatSpec.FormatOptions formatOptions) {
String result = " : buffer type = " final String result = " : buffer type = "
+ ((bufferType == BinaryDictUtils.USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); + ((bufferType == BinaryDictUtils.USE_BYTE_BUFFER) ? "byte buffer" : "byte array");
return result + " : version = " + formatOptions.mVersion; return result + " : version = " + formatOptions.mVersion;
} }
// Tests for readDictionaryBinary and writeDictionaryBinary // Tests for readDictionaryBinary and writeDictionaryBinary
private long timeReadingAndCheckDict(final File file, final List<String> words, private static long timeReadingAndCheckDict(final File file, final List<String> words,
final SparseArray<List<Integer>> bigrams, final SparseArray<List<Integer>> bigrams,
final HashMap<String, List<String>> shortcutMap, final int bufferType) { final HashMap<String, List<String>> shortcutMap, final int bufferType) {
long now, diff = -1; long now, diff = -1;
@ -385,7 +385,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
// Tests for readUnigramsAndBigramsBinary // Tests for readUnigramsAndBigramsBinary
private void checkWordMap(final List<String> expectedWords, private static void checkWordMap(final List<String> expectedWords,
final SparseArray<List<Integer>> expectedBigrams, final SparseArray<List<Integer>> expectedBigrams,
final TreeMap<Integer, String> resultWords, final TreeMap<Integer, String> resultWords,
final TreeMap<Integer, Integer> resultFrequencies, final TreeMap<Integer, Integer> resultFrequencies,
@ -434,9 +434,9 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
assertEquals(actBigrams, expBigrams); assertEquals(actBigrams, expBigrams);
} }
private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words, private static long timeAndCheckReadUnigramsAndBigramsBinary(final File file,
final SparseArray<List<Integer>> bigrams, final int bufferType, final List<String> words, final SparseArray<List<Integer>> bigrams,
final boolean checkProbability) { final int bufferType, final boolean checkProbability) {
final TreeMap<Integer, String> resultWords = new TreeMap<>(); final TreeMap<Integer, String> resultWords = new TreeMap<>();
final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams = new TreeMap<>(); final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams = new TreeMap<>();
final TreeMap<Integer, Integer> resultFreqs = new TreeMap<>(); final TreeMap<Integer, Integer> resultFreqs = new TreeMap<>();
@ -519,7 +519,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
} }
// Tests for getTerminalPosition // Tests for getTerminalPosition
private String getWordFromBinary(final DictDecoder dictDecoder, final int address) { private static String getWordFromBinary(final DictDecoder dictDecoder, final int address) {
if (dictDecoder.getPosition() != 0) dictDecoder.setPosition(0); if (dictDecoder.getPosition() != 0) dictDecoder.setPosition(0);
DictionaryHeader fileHeader = null; DictionaryHeader fileHeader = null;
@ -535,7 +535,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
address).mWord; address).mWord;
} }
private long checkGetTerminalPosition(final DictDecoder dictDecoder, final String word, private static long checkGetTerminalPosition(final DictDecoder dictDecoder, final String word,
final boolean contained) { final boolean contained) {
long diff = -1; long diff = -1;
int position = -1; int position = -1;

View file

@ -113,15 +113,16 @@ public final class BinaryDictDecoderUtils {
/** /**
* Helper method to find out whether this code fits on one byte * Helper method to find out whether this code fits on one byte
*/ */
private static boolean fitsOnOneByte(int character, private static boolean fitsOnOneByte(final int character,
final HashMap<Integer, Integer> codePointToOneByteCodeMap) { final HashMap<Integer, Integer> codePointToOneByteCodeMap) {
int codePoint = character;
if (codePointToOneByteCodeMap != null) { if (codePointToOneByteCodeMap != null) {
if (codePointToOneByteCodeMap.containsKey(character)) { if (codePointToOneByteCodeMap.containsKey(character)) {
character = codePointToOneByteCodeMap.get(character); codePoint = codePointToOneByteCodeMap.get(character);
} }
} }
return character >= FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE return codePoint >= FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE
&& character <= FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE; && codePoint <= FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE;
} }
/** /**
@ -168,8 +169,9 @@ public final class BinaryDictDecoderUtils {
* @param codePointToOneByteCodeMap the map to convert the code point. * @param codePointToOneByteCodeMap the map to convert the code point.
* @return the index after the last character. * @return the index after the last character.
*/ */
static int writeCharArray(final int[] codePoints, final byte[] buffer, int index, static int writeCharArray(final int[] codePoints, final byte[] buffer, final int fromIndex,
final HashMap<Integer, Integer> codePointToOneByteCodeMap) { final HashMap<Integer, Integer> codePointToOneByteCodeMap) {
int index = fromIndex;
for (int codePoint : codePoints) { for (int codePoint : codePoints) {
if (codePointToOneByteCodeMap != null) { if (codePointToOneByteCodeMap != null) {
if (codePointToOneByteCodeMap.containsKey(codePoint)) { if (codePointToOneByteCodeMap.containsKey(codePoint)) {
@ -293,10 +295,9 @@ public final class BinaryDictDecoderUtils {
final int msb = dictBuffer.readUnsignedByte(); final int msb = dictBuffer.readUnsignedByte();
if (FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT >= msb) { if (FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT >= msb) {
return msb; return msb;
} else {
return ((FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT & msb) << 8)
+ dictBuffer.readUnsignedByte();
} }
return ((FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT & msb) << 8)
+ dictBuffer.readUnsignedByte();
} }
/** /**

View file

@ -199,8 +199,9 @@ public class BinaryDictEncoderUtils {
} }
} }
static int writeUIntToBuffer(final byte[] buffer, int position, final int value, static int writeUIntToBuffer(final byte[] buffer, final int fromPosition, final int value,
final int size) { final int size) {
int position = fromPosition;
switch(size) { switch(size) {
case 4: case 4:
buffer[position++] = (byte) ((value >> 24) & 0xFF); buffer[position++] = (byte) ((value >> 24) & 0xFF);
@ -324,11 +325,9 @@ public class BinaryDictEncoderUtils {
return targetNodeArray.mCachedAddressAfterUpdate return targetNodeArray.mCachedAddressAfterUpdate
- (currentNodeArray.mCachedAddressAfterUpdate - (currentNodeArray.mCachedAddressAfterUpdate
+ offsetFromStartOfCurrentNodeArray); + offsetFromStartOfCurrentNodeArray);
} else {
return targetNodeArray.mCachedAddressBeforeUpdate
- (currentNodeArray.mCachedAddressBeforeUpdate
+ offsetFromStartOfCurrentNodeArray);
} }
return targetNodeArray.mCachedAddressBeforeUpdate
- (currentNodeArray.mCachedAddressBeforeUpdate + offsetFromStartOfCurrentNodeArray);
} }
/** /**
@ -356,9 +355,8 @@ public class BinaryDictEncoderUtils {
final int newOffsetBasePoint = currentNodeArray.mCachedAddressAfterUpdate final int newOffsetBasePoint = currentNodeArray.mCachedAddressAfterUpdate
+ offsetFromStartOfCurrentNodeArray; + offsetFromStartOfCurrentNodeArray;
return targetPtNode.mCachedAddressAfterUpdate - newOffsetBasePoint; return targetPtNode.mCachedAddressAfterUpdate - newOffsetBasePoint;
} else {
return targetPtNode.mCachedAddressBeforeUpdate - oldOffsetBasePoint;
} }
return targetPtNode.mCachedAddressBeforeUpdate - oldOffsetBasePoint;
} }
/** /**
@ -541,8 +539,9 @@ public class BinaryDictEncoderUtils {
* @param position the position to write. * @param position the position to write.
* @return the size in bytes the address actually took. * @return the size in bytes the address actually took.
*/ */
/* package */ static int writeChildrenPosition(final byte[] buffer, int index, /* package */ static int writeChildrenPosition(final byte[] buffer, final int fromIndex,
final int position) { final int position) {
int index = fromIndex;
switch (getByteSize(position)) { switch (getByteSize(position)) {
case 1: case 1:
buffer[index++] = (byte)position; buffer[index++] = (byte)position;
@ -623,7 +622,7 @@ public class BinaryDictEncoderUtils {
* @return the flags * @return the flags
*/ */
/* package */ static final int makeBigramFlags(final boolean more, final int offset, /* package */ static final int makeBigramFlags(final boolean more, final int offset,
int bigramFrequency, final int unigramFrequency, final String word) { final int bigramFrequency, final int unigramFrequency, final String word) {
int bigramFlags = (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0) int bigramFlags = (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0)
+ (offset < 0 ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0); + (offset < 0 ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0);
switch (getByteSize(offset)) { switch (getByteSize(offset)) {
@ -639,13 +638,16 @@ public class BinaryDictEncoderUtils {
default: default:
throw new RuntimeException("Strange offset size"); throw new RuntimeException("Strange offset size");
} }
final int frequency;
if (unigramFrequency > bigramFrequency) { if (unigramFrequency > bigramFrequency) {
MakedictLog.e("Unigram freq is superior to bigram freq for \"" + word MakedictLog.e("Unigram freq is superior to bigram freq for \"" + word
+ "\". Bigram freq is " + bigramFrequency + ", unigram freq for " + "\". Bigram freq is " + bigramFrequency + ", unigram freq for "
+ word + " is " + unigramFrequency); + word + " is " + unigramFrequency);
bigramFrequency = unigramFrequency; frequency = unigramFrequency;
} else {
frequency = bigramFrequency;
} }
bigramFlags += getBigramFrequencyDiff(unigramFrequency, bigramFrequency) bigramFlags += getBigramFrequencyDiff(unigramFrequency, frequency)
& FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY; & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY;
return bigramFlags; return bigramFlags;
} }
@ -722,7 +724,6 @@ public class BinaryDictEncoderUtils {
* @param ptNodeArray the node array to write. * @param ptNodeArray the node array to write.
* @param codePointToOneByteCodeMap the map to convert the code points. * @param codePointToOneByteCodeMap the map to convert the code points.
*/ */
@SuppressWarnings("unused")
/* package */ static void writePlacedPtNodeArray(final FusionDictionary dict, /* package */ static void writePlacedPtNodeArray(final FusionDictionary dict,
final DictEncoder dictEncoder, final PtNodeArray ptNodeArray, final DictEncoder dictEncoder, final PtNodeArray ptNodeArray,
final HashMap<Integer, Integer> codePointToOneByteCodeMap) { final HashMap<Integer, Integer> codePointToOneByteCodeMap) {

View file

@ -206,11 +206,7 @@ public final class BinaryDictIOUtils {
if (same) { if (same) {
// found the PtNode matches the word. // found the PtNode matches the word.
if (wordPos + currentInfo.mCharacters.length == wordLen) { if (wordPos + currentInfo.mCharacters.length == wordLen) {
if (!currentInfo.isTerminal()) { return currentInfo.isTerminal() ? ptNodePos : FormatSpec.NOT_VALID_WORD;
return FormatSpec.NOT_VALID_WORD;
} else {
return ptNodePos;
}
} }
wordPos += currentInfo.mCharacters.length; wordPos += currentInfo.mCharacters.length;
if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) { if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {

View file

@ -142,11 +142,7 @@ public final class FusionDictionary implements Iterable<WordProperty> {
} }
public int getProbability() { public int getProbability() {
if (isTerminal()) { return isTerminal() ? mProbabilityInfo.mProbability : NOT_A_TERMINAL;
return mProbabilityInfo.mProbability;
} else {
return NOT_A_TERMINAL;
}
} }
public boolean getIsNotAWord() { public boolean getIsNotAWord() {
@ -235,7 +231,7 @@ public final class FusionDictionary implements Iterable<WordProperty> {
* the existing ones if any. Note: unigram, bigram, and shortcut frequencies are only * the existing ones if any. Note: unigram, bigram, and shortcut frequencies are only
* updated if they are higher than the existing ones. * updated if they are higher than the existing ones.
*/ */
private void update(final ProbabilityInfo probabilityInfo, void update(final ProbabilityInfo probabilityInfo,
final ArrayList<WeightedString> shortcutTargets, final ArrayList<WeightedString> shortcutTargets,
final ArrayList<WeightedString> bigrams, final ArrayList<WeightedString> bigrams,
final boolean isNotAWord, final boolean isPossiblyOffensive) { final boolean isNotAWord, final boolean isPossiblyOffensive) {
@ -337,15 +333,15 @@ public final class FusionDictionary implements Iterable<WordProperty> {
* This method checks that all PtNodes in a node array are ordered as expected. * This method checks that all PtNodes in a node array are ordered as expected.
* If they are, nothing happens. If they aren't, an exception is thrown. * If they are, nothing happens. If they aren't, an exception is thrown.
*/ */
private void checkStack(PtNodeArray ptNodeArray) { private static void checkStack(PtNodeArray ptNodeArray) {
ArrayList<PtNode> stack = ptNodeArray.mData; ArrayList<PtNode> stack = ptNodeArray.mData;
int lastValue = -1; int lastValue = -1;
for (int i = 0; i < stack.size(); ++i) { for (int i = 0; i < stack.size(); ++i) {
int currentValue = stack.get(i).mChars[0]; int currentValue = stack.get(i).mChars[0];
if (currentValue <= lastValue) if (currentValue <= lastValue) {
throw new RuntimeException("Invalid stack"); throw new RuntimeException("Invalid stack");
else }
lastValue = currentValue; lastValue = currentValue;
} }
} }
@ -521,14 +517,14 @@ public final class FusionDictionary implements Iterable<WordProperty> {
* is ignored. * is ignored.
* This comparator imposes orderings that are inconsistent with equals. * This comparator imposes orderings that are inconsistent with equals.
*/ */
static private final class PtNodeComparator implements java.util.Comparator<PtNode> { static final class PtNodeComparator implements java.util.Comparator<PtNode> {
@Override @Override
public int compare(PtNode p1, PtNode p2) { public int compare(PtNode p1, PtNode p2) {
if (p1.mChars[0] == p2.mChars[0]) return 0; if (p1.mChars[0] == p2.mChars[0]) return 0;
return p1.mChars[0] < p2.mChars[0] ? -1 : 1; return p1.mChars[0] < p2.mChars[0] ? -1 : 1;
} }
} }
final static private PtNodeComparator PTNODE_COMPARATOR = new PtNodeComparator(); final static PtNodeComparator PTNODE_COMPARATOR = new PtNodeComparator();
/** /**
* Finds the insertion index of a character within a node array. * Finds the insertion index of a character within a node array.
@ -559,7 +555,8 @@ public final class FusionDictionary implements Iterable<WordProperty> {
/** /**
* Helper method to find a word in a given branch. * Helper method to find a word in a given branch.
*/ */
public static PtNode findWordInTree(PtNodeArray nodeArray, final String string) { public static PtNode findWordInTree(final PtNodeArray rootNodeArray, final String string) {
PtNodeArray nodeArray = rootNodeArray;
int index = 0; int index = 0;
final StringBuilder checker = DBG ? new StringBuilder() : null; final StringBuilder checker = DBG ? new StringBuilder() : null;
final int[] codePoints = getCodePoints(string); final int[] codePoints = getCodePoints(string);

View file

@ -36,17 +36,17 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
/** /**
* A utility class for reading a PtNode. * A utility class for reading a PtNode.
*/ */
protected static class PtNodeReader { static class PtNodeReader {
private static ProbabilityInfo readProbabilityInfo(final DictBuffer dictBuffer) { static ProbabilityInfo readProbabilityInfo(final DictBuffer dictBuffer) {
// Ver2 dicts don't contain historical information. // Ver2 dicts don't contain historical information.
return new ProbabilityInfo(dictBuffer.readUnsignedByte()); return new ProbabilityInfo(dictBuffer.readUnsignedByte());
} }
protected static int readPtNodeOptionFlags(final DictBuffer dictBuffer) { static int readPtNodeOptionFlags(final DictBuffer dictBuffer) {
return dictBuffer.readUnsignedByte(); return dictBuffer.readUnsignedByte();
} }
protected static int readChildrenAddress(final DictBuffer dictBuffer, static int readChildrenAddress(final DictBuffer dictBuffer,
final int ptNodeFlags) { final int ptNodeFlags) {
switch (ptNodeFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) { switch (ptNodeFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE: case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
@ -62,7 +62,7 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
} }
// Reads shortcuts and returns the read length. // Reads shortcuts and returns the read length.
protected static int readShortcut(final DictBuffer dictBuffer, static int readShortcut(final DictBuffer dictBuffer,
final ArrayList<WeightedString> shortcutTargets) { final ArrayList<WeightedString> shortcutTargets) {
final int pointerBefore = dictBuffer.position(); final int pointerBefore = dictBuffer.position();
dictBuffer.readUnsignedShort(); // skip the size dictBuffer.readUnsignedShort(); // skip the size
@ -76,7 +76,7 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
return dictBuffer.position() - pointerBefore; return dictBuffer.position() - pointerBefore;
} }
protected static int readBigramAddresses(final DictBuffer dictBuffer, static int readBigramAddresses(final DictBuffer dictBuffer,
final ArrayList<PendingAttribute> bigrams, final int baseAddress) { final ArrayList<PendingAttribute> bigrams, final int baseAddress) {
int readLength = 0; int readLength = 0;
int bigramCount = 0; int bigramCount = 0;

View file

@ -27,14 +27,12 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
/** /**
* Unit tests for Ver2DictEncoder * Unit tests for Ver2DictEncoder
*/ */
@LargeTest @LargeTest
public class Ver2DictEncoderTests extends AndroidTestCase { public class Ver2DictEncoderTests extends AndroidTestCase {
private static final String TAG = Ver2DictEncoderTests.class.getSimpleName();
private static final int UNIGRAM_FREQ = 10; private static final int UNIGRAM_FREQ = 10;
public void testCodePointTable() { public void testCodePointTable() {
@ -75,7 +73,7 @@ public class Ver2DictEncoderTests extends AndroidTestCase {
/** /**
* Adds unigrams to the dictionary. * Adds unigrams to the dictionary.
*/ */
private void addUnigrams(final FusionDictionary dict, final List<String> words, private static void addUnigrams(final FusionDictionary dict, final List<String> words,
final HashMap<String, List<String>> shortcutMap) { final HashMap<String, List<String>> shortcutMap) {
for (final String word : words) { for (final String word : words) {
final ArrayList<WeightedString> shortcuts = new ArrayList<>(); final ArrayList<WeightedString> shortcuts = new ArrayList<>();

View file

@ -128,7 +128,7 @@ public class BlockingHttpClientTests extends AndroidTestCase {
assertTrue("ResponseProcessor was not invoked", processor.mInvoked); assertTrue("ResponseProcessor was not invoked", processor.mInvoked);
} }
private static class FakeErrorResponseProcessor implements ResponseProcessor<Void> { static class FakeErrorResponseProcessor implements ResponseProcessor<Void> {
@Override @Override
public Void onSuccess(InputStream response) { public Void onSuccess(InputStream response) {
fail("Expected an error but received success"); fail("Expected an error but received success");

Some files were not shown because too many files have changed in this diff Show more