Add Keyboard Theme Switcher

Change-Id: If1bf7d20e4f8a47a7c0429d2445431dc73c1b31b
diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background_1.9.png
similarity index 100%
rename from java/res/drawable-hdpi/keyboard_background.9.png
rename to java/res/drawable-hdpi/keyboard_background_1.9.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key2.xml b/java/res/drawable/btn_keyboard_key2.xml
new file mode 100644
index 0000000..bd745b7
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key2.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Toggle keys. Use checkable/checked state. -->
+
+    <item android:state_checkable="true" android:state_checked="true"
+          android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_pressed_on" />
+    <item android:state_checkable="true" android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+    <item android:state_checkable="true" android:state_checked="true"
+          android:drawable="@drawable/btn_keyboard_key_normal_on" />
+    <item android:state_checkable="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
+
+    <!-- Normal keys -->
+
+    <item android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+    <item android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key3.xml b/java/res/drawable/btn_keyboard_key3.xml
new file mode 100644
index 0000000..dbe82d5
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key3.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Toggle keys. Use checkable/checked state. -->
+
+    <item android:state_checkable="true" android:state_checked="true"
+          android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_pressed_on" />
+    <item android:state_checkable="true" android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
+    <item android:state_checkable="true" android:state_checked="true"
+          android:drawable="@drawable/btn_keyboard_key_normal_on" />
+    <item android:state_checkable="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+
+    <!-- Normal keys -->
+
+    <item android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
+    <item android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_toggle_off.png b/java/res/drawable/btn_keyboard_toggle_off.png
new file mode 100644
index 0000000..21399a4
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_toggle_off.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_toggle_on.png b/java/res/drawable/btn_keyboard_toggle_on.png
new file mode 100644
index 0000000..22d5683
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_toggle_on.png
Binary files differ
diff --git a/java/res/drawable/keyboard_background_2.jpg b/java/res/drawable/keyboard_background_2.jpg
new file mode 100644
index 0000000..400aa27
--- /dev/null
+++ b/java/res/drawable/keyboard_background_2.jpg
Binary files differ
diff --git a/java/res/drawable/keyboard_background_3.jpg b/java/res/drawable/keyboard_background_3.jpg
new file mode 100644
index 0000000..4e64844
--- /dev/null
+++ b/java/res/drawable/keyboard_background_3.jpg
Binary files differ
diff --git a/java/res/drawable/keyboard_background_4.jpg b/java/res/drawable/keyboard_background_4.jpg
new file mode 100755
index 0000000..5998f48
--- /dev/null
+++ b/java/res/drawable/keyboard_background_4.jpg
Binary files differ
diff --git a/java/res/drawable/keyboard_background_5.jpg b/java/res/drawable/keyboard_background_5.jpg
new file mode 100644
index 0000000..2fe7c5f
--- /dev/null
+++ b/java/res/drawable/keyboard_background_5.jpg
Binary files differ
diff --git a/java/res/layout/input2.xml b/java/res/layout/input2.xml
new file mode 100755
index 0000000..2e90c2c
--- /dev/null
+++ b/java/res/layout/input2.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<com.android.inputmethod.latin.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:keyBackground="@drawable/btn_keyboard_key3"
+        android:background="@android:color/black"
+        />
diff --git a/java/res/layout/input3.xml b/java/res/layout/input3.xml
new file mode 100755
index 0000000..a27d09a
--- /dev/null
+++ b/java/res/layout/input3.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<com.android.inputmethod.latin.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:keyBackground="@drawable/btn_keyboard_key2"
+        android:background="@drawable/keyboard_background_4"
+        />
diff --git a/java/res/layout/input4.xml b/java/res/layout/input4.xml
new file mode 100755
index 0000000..58dd51e
--- /dev/null
+++ b/java/res/layout/input4.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<com.android.inputmethod.latin.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:keyBackground="@drawable/btn_keyboard_key3"
+        android:background="@drawable/keyboard_background_4"
+        />
diff --git a/java/res/layout/input5.xml b/java/res/layout/input5.xml
new file mode 100755
index 0000000..5cd0b8d
--- /dev/null
+++ b/java/res/layout/input5.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<com.android.inputmethod.latin.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:keyBackground="@drawable/btn_keyboard_key2"
+        android:background="@drawable/keyboard_background_5"
+        />
diff --git a/java/res/layout/input6.xml b/java/res/layout/input6.xml
new file mode 100755
index 0000000..19197e1
--- /dev/null
+++ b/java/res/layout/input6.xml
@@ -0,0 +1,29 @@
+<?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.
+*/
+-->
+
+<com.android.inputmethod.latin.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:keyBackground="@drawable/btn_keyboard_key3"
+        android:background="@drawable/keyboard_background_5"
+        />
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index d4bb138..6eb362b 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -26,4 +26,4 @@
     <color name="latinkeyboard_bar_language_text">#FF808080</color>
     <color name="latinkeyboard_extension_background">#A0000000</color>
     <color name="latinkeyboard_text_color">#FF000000</color>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 83e0adb..5793758 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -328,4 +328,30 @@
     <string name="prefs_enable_log">Enable user feedback</string>
     <!-- Description for sending logs -->
     <string name="prefs_description_log">Help improve this input method editor by automatically sending usage statistics and crash reports to Google.</string>
+
+    <string name="keyboard_layout">Keyboard Theme</string>
+    <string name="layout_basic" translatable="false">Basic</string>
+    <string name="layout_high_contrast" translatable="false">Basic (High Contrast)</string>
+    <string name="layout_blue_ribbon"  translatable="false">Blue Ribbon</string>
+    <string name="layout_dazzle"  translatable="false">Dazzle</string>
+    <string name="layout_blue_ribbon_high"  translatable="false">Blue Ribbon (High Contrast)</string>
+    <string name="layout_dazzle_high"  translatable="false">Dazzle (High Contrast)</string>
+
+    <string-array name="keyboard_layout_modes" translatable="false">
+        <item>@string/layout_basic</item>
+        <item>@string/layout_high_contrast</item>
+        <item>@string/layout_blue_ribbon</item>
+        <item>@string/layout_blue_ribbon_high</item>
+        <item>@string/layout_dazzle</item>
+        <item>@string/layout_dazzle_high</item>
+    </string-array>
+
+    <string-array name="keyboard_layout_modes_values" translatable="false">
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+        <item>3</item>
+        <item>4</item>
+        <item>5</item>
+    </string-array>
 </resources>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 7346d02..7dc9a36 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -53,6 +53,15 @@
             android:defaultValue="@string/voice_mode_main"
             />
 
+    <ListPreference
+            android:key="keyboard_layout"
+            android:title="@string/keyboard_layout"
+            android:persistent="true"
+            android:entryValues="@array/keyboard_layout_modes_values"
+            android:entries="@array/keyboard_layout_modes"
+            android:defaultValue="2"
+            />
+
     <PreferenceScreen
             android:title="@string/language_selection_title"
             android:summary="@string/language_selection_summary">
@@ -89,5 +98,5 @@
             android:dependency="show_suggestions"
             />
             
-    </PreferenceCategory>            
+    </PreferenceCategory>
 </PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index 1a19644..3cfd814 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -21,11 +21,12 @@
 import java.util.Map;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.inputmethodservice.InputMethodService;
+import android.preference.PreferenceManager;
 
-public class KeyboardSwitcher {
+public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
 
     public static final int MODE_TEXT = 1;
     public static final int MODE_SYMBOLS = 2;
@@ -56,10 +57,15 @@
         KEYBOARDMODE_EMAIL,
         KEYBOARDMODE_IM,
         KEYBOARDMODE_WEB};
+    private static final String PREF_KEYBOARD_LAYOUT = "keyboard_layout";
+    private static final int[] LAYOUTS = new int [] {
+        R.layout.input, R.layout.input2, R.layout.input3, R.layout.input4, R.layout.input5,
+        R.layout.input6
+    };
+    private static final String DEFAULT_LAYOUT_ID = "0";
 
-    //LatinIME mContext;
     Context mContext;
-    InputMethodService mInputMethodService;
+    LatinIME mInputMethodService;
     
     private KeyboardId mSymbolsId;
     private KeyboardId mSymbolsShiftedId;
@@ -79,14 +85,20 @@
     private int mLastDisplayWidth;
     private LanguageSwitcher mLanguageSwitcher;
     private Locale mInputLocale;
-    private boolean mEnableMultipleLanguages;
 
-    KeyboardSwitcher(Context context, InputMethodService ims) {
+    private int mLayoutId;
+
+    KeyboardSwitcher(Context context, LatinIME ims) {
         mContext = context;
         mKeyboards = new HashMap<KeyboardId, LatinKeyboard>();
         mSymbolsId = new KeyboardId(R.xml.kbd_symbols, false);
         mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift, false);
         mInputMethodService = ims;
+
+        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims);
+        int mLayoutId = Integer.valueOf(prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID));
+        prefs.registerOnSharedPreferenceChangeListener(this);
+        changeLatinKeyboardView(mLayoutId, false);
     }
 
     /**
@@ -98,13 +110,12 @@
     void setLanguageSwitcher(LanguageSwitcher languageSwitcher) {
         mLanguageSwitcher = languageSwitcher;
         mInputLocale = mLanguageSwitcher.getInputLocale();
-        mEnableMultipleLanguages = mLanguageSwitcher.getLocaleCount() > 1;
     }
 
     void setInputView(LatinKeyboardView inputView) {
         mInputView = inputView;
     }
-    
+
     void makeKeyboards(boolean forceCreate) {
         if (forceCreate) mKeyboards.clear();
         // Configuration change is coming after the keyboard gets recreated. So don't rely on that.
@@ -140,6 +151,7 @@
             this(xml, 0, false, hasVoice);
         }
 
+        @Override
         public boolean equals(Object other) {
             return other instanceof KeyboardId && equals((KeyboardId) other);
         }
@@ -150,6 +162,7 @@
               && other.mEnableShiftLock == this.mEnableShiftLock;
         }
 
+        @Override
         public int hashCode() {
             return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1)
                     * (mHasVoice ? 4 : 8);
@@ -348,4 +361,38 @@
         }
         return false;
     }
+
+    public LatinKeyboardView getInputView() {
+        return mInputView;
+    }
+
+    public void recreateInputView() {
+        changeLatinKeyboardView(mLayoutId, true);
+    }
+
+    private void changeLatinKeyboardView(int newLayout, boolean forceReset) {
+        if (mLayoutId != newLayout || mInputView == null || forceReset) {
+            if (LAYOUTS.length <= newLayout) {
+                newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID);
+            }
+            mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater().inflate(
+                    LAYOUTS[newLayout], null);
+            mInputView.setOnKeyboardActionListener(mInputMethodService);
+            mLayoutId = newLayout;
+        }
+        mInputMethodService.mHandler.post(new Runnable() {
+            public void run() {
+                if (mInputView != null) {
+                    mInputMethodService.setInputView(mInputView);
+                }
+                mInputMethodService.updateInputViewShown();
+            }});
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        if (PREF_KEYBOARD_LAYOUT.equals(key)) {
+            changeLatinKeyboardView(
+                    Integer.valueOf(sharedPreferences.getString(key, DEFAULT_LAYOUT_ID)), false);
+        }
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d500853..d96ef88 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -145,7 +145,7 @@
     private static final int POS_SETTINGS = 0;
     private static final int POS_METHOD = 1;
 
-    private LatinKeyboardView mInputView;
+    //private LatinKeyboardView mInputView;
     private CandidateViewContainer mCandidateViewContainer;
     private CandidateView mCandidateView;
     private Suggest mSuggest;
@@ -248,8 +248,9 @@
                     break;
                 case MSG_START_TUTORIAL:
                     if (mTutorial == null) {
-                        if (mInputView.isShown()) {
-                            mTutorial = new Tutorial(LatinIME.this, mInputView);
+                        if (mKeyboardSwitcher.getInputView().isShown()) {
+                            mTutorial = new Tutorial(
+                                    LatinIME.this, mKeyboardSwitcher.getInputView());
                             mTutorial.start();
                         } else {
                             // Try again soon if the view is not yet showing
@@ -394,15 +395,12 @@
 
     @Override
     public View onCreateInputView() {
-        mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
-                R.layout.input, null);
-        mKeyboardSwitcher.setInputView(mInputView);
+        mKeyboardSwitcher.recreateInputView();
         mKeyboardSwitcher.makeKeyboards(true);
-        mInputView.setOnKeyboardActionListener(this);
         mKeyboardSwitcher.setKeyboardMode(
                 KeyboardSwitcher.MODE_TEXT, 0,
                 shouldShowVoiceButton(makeFieldContext(), getCurrentInputEditorInfo()));
-        return mInputView;
+        return mKeyboardSwitcher.getInputView();
     }
 
     @Override
@@ -419,8 +417,9 @@
 
     @Override
     public void onStartInputView(EditorInfo attribute, boolean restarting) {
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
         // In landscape mode, this method gets called without the input view being created.
-        if (mInputView == null) {
+        if (inputView == null) {
             return;
         }
 
@@ -529,7 +528,7 @@
                         attribute.imeOptions, enableVoiceButton);
                 updateShiftKeyState(attribute);
         }
-        mInputView.closing();
+        inputView.closing();
         mComposing.setLength(0);
         mPredicting = false;
         mDeleteCount = 0;
@@ -545,7 +544,7 @@
 
         updateCorrectionMode();
 
-        mInputView.setProximityCorrectionEnabled(true);
+        inputView.setProximityCorrectionEnabled(true);
         mPredictionOn = mPredictionOn && (mCorrectionMode > 0 || mShowSuggestions);
         checkTutorial(attribute.privateImeOptions);
         if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
@@ -563,8 +562,8 @@
             mVoiceInput.flushLogs();
             mVoiceInput.cancel();
         }
-        if (mInputView != null) {
-            mInputView.closing();
+        if (mKeyboardSwitcher.getInputView() != null) {
+            mKeyboardSwitcher.getInputView().closing();
         }
         if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites();
     }
@@ -708,7 +707,8 @@
         // TODO: Remove this if we support candidates with hard keyboard
         if (onEvaluateInputViewShown()) {
             // Show the candidates view only if input view is showing
-            super.setCandidatesViewShown(shown && mInputView != null && mInputView.isShown());
+            super.setCandidatesViewShown(shown && mKeyboardSwitcher.getInputView() != null
+                    && mKeyboardSwitcher.getInputView().isShown());
         }
     }
 
@@ -724,8 +724,8 @@
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
-                if (event.getRepeatCount() == 0 && mInputView != null) {
-                    if (mInputView.handleBack()) {
+                if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) {
+                    if (mKeyboardSwitcher.getInputView().handleBack()) {
                         return true;
                     } else if (mTutorial != null) {
                         mTutorial.close();
@@ -757,8 +757,10 @@
                 if (mTutorial != null) {
                     return true;
                 }
+                LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
                 // Enable shift key and DPAD to do selections
-                if (mInputView != null && mInputView.isShown() && mInputView.isShifted()) {
+                if (inputView != null && inputView.isShown()
+                        && inputView.isShifted()) {
                     event = new KeyEvent(event.getDownTime(), event.getEventTime(),
                             event.getAction(), event.getKeyCode(), event.getRepeatCount(),
                             event.getDeviceId(), event.getScanCode(),
@@ -791,7 +793,7 @@
             mKeyboardSwitcher = new KeyboardSwitcher(this, this);
         }
         mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
-        if (mInputView != null) {
+        if (mKeyboardSwitcher.getInputView() != null) {
             mKeyboardSwitcher.setVoiceMode(mEnableVoice && mEnableVoiceButton, mVoiceOnPrimary);
         }
         mKeyboardSwitcher.makeKeyboards(true);
@@ -819,9 +821,10 @@
 
     public void updateShiftKeyState(EditorInfo attr) {
         InputConnection ic = getCurrentInputConnection();
-        if (attr != null && mInputView != null && mKeyboardSwitcher.isAlphabetMode()
-                && ic != null) {
-            mInputView.setShifted(mCapsLock || getCursorCapsMode(ic, attr) != 0);
+        if (attr != null && mKeyboardSwitcher.getInputView() != null
+                && mKeyboardSwitcher.isAlphabetMode() && ic != null) {
+            mKeyboardSwitcher.getInputView().setShifted(
+                    mCapsLock || getCursorCapsMode(ic, attr) != 0);
         }
     }
 
@@ -1070,7 +1073,8 @@
         if (mKeyboardSwitcher.isAlphabetMode()) {
             // Alphabet keyboard
             checkToggleCapsLock();
-            mInputView.setShifted(mCapsLock || !mInputView.isShifted());
+            mKeyboardSwitcher.getInputView().setShifted(mCapsLock
+                    || !mKeyboardSwitcher.getInputView().isShifted());
         } else {
             mKeyboardSwitcher.toggleShift();
         }
@@ -1093,7 +1097,7 @@
                 mWord.reset();
             }
         }
-        if (mInputView.isShifted()) {
+        if (mKeyboardSwitcher.getInputView().isShifted()) {
             // TODO: This doesn't work with ß, need to fix it in the next release.
             if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
                     || keyCodes[0] > Character.MAX_CODE_POINT) {
@@ -1102,7 +1106,7 @@
             primaryCode = new String(keyCodes, 0, 1).toUpperCase().charAt(0);
         }
         if (mPredicting) {
-            if (mInputView.isShifted() && mComposing.length() == 0) {
+            if (mKeyboardSwitcher.getInputView().isShifted() && mComposing.length() == 0) {
                 mWord.setCapitalized(true);
             }
             mComposing.append((char) primaryCode);
@@ -1197,12 +1201,12 @@
             mVoiceInput.cancel();
         }
         requestHideSelf(0);
-        mInputView.closing();
+        mKeyboardSwitcher.getInputView().closing();
         TextEntryState.endSession();
     }
 
     private void checkToggleCapsLock() {
-        if (mInputView.getKeyboard().isShifted()) {
+        if (mKeyboardSwitcher.getInputView().getKeyboard().isShifted()) {
             toggleCapsLock();
         }
     }
@@ -1210,7 +1214,8 @@
     private void toggleCapsLock() {
         mCapsLock = !mCapsLock;
         if (mKeyboardSwitcher.isAlphabetMode()) {
-            ((LatinKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock);
+            ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setShiftLocked(
+                    mCapsLock);
         }
     }
 
@@ -1238,8 +1243,8 @@
       mHandler.post(new Runnable() {
           public void run() {
               mRecognizing = false;
-              if (mInputView != null) {
-                setInputView(mInputView);
+              if (mKeyboardSwitcher.getInputView() != null) {
+                setInputView(mKeyboardSwitcher.getInputView());
               }
               updateInputViewShown();
           }});
@@ -1338,7 +1343,7 @@
 
         Window window = mVoiceWarningDialog.getWindow();
         WindowManager.LayoutParams lp = window.getAttributes();
-        lp.token = mInputView.getWindowToken();
+        lp.token = mKeyboardSwitcher.getInputView().getWindowToken();
         lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
         window.setAttributes(lp);
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
@@ -1374,7 +1379,8 @@
 
         final List<CharSequence> nBest = new ArrayList<CharSequence>();
         boolean capitalizeFirstWord = preferCapitalization()
-                || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted());
+                || (mKeyboardSwitcher.isAlphabetMode()
+                        && mKeyboardSwitcher.getInputView().isShifted());
         for (String c : mVoiceResults.candidates) {
             if (capitalizeFirstWord) {
                 c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length());
@@ -1432,7 +1438,8 @@
     private void updateSuggestions() {
         mSuggestionShouldReplaceCurrentWord = false;
 
-        ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(null);
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+        ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
 
         // Check if we have a suggestion engine attached.
         if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) {
@@ -1444,17 +1451,20 @@
             return;
         }
 
-        List<CharSequence> stringList = mSuggest.getSuggestions(mInputView, mWord, false);
+        List<CharSequence> stringList = mSuggest.getSuggestions(inputView,
+                mWord, false);
         int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies();
 
-        ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(nextLettersFrequencies);
+        ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(
+                nextLettersFrequencies);
 
         boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasMinimalCorrection();
         //|| mCorrectionMode == mSuggest.CORRECTION_FULL;
         CharSequence typedWord = mWord.getTypedWord();
         // If we're in basic correct
         boolean typedWordValid = mSuggest.isValidWord(typedWord) ||
-                (preferCapitalization() && mSuggest.isValidWord(typedWord.toString().toLowerCase()));
+                (preferCapitalization()
+                        && mSuggest.isValidWord(typedWord.toString().toLowerCase()));
         if (mCorrectionMode == Suggest.CORRECTION_FULL) {
             correctionAvailable |= typedWordValid;
         }
@@ -1556,10 +1566,12 @@
     }
 
     private void pickSuggestion(CharSequence suggestion) {
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
         if (mCapsLock) {
             suggestion = suggestion.toString().toUpperCase();
         } else if (preferCapitalization()
-                || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted())) {
+                || (mKeyboardSwitcher.isAlphabetMode()
+                        && inputView.isShifted())) {
             suggestion = suggestion.toString().toUpperCase().charAt(0)
                     + suggestion.subSequence(1, suggestion.length()).toString();
         }
@@ -1574,7 +1586,7 @@
         }
         mPredicting = false;
         mCommittedLength = suggestion.length();
-        ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(null);
+        ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
         setNextSuggestions();
         updateShiftKeyState(getCurrentInputEditorInfo());
     }
@@ -1674,7 +1686,7 @@
             ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE));
             CharSequence text = cm.getText();
             if (!TextUtils.isEmpty(text)) {
-                mInputView.startPlaying(text.toString());
+                mKeyboardSwitcher.getInputView().startPlaying(text.toString());
             }
         }
     }
@@ -1725,7 +1737,7 @@
 
     public void onRelease(int primaryCode) {
         // Reset any drag flags in the keyboard
-        ((LatinKeyboard) mInputView.getKeyboard()).keyReleased();
+        ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased();
         //vibrate();
     }
 
@@ -1777,7 +1789,7 @@
         // if mAudioManager is null, we don't have the ringer state yet
         // mAudioManager will be set by updateRingerMode
         if (mAudioManager == null) {
-            if (mInputView != null) {
+            if (mKeyboardSwitcher.getInputView() != null) {
                 updateRingerMode();
             }
         }
@@ -1804,8 +1816,9 @@
         if (!mVibrateOn) {
             return;
         }
-        if (mInputView != null) {
-            mInputView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
+        if (mKeyboardSwitcher.getInputView() != null) {
+            mKeyboardSwitcher.getInputView().performHapticFeedback(
+                    HapticFeedbackConstants.KEYBOARD_TAP,
                     HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
         }
     }
@@ -1956,7 +1969,7 @@
         mOptionsDialog = builder.create();
         Window window = mOptionsDialog.getWindow();
         WindowManager.LayoutParams lp = window.getAttributes();
-        lp.token = mInputView.getWindowToken();
+        lp.token = mKeyboardSwitcher.getInputView().getWindowToken();
         lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
         window.setAttributes(lp);
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
@@ -1966,7 +1979,8 @@
     private void changeKeyboardMode() {
         mKeyboardSwitcher.toggleSymbols();
         if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) {
-            ((LatinKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock);
+            ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setShiftLocked(
+                    mCapsLock);
         }
 
         updateShiftKeyState(getCurrentInputEditorInfo());