Skip to content
Snippets Groups Projects
Commit 4d8f9f1c authored by Jean Chalard's avatar Jean Chalard
Browse files

Cache three main keyboards to improve average switch time

This typically improves the average loading time by about
35%, after the first time.

Bug: 8689779
Change-Id: I7b0ab6b942af1d3250b9dcbf875f27f9f64692f3
parent 8ea77542
No related branches found
No related tags found
No related merge requests found
......@@ -80,6 +80,14 @@ public final class KeyboardLayoutSet {
private final Context mContext;
private final Params mParams;
// How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and
// ALPHABET_AUTOMATIC_SHIFTED layouts - other layouts may stay in memory in the map of
// soft-references, but we forcibly cache this many alphabetic/auto-shifted layouts.
private static final int FORCIBLE_CACHE_SIZE = 4;
// By construction of soft references, anything that is also referenced somewhere else
// will stay in the cache. So we forcibly keep some references in an array to prevent
// them from disappearing from sKeyboardCache.
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
CollectionUtils.newHashMap();
private static final KeysCache sKeysCache = new KeysCache();
......@@ -110,6 +118,7 @@ public final class KeyboardLayoutSet {
boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled;
InputMethodSubtype mSubtype;
boolean mIsSpellChecker;
int mOrientation;
int mKeyboardWidth;
int mKeyboardHeight;
......@@ -185,7 +194,18 @@ public final class KeyboardLayoutSet {
elementParams.mProximityCharsCorrectionEnabled);
keyboard = builder.build();
sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
if ((id.mElementId == KeyboardId.ELEMENT_ALPHABET
|| id.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)
&& !mParams.mIsSpellChecker) {
// We only forcibly cache the primary, "ALPHABET", layouts.
for (int i = sForcibleKeyboardCache.length - 1; i >= 1; --i) {
sForcibleKeyboardCache[i] = sForcibleKeyboardCache[i - 1];
}
sForcibleKeyboardCache[0] = keyboard;
if (DEBUG_CACHE) {
Log.d(TAG, "forcing caching of keyboard with id=" + id);
}
}
if (DEBUG_CACHE) {
Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
......@@ -272,6 +292,11 @@ public final class KeyboardLayoutSet {
return this;
}
public Builder setIsSpellChecker(final boolean isSpellChecker) {
mParams.mIsSpellChecker = true;
return this;
}
public Builder setOptions(final boolean voiceKeyEnabled, final boolean voiceKeyOnMain,
final boolean languageSwitchKeyEnabled) {
@SuppressWarnings("deprecation")
......@@ -422,7 +447,8 @@ public final class KeyboardLayoutSet {
final InputMethodSubtype subtype =
AdditionalSubtype.createAdditionalSubtype(locale, layout, null);
return createKeyboardSet(context, subtype, SPELLCHECKER_DUMMY_KEYBOARD_WIDTH,
SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false);
SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false /* testCasesHaveTouchCoordinates */,
true /* isSpellChecker */);
}
@UsedForTesting
......@@ -442,18 +468,20 @@ public final class KeyboardLayoutSet {
throw new RuntimeException("Orientation should be ORIENTATION_LANDSCAPE or "
+ "ORIENTATION_PORTRAIT: orientation=" + orientation);
}
return createKeyboardSet(context, subtype, width, height, testCasesHaveTouchCoordinates);
return createKeyboardSet(context, subtype, width, height, testCasesHaveTouchCoordinates,
false /* isSpellChecker */);
}
private static KeyboardLayoutSet createKeyboardSet(final Context context,
final InputMethodSubtype subtype, final int width, final int height,
final boolean testCasesHaveTouchCoordinates) {
final boolean testCasesHaveTouchCoordinates, final boolean isSpellChecker) {
final EditorInfo editorInfo = new EditorInfo();
editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
context, editorInfo);
builder.setScreenGeometry(width, height);
builder.setSubtype(subtype);
builder.setIsSpellChecker(isSpellChecker);
if (!testCasesHaveTouchCoordinates) {
// For spell checker and tests
builder.disableTouchPositionCorrectionData();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment