Support dedicated number/date keyboard layout

Bug: 3009716
Change-Id: Idc12cc9d8ee4f5febfae4e11712e2aaca327a6ea
diff --git a/java/res/xml-xlarge/kbd_number.xml b/java/res/xml-xlarge/kbd_number.xml
new file mode 100644
index 0000000..dd251ea
--- /dev/null
+++ b/java/res/xml-xlarge/kbd_number.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<Keyboard
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    latin:keyWidth="11.949%p"
+    latin:horizontalGap="@dimen/key_horizontal_gap"
+    latin:verticalGap="@dimen/key_bottom_gap"
+    latin:keyHeight="@dimen/key_height"
+>
+    <!-- This row is intentionally not marked as a top row -->
+    <Row>
+        <Key
+            latin:codes="@integer/key_tab"
+            latin:keyLabel="@string/label_tab_key"
+            latin:keyLabelOption="fontNormal|alignLeft|alignBottom"
+            latin:isModifier="true"
+            latin:keyEdgeFlags="left" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:keyLabel="-"
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel="+"
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel="."
+            latin:keyWidth="8.042%p" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:keyLabel="1" />
+        <Key
+            latin:keyLabel="2" />
+        <Key
+            latin:keyLabel="3" />
+        <Spacer
+            latin:horizontalGap="9.360%p" />
+        <Key
+            latin:codes="@integer/key_delete"
+            latin:keyLabel="@string/label_backspace_key"
+            latin:keyLabelOption="fontNormal|alignRight|alignBottom"
+            latin:keyWidth="9.804%p"
+            latin:isModifier="true"
+            latin:isRepeatable="true"
+            latin:keyEdgeFlags="right" />
+    </Row>
+    <Row>
+        <Spacer
+            latin:horizontalGap="16.406%p" />
+        <Key
+            latin:keyLabel="*"
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel="/"
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel=","
+            latin:keyWidth="8.042%p" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:keyLabel="4" />
+        <Key
+            latin:keyLabel="5" />
+        <Key
+            latin:keyLabel="6" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:codes="@integer/key_return"
+            latin:keyLabel="@string/label_return_key"
+            latin:keyLabelOption="fontNormal|alignRight|alignBottom"
+            latin:keyWidth="14.706%p"
+            latin:isModifier="true"
+            latin:keyEdgeFlags="right" />
+    </Row>
+    <Row>
+        <!-- There is an empty area bellow the "More" key and left of the "(" key.  To ignore
+             the touch event on the area, "(" is intentionally not marked as a left edge key. -->
+        <Spacer
+            latin:horizontalGap="16.406%p" />
+        <Key
+            latin:keyLabel="("
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel=")"
+            latin:keyWidth="8.042%p" />
+        <Key
+            latin:keyLabel="="
+            latin:keyWidth="8.042%p" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:keyLabel="7" />
+        <Key
+            latin:keyLabel="8" />
+        <Key
+            latin:keyLabel="9" />
+        <!-- There is an empty area bellow the "Enter" key and right of the "9" key.  To ignore
+             the touch event on the area, "9" is intentionally not marked as a right edge key. -->
+    </Row>
+    <!-- This row is intentionally not marked as a bottom row -->
+    <Row>
+        <!-- There is an empty area bellow the "More" key and left of the "space" key.  To ignore
+             the touch event on the area, "space" is intentionally not marked as a left edge key. -->
+        <Spacer
+            latin:horizontalGap="16.406%p" />
+        <Key
+            latin:codes="@integer/key_space"
+            latin:keyIcon="@drawable/sym_keyboard_space"
+            latin:iconPreview="@drawable/sym_keyboard_feedback_space"
+            latin:keyWidth="24.127%p" />
+        <Spacer
+            latin:horizontalGap="4.458%p" />
+        <Key
+            latin:keyLabel="*" />
+        <Key
+            latin:keyLabel="0" />
+        <Key
+            latin:keyLabel="#" />
+        <!-- There is an empty area bellow the "Enter" key and right of the "#" key.  To ignore
+             the touch event on the area, "#" is intentionally not marked as a right edge key. -->
+    </Row>
+</Keyboard>
diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml
new file mode 100644
index 0000000..cde7205
--- /dev/null
+++ b/java/res/xml/kbd_number.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    latin:keyWidth="26.67%p"
+    latin:horizontalGap="@dimen/key_horizontal_gap"
+    latin:verticalGap="@dimen/key_bottom_gap"
+    latin:keyHeight="@dimen/key_height"
+>
+    <include
+        latin:keyboardLayout="@xml/kbd_key_styles" />
+   <switch>
+        <case
+            latin:colorScheme="white"
+        >
+            <key-style
+                latin:styleName="numSpaceKeyStyle"
+                latin:codes="@integer/key_space"
+                latin:keyIcon="@drawable/sym_keyboard_space"
+                latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
+        </case>
+        <case
+            latin:colorScheme="black"
+        >
+            <key-style
+                latin:styleName="numSpaceKeyStyle"
+                latin:codes="@integer/key_space"
+                latin:keyIcon="@drawable/sym_bkeyboard_space"
+                latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
+        </case>
+    </switch>
+    <Row
+        latin:rowEdgeFlags="top"
+    >
+        <Key
+            latin:keyLabel="1"
+            latin:keyEdgeFlags="left" />
+        <Key
+            latin:keyLabel="2" />
+        <Key
+            latin:keyLabel="3" />
+        <Key
+            latin:keyLabel="-"
+            latin:keyStyle="functionalKeyStyle"
+            latin:keyWidth="20%p"
+            latin:keyEdgeFlags="right" />
+    </Row>
+    <Row>
+        <Key
+            latin:keyLabel="4"
+            latin:keyEdgeFlags="left" />
+        <Key
+            latin:keyLabel="5" />
+        <Key
+            latin:keyLabel="6" />
+        <Key
+            latin:keyLabel=","
+            latin:keyStyle="functionalKeyStyle"
+            latin:keyWidth="20%p"
+            latin:keyEdgeFlags="right" />
+    </Row>
+    <Row>
+        <Key
+            latin:keyLabel="7"
+            latin:keyEdgeFlags="left" />
+        <Key
+            latin:keyLabel="8" />
+        <Key
+            latin:keyLabel="9" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="20%p"
+            latin:keyEdgeFlags="right" />
+    </Row>
+    <Row
+        latin:rowEdgeFlags="bottom"
+    >
+        <Key
+            latin:keyStyle="numSpaceKeyStyle"
+            latin:keyEdgeFlags="left" />
+        <Key
+            latin:keyLabel="0" />
+        <Key
+            latin:keyLabel="." />
+        <Key
+            latin:keyStyle="returnKeyStyle"
+            latin:keyWidth="20%p"
+            latin:keyEdgeFlags="right" />
+    </Row>
+</Keyboard>
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index 68c3579..b5dd3ee 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -40,6 +40,7 @@
     public static final int MODE_IM = 3;
     public static final int MODE_WEB = 4;
     public static final int MODE_PHONE = 5;
+    public static final int MODE_NUMBER = 6;
 
     // Changing DEFAULT_LAYOUT_ID also requires prefs_for_debug.xml to be matched with.
     public static final String DEFAULT_LAYOUT_ID = "5";
@@ -239,6 +240,7 @@
             case MODE_IM: return "im";
             case MODE_WEB: return "web";
             case MODE_PHONE: return "phone";
+            case MODE_NUMBER: return "number";
             }
             return null;
         }
@@ -287,10 +289,6 @@
         KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
         LatinKeyboard keyboard = getKeyboard(id);
 
-        if (mode == MODE_PHONE) {
-            mInputView.setPhoneKeyboard(keyboard);
-        }
-
         mCurrentId = id;
         mInputView.setKeyboard(keyboard);
     }
@@ -331,11 +329,26 @@
         final boolean enableShiftLock;
 
         if (isSymbols) {
-            xmlId = mode == MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols;
+            if (mode == MODE_PHONE) {
+                xmlId = R.xml.kbd_phone_symbols;
+            } else if (mode == MODE_NUMBER) {
+                // Note: MODE_NUMBER keyboard layout has no "switch alpha symbol" key.
+                xmlId = R.xml.kbd_number;
+            } else {
+                xmlId = R.xml.kbd_symbols;
+            }
             enableShiftLock = false;
-        } else {  // QWERTY
-            xmlId = mode == MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_qwerty;
-            enableShiftLock = mode == MODE_PHONE ? false : true;
+        } else {
+            if (mode == MODE_PHONE) {
+                xmlId = R.xml.kbd_phone;
+                enableShiftLock = false;
+            } else if (mode == MODE_NUMBER) {
+                xmlId = R.xml.kbd_number;
+                enableShiftLock = false;
+            } else {
+                xmlId = R.xml.kbd_qwerty;
+                enableShiftLock = true;
+            }
         }
         final int orientation = mInputMethodService.getResources().getConfiguration().orientation;
         final Locale locale = mSubtypeSwitcher.getInputLocale();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4989d8e..6554954 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -545,10 +545,8 @@
         switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) {
             case EditorInfo.TYPE_CLASS_NUMBER:
             case EditorInfo.TYPE_CLASS_DATETIME:
-                // fall through
-                // NOTE: For now, we use the phone keyboard for NUMBER and DATETIME until we get
-                // a dedicated number entry keypad.
-                // TODO: Use a dedicated number entry keypad here when we get one.
+                mode = KeyboardSwitcher.MODE_NUMBER;
+                break;
             case EditorInfo.TYPE_CLASS_PHONE:
                 mode = KeyboardSwitcher.MODE_PHONE;
                 break;
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/latin/LatinKeyboard.java
index 74aa899..c6e9116 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboard.java
@@ -189,6 +189,14 @@
         return mId.getXmlId() == R.xml.kbd_qwerty;
     }
 
+    public boolean isPhoneKeyboard() {
+        return mId.mMode == KeyboardSwitcher.MODE_PHONE;
+    }
+
+    public boolean isNumberKeyboard() {
+        return mId.mMode == KeyboardSwitcher.MODE_NUMBER;
+    }
+
     /**
      * @return a key which should be invalidated.
      */
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index fb8b69e..4fcfe01 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -40,8 +40,6 @@
     public static final int KEYCODE_PREV_LANGUAGE = -105;
     public static final int KEYCODE_CAPSLOCK = -106;
 
-    private LatinKeyboard mPhoneKeyboard;
-
     /** Whether we've started dropping move events because we found a big jump */
     private boolean mDroppingEvents;
     /**
@@ -62,14 +60,12 @@
         super(context, attrs, defStyle);
     }
 
-    public void setPhoneKeyboard(LatinKeyboard phoneKeyboard) {
-        mPhoneKeyboard = phoneKeyboard;
-    }
-
     @Override
     public void setPreviewEnabled(boolean previewEnabled) {
-        if (getLatinKeyboard() == mPhoneKeyboard) {
-            // Phone keyboard never shows popup preview (except language switch).
+        LatinKeyboard latinKeyboard = getLatinKeyboard();
+        if (latinKeyboard != null
+                && (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard())) {
+            // Phone and number keyboard never shows popup preview (except language switch).
             super.setPreviewEnabled(false);
         } else {
             super.setPreviewEnabled(previewEnabled);
@@ -100,7 +96,7 @@
         int primaryCode = key.codes[0];
         if (primaryCode == KEYCODE_OPTIONS) {
             return invokeOnKey(KEYCODE_OPTIONS_LONGPRESS);
-        } else if (primaryCode == '0' && getLatinKeyboard() == mPhoneKeyboard) {
+        } else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
             // Long pressing on 0 in phone number keypad gives you a '+'.
             return invokeOnKey('+');
         } else {