Merge "Remove manual config item controlling to show input language settings"
diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
index e14a49c..290e6b5 100644
--- a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2011 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
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 753dcee..1f2f4fb 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index b8655d1..fe70eef 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
+ * Copyright (C) 2008-2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 8dc833d..1eedb5e 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
index 0ef73d2..3c79cc2 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/Hints.java b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
index 52a4f4e..06b2343 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/Hints.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
index b57c16f..dcb826e 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
index 7721fe2..855a09a 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
index 8cc79de..25b3140 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2011 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
index 3842c53..92cc1c3 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
index 87b9434..22e8207 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * Copyright (C) 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
index a3025f2..8ed279f 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
+ * Copyright (C) 2008-2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
index 310689c..6c5f52a 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 33b55b5..ef86d66 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
@@ -275,7 +275,7 @@
     }
 
     private static boolean isDigitPopupCharacter(CharSequence label) {
-        return label.length() == 1 && Character.isDigit(label.charAt(0));
+        return label != null && label.length() == 1 && Character.isDigit(label.charAt(0));
     }
 
     private static CharSequence[] filterOutDigitPopupCharacters(CharSequence[] popupCharacters) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 0b13afe..7add43a 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
index d464c20..d53df78 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 492883c..267abcc 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
@@ -151,16 +151,11 @@
      * @param context the application or service context
      * @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
      * @param id keyboard identifier
+     * @param width keyboard width
      */
-    public Keyboard(Context context, int xmlLayoutResId, KeyboardId id) {
-        this(context, xmlLayoutResId, id,
-                context.getResources().getDisplayMetrics().widthPixels,
-                context.getResources().getDisplayMetrics().heightPixels);
-    }
 
-    private Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width,
-            int height) {
-        Resources res = context.getResources();
+    public Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width) {
+        final Resources res = context.getResources();
         GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
         GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
         GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
@@ -168,7 +163,8 @@
         final int horizontalEdgesPadding = (int)res.getDimension(
                 R.dimen.keyboard_horizontal_edges_padding);
         mDisplayWidth = width - horizontalEdgesPadding * 2;
-        mDisplayHeight = height;
+        // TODO: Adjust the height by referring to the height of area available for drawing as well.
+        mDisplayHeight = res.getDisplayMetrics().heightPixels;
 
         mDefaultHorizontalGap = 0;
         setKeyWidth(mDisplayWidth / 10);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 098af21..7e67d6f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index f68b68f..2a5e177 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
@@ -40,6 +40,7 @@
 
     public final Locale mLocale;
     public final int mOrientation;
+    public final int mWidth;
     public final int mMode;
     public final int mXmlId;
     public final int mColorScheme;
@@ -49,17 +50,20 @@
     public final boolean mHasVoiceKey;
     public final int mImeAction;
     public final boolean mEnableShiftLock;
+
     public final String mXmlName;
+    public final EditorInfo mAttribute;
 
     private final int mHashCode;
 
     public KeyboardId(String xmlName, int xmlId, int colorScheme, Locale locale, int orientation,
-            int mode, EditorInfo attribute, boolean hasSettingsKey, boolean voiceKeyEnabled,
-            boolean hasVoiceKey, boolean enableShiftLock) {
+            int width, int mode, EditorInfo attribute, boolean hasSettingsKey,
+            boolean voiceKeyEnabled, boolean hasVoiceKey, boolean enableShiftLock) {
         final int inputType = (attribute != null) ? attribute.inputType : 0;
         final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
         this.mLocale = locale;
         this.mOrientation = orientation;
+        this.mWidth = width;
         this.mMode = mode;
         this.mXmlId = xmlId;
         this.mColorScheme = colorScheme;
@@ -73,11 +77,14 @@
         this.mImeAction = imeOptions & (
                 EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
         this.mEnableShiftLock = enableShiftLock;
+
         this.mXmlName = xmlName;
+        this.mAttribute = attribute;
 
         this.mHashCode = Arrays.hashCode(new Object[] {
                 locale,
                 orientation,
+                width,
                 mode,
                 xmlId,
                 colorScheme,
@@ -90,6 +97,18 @@
         });
     }
 
+    public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) {
+        return new KeyboardId(xmlName, xmlId, mColorScheme, mLocale, mOrientation, mWidth, mMode,
+                mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+    }
+
+    public KeyboardId cloneWithNewGeometry(int width) {
+        if (mWidth == width)
+            return this;
+        return new KeyboardId(mXmlName, mXmlId, mColorScheme, mLocale, mOrientation, width, mMode,
+                mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+    }
+
     public int getXmlId() {
         return mXmlId;
     }
@@ -118,6 +137,7 @@
     boolean equals(KeyboardId other) {
         return other.mLocale.equals(this.mLocale)
             && other.mOrientation == this.mOrientation
+            && other.mWidth == this.mWidth
             && other.mMode == this.mMode
             && other.mXmlId == this.mXmlId
             && other.mColorScheme == this.mColorScheme
@@ -136,10 +156,10 @@
 
     @Override
     public String toString() {
-        return String.format("[%s.xml %s %s %s imeAction=%s %s%s%s%s%s%s]",
+        return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s]",
                 mXmlName,
                 mLocale,
-                (mOrientation == 1 ? "port" : "land"),
+                (mOrientation == 1 ? "port" : "land"), mWidth,
                 modeName(mMode),
                 EditorInfoCompatUtils.imeOptionsName(mImeAction),
                 (mPasswordInput ? " passwordInput" : ""),
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 31fd0bf..5980f02 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
index d541279..e015b51 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 3841391..8882310 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -37,7 +37,7 @@
 
 public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String TAG = "KeyboardSwitcher";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_CACHE = false;
     public static final boolean DEBUG_STATE = false;
 
     private static String sConfigDefaultKeyboardThemeId;
@@ -99,6 +99,7 @@
     private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
 
     private int mLayoutId;
+    private int mKeyboardWidth;
 
     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
 
@@ -151,17 +152,39 @@
         // Update the settings key state because number of enabled IMEs could have been changed
         mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService);
         final KeyboardId id = getKeyboardId(attribute, isSymbols);
-        makeSymbolsKeyboardIds(id.mMode, attribute);
-        mCurrentId = id;
-        final Resources res = mInputMethodService.getResources();
-        mInputView.setKeyPreviewPopupEnabled(Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res),
-                Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res));
+
+        // Note: This comment is only applied for phone number keyboard layout.
+        // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch
+        // between "phone keyboard" and "phone symbols keyboard".  But on xlarge device,
+        // "@integer/key_shift" key code is used for that purpose in order to properly display
+        // "more" and "locked more" key labels.  To achieve these behavior, we should initialize
+        // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard"
+        // respectively here for xlarge device's layout switching.
+        mSymbolsId = makeSiblingKeyboardId(id, R.xml.kbd_symbols, R.xml.kbd_phone);
+        mSymbolsShiftedId = makeSiblingKeyboardId(
+                id, R.xml.kbd_symbols_shift, R.xml.kbd_phone_symbols);
+
         setKeyboard(getKeyboard(id));
     }
 
+    public void onSizeChanged() {
+        final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth();
+        if (width == 0)
+            return;
+        mKeyboardWidth = width;
+        // Set keyboard with new width.
+        final KeyboardId newId = mCurrentId.cloneWithNewGeometry(width);
+        setKeyboard(getKeyboard(newId));
+    }
+
     private void setKeyboard(final Keyboard newKeyboard) {
         final Keyboard oldKeyboard = mInputView.getKeyboard();
         mInputView.setKeyboard(newKeyboard);
+        mCurrentId = newKeyboard.mId;
+        final Resources res = mInputMethodService.getResources();
+        mInputView.setKeyPreviewPopupEnabled(
+                Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res),
+                Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res));
         final boolean localeChanged = (oldKeyboard == null)
                 || !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
         mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
@@ -175,19 +198,19 @@
             final Locale savedLocale = Utils.setSystemLocale(res,
                     mSubtypeSwitcher.getInputLocale());
 
-            keyboard = new LatinKeyboard(mInputMethodService, id);
+            keyboard = new LatinKeyboard(mInputMethodService, id, id.mWidth);
 
             if (id.mEnableShiftLock) {
                 keyboard.enableShiftLock();
             }
 
             mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
-            if (DEBUG)
+            if (DEBUG_CACHE)
                 Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
                         + ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
 
             Utils.setSystemLocale(res, savedLocale);
-        } else if (DEBUG) {
+        } else if (DEBUG_CACHE) {
             Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT  id=" + id);
         }
 
@@ -244,33 +267,19 @@
         final boolean hasSettingsKey = hasSettingsKey(attribute);
         final Resources res = mInputMethodService.getResources();
         final int orientation = res.getConfiguration().orientation;
+        if (mKeyboardWidth == 0)
+            mKeyboardWidth = res.getDisplayMetrics().widthPixels;
         final Locale locale = mSubtypeSwitcher.getInputLocale();
         return new KeyboardId(
-                res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation, mode,
-                attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, enableShiftLock);
+                res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation,
+                mKeyboardWidth, mode, attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey,
+                enableShiftLock);
     }
 
-    private void makeSymbolsKeyboardIds(final int mode, EditorInfo attribute) {
-        final Locale locale = mSubtypeSwitcher.getInputLocale();
-        final Resources res = mInputMethodService.getResources();
-        final int orientation = res.getConfiguration().orientation;
-        final int colorScheme = getColorScheme();
-        final boolean hasVoiceKey = mVoiceKeyEnabled && !mVoiceButtonOnPrimary;
-        final boolean hasSettingsKey = hasSettingsKey(attribute);
-        // Note: This comment is only applied for phone number keyboard layout.
-        // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch
-        // between "phone keyboard" and "phone symbols keyboard".  But on xlarge device,
-        // "@integer/key_shift" key code is used for that purpose in order to properly display
-        // "more" and "locked more" key labels.  To achieve these behavior, we should initialize
-        // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard"
-        // respectively here for xlarge device's layout switching.
-        int xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols;
-        final String xmlName = res.getResourceEntryName(xmlId);
-        mSymbolsId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
-                attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
-        xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift;
-        mSymbolsShiftedId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
-                attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
+    private KeyboardId makeSiblingKeyboardId(KeyboardId base, int alphabet, int phone) {
+        final int xmlId = base.mMode == KeyboardId.MODE_PHONE ? phone : alphabet;
+        final String xmlName = mInputMethodService.getResources().getResourceEntryName(xmlId);
+        return base.cloneWithNewLayout(xmlName, xmlId);
     }
 
     public int getKeyboardMode() {
@@ -561,14 +570,12 @@
             return;
         final LatinKeyboard keyboard;
         if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) {
-            mCurrentId = mSymbolsShiftedId;
-            keyboard = getKeyboard(mCurrentId);
+            keyboard = getKeyboard(mSymbolsShiftedId);
             // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To
             // enable the indicator, we need to call setShiftLocked(true).
             keyboard.setShiftLocked(true);
         } else {
-            mCurrentId = mSymbolsId;
-            keyboard = getKeyboard(mCurrentId);
+            keyboard = getKeyboard(mSymbolsId);
             // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
             // indicator, we need to call setShiftLocked(false).
             keyboard.setShiftLocked(false);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 4f85c03..1df6444 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -462,6 +462,12 @@
         return mKeyboardActionListener;
     }
 
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        // TODO: Should notify InputMethodService instead?
+        KeyboardSwitcher.getInstance().onSizeChanged();
+    }
+
     /**
      * Attaches a keyboard to this view. The keyboard can be switched at any time and the
      * view will re-layout itself to accommodate the keyboard.
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 7552b8e..fe27ab4 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -88,8 +88,8 @@
     private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
     private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
 
-    public LatinKeyboard(Context context, KeyboardId id) {
-        super(context, id.getXmlId(), id);
+    public LatinKeyboard(Context context, KeyboardId id, int width) {
+        super(context, id.getXmlId(), id, width);
         final Resources res = context.getResources();
         mContext = context;
 
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 5dde15e..2d6766f 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2011 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
@@ -23,8 +23,8 @@
 public class MiniKeyboard extends Keyboard {
     private int mDefaultKeyCoordX;
 
-    public MiniKeyboard(Context context, int xmlLayoutResId, KeyboardId id) {
-        super(context, xmlLayoutResId, id);
+    public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) {
+        super(context, xmlLayoutResId, null, parentKeyboard.getMinWidth());
     }
 
     public void setDefaultCoordX(int pos) {
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
index 2b83c3f..6e93912 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
@@ -185,7 +185,8 @@
             Keyboard parentKeyboard) {
         final Context context = view.getContext();
         mRes = context.getResources();
-        final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null);
+        final MiniKeyboard keyboard = new MiniKeyboard(
+                context, layoutTemplateResId, parentKeyboard);
         mKeyboard = keyboard;
         mPopupCharacters = parentKey.mPopupCharacters;
 
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index c4459f6..cc5c3bb 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
index f215db8..ebbc79a 100644
--- a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 953d487..a489245 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
index b3ed1e2..eecbb26 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
index 68de8df..9e287c6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java b/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
index 32c2580..ff78ee5 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 80d6de9..33acc69 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2011 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
diff --git a/java/src/com/android/inputmethod/keyboard/Row.java b/java/src/com/android/inputmethod/keyboard/Row.java
index 3618c04..40d7e14 100644
--- a/java/src/com/android/inputmethod/keyboard/Row.java
+++ b/java/src/com/android/inputmethod/keyboard/Row.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
index 9229208..ba15624 100644
--- a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
index 173e879..5cf31cb 100644
--- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
+++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
index 730cdc3..975b13b 100644
--- a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/latin/AutoDictionary.java b/java/src/com/android/inputmethod/latin/AutoDictionary.java
index 307b81d..c264616 100644
--- a/java/src/com/android/inputmethod/latin/AutoDictionary.java
+++ b/java/src/com/android/inputmethod/latin/AutoDictionary.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 39e7e40..e56aa69 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4db34c5..6562595 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -624,6 +624,13 @@
     }
 
     @Override
+    public void onWindowHidden() {
+        super.onWindowHidden();
+        KeyboardView inputView = mKeyboardSwitcher.getInputView();
+        if (inputView != null) inputView.closing();
+    }
+
+    @Override
     public void onFinishInput() {
         super.onFinishInput();
 
@@ -809,7 +816,7 @@
             if (isExtractViewShown()) {
                 // No need to have extra space to show the key preview.
                 mCandidateViewContainer.setMinimumHeight(0);
-                super.setCandidatesViewShown(shown);
+                super.setCandidatesViewShown(shouldShowCandidates);
             } else {
                 // We must control the visibility of the suggestion strip in order to avoid clipped
                 // key previews, even when we don't show the suggestion strip.
diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
index a32a646..b4df5d7 100644
--- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Google Inc.
+ * 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
diff --git a/tests/src/com/android/inputmethod/latin/SuggestHelper.java b/tests/src/com/android/inputmethod/latin/SuggestHelper.java
index 8a11ff9..87ea011 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestHelper.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestHelper.java
@@ -36,7 +36,7 @@
         // Use null as the locale for Suggest so as to force it to use the internal dictionary
         // (and not try to find a dictionary provider for a specified locale)
         mSuggest = new Suggest(context, dictionaryId, null);
-        mKeyboard = new LatinKeyboard(context, keyboardId);
+        mKeyboard = new LatinKeyboard(context, keyboardId, keyboardId.mWidth);
         mKeyDetector = new KeyDetector();
         init();
     }
@@ -44,7 +44,7 @@
     protected SuggestHelper(Context context, File dictionaryPath, long startOffset, long length,
             KeyboardId keyboardId) {
         mSuggest = new Suggest(context, dictionaryPath, startOffset, length, null);
-        mKeyboard = new LatinKeyboard(context, keyboardId);
+        mKeyboard = new LatinKeyboard(context, keyboardId, keyboardId.mWidth);
         mKeyDetector = new KeyDetector();
         init();
     }
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
index 64f2674..cf4ccfe 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
@@ -38,10 +38,11 @@
         mTestPackageFile = new File(getTestContext().getApplicationInfo().sourceDir);
     }
 
-    protected static KeyboardId createKeyboardId(Locale locale) {
+    protected KeyboardId createKeyboardId(Locale locale) {
+        final int displayWidth = getContext().getResources().getDisplayMetrics().widthPixels;
         return new KeyboardId(locale.toString() + " keyboard",
                 com.android.inputmethod.latin.R.xml.kbd_qwerty, KeyboardView.COLOR_SCHEME_WHITE,
-                locale, Configuration.ORIENTATION_LANDSCAPE, KeyboardId.MODE_TEXT,
+                locale, displayWidth, Configuration.ORIENTATION_LANDSCAPE, KeyboardId.MODE_TEXT,
                 new EditorInfo(), false, false, false, false);
     }