Merge "Update SoftKeyboard sample to use InputMethodSubtype" into ics-mr0
diff --git a/samples/SoftKeyboard/AndroidManifest.xml b/samples/SoftKeyboard/AndroidManifest.xml
index 61b5131..3d30779 100755
--- a/samples/SoftKeyboard/AndroidManifest.xml
+++ b/samples/SoftKeyboard/AndroidManifest.xml
@@ -8,5 +8,12 @@
             </intent-filter>
             <meta-data android:name="android.view.im" android:resource="@xml/method" />
         </service>
+
+        <activity android:name=".ImePreferences" android:label="@string/settings_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/icon_en_gb.png b/samples/SoftKeyboard/res/drawable-hdpi/icon_en_gb.png
new file mode 100644
index 0000000..53088d9
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/icon_en_gb.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/icon_en_us.png b/samples/SoftKeyboard/res/drawable-hdpi/icon_en_us.png
new file mode 100644
index 0000000..bc8b66e
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/icon_en_us.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-mdpi/icon_en_gb.png b/samples/SoftKeyboard/res/drawable-mdpi/icon_en_gb.png
new file mode 100644
index 0000000..03c665a
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-mdpi/icon_en_gb.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-mdpi/icon_en_us.png b/samples/SoftKeyboard/res/drawable-mdpi/icon_en_us.png
new file mode 100644
index 0000000..da8d43f
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-mdpi/icon_en_us.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/values/strings.xml b/samples/SoftKeyboard/res/values/strings.xml
index bc645b2..952a629 100644
--- a/samples/SoftKeyboard/res/values/strings.xml
+++ b/samples/SoftKeyboard/res/values/strings.xml
@@ -28,4 +28,14 @@
     <string name="label_go_key">Go</string>
     <string name="label_next_key">Next</string>
     <string name="label_send_key">Send</string>
+
+    <!-- Labels for subtype -->
+    <string name="label_subtype_generic">%s</string>
+    <string name="label_subtype_en_GB">English (GB)</string>
+
+    <!-- Titles for ImePreference -->
+    <string name="settings_name">Sample Soft Keyboard Settings</string>
+    <string name="language_selection_title">Input languages</string>
+    <string name="select_language">Select input languages</string>
+    <string name="general_category">General</string>
 </resources>
diff --git a/samples/SoftKeyboard/res/xml/ime_preferences.xml b/samples/SoftKeyboard/res/xml/ime_preferences.xml
new file mode 100644
index 0000000..1e973a6
--- /dev/null
+++ b/samples/SoftKeyboard/res/xml/ime_preferences.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 Google Inc.
+
+     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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        android:title="@string/settings_name">
+</PreferenceScreen>
diff --git a/samples/SoftKeyboard/res/xml/method.xml b/samples/SoftKeyboard/res/xml/method.xml
index d246624..2f2d6f0 100644
--- a/samples/SoftKeyboard/res/xml/method.xml
+++ b/samples/SoftKeyboard/res/xml/method.xml
@@ -20,4 +20,17 @@
 <!-- The attributes in this XML file provide configuration information -->
 <!-- for the Search Manager. -->
 
-<input-method xmlns:android="http://schemas.android.com/apk/res/android" />
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+        android:settingsActivity="com.example.android.softkeyboard.ImePreferences"
+>
+    <subtype
+        android:label="@string/label_subtype_generic"
+        android:icon="@drawable/icon_en_us"
+        android:imeSubtypeLocale="en_US"
+        android:imeSubtypeMode="keyboard" />
+    <subtype
+        android:label="@string/label_subtype_en_GB"
+        android:icon="@drawable/icon_en_gb"
+        android:imeSubtypeLocale="en_GB"
+        android:imeSubtypeMode="keyboard" />
+</input-method>
diff --git a/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java
new file mode 100644
index 0000000..b3b7c8c
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsFragment.java
@@ -0,0 +1,101 @@
+/*
+ * 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 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.
+ */
+
+/**
+ * This is a part of the inputmethod-common static Java library.
+ * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source
+ * Project.
+ */
+
+package com.android.inputmethodcommon;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+
+/**
+ * This is a helper class for an IME's settings preference fragment. It's recommended for every
+ * IME to have its own settings preference fragment which inherits this class.
+ */
+public abstract class InputMethodSettingsFragment extends PreferenceFragment
+        implements InputMethodSettingsInterface {
+    private final InputMethodSettingsImpl mSettings = new InputMethodSettingsImpl();
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final Context context = getActivity();
+        setPreferenceScreen(getPreferenceManager().createPreferenceScreen(context));
+        mSettings.init(context, getPreferenceScreen());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setInputMethodSettingsCategoryTitle(int resId) {
+        mSettings.setInputMethodSettingsCategoryTitle(resId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setInputMethodSettingsCategoryTitle(CharSequence title) {
+        mSettings.setInputMethodSettingsCategoryTitle(title);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerTitle(int resId) {
+        mSettings.setSubtypeEnablerTitle(resId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerTitle(CharSequence title) {
+        mSettings.setSubtypeEnablerTitle(title);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerIcon(int resId) {
+        mSettings.setSubtypeEnablerIcon(resId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerIcon(Drawable drawable) {
+        mSettings.setSubtypeEnablerIcon(drawable);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onResume() {
+        super.onResume();
+        mSettings.updateSubtypeEnabler();
+    }
+}
diff --git a/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java
new file mode 100644
index 0000000..722148d
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsImpl.java
@@ -0,0 +1,198 @@
+/*
+ * 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 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.
+ */
+
+/**
+ * This is a part of the inputmethod-common static Java library.
+ * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source
+ * Project.
+ */
+
+package com.android.inputmethodcommon;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.List;
+
+/* package private */ class InputMethodSettingsImpl implements InputMethodSettingsInterface {
+    private Preference mSubtypeEnablerPreference;
+    private int mInputMethodSettingsCategoryTitleRes;
+    private CharSequence mInputMethodSettingsCategoryTitle;
+    private int mSubtypeEnablerTitleRes;
+    private CharSequence mSubtypeEnablerTitle;
+    private int mSubtypeEnablerIconRes;
+    private Drawable mSubtypeEnablerIcon;
+    private InputMethodManager mImm;
+    private InputMethodInfo mImi;
+    private Context mContext;
+
+    /**
+     * Initialize internal states of this object.
+     * @param context the context for this application.
+     * @param prefScreen a PreferenceScreen of PreferenceActivity or PreferenceFragment.
+     * @return true if this application is an IME and has two or more subtypes, false otherwise.
+     */
+    public boolean init(final Context context, final PreferenceScreen prefScreen) {
+        mContext = context;
+        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        mImi = getMyImi(context, mImm);
+        if (mImi == null || mImi.getSubtypeCount() <= 1) {
+            return false;
+        }
+        mSubtypeEnablerPreference = new Preference(context);
+        mSubtypeEnablerPreference
+                .setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                    @Override
+                    public boolean onPreferenceClick(Preference preference) {
+                        final CharSequence title = getSubtypeEnablerTitle(context);
+                        final Intent intent =
+                                new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
+                        intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, mImi.getId());
+                        if (!TextUtils.isEmpty(title)) {
+                            intent.putExtra(Intent.EXTRA_TITLE, title);
+                        }
+                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+                                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                        context.startActivity(intent);
+                        return true;
+                    }
+                });
+        prefScreen.addPreference(mSubtypeEnablerPreference);
+        updateSubtypeEnabler();
+        return true;
+    }
+
+    private static InputMethodInfo getMyImi(Context context, InputMethodManager imm) {
+        final List<InputMethodInfo> imis = imm.getInputMethodList();
+        for (int i = 0; i < imis.size(); ++i) {
+            final InputMethodInfo imi = imis.get(i);
+            if (imis.get(i).getPackageName().equals(context.getPackageName())) {
+                return imi;
+            }
+        }
+        return null;
+    }
+
+    private static String getEnabledSubtypesLabel(
+            Context context, InputMethodManager imm, InputMethodInfo imi) {
+        if (context == null || imm == null || imi == null) return null;
+        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true);
+        final StringBuilder sb = new StringBuilder();
+        final int N = subtypes.size();
+        for (int i = 0; i < N; ++i) {
+            final InputMethodSubtype subtype = subtypes.get(i);
+            if (sb.length() > 0) {
+                sb.append(", ");
+            }
+            sb.append(subtype.getDisplayName(context, imi.getPackageName(),
+                    imi.getServiceInfo().applicationInfo));
+        }
+        return sb.toString();
+    }
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setInputMethodSettingsCategoryTitle(int resId) {
+        mInputMethodSettingsCategoryTitleRes = resId;
+        updateSubtypeEnabler();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setInputMethodSettingsCategoryTitle(CharSequence title) {
+        mInputMethodSettingsCategoryTitleRes = 0;
+        mInputMethodSettingsCategoryTitle = title;
+        updateSubtypeEnabler();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerTitle(int resId) {
+        mSubtypeEnablerTitleRes = resId;
+        updateSubtypeEnabler();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerTitle(CharSequence title) {
+        mSubtypeEnablerTitleRes = 0;
+        mSubtypeEnablerTitle = title;
+        updateSubtypeEnabler();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerIcon(int resId) {
+        mSubtypeEnablerIconRes = resId;
+        updateSubtypeEnabler();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setSubtypeEnablerIcon(Drawable drawable) {
+        mSubtypeEnablerIconRes = 0;
+        mSubtypeEnablerIcon = drawable;
+        updateSubtypeEnabler();
+    }
+
+    private CharSequence getSubtypeEnablerTitle(Context context) {
+        if (mSubtypeEnablerTitleRes != 0) {
+            return context.getString(mSubtypeEnablerTitleRes);
+        } else {
+            return mSubtypeEnablerTitle;
+        }
+    }
+
+    public void updateSubtypeEnabler() {
+        if (mSubtypeEnablerPreference != null) {
+            if (mSubtypeEnablerTitleRes != 0) {
+                mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitleRes);
+            } else if (!TextUtils.isEmpty(mSubtypeEnablerTitle)) {
+                mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitle);
+            }
+            final String summary = getEnabledSubtypesLabel(mContext, mImm, mImi);
+            if (!TextUtils.isEmpty(summary)) {
+                mSubtypeEnablerPreference.setSummary(summary);
+            }
+            if (mSubtypeEnablerIconRes != 0) {
+                mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIconRes);
+            } else if (mSubtypeEnablerIcon != null) {
+                mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIcon);
+            }
+        }
+    }
+}
diff --git a/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java
new file mode 100644
index 0000000..f41e224
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/android/inputmethodcommon/InputMethodSettingsInterface.java
@@ -0,0 +1,69 @@
+/*
+ * 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 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
+ */
+
+/**
+ * This is a part of the inputmethod-common static Java library.
+ * The original source code can be found at frameworks/opt/inputmethodcommon of Android Open Source
+ * Project.
+ */
+
+package com.android.inputmethodcommon;
+
+import android.graphics.drawable.Drawable;
+
+/**
+ * InputMethodSettingsInterface is the interface for adding IME related preferences to
+ * PreferenceActivity or PreferenceFragment.
+ */
+public interface InputMethodSettingsInterface {
+    /**
+     * Sets the title for the input method settings category with a resource ID.
+     * @param resId The resource ID of the title.
+     */
+    public void setInputMethodSettingsCategoryTitle(int resId);
+
+    /**
+     * Sets the title for the input method settings category with a CharSequence.
+     * @param title The title for this preference.
+     */
+    public void setInputMethodSettingsCategoryTitle(CharSequence title);
+
+    /**
+     * Sets the title for the input method enabler preference for launching subtype enabler with a
+     * resource ID.
+     * @param resId The resource ID of the title.
+     */
+    public void setSubtypeEnablerTitle(int resId);
+
+    /**
+     * Sets the title for the input method enabler preference for launching subtype enabler with a
+     * CharSequence.
+     * @param title The title for this preference.
+     */
+    public void setSubtypeEnablerTitle(CharSequence title);
+
+    /**
+     * Sets the icon for the preference for launching subtype enabler with a resource ID.
+     * @param resId The resource id of an optional icon for the preference.
+     */
+    public void setSubtypeEnablerIcon(int resId);
+
+    /**
+     * Sets the icon for the Preference for launching subtype enabler with a Drawable.
+     * @param drawable The drawable of an optional icon for the preference.
+     */
+    public void setSubtypeEnablerIcon(Drawable drawable);
+}
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java
index 7cadead..33ee467 100755
--- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java
@@ -1,17 +1,17 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
- * 
- * 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
- * 
+ * 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 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.
+ * 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.example.android.softkeyboard;
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/ImePreferences.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/ImePreferences.java
new file mode 100644
index 0000000..db6c1d9
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/ImePreferences.java
@@ -0,0 +1,55 @@
+/*
+ * 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 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.example.android.softkeyboard;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import com.android.inputmethodcommon.InputMethodSettingsFragment;
+
+/**
+ * Displays the IME preferences inside the input method setting.
+ */
+public class ImePreferences extends PreferenceActivity {
+    @Override
+    public Intent getIntent() {
+        final Intent modIntent = new Intent(super.getIntent());
+        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, Settings.class.getName());
+        modIntent.putExtra(EXTRA_NO_HEADERS, true);
+        return modIntent;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // We overwrite the title of the activity, as the default one is "Voice Search".
+        setTitle(R.string.settings_name);
+    }
+
+    public static class Settings extends InputMethodSettingsFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setInputMethodSettingsCategoryTitle(R.string.language_selection_title);
+            setSubtypeEnablerTitle(R.string.select_language);
+
+            // Load the preferences from an XML resource
+            addPreferencesFromResource(R.xml.ime_preferences);
+        }
+    }
+}
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java
index 1798442..67787dc 100644
--- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java
@@ -1,17 +1,17 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
- * 
- * 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
- * 
+ * 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 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.
+ * 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.example.android.softkeyboard;
@@ -19,14 +19,14 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
 import android.inputmethodservice.Keyboard;
-import android.inputmethodservice.Keyboard.Key;
-import android.inputmethodservice.Keyboard.Row;
 import android.view.inputmethod.EditorInfo;
 
 public class LatinKeyboard extends Keyboard {
 
     private Key mEnterKey;
+    private Key mSpaceKey;
     
     public LatinKeyboard(Context context, int xmlLayoutResId) {
         super(context, xmlLayoutResId);
@@ -43,6 +43,8 @@
         Key key = new LatinKey(res, parent, x, y, parser);
         if (key.codes[0] == 10) {
             mEnterKey = key;
+        } else if (key.codes[0] == ' ') {
+            mSpaceKey = key;
         }
         return key;
     }
@@ -68,8 +70,7 @@
                 mEnterKey.label = res.getText(R.string.label_next_key);
                 break;
             case EditorInfo.IME_ACTION_SEARCH:
-                mEnterKey.icon = res.getDrawable(
-                        R.drawable.sym_keyboard_search);
+                mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
                 mEnterKey.label = null;
                 break;
             case EditorInfo.IME_ACTION_SEND:
@@ -78,13 +79,18 @@
                 mEnterKey.label = res.getText(R.string.label_send_key);
                 break;
             default:
-                mEnterKey.icon = res.getDrawable(
-                        R.drawable.sym_keyboard_return);
+                mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_return);
                 mEnterKey.label = null;
                 break;
         }
     }
-    
+
+    void setSpaceIcon(final Drawable icon) {
+        if (mSpaceKey != null) {
+            mSpaceKey.icon = icon;
+        }
+    }
+
     static class LatinKey extends Keyboard.Key {
         
         public LatinKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser) {
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java
index 7464607..489c283 100644
--- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java
@@ -1,26 +1,27 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
- * 
- * 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
- * 
+ * 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 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.
+ * 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.example.android.softkeyboard;
 
 import android.content.Context;
 import android.inputmethodservice.Keyboard;
-import android.inputmethodservice.KeyboardView;
 import android.inputmethodservice.Keyboard.Key;
+import android.inputmethodservice.KeyboardView;
 import android.util.AttributeSet;
+import android.view.inputmethod.InputMethodSubtype;
 
 public class LatinKeyboardView extends KeyboardView {
 
@@ -43,4 +44,10 @@
             return super.onLongPress(key);
         }
     }
+
+    void setSubtypeOnSpaceKey(final InputMethodSubtype subtype) {
+        final LatinKeyboard keyboard = (LatinKeyboard)getKeyboard();
+        keyboard.setSpaceIcon(getResources().getDrawable(subtype.getIconResId()));
+        invalidateAllKeys();
+    }
 }
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
index 50b3536..7c4a17e 100644
--- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
@@ -1,17 +1,17 @@
 /*
- * Copyright (C) 2008-2009 Google Inc.
- * 
- * 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
- * 
+ * 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 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.
+ * 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.example.android.softkeyboard;
@@ -19,8 +19,8 @@
 import android.inputmethodservice.InputMethodService;
 import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.KeyboardView;
+import android.text.InputType;
 import android.text.method.MetaKeyKeyListener;
-import android.util.Log;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
@@ -28,6 +28,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -52,8 +53,10 @@
      * that are primarily intended to be used for on-screen text entry.
      */
     static final boolean PROCESS_HARD_KEYS = true;
-    
-    private KeyboardView mInputView;
+
+    private InputMethodManager mInputMethodManager;
+
+    private LatinKeyboardView mInputView;
     private CandidateView mCandidateView;
     private CompletionInfo[] mCompletions;
     
@@ -79,6 +82,7 @@
      */
     @Override public void onCreate() {
         super.onCreate();
+        mInputMethodManager = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
         mWordSeparators = getResources().getString(R.string.word_separators);
     }
     
@@ -107,7 +111,7 @@
      * a configuration change.
      */
     @Override public View onCreateInputView() {
-        mInputView = (KeyboardView) getLayoutInflater().inflate(
+        mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
                 R.layout.input, null);
         mInputView.setOnKeyboardActionListener(this);
         mInputView.setKeyboard(mQwertyKeyboard);
@@ -149,21 +153,21 @@
         
         // We are now going to initialize our state based on the type of
         // text being edited.
-        switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {
-            case EditorInfo.TYPE_CLASS_NUMBER:
-            case EditorInfo.TYPE_CLASS_DATETIME:
+        switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
+            case InputType.TYPE_CLASS_NUMBER:
+            case InputType.TYPE_CLASS_DATETIME:
                 // Numbers and dates default to the symbols keyboard, with
                 // no extra features.
                 mCurKeyboard = mSymbolsKeyboard;
                 break;
                 
-            case EditorInfo.TYPE_CLASS_PHONE:
+            case InputType.TYPE_CLASS_PHONE:
                 // Phones will also default to the symbols keyboard, though
                 // often you will want to have a dedicated phone keyboard.
                 mCurKeyboard = mSymbolsKeyboard;
                 break;
                 
-            case EditorInfo.TYPE_CLASS_TEXT:
+            case InputType.TYPE_CLASS_TEXT:
                 // This is general text editing.  We will default to the
                 // normal alphabetic keyboard, and assume that we should
                 // be doing predictive text (showing candidates as the
@@ -173,23 +177,23 @@
                 
                 // We now look for a few special variations of text that will
                 // modify our behavior.
-                int variation = attribute.inputType &  EditorInfo.TYPE_MASK_VARIATION;
-                if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD ||
-                        variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
+                int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION;
+                if (variation == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
+                        variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
                     // Do not display predictions / what the user is typing
                     // when they are entering a password.
                     mPredictionOn = false;
                 }
                 
-                if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 
-                        || variation == EditorInfo.TYPE_TEXT_VARIATION_URI
-                        || variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
+                if (variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
+                        || variation == InputType.TYPE_TEXT_VARIATION_URI
+                        || variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
                     // Our predictions are not useful for e-mail addresses
                     // or URIs.
                     mPredictionOn = false;
                 }
                 
-                if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
+                if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
                     // If this is an auto-complete text view, then our predictions
                     // will not be shown and instead we will allow the editor
                     // to supply their own.  We only show the editor's
@@ -245,8 +249,15 @@
         // Apply the selected keyboard to the input view.
         mInputView.setKeyboard(mCurKeyboard);
         mInputView.closing();
+        final InputMethodSubtype subtype = mInputMethodManager.getCurrentInputMethodSubtype();
+        mInputView.setSubtypeOnSpaceKey(subtype);
     }
-    
+
+    @Override
+    public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
+        mInputView.setSubtypeOnSpaceKey(subtype);
+    }
+
     /**
      * Deal with the editor reporting movement of its cursor.
      */
@@ -284,7 +295,7 @@
             }
             
             List<String> stringList = new ArrayList<String>();
-            for (int i=0; i<(completions != null ? completions.length : 0); i++) {
+            for (int i = 0; i < completions.length; i++) {
                 CompletionInfo ci = completions[i];
                 if (ci != null) stringList.add(ci.getText().toString());
             }
@@ -435,7 +446,7 @@
                 && mInputView != null && mQwertyKeyboard == mInputView.getKeyboard()) {
             int caps = 0;
             EditorInfo ei = getCurrentInputEditorInfo();
-            if (ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
+            if (ei != null && ei.inputType != InputType.TYPE_NULL) {
                 caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
             }
             mInputView.setShifted(mCapsLock || caps != 0);