aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml10
-rw-r--r--java/res/xml-sw768dp/key_styles_common.xml10
-rw-r--r--java/res/xml/key_styles_common.xml9
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java102
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java159
7 files changed, 215 insertions, 90 deletions
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index f407ba346..fc9342b91 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -178,16 +178,6 @@
latin:keyLabel="!text/label_to_alpha_key"
latin:parentStyle="baseForLayoutSwitchKeyStyle" />
<key-style
- latin:styleName="toMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_more_symbol_for_tablet_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="backFromMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_symbol_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
latin:styleName="comKeyStyle"
latin:keyLabel="!text/keylabel_for_popular_domain"
latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase"
diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml
index 7c0a82a71..538930948 100644
--- a/java/res/xml-sw768dp/key_styles_common.xml
+++ b/java/res/xml-sw768dp/key_styles_common.xml
@@ -168,16 +168,6 @@
latin:keyLabel="!text/label_to_alpha_key"
latin:parentStyle="baseForLayoutSwitchKeyStyle" />
<key-style
- latin:styleName="toMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_more_symbol_for_tablet_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="backFromMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_symbol_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
latin:styleName="comKeyStyle"
latin:keyLabel="!text/keylabel_for_popular_domain"
latin:keyLabelFlags="fontNormal|hasPopupHint|preserveCase"
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 355455e3b..dabe1e7eb 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -179,15 +179,6 @@
latin:keyLabel="!text/label_to_alpha_key"
latin:parentStyle="baseForLayoutSwitchKeyStyle" />
<key-style
- latin:styleName="toMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_more_symbol_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="backFromMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:parentStyle="baseForToSymbolKeyStyle" />
- <key-style
latin:styleName="punctuationKeyStyle"
latin:keyLabel="."
latin:keyLabelFlags="hasPopupHint"
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index fce245824..507080db4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -226,32 +226,30 @@ public final class KeyboardTextsSet {
/* 121 */ "shortcut_as_more_key",
/* 122 */ "action_next_as_more_key",
/* 123 */ "action_previous_as_more_key",
- /* 124 */ "label_to_more_symbol_key",
- /* 125 */ "label_to_more_symbol_for_tablet_key",
- /* 126 */ "label_tab_key",
- /* 127 */ "label_to_phone_numeric_key",
- /* 128 */ "label_to_phone_symbols_key",
- /* 129 */ "label_time_am",
- /* 130 */ "label_time_pm",
- /* 131 */ "label_to_symbol_key_pcqwerty",
- /* 132 */ "keylabel_for_popular_domain",
- /* 133 */ "more_keys_for_popular_domain",
- /* 134 */ "more_keys_for_smiley",
- /* 135 */ "single_laqm_raqm",
- /* 136 */ "single_laqm_raqm_rtl",
- /* 137 */ "single_raqm_laqm",
- /* 138 */ "double_laqm_raqm",
- /* 139 */ "double_laqm_raqm_rtl",
- /* 140 */ "double_raqm_laqm",
- /* 141 */ "single_lqm_rqm",
- /* 142 */ "single_9qm_lqm",
- /* 143 */ "single_9qm_rqm",
- /* 144 */ "double_lqm_rqm",
- /* 145 */ "double_9qm_lqm",
- /* 146 */ "double_9qm_rqm",
- /* 147 */ "more_keys_for_single_quote",
- /* 148 */ "more_keys_for_double_quote",
- /* 149 */ "more_keys_for_tablet_double_quote",
+ /* 124 */ "label_tab_key",
+ /* 125 */ "label_to_phone_numeric_key",
+ /* 126 */ "label_to_phone_symbols_key",
+ /* 127 */ "label_time_am",
+ /* 128 */ "label_time_pm",
+ /* 129 */ "label_to_symbol_key_pcqwerty",
+ /* 130 */ "keylabel_for_popular_domain",
+ /* 131 */ "more_keys_for_popular_domain",
+ /* 132 */ "more_keys_for_smiley",
+ /* 133 */ "single_laqm_raqm",
+ /* 134 */ "single_laqm_raqm_rtl",
+ /* 135 */ "single_raqm_laqm",
+ /* 136 */ "double_laqm_raqm",
+ /* 137 */ "double_laqm_raqm_rtl",
+ /* 138 */ "double_raqm_laqm",
+ /* 139 */ "single_lqm_rqm",
+ /* 140 */ "single_9qm_lqm",
+ /* 141 */ "single_9qm_rqm",
+ /* 142 */ "double_lqm_rqm",
+ /* 143 */ "double_9qm_lqm",
+ /* 144 */ "double_9qm_rqm",
+ /* 145 */ "more_keys_for_single_quote",
+ /* 146 */ "more_keys_for_double_quote",
+ /* 147 */ "more_keys_for_tablet_double_quote",
};
private static final String EMPTY = "";
@@ -379,28 +377,24 @@ public final class KeyboardTextsSet {
/* 121 */ "!icon/shortcut_key|!code/key_shortcut",
/* 122 */ "!hasLabels!,!text/label_next_key|!code/key_action_next",
/* 123 */ "!hasLabels!,!text/label_previous_key|!code/key_action_previous",
- // Label for "switch to more symbol" modifier key. Must be short to fit on key!
- /* 124 */ "= \\ <",
- // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key!
- /* 125 */ "~ \\ {",
// Label for "Tab" key. Must be short to fit on key!
- /* 126 */ "Tab",
+ /* 124 */ "Tab",
// Label for "switch to phone numeric" key. Must be short to fit on key!
- /* 127 */ "123",
+ /* 125 */ "123",
// Label for "switch to phone symbols" key. Must be short to fit on key!
// U+FF0A: "*" FULLWIDTH ASTERISK
// U+FF03: "#" FULLWIDTH NUMBER SIGN
- /* 128 */ "\uFF0A\uFF03",
+ /* 126 */ "\uFF0A\uFF03",
// Key label for "ante meridiem"
- /* 129 */ "AM",
+ /* 127 */ "AM",
// Key label for "post meridiem"
- /* 130 */ "PM",
+ /* 128 */ "PM",
// Label for "switch to symbols" key on PC QWERTY layout
- /* 131 */ "Sym",
- /* 132 */ ".com",
+ /* 129 */ "Sym",
+ /* 130 */ ".com",
// popular web domains for the locale - most popular, displayed on the keyboard
- /* 133 */ "!hasLabels!,.net,.org,.gov,.edu",
- /* 134 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ",
+ /* 131 */ "!hasLabels!,.net,.org,.gov,.edu",
+ /* 132 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ",
// U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
// U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
@@ -422,24 +416,24 @@ public final class KeyboardTextsSet {
// The following each quotation mark pair consist of
// <opening quotation mark>, <closing quotation mark>
// and is named after (single|double)_<opening quotation mark>_<closing quotation mark>.
- /* 135 */ "\u2039,\u203A",
- /* 136 */ "\u2039|\u203A,\u203A|\u2039",
- /* 137 */ "\u203A,\u2039",
- /* 138 */ "\u00AB,\u00BB",
- /* 139 */ "\u00AB|\u00BB,\u00BB|\u00AB",
- /* 140 */ "\u00BB,\u00AB",
+ /* 133 */ "\u2039,\u203A",
+ /* 134 */ "\u2039|\u203A,\u203A|\u2039",
+ /* 135 */ "\u203A,\u2039",
+ /* 136 */ "\u00AB,\u00BB",
+ /* 137 */ "\u00AB|\u00BB,\u00BB|\u00AB",
+ /* 138 */ "\u00BB,\u00AB",
// The following each quotation mark triplet consists of
// <another quotation mark>, <opening quotation mark>, <closing quotation mark>
// and is named after (single|double)_<opening quotation mark>_<closing quotation mark>.
- /* 141 */ "\u201A,\u2018,\u2019",
- /* 142 */ "\u2019,\u201A,\u2018",
- /* 143 */ "\u2018,\u201A,\u2019",
- /* 144 */ "\u201E,\u201C,\u201D",
- /* 145 */ "\u201D,\u201E,\u201C",
- /* 146 */ "\u201C,\u201E,\u201D",
- /* 147 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes",
- /* 148 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes",
- /* 149 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes",
+ /* 139 */ "\u201A,\u2018,\u2019",
+ /* 140 */ "\u2019,\u201A,\u2018",
+ /* 141 */ "\u2018,\u201A,\u2019",
+ /* 142 */ "\u201E,\u201C,\u201D",
+ /* 143 */ "\u201D,\u201E,\u201C",
+ /* 144 */ "\u201C,\u201E,\u201D",
+ /* 145 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes",
+ /* 146 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes",
+ /* 147 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes",
};
/* Language af: Afrikaans */
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 37256770a..7124c4c97 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -23,6 +23,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter;
import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.File;
@@ -118,10 +119,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
private static AbstractDictionaryWriter getDictionaryWriter(final Context context,
- final String dictType, final boolean isUpdatable) {
- if (isUpdatable) {
- // TODO: Employ dynamically updatable DictionaryWriter.
- return new DictionaryWriter(context, dictType);
+ final String dictType, final boolean isDynamicPersonalizationDictionary) {
+ if (isDynamicPersonalizationDictionary) {
+ return new DynamicPersonalizationDictionaryWriter(context, dictType);
} else {
return new DictionaryWriter(context, dictType);
}
@@ -145,6 +145,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mIsUpdatable = isUpdatable;
mBinaryDictionary = null;
mSharedDictionaryController = getSharedDictionaryController(filename);
+ // Currently, only dynamic personalization dictionary is updatable.
mDictionaryWriter = getDictionaryWriter(context, dictType, isUpdatable);
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index fc87cfac2..491964f38 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -327,7 +327,7 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? false : !node.mShortcutOnly;
}
- protected boolean removeBigram(final String word1, final String word2) {
+ public boolean removeBigram(final String word1, final String word2) {
// Refer to addOrSetBigram() about word1.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null);
@@ -359,7 +359,7 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? -1 : node.mFrequency;
}
- protected NextWord getBigramWord(final String word1, final String word2) {
+ public NextWord getBigramWord(final String word1, final String word2) {
// Refer to addOrSetBigram() about word1.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null);
@@ -700,7 +700,7 @@ public class ExpandableDictionary extends Dictionary {
return null;
}
- protected void clearDictionary() {
+ public void clearDictionary() {
mRoots = new NodeArray();
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
new file mode 100644
index 000000000..a1d93efc4
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2013 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.personalization;
+
+import android.content.Context;
+
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.AbstractDictionaryWriter;
+import com.android.inputmethod.latin.ExpandableDictionary;
+import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.ExpandableDictionary.NextWord;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.makedict.DictEncoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+// Currently this class is used to implement dynamic prodiction dictionary.
+// TODO: Move to native code.
+public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWriter {
+ private static final String TAG = DynamicPersonalizationDictionaryWriter.class.getSimpleName();
+ /** Maximum number of pairs. Pruning will start when databases goes above this number. */
+ public static final int MAX_HISTORY_BIGRAMS = 10000;
+
+ /** Any pair being typed or picked */
+ private static final int FREQUENCY_FOR_TYPED = 2;
+
+ private static final int BINARY_DICT_VERSION = 3;
+ private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
+ new FormatSpec.FormatOptions(BINARY_DICT_VERSION, true /* supportsDynamicUpdate */);
+
+ private final UserHistoryDictionaryBigramList mBigramList =
+ new UserHistoryDictionaryBigramList();
+ private final ExpandableDictionary mExpandableDictionary;
+
+ public DynamicPersonalizationDictionaryWriter(final Context context, final String dictType) {
+ super(context, dictType);
+ mExpandableDictionary = new ExpandableDictionary(context, dictType);
+ }
+
+ @Override
+ public void clear() {
+ mBigramList.evictAll();
+ mExpandableDictionary.clearDictionary();
+ }
+
+ /**
+ * Adds a word unigram to the fusion dictionary. Call updateBinaryDictionary when all changes
+ * are done to update the binary dictionary.
+ */
+ @Override
+ public void addUnigramWord(final String word, final String shortcutTarget, final int frequency,
+ final boolean isNotAWord) {
+ mExpandableDictionary.addWord(word, shortcutTarget, frequency);
+ mBigramList.addBigram(null, word, (byte)frequency);
+ }
+
+ @Override
+ public void addBigramWords(final String word0, final String word1, final int frequency,
+ final boolean isValid, final long lastModifiedTime) {
+ if (lastModifiedTime > 0) {
+ mExpandableDictionary.setBigramAndGetFrequency(word0, word1,
+ new ForgettingCurveParams(frequency, System.currentTimeMillis(),
+ lastModifiedTime));
+ mBigramList.addBigram(word0, word1, (byte)frequency);
+ } else {
+ mExpandableDictionary.setBigramAndGetFrequency(word0, word1,
+ new ForgettingCurveParams(isValid));
+ mBigramList.addBigram(word0, word1, (byte)frequency);
+ }
+ }
+
+ @Override
+ public void removeBigramWords(final String word0, final String word1) {
+ if (mBigramList.removeBigram(word0, word1)) {
+ mExpandableDictionary.removeBigram(word0, word1);
+ }
+ }
+
+ @Override
+ protected void writeDictionary(final DictEncoder dictEncoder)
+ throws IOException, UnsupportedFormatException {
+ UserHistoryDictIOUtils.writeDictionary(dictEncoder,
+ new FrequencyProvider(mBigramList, mExpandableDictionary), mBigramList,
+ FORMAT_OPTIONS);
+ }
+
+ private static class FrequencyProvider implements BigramDictionaryInterface {
+ final private UserHistoryDictionaryBigramList mBigramList;
+ final private ExpandableDictionary mExpandableDictionary;
+
+ public FrequencyProvider(final UserHistoryDictionaryBigramList bigramList,
+ final ExpandableDictionary expandableDictionary) {
+ mBigramList = bigramList;
+ mExpandableDictionary = expandableDictionary;
+ }
+ @Override
+ public int getFrequency(final String word0, final String word1) {
+ final int freq;
+ if (word0 == null) { // unigram
+ freq = FREQUENCY_FOR_TYPED;
+ } else { // bigram
+ final NextWord nw = mExpandableDictionary.getBigramWord(word0, word1);
+ if (nw != null) {
+ final ForgettingCurveParams forgettingCurveParams = nw.getFcParams();
+ final byte prevFc = mBigramList.getBigrams(word0).get(word1);
+ final byte fc = forgettingCurveParams.getFc();
+ final boolean isValid = forgettingCurveParams.isValid();
+ if (prevFc > 0 && prevFc == fc) {
+ freq = fc & 0xFF;
+ } else if (UserHistoryForgettingCurveUtils.
+ needsToSave(fc, isValid, mBigramList.size() <= MAX_HISTORY_BIGRAMS)) {
+ freq = fc & 0xFF;
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ }
+ return freq;
+ }
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ boolean blockOffensiveWords) {
+ return mExpandableDictionary.getSuggestions(composer, prevWord, proximityInfo,
+ blockOffensiveWords);
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ return mExpandableDictionary.isValidWord(word);
+ }
+}