Unicode 8.0 emoji additions to Google Keyboard.
am: 7674a65367
* commit '7674a653678b542d795b0bd05c241654ffe1015a':
Unicode 8.0 emoji additions to Google Keyboard.
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 86fc672..10895cb 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -95,7 +95,7 @@
<string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"برای ذخیره اینجا را لمس کنید"</string>
<string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحهکلید"</string>
- <string name="switch_accounts" msgid="3321216593719006162">"جابهجایی بین حسابها"</string>
+ <string name="switch_accounts" msgid="3321216593719006162">"رفتن به حساب دیگر"</string>
<string name="no_accounts_selected" msgid="2073821619103904330">"هیچ حسابی انتخاب نشده است"</string>
<string name="account_selected" msgid="2846876462199625974">"در حال حاضر در حال استفاده از <xliff:g id="EMAIL_ADDRESS">%1$s</xliff:g>"</string>
<string name="account_select_ok" msgid="9141195141763227797">"تأیید"</string>
diff --git a/java/res/values-ky-rKG/strings.xml b/java/res/values-ky-rKG/strings.xml
index 3ef2b44..aa145f6 100644
--- a/java/res/values-ky-rKG/strings.xml
+++ b/java/res/values-ky-rKG/strings.xml
@@ -89,7 +89,7 @@
<string name="voice_input_disabled_summary" msgid="8141750303464726129">"Үн менен киргизүү ыкмаларынын бири да иштетилген эмес. Тил & киргизүү жөндөөлөрүн текшериңиз."</string>
<string name="configure_input_method" msgid="373356270290742459">"Дайндрд киргзүү ыкмалрн конфигрцлоо"</string>
<string name="language_selection_title" msgid="3666971864764478269">"Тилдер"</string>
- <string name="help_and_feedback" msgid="5328219371839879161">"Жардам & жооп пикир"</string>
+ <string name="help_and_feedback" msgid="5328219371839879161">"Жардам жана жооп пикир"</string>
<string name="select_language" msgid="5709487854987078367">"Тилдер"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Сактоо үчүн кайра тийип коюңуз"</string>
<string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Сактоо үчүн бул жерди басыңыз"</string>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index 23b8f53..6170d4f 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -40,7 +40,7 @@
<string name="sync_now_title" msgid="3088838136743277721">"अहिले सिंक गर्नुहोस्"</string>
<string name="clear_sync_data_title" msgid="8582001557037069154">"क्लाउड डेटा मेटाउनुहोस्"</string>
<string name="clear_sync_data_summary" msgid="993477139012576584">"Google बाट तपाईँको सिङ्क गरिएको डाटा मेटाउँछ"</string>
- <string name="clear_sync_data_confirmation" msgid="2811931135574727678">"तपाईंको सिंक गरिएको डेटालाई क्लाउडबाट मेटाइनेछ। के तपाईं निश्चित हुनुहुन्छ?"</string>
+ <string name="clear_sync_data_confirmation" msgid="2811931135574727678">"तपाईँको सिंक गरिएको डेटालाई क्लाउडबाट मेटाइनेछ। के तपाईँ निश्चित हुनुहुन्छ?"</string>
<string name="clear_sync_data_ok" msgid="613104067705915132">"मेटाउनुहोस्"</string>
<string name="cloud_sync_cancel" msgid="5877481252150919037">"रद्द गर्नुहोस्"</string>
<string name="cloud_sync_opt_in_text" msgid="9176039655776298248">"तपाईँको व्यक्तिगत शब्दकोश सिंक गरेर Google सर्भरहरूमा जगेडा राखिने छ। शब्द आवृत्तिको तथ्याङ्क जानकारी हाम्रो उत्पादनहरू सुधार गर्न मद्दतका लागि संकलन हुन सक्छ। संग्रह र सबै जानकारीको प्रयोग "<a href="https://www.google.com/policies/privacy">" Google को गोपनीयता नीति "</a>" अनुरूप हुने छ।"</string>
diff --git a/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java
index 2529424..8924e0a 100644
--- a/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java
+++ b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java
@@ -18,14 +18,15 @@
import android.content.res.Resources;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.settings.Settings;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Map;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
@@ -35,28 +36,155 @@
*/
final class EmojiAltPhysicalKeyDetector {
private static final String TAG = "EmojiAltPhysicalKeyDetector";
+ private static final boolean DEBUG = false;
- private final Map<Integer, Integer> mEmojiSwitcherMap;
- private final Map<Integer, Integer> mSymbolsShiftedSwitcherMap;
- private final Map<Integer, Integer> mCombinedSwitcherMap;
+ private List<EmojiHotKeys> mHotKeysList;
- // Set of keys codes that have been used as modifiers.
- private Set<Integer> mActiveModifiers;
+ private static class HotKeySet extends HashSet<Pair<Integer, Integer>> { };
- public EmojiAltPhysicalKeyDetector(@Nonnull final Resources resources) {
- mEmojiSwitcherMap = parseSwitchDefinition(resources, R.array.keyboard_switcher_emoji);
- mSymbolsShiftedSwitcherMap = parseSwitchDefinition(
- resources, R.array.keyboard_switcher_symbols_shifted);
- mCombinedSwitcherMap = new HashMap<>();
- mCombinedSwitcherMap.putAll(mEmojiSwitcherMap);
- mCombinedSwitcherMap.putAll(mSymbolsShiftedSwitcherMap);
- mActiveModifiers = new HashSet<>();
+ private abstract class EmojiHotKeys {
+ private final String mName;
+ private final HotKeySet mKeySet;
+
+ boolean mCanFire;
+ int mMetaState;
+
+ public EmojiHotKeys(final String name, HotKeySet keySet) {
+ mName = name;
+ mKeySet = keySet;
+ mCanFire = false;
+ }
+
+ public void onKeyDown(@Nonnull final KeyEvent keyEvent) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyDown() - " + mName + " - considering " + keyEvent);
+ }
+
+ final Pair<Integer, Integer> key =
+ Pair.create(keyEvent.getKeyCode(), keyEvent.getMetaState());
+ if (mKeySet.contains(key)) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyDown() - " + mName + " - enabling action");
+ }
+ mCanFire = true;
+ mMetaState = keyEvent.getMetaState();
+ } else if (mCanFire) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyDown() - " + mName + " - disabling action");
+ }
+ mCanFire = false;
+ }
+ }
+
+ public void onKeyUp(@Nonnull final KeyEvent keyEvent) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyUp() - " + mName + " - considering " + keyEvent);
+ }
+
+ final int keyCode = keyEvent.getKeyCode();
+ int metaState = keyEvent.getMetaState();
+ if (KeyEvent.isModifierKey(keyCode)) {
+ // Try restoring meta stat in case the released key was a modifier.
+ // I am sure one can come up with scenarios to break this, but it
+ // seems to work well in practice.
+ metaState |= mMetaState;
+ }
+
+ final Pair<Integer, Integer> key = Pair.create(keyCode, metaState);
+ if (mKeySet.contains(key)) {
+ if (mCanFire) {
+ if (!keyEvent.isCanceled()) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyUp() - " + mName + " - firing action");
+ }
+ action();
+ } else {
+ // This key up event was a part of key combinations and
+ // should be ignored.
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyUp() - " + mName + " - canceled, ignoring action");
+ }
+ }
+ mCanFire = false;
+ }
+ }
+
+ if (mCanFire) {
+ if (DEBUG) {
+ Log.d(TAG, "EmojiHotKeys.onKeyUp() - " + mName + " - disabling action");
+ }
+ mCanFire = false;
+ }
+ }
+
+ protected abstract void action();
}
- private static Map<Integer, Integer> parseSwitchDefinition(
- @Nonnull final Resources resources,
- final int resourceId) {
- final Map<Integer, Integer> definition = new HashMap<>();
+ public EmojiAltPhysicalKeyDetector(@Nonnull final Resources resources) {
+ mHotKeysList = new ArrayList<EmojiHotKeys>();
+
+ final HotKeySet emojiSwitchSet = parseHotKeys(
+ resources, R.array.keyboard_switcher_emoji);
+ final EmojiHotKeys emojiHotKeys = new EmojiHotKeys("emoji", emojiSwitchSet) {
+ @Override
+ protected void action() {
+ final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
+ switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.EMOJI);
+ }
+ };
+ mHotKeysList.add(emojiHotKeys);
+
+ final HotKeySet symbolsSwitchSet = parseHotKeys(
+ resources, R.array.keyboard_switcher_symbols_shifted);
+ final EmojiHotKeys symbolsHotKeys = new EmojiHotKeys("symbols", symbolsSwitchSet) {
+ @Override
+ protected void action() {
+ final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
+ switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.SYMBOLS_SHIFTED);
+ }
+ };
+ mHotKeysList.add(symbolsHotKeys);
+ }
+
+ public void onKeyDown(@Nonnull final KeyEvent keyEvent) {
+ if (DEBUG) {
+ Log.d(TAG, "onKeyDown(): " + keyEvent);
+ }
+
+ if (shouldProcessEvent(keyEvent)) {
+ for (EmojiHotKeys hotKeys : mHotKeysList) {
+ hotKeys.onKeyDown(keyEvent);
+ }
+ }
+ }
+
+ public void onKeyUp(@Nonnull final KeyEvent keyEvent) {
+ if (DEBUG) {
+ Log.d(TAG, "onKeyUp(): " + keyEvent);
+ }
+
+ if (shouldProcessEvent(keyEvent)) {
+ for (EmojiHotKeys hotKeys : mHotKeysList) {
+ hotKeys.onKeyUp(keyEvent);
+ }
+ }
+ }
+
+ private static boolean shouldProcessEvent(@Nonnull final KeyEvent keyEvent) {
+ if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
+ // The feature is disabled.
+ if (DEBUG) {
+ Log.d(TAG, "shouldProcessEvent(): Disabled");
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ private static HotKeySet parseHotKeys(
+ @Nonnull final Resources resources, final int resourceId) {
+ final HotKeySet keySet = new HotKeySet();
final String name = resources.getResourceEntryName(resourceId);
final String[] values = resources.getStringArray(resourceId);
for (int i = 0; values != null && i < values.length; i++) {
@@ -65,91 +193,15 @@
Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]);
}
try {
- definition.put(Integer.parseInt(valuePair[0]), Integer.parseInt(valuePair[1]));
+ final Integer keyCode = Integer.parseInt(valuePair[0]);
+ final Integer metaState = Integer.parseInt(valuePair[1]);
+ final Pair<Integer, Integer> key = Pair.create(
+ keyCode, KeyEvent.normalizeMetaState(metaState));
+ keySet.add(key);
} catch (NumberFormatException e) {
Log.w(TAG, "Failed to parse " + name + "[" + i + "] : " + values[i], e);
}
}
- return definition;
- }
-
- /**
- * Determine whether an up key event came from a mapped modifier key.
- *
- * @param keyEvent an up key event.
- */
- public void onKeyUp(@Nonnull final KeyEvent keyEvent) {
- Log.d(TAG, "onKeyUp() : " + keyEvent);
- if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
- // The feature is disabled.
- Log.d(TAG, "onKeyUp() : Disabled");
- return;
- }
- if (keyEvent.isCanceled()) {
- // This key up event was a part of key combinations and should be ignored.
- Log.d(TAG, "onKeyUp() : Canceled");
- return;
- }
- final Integer mappedModifier = getMappedModifier(keyEvent);
- if (mappedModifier != null) {
- // If the key was modified by a mapped key, then ignore the next time
- // the same modifier key comes up.
- Log.d(TAG, "onKeyUp() : Using Modifier: " + mappedModifier);
- mActiveModifiers.add(mappedModifier);
- return;
- }
- final int keyCode = keyEvent.getKeyCode();
- if (mActiveModifiers.contains(keyCode)) {
- // Used as a modifier, not a standalone key press.
- Log.d(TAG, "onKeyUp() : Used as Modifier: " + keyCode);
- mActiveModifiers.remove(keyCode);
- return;
- }
- if (!isMappedKeyCode(keyEvent)) {
- // Nothing special about this key.
- Log.d(TAG, "onKeyUp() : Not Mapped: " + keyCode);
- return;
- }
- final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
- if (mEmojiSwitcherMap.keySet().contains(keyCode)) {
- switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.EMOJI);
- } else if (mSymbolsShiftedSwitcherMap.keySet().contains(keyCode)) {
- switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.SYMBOLS_SHIFTED);
- } else {
- Log.w(TAG, "Cannot toggle on keyCode: " + keyCode);
- }
- }
-
- /**
- * @param keyEvent pressed key event
- * @return true iff the user pressed a mapped modifier key.
- */
- private boolean isMappedKeyCode(@Nonnull final KeyEvent keyEvent) {
- return mCombinedSwitcherMap.get(keyEvent.getKeyCode()) != null;
- }
-
- /**
- * @param keyEvent pressed key event
- * @return the mapped modifier used with this key opress, if any.
- */
- private Integer getMappedModifier(@Nonnull final KeyEvent keyEvent) {
- final int keyCode = keyEvent.getKeyCode();
- final int metaState = keyEvent.getMetaState();
- for (int mappedKeyCode : mCombinedSwitcherMap.keySet()) {
- if (keyCode == mappedKeyCode) {
- Log.d(TAG, "getMappedModifier() : KeyCode = MappedKeyCode = " + mappedKeyCode);
- continue;
- }
- final Integer mappedMeta = mCombinedSwitcherMap.get(mappedKeyCode);
- if (mappedMeta == null || mappedMeta.intValue() == -1) {
- continue;
- }
- if ((metaState & mappedMeta) != 0) {
- Log.d(TAG, "getMappedModifier() : MetaState(" + metaState
- + ") contains MappedMeta(" + mappedMeta + ")");
- return mappedKeyCode;
- }
- }
- return null;
+ return keySet;
}
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 25a5de2..e02dbcc 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1650,6 +1650,11 @@
// Hooks for hardware keyboard
@Override
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
+ if (mEmojiAltPhysicalKeyDetector == null) {
+ mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector(
+ getApplicationContext().getResources());
+ }
+ mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent);
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
return super.onKeyDown(keyCode, keyEvent);
}