aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java15
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java14
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java2
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java71
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java32
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java78
8 files changed, 191 insertions, 33 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 811470c26..21477a992 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -280,7 +280,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
setKeyboard(getKeyboard(mSavedKeyboardState.getKeyboardId()));
- updateShiftState();
} catch (RuntimeException e) {
Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
LatinImeLogger.logOnException(mMainKeyboardId.toString(), e);
@@ -331,6 +330,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final boolean localeChanged = (oldKeyboard == null)
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
+ updateShiftState();
}
private int getSwitchState(KeyboardId id) {
@@ -543,11 +543,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
private void setAutomaticTemporaryUpperCase() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null) {
- latinKeyboard.setAutomaticTemporaryUpperCase();
- mKeyboardView.invalidateAllKeys();
+ if (mKeyboardView == null) return;
+ final Keyboard keyboard = mKeyboardView.getKeyboard();
+ if (keyboard != null) {
+ keyboard.setAutomaticTemporaryUpperCase();
}
+ mKeyboardView.invalidateAllKeys();
}
/**
@@ -559,7 +560,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
Log.d(TAG, "updateShiftState:"
+ " autoCaps=" + mInputMethodService.getCurrentAutoCapsState()
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + shiftKeyState);
+ + " shiftKeyState=" + shiftKeyState
+ + " isAlphabetMode=" + isAlphabetMode()
+ + " isShiftLocked=" + isShiftLocked());
if (isAlphabetMode()) {
if (!isShiftLocked() && !shiftKeyState.isIgnoring()) {
if (shiftKeyState.isReleasing() && mInputMethodService.getCurrentAutoCapsState()) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 2df2994f6..bc021a690 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -83,6 +83,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// HORIZONTAL ELLIPSIS "...", character for popup hint.
private static final String POPUP_HINT_CHAR = "\u2026";
+ // Margin between the label and the icon on a key that has both of them.
+ // Specified by the fraction of the key width.
+ // TODO: Use resource parameter for this value.
+ private static final float LABEL_ICON_MARGIN = 0.05f;
+
// Main keyboard
private Keyboard mKeyboard;
private final KeyDrawParams mKeyDrawParams;
@@ -538,11 +543,13 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
positionX = centerX - labelCharWidth * 7 / 4;
paint.setTextAlign(Align.LEFT);
} else if (key.hasLabelWithIconLeft() && icon != null) {
- labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth();
+ labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth()
+ + (int)(LABEL_ICON_MARGIN * keyWidth);
positionX = centerX + labelWidth / 2;
paint.setTextAlign(Align.RIGHT);
} else if (key.hasLabelWithIconRight() && icon != null) {
- labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth();
+ labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth()
+ + (int)(LABEL_ICON_MARGIN * keyWidth);
positionX = centerX - labelWidth / 2;
paint.setTextAlign(Align.LEFT);
} else {
@@ -734,7 +741,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
canvas.translate(-x, -y);
}
- private static void drawHorizontalLine(Canvas canvas, float y, float w, int color, Paint paint) {
+ private static void drawHorizontalLine(Canvas canvas, float y, float w, int color,
+ Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 5e73d6300..7190b051d 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -56,12 +56,12 @@ public class ProximityInfo {
computeNearestNeighbors(keyWidth, keys);
}
- public static ProximityInfo getDummyProximityInfo() {
+ public static ProximityInfo createDummyProximityInfo() {
return new ProximityInfo(1, 1, 1, 1, 1, Collections.<Key>emptyList());
}
- public static ProximityInfo getSpellCheckerProximityInfo() {
- final ProximityInfo spellCheckerProximityInfo = getDummyProximityInfo();
+ public static ProximityInfo createSpellCheckerProximityInfo() {
+ final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
spellCheckerProximityInfo.mNativeProximityInfo =
spellCheckerProximityInfo.setProximityInfoNative(
SpellCheckerProximityInfo.ROW_SIZE,
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index de04ecd6c..f599def36 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -132,6 +132,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
private int mCurrentY = 0;
private Row mCurrentRow = null;
private boolean mLeftEdge;
+ private boolean mTopEdge;
private Key mRightEdgeKey = null;
private final KeyStyles mKeyStyles = new KeyStyles();
@@ -650,6 +651,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
private void startKeyboard() {
mCurrentY += mParams.mTopPadding;
+ mTopEdge = true;
}
private void startRow(Row row) {
@@ -670,6 +672,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
setSpacer(mCurrentX, mParams.mHorizontalEdgesPadding);
mCurrentY += mCurrentRow.mRowHeight;
mCurrentRow = null;
+ mTopEdge = false;
}
private void endKey(Key key) {
@@ -678,6 +681,9 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
key.addEdgeFlags(Keyboard.EDGE_LEFT);
mLeftEdge = false;
}
+ if (mTopEdge) {
+ key.addEdgeFlags(Keyboard.EDGE_TOP);
+ }
mRightEdgeKey = key;
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
index 0cde4e5b5..fd98456a8 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
@@ -21,7 +21,7 @@ import android.util.Log;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
public class KeyboardShiftState {
- private static final String TAG = "KeyboardShiftState";
+ private static final String TAG = KeyboardShiftState.class.getSimpleName();
private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
private static final int NORMAL = 0;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 44e999572..649774d78 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -16,9 +16,11 @@
package com.android.inputmethod.latin.spellcheck;
+import android.content.Intent;
import android.content.res.Resources;
import android.service.textservice.SpellCheckerService;
import android.service.textservice.SpellCheckerService.Session;
+import android.util.Log;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
@@ -34,8 +36,6 @@ import com.android.inputmethod.latin.WordComposer;
import java.util.Arrays;
import java.util.Collections;
-import java.util.List;
-import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
@@ -45,12 +45,12 @@ import java.util.TreeMap;
*/
public class AndroidSpellCheckerService extends SpellCheckerService {
private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
+ private static final int POOL_SIZE = 2;
private final static String[] emptyArray = new String[0];
- private final ProximityInfo mProximityInfo = ProximityInfo.getSpellCheckerProximityInfo();
- private final Map<String, Dictionary> mDictionaries =
- Collections.synchronizedMap(new TreeMap<String, Dictionary>());
+ private Map<String, DictionaryPool> mDictionaryPools =
+ Collections.synchronizedMap(new TreeMap<String, DictionaryPool>());
@Override
public Session createSession() {
@@ -105,35 +105,53 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
}
}
- private Dictionary getDictionary(final String locale) {
- Dictionary dictionary = mDictionaries.get(locale);
- if (null == dictionary) {
- final Resources resources = getResources();
- final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ @Override
+ public boolean onUnbind(final Intent intent) {
+ final Map<String, DictionaryPool> oldPools = mDictionaryPools;
+ mDictionaryPools = Collections.synchronizedMap(new TreeMap<String, DictionaryPool>());
+ for (DictionaryPool pool : oldPools.values()) {
+ pool.close();
+ }
+ return false;
+ }
+
+ private DictionaryPool getDictionaryPool(final String locale) {
+ DictionaryPool pool = mDictionaryPools.get(locale);
+ if (null == pool) {
final Locale localeObject = Utils.constructLocaleFromString(locale);
- dictionary = DictionaryFactory.createDictionaryFromManager(this, localeObject,
- fallbackResourceId);
- mDictionaries.put(locale, dictionary);
+ pool = new DictionaryPool(POOL_SIZE, this, localeObject);
+ mDictionaryPools.put(locale, pool);
}
- return dictionary;
+ return pool;
+ }
+
+ public DictAndProximity createDictAndProximity(final Locale locale) {
+ final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo();
+ final Resources resources = getResources();
+ final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ final Dictionary dictionary =
+ DictionaryFactory.createDictionaryFromManager(this, locale, fallbackResourceId);
+ return new DictAndProximity(dictionary, proximityInfo);
}
private class AndroidSpellCheckerSession extends Session {
+ // Immutable, but need the locale which is not available in the constructor yet
+ DictionaryPool mDictionaryPool;
+
@Override
public void onCreate() {
+ mDictionaryPool = getDictionaryPool(getLocale());
}
// Note : this must be reentrant
/**
* Gets a list of suggestions for a specific string. This returns a list of possible
- * corrections for the text passed as an arguments. It may split or group words, and
+ * corrections for the text passed as an argument. It may split or group words, and
* even perform grammatical analysis.
*/
@Override
public SuggestionsInfo onGetSuggestions(final TextInfo textInfo,
final int suggestionsLimit) {
- final String locale = getLocale();
- final Dictionary dictionary = getDictionary(locale);
final String text = textInfo.getText();
final SuggestionsGatherer suggestionsGatherer =
@@ -153,8 +171,21 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
composer.add(character, proximities,
WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
}
- dictionary.getWords(composer, suggestionsGatherer, mProximityInfo);
- final boolean isInDict = dictionary.isValidWord(text);
+
+ boolean isInDict = true;
+ try {
+ final DictAndProximity dictInfo = mDictionaryPool.take();
+ dictInfo.mDictionary.getWords(composer, suggestionsGatherer,
+ dictInfo.mProximityInfo);
+ isInDict = dictInfo.mDictionary.isValidWord(text);
+ if (!mDictionaryPool.offer(dictInfo)) {
+ Log.e(TAG, "Can't re-insert a dictionary into its pool");
+ }
+ } catch (InterruptedException e) {
+ // I don't think this can happen.
+ return new SuggestionsInfo(0, new String[0]);
+ }
+
final String[] suggestions = suggestionsGatherer.getGatheredSuggestions();
final int flags =
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java b/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java
new file mode 100644
index 000000000..3dbbd40cd
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.spellcheck;
+
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.keyboard.ProximityInfo;
+
+/**
+ * A simple container for both a Dictionary and a ProximityInfo.
+ */
+public class DictAndProximity {
+ public final Dictionary mDictionary;
+ public final ProximityInfo mProximityInfo;
+ public DictAndProximity(final Dictionary dictionary, final ProximityInfo proximityInfo) {
+ mDictionary = dictionary;
+ mProximityInfo = proximityInfo;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
new file mode 100644
index 000000000..ee294f6b0
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.spellcheck;
+
+import android.content.Context;
+
+import java.util.Locale;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * A blocking queue that creates dictionaries up to a certain limit as necessary.
+ */
+public class DictionaryPool extends LinkedBlockingQueue<DictAndProximity> {
+ private final AndroidSpellCheckerService mService;
+ private final int mMaxSize;
+ private final Locale mLocale;
+ private int mSize;
+ private volatile boolean mClosed;
+
+ public DictionaryPool(final int maxSize, final AndroidSpellCheckerService service,
+ final Locale locale) {
+ super();
+ mMaxSize = maxSize;
+ mService = service;
+ mLocale = locale;
+ mSize = 0;
+ mClosed = false;
+ }
+
+ @Override
+ public DictAndProximity take() throws InterruptedException {
+ final DictAndProximity dict = poll();
+ if (null != dict) return dict;
+ synchronized(this) {
+ if (mSize >= mMaxSize) {
+ // Our pool is already full. Wait until some dictionary is ready.
+ return super.take();
+ } else {
+ ++mSize;
+ return mService.createDictAndProximity(mLocale);
+ }
+ }
+ }
+
+ public void close() {
+ synchronized(this) {
+ mClosed = true;
+ for (DictAndProximity dict : this) {
+ dict.mDictionary.close();
+ }
+ clear();
+ }
+ }
+
+ @Override
+ public boolean offer(final DictAndProximity dict) {
+ if (mClosed) {
+ dict.mDictionary.close();
+ return false;
+ } else {
+ return super.offer(dict);
+ }
+ }
+}