aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/AndroidManifest.xml3
-rw-r--r--java/res/raw/main_de.dictbin1605716 -> 1605703 bytes
-rw-r--r--java/res/raw/main_en.dictbin1069229 -> 1069220 bytes
-rw-r--r--java/res/raw/main_es.dictbin1138868 -> 1138855 bytes
-rw-r--r--java/res/raw/main_fr.dictbin1328417 -> 1328404 bytes
-rw-r--r--java/res/raw/main_it.dictbin1143332 -> 1143320 bytes
-rw-r--r--java/res/values-en/whitelist.xml512
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java7
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java12
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java30
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java22
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java14
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java17
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java31
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java1
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java47
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java211
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java7
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java2
24 files changed, 390 insertions, 557 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index 393bc18b8..06d852bb0 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -30,7 +30,8 @@
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker" />
</service>
- <activity android:name="SettingsActivity" android:label="@string/english_ime_settings">
+ <activity android:name="SettingsActivity" android:label="@string/english_ime_settings"
+ android:uiOptions="splitActionBarWhenNarrow">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
diff --git a/java/res/raw/main_de.dict b/java/res/raw/main_de.dict
index 68b0dceb2..1a7b305d6 100644
--- a/java/res/raw/main_de.dict
+++ b/java/res/raw/main_de.dict
Binary files differ
diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict
index f544da61a..14865a28e 100644
--- a/java/res/raw/main_en.dict
+++ b/java/res/raw/main_en.dict
Binary files differ
diff --git a/java/res/raw/main_es.dict b/java/res/raw/main_es.dict
index 8321c70f8..71370aac2 100644
--- a/java/res/raw/main_es.dict
+++ b/java/res/raw/main_es.dict
Binary files differ
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 084ef7c10..4723961c2 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/raw/main_it.dict b/java/res/raw/main_it.dict
index ed260f2a2..00bbdbe90 100644
--- a/java/res/raw/main_it.dict
+++ b/java/res/raw/main_it.dict
Binary files differ
diff --git a/java/res/values-en/whitelist.xml b/java/res/values-en/whitelist.xml
index bcb884e1d..0a1646fed 100644
--- a/java/res/values-en/whitelist.xml
+++ b/java/res/values-en/whitelist.xml
@@ -30,62 +30,15 @@
<item>ill</item>
<item>I\'ll</item>
- <!-- Following entries came from AutoText -->
- <!-- TODO: Trim down these entries by removing ones getting auto-corrected by the typing
- error correction algorithms. -->
- <item>255</item>
- <item>abouta</item>
- <item>about a</item>
-
- <item>255</item>
- <item>aboutit</item>
- <item>about it</item>
-
- <item>255</item>
- <item>aboutthe</item>
- <item>about the</item>
-
- <item>255</item>
- <item>acheive</item>
- <item>achieve</item>
-
- <item>255</item>
- <item>acheived</item>
- <item>achieved</item>
-
- <item>255</item>
- <item>acheiving</item>
- <item>achieving</item>
+ <!-- Following entries came from AutoText the Android keyboard no longer uses. -->
+ <!-- TODO: Trim down more entries by removing ones that get auto-corrected by the
+ Android keyboard's own typing error correction algorithms. -->
<item>255</item>
<item>acomodate</item>
<item>accommodate</item>
<item>255</item>
- <item>accomodate</item>
- <item>accommodate</item>
-
- <item>255</item>
- <item>acn</item>
- <item>can</item>
-
- <item>255</item>
- <item>adn</item>
- <item>and</item>
-
- <item>255</item>
- <item>agian</item>
- <item>again</item>
-
- <item>255</item>
- <item>ahd</item>
- <item>had</item>
-
- <item>255</item>
- <item>ahve</item>
- <item>have</item>
-
- <item>255</item>
<item>aint</item>
<item>ain\'t</item>
@@ -94,82 +47,14 @@
<item>a lot</item>
<item>255</item>
- <item>amde</item>
- <item>made</item>
-
- <item>255</item>
- <item>amke</item>
- <item>make</item>
-
- <item>255</item>
- <item>andone</item>
- <item>and one</item>
-
- <item>255</item>
<item>andteh</item>
<item>and the</item>
<item>255</item>
- <item>anothe</item>
- <item>another</item>
-
- <item>255</item>
<item>arent</item>
<item>aren\'t</item>
<item>255</item>
- <item>asthe</item>
- <item>as the</item>
-
- <item>255</item>
- <item>atthe</item>
- <item>at the</item>
-
- <item>255</item>
- <item>bakc</item>
- <item>back</item>
-
- <item>255</item>
- <item>beacuse</item>
- <item>because</item>
-
- <item>255</item>
- <item>becasue</item>
- <item>because</item>
-
- <item>255</item>
- <item>becaus</item>
- <item>because</item>
-
- <item>255</item>
- <item>becausea</item>
- <item>because a</item>
-
- <item>255</item>
- <item>becauseof</item>
- <item>because of</item>
-
- <item>255</item>
- <item>becausethe</item>
- <item>because the</item>
-
- <item>255</item>
- <item>becauseyou</item>
- <item>because you</item>
-
- <item>255</item>
- <item>becuase</item>
- <item>because</item>
-
- <item>255</item>
- <item>becuse</item>
- <item>because</item>
-
- <item>255</item>
- <item>beleive</item>
- <item>believe</item>
-
- <item>255</item>
<item>bot</item>
<item>not</item>
@@ -178,126 +63,18 @@
<item>but</item>
<item>255</item>
- <item>butthe</item>
- <item>but the</item>
-
- <item>255</item>
<item>cant</item>
<item>can\'t</item>
<item>255</item>
- <item>certian</item>
- <item>certain</item>
-
- <item>255</item>
- <item>changable</item>
- <item>changeable</item>
-
- <item>255</item>
- <item>chekc</item>
- <item>check</item>
-
- <item>255</item>
- <item>chnage</item>
- <item>change</item>
-
- <item>255</item>
- <item>couldnt</item>
- <item>couldn\'t</item>
-
- <item>255</item>
- <item>couldthe</item>
- <item>could the</item>
-
- <item>255</item>
- <item>couldve</item>
- <item>could\'ve</item>
-
- <item>255</item>
- <item>cna</item>
- <item>can</item>
-
- <item>255</item>
- <item>committment</item>
- <item>commitment</item>
-
- <item>255</item>
- <item>committments</item>
- <item>commitments</item>
-
- <item>255</item>
- <item>companys</item>
- <item>company\'s</item>
-
- <item>255</item>
- <item>cxan</item>
- <item>can</item>
-
- <item>255</item>
<item>didint</item>
<item>didn\'t</item>
<item>255</item>
- <item>didnot</item>
- <item>did not</item>
-
- <item>255</item>
- <item>didnt</item>
- <item>didn\'t</item>
-
- <item>255</item>
- <item>doesnt</item>
- <item>doesn\'t</item>
-
- <item>255</item>
- <item>dont</item>
- <item>don\'t</item>
-
- <item>255</item>
- <item>eyt</item>
- <item>yet</item>
-
- <item>255</item>
- <item>fidn</item>
- <item>find</item>
-
- <item>255</item>
<item>fora</item>
<item>for a</item>
<item>255</item>
- <item>freind</item>
- <item>friend</item>
-
- <item>255</item>
- <item>friday</item>
- <item>Friday</item>
-
- <item>255</item>
- <item>hadbeen</item>
- <item>had been</item>
-
- <item>255</item>
- <item>hadnt</item>
- <item>hadn\'t</item>
-
- <item>255</item>
- <item>haev</item>
- <item>have</item>
-
- <item>255</item>
- <item>hasbeen</item>
- <item>has been</item>
-
- <item>255</item>
- <item>hasnt</item>
- <item>hasn\'t</item>
-
- <item>255</item>
- <item>havent</item>
- <item>haven\'t</item>
-
- <item>255</item>
<item>hed</item>
<item>he\'d</item>
@@ -310,14 +87,6 @@
<item>here\'s</item>
<item>255</item>
- <item>hes</item>
- <item>he\'s</item>
-
- <item>255</item>
- <item>hlep</item>
- <item>help</item>
-
- <item>255</item>
<item>hoe</item>
<item>how</item>
@@ -342,18 +111,6 @@
<item>how\'ve</item>
<item>255</item>
- <item>hte</item>
- <item>the</item>
-
- <item>255</item>
- <item>htis</item>
- <item>this</item>
-
- <item>255</item>
- <item>hvae</item>
- <item>have</item>
-
- <item>255</item>
<item>i</item>
<item>I</item>
@@ -366,50 +123,18 @@
<item>I\'m</item>
<item>255</item>
- <item>i\'m</item>
- <item>I\'m</item>
-
- <item>255</item>
- <item>i\'ll</item>
- <item>I\'ll</item>
-
- <item>255</item>
- <item>i\'ve</item>
- <item>I\'ve</item>
-
- <item>255</item>
<item>inteh</item>
<item>in the</item>
<item>255</item>
- <item>isnt</item>
- <item>isn\'t</item>
-
- <item>255</item>
- <item>isthe</item>
- <item>is the</item>
-
- <item>255</item>
<item>itd</item>
<item>it\'d</item>
<item>255</item>
- <item>itis</item>
- <item>it is</item>
-
- <item>255</item>
- <item>itll</item>
- <item>it\'ll</item>
-
- <item>255</item>
<item>itsa</item>
<item>it\'s a</item>
<item>255</item>
- <item>ive</item>
- <item>I\'ve</item>
-
- <item>255</item>
<item>jot</item>
<item>not</item>
@@ -426,217 +151,37 @@
<item>more</item>
<item>255</item>
- <item>mkae</item>
- <item>make</item>
-
- <item>255</item>
- <item>mkaes</item>
- <item>makes</item>
-
- <item>255</item>
<item>moat</item>
<item>most</item>
<item>255</item>
- <item>monday</item>
- <item>Monday</item>
-
- <item>255</item>
<item>mot</item>
<item>not</item>
<item>255</item>
- <item>mustnt</item>
- <item>mustn\'t</item>
-
- <item>255</item>
- <item>neednt</item>
- <item>needn\'t</item>
-
- <item>255</item>
<item>nit</item>
<item>not</item>
<item>255</item>
- <item>oclock</item>
- <item>o\'clock</item>
-
- <item>255</item>
- <item>ofits</item>
- <item>of its</item>
-
- <item>255</item>
- <item>ofthe</item>
- <item>of the</item>
-
- <item>255</item>
- <item>omre</item>
- <item>more</item>
-
- <item>255</item>
- <item>oneof</item>
- <item>one of</item>
-
- <item>255</item>
<item>os</item>
<item>is</item>
<item>255</item>
- <item>otehr</item>
- <item>other</item>
-
- <item>255</item>
- <item>outof</item>
- <item>out of</item>
-
- <item>255</item>
- <item>overthe</item>
- <item>over the</item>
-
- <item>255</item>
- <item>owrk</item>
- <item>work</item>
-
- <item>255</item>
- <item>percentof</item>
- <item>percent of</item>
-
- <item>255</item>
- <item>recieve</item>
- <item>receive</item>
-
- <item>255</item>
- <item>recieved</item>
- <item>received</item>
-
- <item>255</item>
- <item>recieving</item>
- <item>receiving</item>
-
- <item>255</item>
- <item>saidthat</item>
- <item>said that</item>
-
- <item>255</item>
- <item>saidthe</item>
- <item>said the</item>
-
- <item>255</item>
- <item>saturday</item>
- <item>Saturday</item>
-
- <item>255</item>
- <item>seh</item>
- <item>she</item>
-
- <item>255</item>
- <item>shant</item>
- <item>shan\'t</item>
-
- <item>255</item>
- <item>she\'</item>
- <item>she\'ll</item>
-
- <item>255</item>
<item>shel</item>
<item>she\'ll</item>
<item>255</item>
- <item>shes</item>
- <item>she\'s</item>
-
- <item>255</item>
<item>shouldent</item>
<item>shouldn\'t</item>
<item>255</item>
- <item>shouldnt</item>
- <item>shouldn\'t</item>
-
- <item>255</item>
- <item>shouldve</item>
- <item>should\'ve</item>
-
- <item>255</item>
- <item>sone</item>
- <item>some</item>
-
- <item>255</item>
- <item>sunday</item>
- <item>Sunday</item>
-
- <item>255</item>
- <item>tahn</item>
- <item>than</item>
-
- <item>255</item>
- <item>taht</item>
- <item>that</item>
-
- <item>255</item>
- <item>teh</item>
- <item>the</item>
-
- <item>255</item>
<item>thatd</item>
<item>that\'d</item>
<item>255</item>
- <item>thatll</item>
- <item>that\'ll</item>
-
- <item>255</item>
- <item>thats</item>
- <item>that\'s</item>
-
- <item>255</item>
- <item>thatthe</item>
- <item>that the</item>
-
- <item>255</item>
- <item>theres</item>
- <item>there\'s</item>
-
- <item>255</item>
- <item>theyd</item>
- <item>they\'d</item>
-
- <item>255</item>
- <item>theyll</item>
- <item>they\'ll</item>
-
- <item>255</item>
- <item>theyre</item>
- <item>they\'re</item>
-
- <item>255</item>
- <item>theyve</item>
- <item>they\'ve</item>
-
- <item>255</item>
- <item>thier</item>
- <item>their</item>
-
- <item>255</item>
- <item>thsi</item>
- <item>this</item>
-
- <item>255</item>
- <item>thursday</item>
- <item>Thursday</item>
-
- <item>255</item>
<item>tine</item>
<item>time</item>
- <item>255</item>
- <item>tothe</item>
- <item>to the</item>
-
- <item>255</item>
- <item>tuesday</item>
- <item>Tuesday</item>
-
<!-- through additional proximity, 'uf' becomes 'of'. 'o' is not next to 'u' so anyone
typing 'uf' probably meant 'if', but 'of' is much more common and should be left
higher than 'if', hence the need for this entry. -->
@@ -664,14 +209,6 @@
<item>vis-a-vis</item>
<item>255</item>
- <item>wasnt</item>
- <item>wasn\'t</item>
-
- <item>255</item>
- <item>wednesday</item>
- <item>Wednesday</item>
-
- <item>255</item>
<item>wierd</item>
<item>weird</item>
@@ -684,22 +221,10 @@
<item>we\'re</item>
<item>255</item>
- <item>werent</item>
- <item>weren\'t</item>
-
- <item>255</item>
- <item>weve</item>
- <item>we\'ve</item>
-
- <item>255</item>
<item>whatd</item>
<item>what\'d</item>
<item>255</item>
- <item>whatll</item>
- <item>what\'ll</item>
-
- <item>255</item>
<item>whatm</item>
<item>what\'m</item>
@@ -728,18 +253,10 @@
<item>where\'s</item>
<item>255</item>
- <item>whod</item>
- <item>who\'d</item>
-
- <item>255</item>
<item>wholl</item>
<item>who\'ll</item>
<item>255</item>
- <item>whos</item>
- <item>who\'s</item>
-
- <item>255</item>
<item>whove</item>
<item>who\'ve</item>
@@ -760,22 +277,10 @@
<item>why\'ve</item>
<item>255</item>
- <item>witha</item>
- <item>with a</item>
-
- <item>255</item>
<item>wont</item>
<item>won\'t</item>
<item>255</item>
- <item>wouldnt</item>
- <item>wouldn\'t</item>
-
- <item>255</item>
- <item>wouldve</item>
- <item>would\'ve</item>
-
- <item>255</item>
<item>yall</item>
<item>y\'all</item>
@@ -787,16 +292,5 @@
<item>youd</item>
<item>you\'d</item>
- <item>255</item>
- <item>youll</item>
- <item>you\'ll</item>
-
- <item>255</item>
- <item>youre</item>
- <item>you\'re</item>
-
- <item>255</item>
- <item>youve</item>
- <item>you\'ve</item>
</string-array>
</resources>
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 67e21b10c..3cfef972a 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -282,7 +282,12 @@ public class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat
return;
}
- parent.requestSendAccessibilityEvent(mKeyboardView, event);
+ if (!parent.requestSendAccessibilityEvent(mKeyboardView, event)) {
+ // TODO: Remove this line after the top-level view for the IME
+ // window is fixed to be non-null and requestSendAccessibilityEvent
+ // can return true.
+ mAccessibilityUtils.requestSendAccessibilityEvent(event);
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index 2ea7d83e4..616b1c6d7 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -174,4 +174,16 @@ public class AccessibilityUtils {
speak(text);
}
}
+
+ /**
+ * Sends the specified {@link AccessibilityEvent} if accessibility is
+ * enabled. No operation if accessibility is disabled.
+ *
+ * @param event The event to send.
+ */
+ public void requestSendAccessibilityEvent(AccessibilityEvent event) {
+ if (mAccessibilityManager.isEnabled()) {
+ mAccessibilityManager.sendAccessibilityEvent(event);
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index f4e4105e3..7e1889a74 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -111,9 +111,6 @@ public class KeyCodeDescriptionMapper {
if (mKeyLabelMap.containsKey(label)) {
return context.getString(mKeyLabelMap.get(label));
}
-
- // Otherwise, return the label.
- return key.mLabel;
}
// Just attempt to speak the description.
@@ -229,6 +226,8 @@ public class KeyCodeDescriptionMapper {
return context.getString(mKeyCodeMap.get(code));
} else if (isDefinedNonCtrl) {
return Character.toString((char) code);
+ } else if (!TextUtils.isEmpty(key.mLabel)) {
+ return key.mLabel;
} else {
return context.getString(R.string.spoken_description_unknown, code);
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index e50d922ea..37fa674c2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -71,7 +71,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
private InputView mCurrentInputView;
private LatinKeyboardView mKeyboardView;
- private LatinIME mInputMethodService;
+ private LatinIME mLatinIME;
private Resources mResources;
private KeyboardState mState;
@@ -95,17 +95,17 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Intentional empty constructor for singleton.
}
- public static void init(LatinIME ims, SharedPreferences prefs) {
- sInstance.initInternal(ims, prefs);
+ public static void init(LatinIME latinIme, SharedPreferences prefs) {
+ sInstance.initInternal(latinIme, prefs);
}
- private void initInternal(LatinIME ims, SharedPreferences prefs) {
- mInputMethodService = ims;
- mResources = ims.getResources();
+ private void initInternal(LatinIME latinIme, SharedPreferences prefs) {
+ mLatinIME = latinIme;
+ mResources = latinIme.getResources();
mPrefs = prefs;
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mState = new KeyboardState(this);
- setContextThemeWrapper(ims, getKeyboardTheme(ims, prefs));
+ setContextThemeWrapper(latinIme, getKeyboardTheme(latinIme, prefs));
mForceNonDistinctMultitouch = prefs.getBoolean(
DebugSettings.FORCE_NON_DISTINCT_MULTITOUCH_KEY, false);
}
@@ -194,14 +194,14 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
* Update keyboard shift state triggered by connected EditText status change.
*/
public void updateShiftState() {
- mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
+ mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState());
}
public void onPressKey(int code) {
if (isVibrateAndSoundFeedbackRequired()) {
- mInputMethodService.hapticAndAudioFeedback(code);
+ mLatinIME.hapticAndAudioFeedback(code);
}
- mState.onPressKey(code);
+ mState.onPressKey(code, isSinglePointer(), mLatinIME.getCurrentAutoCapsState());
}
public void onReleaseKey(int code, boolean withSliding) {
@@ -257,7 +257,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void requestUpdatingShiftState() {
- mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
+ mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState());
}
// Implements {@link KeyboardState.SwitchActions}.
@@ -311,7 +311,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void hapticAndAudioFeedback(int code) {
- mInputMethodService.hapticAndAudioFeedback(code);
+ mLatinIME.hapticAndAudioFeedback(code);
}
public void onLongPressTimeout(int code) {
@@ -338,7 +338,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
* Updates state machine to figure out when to automatically switch back to the previous mode.
*/
public void onCodeInput(int code) {
- mState.onCodeInput(code, isSinglePointer(), mInputMethodService.getCurrentAutoCapsState());
+ mState.onCodeInput(code, isSinglePointer(), mLatinIME.getCurrentAutoCapsState());
}
public LatinKeyboardView getKeyboardView() {
@@ -354,7 +354,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
boolean tryGC = true;
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
try {
- setContextThemeWrapper(mInputMethodService, mKeyboardTheme);
+ setContextThemeWrapper(mLatinIME, mKeyboardTheme);
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
R.layout.input_view, null);
tryGC = false;
@@ -368,7 +368,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
- mKeyboardView.setKeyboardActionListener(mInputMethodService);
+ mKeyboardView.setKeyboardActionListener(mLatinIME);
if (mForceNonDistinctMultitouch) {
mKeyboardView.setDistinctMultitouch(false);
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 2045b0c82..51a0f537f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -389,11 +389,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @param keyboard the keyboard to display in this view
*/
public void setKeyboard(Keyboard keyboard) {
- // Remove any pending messages.
- mDrawingHandler.cancelAllMessages();
- if (mKeyboard != null) {
- PointerTracker.dismissAllKeyPreviews();
- }
mKeyboard = keyboard;
LatinImeLogger.onSetKeyboard(keyboard);
requestLayout();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index e3661a9f8..c85122ad3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -30,7 +30,7 @@ import com.android.inputmethod.latin.define.ProductionFlag;
* This class contains all keyboard state transition logic.
*
* The input events are {@link #onLoadKeyboard(String)}, {@link #onSaveKeyboardState()},
- * {@link #onPressKey(int)}, {@link #onReleaseKey(int, boolean)},
+ * {@link #onPressKey(int, boolean, int)}, {@link #onReleaseKey(int, boolean)},
* {@link #onCodeInput(int, boolean, int)}, {@link #onCancelInput(boolean)},
* {@link #onUpdateShiftState(int)}, {@link #onLongPressTimeout(int)}.
*
@@ -297,9 +297,10 @@ public class KeyboardState {
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
}
- public void onPressKey(int code) {
+ public void onPressKey(int code, boolean isSinglePointer, int autoCaps) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onPressKey: code=" + Keyboard.printableCode(code) + " " + this);
+ Log.d(TAG, "onPressKey: code=" + Keyboard.printableCode(code)
+ + " single=" + isSinglePointer + " autoCaps=" + autoCaps + " " + this);
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.keyboardState_onPressKey(code, this);
@@ -313,6 +314,21 @@ public class KeyboardState {
mSwitchActions.cancelLongPressTimer();
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
+ // It is required to reset the auto caps state when all of the following conditions
+ // are met:
+ // 1) two or more fingers are in action
+ // 2) in alphabet layout
+ // 3) not in all characters caps mode
+ // As for #3, please note that it's required to check even when the auto caps mode is
+ // off because, for example, we may be in the #1 state within the manual temporary
+ // shifted mode.
+ if (!isSinglePointer && mIsAlphabetMode && autoCaps != TextUtils.CAP_MODE_CHARACTERS) {
+ final boolean needsToResetAutoCaps = mAlphabetShiftState.isAutomaticShifted()
+ || (mAlphabetShiftState.isManualShifted() && mShiftKeyState.isReleasing());
+ if (needsToResetAutoCaps) {
+ mSwitchActions.setAlphabetKeyboard();
+ }
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 22787c218..0a09c845e 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -60,7 +60,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private final boolean mUseFirstLastBigrams;
public ContactsBinaryDictionary(final Context context, final int dicTypeId, Locale locale) {
- super(context, getFilenameWithLocale(locale), dicTypeId);
+ super(context, getFilenameWithLocale(NAME, locale.toString()), dicTypeId);
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
registerObserver(context);
@@ -69,10 +69,6 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
loadDictionary();
}
- private static String getFilenameWithLocale(Locale locale) {
- return NAME + "." + locale.toString() + ".dict";
- }
-
private synchronized void registerObserver(final Context context) {
// Perform a managed query. The Activity will handle closing and requerying the cursor
// when needed.
@@ -153,7 +149,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
final Cursor cursor = mContext.getContentResolver().query(
Contacts.CONTENT_URI, PROJECTION_ID_ONLY, null, null, null);
if (cursor != null) {
- return cursor.getCount();
+ try {
+ return cursor.getCount();
+ } finally {
+ cursor.close();
+ }
}
return 0;
}
@@ -175,7 +175,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
// capitalization of i.
final int wordLen = word.codePointCount(0, word.length());
if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
- super.addWord(word, FREQUENCY_FOR_CONTACTS);
+ super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS);
if (!TextUtils.isEmpty(prevWord)) {
if (mUseFirstLastBigrams) {
super.setBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM);
diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
index 83bc9046b..2f3395245 100644
--- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
@@ -28,6 +28,12 @@ import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard;
+// TODO: This class is superseded by {@link ContactsBinaryDictionary}. Should be cleaned up.
+/**
+ * An expandable dictionary that stores the words from Contacts provider.
+ *
+ * @deprecated Use {@link ContactsBinaryDictionary}.
+ */
public class ContactsDictionary extends ExpandableDictionary {
private static final String[] PROJECTION = {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 22d8f24f1..08f585485 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -22,11 +22,13 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
@@ -133,6 +135,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
clearFusionDictionary();
}
+ protected static String getFilenameWithLocale(final String name, final String localeStr) {
+ return name + "." + localeStr + ".dict";
+ }
+
/**
* Closes and cleans up the binary dictionary.
*/
@@ -166,8 +172,15 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
// TODO: Create "cache dictionary" to cache fresh words for frequently updated dictionaries,
// considering performance regression.
- protected void addWord(final String word, final int frequency) {
- mFusionDictionary.add(word, frequency, null /* shortcutTargets */);
+ protected void addWord(final String word, final String shortcutTarget, final int frequency) {
+ if (shortcutTarget == null) {
+ mFusionDictionary.add(word, frequency, null);
+ } else {
+ // TODO: Do this in the subclass, with this class taking an arraylist.
+ final ArrayList<WeightedString> shortcutTargets = new ArrayList<WeightedString>();
+ shortcutTargets.add(new WeightedString(shortcutTarget, frequency));
+ mFusionDictionary.add(word, frequency, shortcutTargets);
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b632d34bf..b474a8558 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -106,6 +106,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
/** Whether to use the binary version of the contacts dictionary */
public static final boolean USE_BINARY_CONTACTS_DICTIONARY = true;
+ /** Whether to use the binary version of the user dictionary */
+ public static final boolean USE_BINARY_USER_DICTIONARY = true;
+
// TODO: migrate this to SettingsValues
private int mSuggestionVisibility;
private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE
@@ -158,7 +161,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mShouldSwitchToLastSubtype = true;
private boolean mIsMainDictionaryAvailable;
- private UserDictionary mUserDictionary;
+ // TODO: revert this back to the concrete class after transition.
+ private Dictionary mUserDictionary;
private UserHistoryDictionary mUserHistoryDictionary;
private boolean mIsUserDictionaryAvailable;
@@ -476,9 +480,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
- mUserDictionary = new UserDictionary(this, localeStr);
+ if (USE_BINARY_USER_DICTIONARY) {
+ mUserDictionary = new UserBinaryDictionary(this, localeStr);
+ mIsUserDictionaryAvailable = ((UserBinaryDictionary)mUserDictionary).isEnabled();
+ } else {
+ mUserDictionary = new UserDictionary(this, localeStr);
+ mIsUserDictionaryAvailable = ((UserDictionary)mUserDictionary).isEnabled();
+ }
mSuggest.setUserDictionary(mUserDictionary);
- mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
resetContactsDictionary(oldContactsDictionary);
@@ -1047,6 +1056,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
| InputType.TYPE_TEXT_FLAG_CAP_WORDS)) == 0;
if (noNeedToCheckCapsMode) return Constants.TextUtils.CAP_MODE_OFF;
+ // Avoid making heavy round-trip IPC calls of {@link InputConnection#getCursorCapsMode}
+ // unless needed.
+ if (mWordComposer.isComposingWord()) return Constants.TextUtils.CAP_MODE_OFF;
+
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return Constants.TextUtils.CAP_MODE_OFF;
// TODO: This blocking IPC call is heavy. Consider doing this without using IPC calls.
@@ -1123,7 +1136,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public boolean addWordToDictionary(String word) {
- mUserDictionary.addWordToUserDictionary(word, 128);
+ if (USE_BINARY_USER_DICTIONARY) {
+ ((UserBinaryDictionary)mUserDictionary).addWordToUserDictionary(word, 128);
+ } else {
+ ((UserDictionary)mUserDictionary).addWordToUserDictionary(word, 128);
+ }
// Suggestion strip should be updated after the operation of adding word to the
// user dictionary
mHandler.postUpdateSuggestions();
@@ -1141,7 +1158,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Virtual codes representing custom requests. These are used in onCustomRequest() below.
public static final int CODE_SHOW_INPUT_METHOD_PICKER = 1;
- public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK = 2;
@Override
public boolean onCustomRequest(int requestCode) {
@@ -1154,9 +1170,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return true;
}
return false;
- case CODE_HAPTIC_AND_AUDIO_FEEDBACK:
- hapticAndAudioFeedback(Keyboard.CODE_UNSPECIFIED);
- return true;
}
return false;
}
@@ -2252,6 +2265,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
+ // TODO: Remove this method from {@link LatinIME} and move {@link FeedbackManager} to
+ // {@link KeyboardSwitcher}.
public void hapticAndAudioFeedback(final int primaryCode) {
mFeedbackManager.hapticAndAudioFeedback(primaryCode, mKeyboardSwitcher.getKeyboardView());
}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index 188259ff8..4994e5902 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -26,7 +26,6 @@ public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryD
public SynchronouslyLoadedContactsBinaryDictionary(final Context context) {
// TODO: add locale information.
super(context, Suggest.DIC_CONTACTS, null);
- mClosed = false;
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
new file mode 100644
index 000000000..1606a34e0
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 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;
+
+import android.content.Context;
+
+import com.android.inputmethod.keyboard.ProximityInfo;
+
+public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary {
+
+ public SynchronouslyLoadedUserBinaryDictionary(final Context context, final String locale) {
+ this(context, locale, false);
+ }
+
+ public SynchronouslyLoadedUserBinaryDictionary(final Context context, final String locale,
+ final boolean alsoUseMoreRestrictiveLocales) {
+ super(context, locale, alsoUseMoreRestrictiveLocales);
+ }
+
+ @Override
+ public synchronized void getWords(final WordComposer codes,
+ final CharSequence prevWordForBigrams, final WordCallback callback,
+ final ProximityInfo proximityInfo) {
+ syncReloadDictionaryIfRequired();
+ getWordsInner(codes, prevWordForBigrams, callback, proximityInfo);
+ }
+
+ @Override
+ public synchronized boolean isValidWord(CharSequence word) {
+ syncReloadDictionaryIfRequired();
+ return isValidWordInner(word);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
index b78be89b8..23a49c192 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
@@ -21,6 +21,7 @@ import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo;
public class SynchronouslyLoadedUserDictionary extends UserDictionary {
+ private boolean mClosed;
public SynchronouslyLoadedUserDictionary(final Context context, final String locale) {
this(context, locale, false);
@@ -44,4 +45,12 @@ public class SynchronouslyLoadedUserDictionary extends UserDictionary {
blockingReloadDictionaryIfRequired();
return super.isValidWord(word);
}
+
+ // Protect against multiple closing
+ @Override
+ public synchronized void close() {
+ if (mClosed) return;
+ mClosed = true;
+ super.close();
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
new file mode 100644
index 000000000..6fa1a25a1
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2012 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;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.provider.UserDictionary.Words;
+import android.text.TextUtils;
+
+import java.util.Arrays;
+
+/**
+ * An expandable dictionary that stores the words in the user unigram dictionary.
+ *
+ * Largely a copy of UserDictionary, will replace that class in the future.
+ */
+public class UserBinaryDictionary extends ExpandableBinaryDictionary {
+
+ // TODO: use Words.SHORTCUT when it's public in the SDK
+ final static String SHORTCUT = "shortcut";
+ private static final String[] PROJECTION_QUERY = {
+ Words.WORD,
+ SHORTCUT,
+ Words.FREQUENCY,
+ };
+
+ private static final String NAME = "userunigram";
+
+ // This is not exported by the framework so we pretty much have to write it here verbatim
+ private static final String ACTION_USER_DICTIONARY_INSERT =
+ "com.android.settings.USER_DICTIONARY_INSERT";
+
+ private ContentObserver mObserver;
+ final private String mLocale;
+ final private boolean mAlsoUseMoreRestrictiveLocales;
+
+ public UserBinaryDictionary(final Context context, final String locale) {
+ this(context, locale, false);
+ }
+
+ public UserBinaryDictionary(final Context context, final String locale,
+ final boolean alsoUseMoreRestrictiveLocales) {
+ super(context, getFilenameWithLocale(NAME, locale), Suggest.DIC_USER);
+ if (null == locale) throw new NullPointerException(); // Catch the error earlier
+ mLocale = locale;
+ mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales;
+ // Perform a managed query. The Activity will handle closing and re-querying the cursor
+ // when needed.
+ ContentResolver cres = context.getContentResolver();
+
+ mObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean self) {
+ setRequiresReload(true);
+ }
+ };
+ cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
+
+ loadDictionary();
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mObserver != null) {
+ mContext.getContentResolver().unregisterContentObserver(mObserver);
+ mObserver = null;
+ }
+ super.close();
+ }
+
+ @Override
+ public void loadDictionaryAsync() {
+ // Split the locale. For example "en" => ["en"], "de_DE" => ["de", "DE"],
+ // "en_US_foo_bar_qux" => ["en", "US", "foo_bar_qux"] because of the limit of 3.
+ // This is correct for locale processing.
+ // For this example, we'll look at the "en_US_POSIX" case.
+ final String[] localeElements =
+ TextUtils.isEmpty(mLocale) ? new String[] {} : mLocale.split("_", 3);
+ final int length = localeElements.length;
+
+ final StringBuilder request = new StringBuilder("(locale is NULL)");
+ String localeSoFar = "";
+ // At start, localeElements = ["en", "US", "POSIX"] ; localeSoFar = "" ;
+ // and request = "(locale is NULL)"
+ for (int i = 0; i < length; ++i) {
+ // i | localeSoFar | localeElements
+ // 0 | "" | ["en", "US", "POSIX"]
+ // 1 | "en_" | ["en", "US", "POSIX"]
+ // 2 | "en_US_" | ["en", "en_US", "POSIX"]
+ localeElements[i] = localeSoFar + localeElements[i];
+ localeSoFar = localeElements[i] + "_";
+ // i | request
+ // 0 | "(locale is NULL)"
+ // 1 | "(locale is NULL) or (locale=?)"
+ // 2 | "(locale is NULL) or (locale=?) or (locale=?)"
+ request.append(" or (locale=?)");
+ }
+ // At the end, localeElements = ["en", "en_US", "en_US_POSIX"]; localeSoFar = en_US_POSIX_"
+ // and request = "(locale is NULL) or (locale=?) or (locale=?) or (locale=?)"
+
+ final String[] requestArguments;
+ // If length == 3, we already have all the arguments we need (common prefix is meaningless
+ // inside variants
+ if (mAlsoUseMoreRestrictiveLocales && length < 3) {
+ request.append(" or (locale like ?)");
+ // The following creates an array with one more (null) position
+ final String[] localeElementsWithMoreRestrictiveLocalesIncluded =
+ Arrays.copyOf(localeElements, length + 1);
+ localeElementsWithMoreRestrictiveLocalesIncluded[length] =
+ localeElements[length - 1] + "_%";
+ requestArguments = localeElementsWithMoreRestrictiveLocalesIncluded;
+ // If for example localeElements = ["en"]
+ // then requestArguments = ["en", "en_%"]
+ // and request = (locale is NULL) or (locale=?) or (locale like ?)
+ // If localeElements = ["en", "en_US"]
+ // then requestArguments = ["en", "en_US", "en_US_%"]
+ } else {
+ requestArguments = localeElements;
+ }
+ final Cursor cursor = mContext.getContentResolver().query(
+ Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+ try {
+ addWords(cursor);
+ } finally {
+ if (null != cursor) cursor.close();
+ }
+ }
+
+ public boolean isEnabled() {
+ final ContentResolver cr = mContext.getContentResolver();
+ final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI);
+ if (client != null) {
+ client.release();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Adds a word to the user dictionary and makes it persistent.
+ *
+ * This will call upon the system interface to do the actual work through the intent readied by
+ * the system to this effect.
+ *
+ * @param word the word to add. If the word is capitalized, then the dictionary will
+ * recognize it as a capitalized word when searched.
+ * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
+ * the highest.
+ * @TODO use a higher or float range for frequency
+ */
+ public synchronized void addWordToUserDictionary(final String word, final int frequency) {
+ // TODO: do something for the UI. With the following, any sufficiently long word will
+ // look like it will go to the user dictionary but it won't.
+ // Safeguard against adding long words. Can cause stack overflow.
+ if (word.length() >= MAX_WORD_LENGTH) return;
+
+ // TODO: Add an argument to the intent to specify the frequency.
+ Intent intent = new Intent(ACTION_USER_DICTIONARY_INSERT);
+ intent.putExtra(Words.WORD, word);
+ intent.putExtra(Words.LOCALE, mLocale);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ }
+
+ private void addWords(Cursor cursor) {
+ clearFusionDictionary();
+ if (cursor == null) return;
+ if (cursor.moveToFirst()) {
+ final int indexWord = cursor.getColumnIndex(Words.WORD);
+ final int indexShortcut = cursor.getColumnIndex(SHORTCUT);
+ final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY);
+ while (!cursor.isAfterLast()) {
+ String word = cursor.getString(indexWord);
+ String shortcut = cursor.getString(indexShortcut);
+ int frequency = cursor.getInt(indexFrequency);
+ // Safeguard against adding really long words.
+ if (word.length() < MAX_WORD_LENGTH) {
+ super.addWord(word, null, frequency);
+ }
+ if (null != shortcut && shortcut.length() < MAX_WORD_LENGTH) {
+ super.addWord(shortcut, word, frequency);
+ }
+ cursor.moveToNext();
+ }
+ }
+ }
+
+ @Override
+ protected boolean hasContentChanged() {
+ return true;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index 218bac72a..81e2fdce4 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -29,6 +29,12 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import java.util.Arrays;
+// TODO: This class is superseded by {@link UserBinaryDictionary}. Should be cleaned up.
+/**
+ * An expandable dictionary that stores the words in the user unigram dictionary.
+ *
+ * @deprecated Use {@link UserBinaryDictionary}.
+ */
public class UserDictionary extends ExpandableDictionary {
// TODO: use Words.SHORTCUT when it's public in the SDK
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index d7c8e3850..9807d2892 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -40,6 +40,7 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StringUtils;
import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary;
import com.android.inputmethod.latin.SynchronouslyLoadedContactsDictionary;
+import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary;
import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary;
import com.android.inputmethod.latin.WhitelistDictionary;
import com.android.inputmethod.latin.WordComposer;
@@ -403,7 +404,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService
final String localeStr = locale.toString();
Dictionary userDictionary = mUserDictionaries.get(localeStr);
if (null == userDictionary) {
- userDictionary = new SynchronouslyLoadedUserDictionary(this, localeStr, true);
+ if (LatinIME.USE_BINARY_USER_DICTIONARY) {
+ userDictionary = new SynchronouslyLoadedUserBinaryDictionary(this, localeStr, true);
+ } else {
+ userDictionary = new SynchronouslyLoadedUserDictionary(this, localeStr, true);
+ }
mUserDictionaries.put(localeStr, userDictionary);
}
dictionaryCollection.addDictionary(userDictionary);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
index 26a9415c4..3d593aaa7 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
@@ -596,7 +596,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
}
/**
- * Construct a {@link SuggestionsView} for showing suggested words for completion.
+ * Construct a {@link SuggestionsView} for showing suggestions to be picked by the user.
* @param context
* @param attrs
*/