From f7e01e866ffa89b4dd7e66c471ed9fc275a637a2 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Mon, 27 Oct 2014 11:59:57 +0900
Subject: [PATCH] Remove device checking of Emoji physical key

This CL also adds a settings option to enable/disable an Emoji-ALT
physical key.

Bug: 18122464
Change-Id: Iee1d97efec979a902b0492071d5e511ca1792ff0
---
 .../inputmethod/latin/SpecialKeyDetector.java | 43 ---------
 .../values/donottranslate-debug-settings.xml  |  1 -
 java/res/values/strings.xml                   |  6 ++
 java/res/xml/prefs_screen_advanced.xml        |  6 ++
 java/res/xml/prefs_screen_debug.xml           |  5 -
 .../latin/EmojiAltPhysicalKeyDetector.java    | 93 +++++++++++++++++++
 .../android/inputmethod/latin/LatinIME.java   | 10 +-
 .../latin/settings/DebugSettings.java         |  2 -
 .../latin/settings/DebugSettingsFragment.java |  3 +-
 .../settings/LocalSettingsConstants.java      |  1 -
 .../inputmethod/latin/settings/Settings.java  |  2 +
 .../latin/settings/SettingsValues.java        |  3 +
 12 files changed, 117 insertions(+), 58 deletions(-)
 delete mode 100644 java-overridable/src/com/android/inputmethod/latin/SpecialKeyDetector.java
 create mode 100644 java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java

diff --git a/java-overridable/src/com/android/inputmethod/latin/SpecialKeyDetector.java b/java-overridable/src/com/android/inputmethod/latin/SpecialKeyDetector.java
deleted file mode 100644
index 27b2f50122..0000000000
--- a/java-overridable/src/com/android/inputmethod/latin/SpecialKeyDetector.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014, 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 android.view.KeyEvent;
-
-final class SpecialKeyDetector {
-    /**
-     * Special physical key detector
-     * @param context a context of this detector.
-     */
-    public SpecialKeyDetector(final Context context) {
-    }
-
-    /**
-     * Record a down key event.
-     * @param keyEvent a down key event.
-     */
-    public void onKeyDown(final KeyEvent keyEvent) {
-    }
-
-    /**
-     * Record an up key event.
-     * @param keyEvent an up key event.
-     */
-    public void onKeyUp(final KeyEvent keyEvent) {
-    }
-}
diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml
index cc8c1a01d6..c612010f63 100644
--- a/java/res/values/donottranslate-debug-settings.xml
+++ b/java/res/values/donottranslate-debug-settings.xml
@@ -22,7 +22,6 @@
     <string name="english_ime_debug_settings">Android Keyboard Debug settings</string>
     <string name="prefs_debug_mode">Debug Mode</string>
     <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
-    <string name="prefs_force_physical_keyboard_special_key">Force physical keyboard special key</string>
     <string name="prefs_should_show_lxx_suggestion_ui">Show LXX suggestion UI</string>
     <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
     <string name="sliding_key_input_preview">Show slide indicator</string>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 54bfc51d32..583c3b1238 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -363,6 +363,12 @@ mobile devices. [CHAR LIMIT=25] -->
     <string name="prefs_keypress_sound_volume_settings">Keypress sound volume</string>
     <!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
     <string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
+    <!-- TODO: Let's finalize title of the settings and remove translatable="false" -->
+    <!-- Title of the settings for enabling Emoji palette triggered by the Alt key on physical keyboards [CHAR LIMIT=35] -->
+    <string name="prefs_enable_emoji_alt_physical_key" translatable="false">Emoji for physical keyboard</string>
+    <!-- TODO: Let's finalize title of the settings and remove translatable="false" -->
+    <!-- Description of the settings for enabling Emoji palette triggered by the Alt key on physical keyboards [CHAR LIMIT=64] -->
+    <string name="prefs_enable_emoji_alt_physical_key_summary" translatable="false">Physical Alt key shows the emoji palette</string>
 
     <!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] -->
     <string name="button_default">Default</string>
diff --git a/java/res/xml/prefs_screen_advanced.xml b/java/res/xml/prefs_screen_advanced.xml
index 3298220938..1fa6fd0c43 100644
--- a/java/res/xml/prefs_screen_advanced.xml
+++ b/java/res/xml/prefs_screen_advanced.xml
@@ -37,6 +37,12 @@
         latin:minValue="@integer/config_min_longpress_timeout"
         latin:maxValue="@integer/config_max_longpress_timeout"
         latin:stepValue="@integer/config_longpress_timeout_step" />
+    <CheckBoxPreference
+        android:key="pref_enable_emoji_alt_physical_key"
+        android:title="@string/prefs_enable_emoji_alt_physical_key"
+        android:summary="@string/prefs_enable_emoji_alt_physical_key_summary"
+        android:defaultValue="true"
+        android:persistent="true" />
     <!-- The settings for showing setup wizard application icon shouldn't be persistent and
          the default value is added programmatically. -->
     <CheckBoxPreference
diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml
index 486d2367ec..13edf3ec64 100644
--- a/java/res/xml/prefs_screen_debug.xml
+++ b/java/res/xml/prefs_screen_debug.xml
@@ -30,11 +30,6 @@
         android:title="@string/prefs_force_non_distinct_multitouch"
         android:defaultValue="false"
         android:persistent="true" />
-    <CheckBoxPreference
-        android:key="force_physical_keyboard_special_key"
-        android:title="@string/prefs_force_physical_keyboard_special_key"
-        android:defaultValue="false"
-        android:persistent="true" />
     <CheckBoxPreference
         android:key="pref_should_show_lxx_suggestion_ui"
         android:title="@string/prefs_should_show_lxx_suggestion_ui"
diff --git a/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java
new file mode 100644
index 0000000000..8116a4983a
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014, 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.view.KeyEvent;
+
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.settings.Settings;
+
+/**
+ * A class for detecting Emoji-Alt physical key.
+ */
+final class EmojiAltPhysicalKeyDetector {
+    // True if the Alt key has been used as a modifier. In this case the Alt key up isn't
+    // recognized as an emoji key.
+    private boolean mAltHasBeenUsedAsAModifier;
+
+    /**
+     * Record a down key event.
+     * @param keyEvent a down key event.
+     */
+    public void onKeyDown(final KeyEvent keyEvent) {
+        if (isAltKey(keyEvent)) {
+            mAltHasBeenUsedAsAModifier = false;
+        }
+        if (containsAltModifier(keyEvent)) {
+            mAltHasBeenUsedAsAModifier = true;
+        }
+    }
+
+    /**
+     * Determine whether an up key event is a special key up or not.
+     * @param keyEvent an up key event.
+     */
+    public void onKeyUp(final KeyEvent keyEvent) {
+        if (keyEvent.isCanceled()) {
+            // This key up event was a part of key combinations and should be ignored.
+            return;
+        }
+        if (!isAltKey(keyEvent)) {
+            mAltHasBeenUsedAsAModifier |= containsAltModifier(keyEvent);
+            return;
+        }
+        if (containsAltModifier(keyEvent)) {
+            mAltHasBeenUsedAsAModifier = true;
+            return;
+        }
+        if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
+            return;
+        }
+        if (!mAltHasBeenUsedAsAModifier) {
+            onEmojiAltKeyDetected();
+        }
+    }
+
+    private static void onEmojiAltKeyDetected() {
+        KeyboardSwitcher.getInstance().onToggleEmojiKeyboard();
+    }
+
+    private static boolean isAltKey(final KeyEvent keyEvent) {
+        final int keyCode = keyEvent.getKeyCode();
+        return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT;
+    }
+
+    private static boolean containsAltModifier(final KeyEvent keyEvent) {
+        final int metaState = keyEvent.getMetaState();
+        // TODO: Support multiple keyboards. Take device id into account.
+        switch (keyEvent.getKeyCode()) {
+        case KeyEvent.KEYCODE_ALT_LEFT:
+            // Return true if Left-Alt is pressed with Right-Alt pressed.
+            return (metaState & KeyEvent.META_ALT_RIGHT_ON) != 0;
+        case KeyEvent.KEYCODE_ALT_RIGHT:
+            // Return true if Right-Alt is pressed with Left-Alt pressed.
+            return (metaState & KeyEvent.META_ALT_LEFT_ON) != 0;
+        default:
+            return (metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0;
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 11cbec3785..ff82087aeb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -167,7 +167,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
     final SubtypeSwitcher mSubtypeSwitcher;
     private final SubtypeState mSubtypeState = new SubtypeState();
-    private final SpecialKeyDetector mSpecialKeyDetector;
+    private final EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector =
+            new EmojiAltPhysicalKeyDetector();
     private StatsUtilsManager mStatsUtilsManager;
     // Working variable for {@link #startShowingInputView()} and
     // {@link #onEvaluateInputViewShown()}.
@@ -545,7 +546,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         mSettings = Settings.getInstance();
         mSubtypeSwitcher = SubtypeSwitcher.getInstance();
         mKeyboardSwitcher = KeyboardSwitcher.getInstance();
-        mSpecialKeyDetector = new SpecialKeyDetector(this);
         mStatsUtilsManager = StatsUtilsManager.getInstance();
         mIsHardwareAcceleratedDrawingEnabled =
                 InputMethodServiceCompatUtils.enableHardwareAcceleration(this);
@@ -1765,7 +1765,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     // Hooks for hardware keyboard
     @Override
     public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
-        mSpecialKeyDetector.onKeyDown(keyEvent);
+        // TODO: This should be processed in {@link InputLogic}.
+        mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent);
         if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
             return super.onKeyDown(keyCode, keyEvent);
         }
@@ -1786,7 +1787,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     @Override
     public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) {
-        mSpecialKeyDetector.onKeyUp(keyEvent);
+        // TODO: This should be processed in {@link InputLogic}.
+        mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent);
         if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
             return super.onKeyUp(keyCode, keyEvent);
         }
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 768cba9b2f..4985c2f088 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -27,8 +27,6 @@ package com.android.inputmethod.latin.settings;
 public final class DebugSettings {
     public static final String PREF_DEBUG_MODE = "debug_mode";
     public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
-    public static final String PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY =
-            "force_physical_keyboard_special_key";
     public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
             "pref_has_custom_key_preview_animation_params";
     public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index 475f1def73..2e5c3c4795 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -142,8 +142,7 @@ public final class DebugSettingsFragment extends SubScreenFragment
             mServiceNeedsRestart = true;
             return;
         }
-        if (key.equals(DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH)
-                || key.equals(DebugSettings.PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY)) {
+        if (key.equals(DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH)) {
             mServiceNeedsRestart = true;
             return;
         }
diff --git a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
index c9e9dc8d97..0fd94b0f87 100644
--- a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
+++ b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
@@ -46,7 +46,6 @@ public class LocalSettingsConstants {
         // correctly set for it to work on a new device.
         DebugSettings.PREF_DEBUG_MODE,
         DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH,
-        DebugSettings.PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY,
         DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS,
         DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
         DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 5e23693d20..2ac6e8576d 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -97,6 +97,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
             "pref_vibration_duration_settings";
     public static final String PREF_KEYPRESS_SOUND_VOLUME = "pref_keypress_sound_volume";
     public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
+    public static final String PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY =
+            "pref_enable_emoji_alt_physical_key";
     public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail";
     public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
             "pref_gesture_floating_preview_text";
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 660be06d62..e488cb10c6 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -80,6 +80,7 @@ public class SettingsValues {
     public final boolean mSlidingKeyInputPreviewEnabled;
     public final boolean mPhraseGestureEnabled;
     public final int mKeyLongpressTimeout;
+    public final boolean mEnableEmojiAltPhysicalKey;
     public final boolean mEnableMetricsLogging;
     public final boolean mShouldShowLxxSuggestionUi;
     // Use split layout for keyboard.
@@ -166,6 +167,8 @@ public class SettingsValues {
         mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
         mKeypressSoundVolume = Settings.readKeypressSoundVolume(prefs, res);
         mKeyPreviewPopupDismissDelay = Settings.readKeyPreviewPopupDismissDelay(prefs, res);
+        mEnableEmojiAltPhysicalKey = prefs.getBoolean(
+                Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
         mAutoCorrectionThreshold = readAutoCorrectionThreshold(res,
                 autoCorrectionThresholdRawValue);
         mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
-- 
GitLab