Add a setter of InputMethodSubtype to InputMethodManager

- Public API: void setCurrentInputMethodSubtype(int pos)

Change-Id: I55daa19ba924999def544bf841f00bf54852f3e1
diff --git a/api/current.xml b/api/current.xml
index ba168be..15224ce 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -219249,6 +219249,19 @@
 <parameter name="data" type="android.os.Bundle">
 </parameter>
 </method>
+<method name="setCurrentInputMethodSubtype"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="subtype" type="android.view.inputmethod.InputMethodSubtype">
+</parameter>
+</method>
 <method name="setInputMethod"
  return="void"
  abstract="false"
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 1d75b42..5e7a133 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1432,6 +1432,17 @@
         }
     }
 
+    public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
+        synchronized (mH) {
+            try {
+                return mService.setCurrentInputMethodSubtype(subtype);
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+                return false;
+            }
+        }
+    }
+
     public boolean switchToLastInputMethod(IBinder imeToken) {
         synchronized (mH) {
             try {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 7d8e624..7592e8b 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -57,7 +57,7 @@
     void updateStatusIcon(in IBinder token, String packageName, int iconId);
     void setIMEButtonVisible(in IBinder token, boolean visible);
     InputMethodSubtype getCurrentInputMethodSubtype();
+    boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
     boolean switchToLastInputMethod(in IBinder token);
-    
     boolean setInputMethodEnabled(String id, boolean enabled);
 }
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 7c1c992..4f8862c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -988,8 +988,9 @@
         }
 
         if (id.equals(mCurMethodId)) {
-            if (subtypeId != NOT_A_SUBTYPE_ID) {
-                InputMethodSubtype subtype = info.getSubtypes().get(subtypeId);
+            ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
+            if (subtypeId >= 0 && subtypeId < subtypes.size()) {
+                InputMethodSubtype subtype = subtypes.get(subtypeId);
                 if (subtype != mCurrentSubtype) {
                     synchronized (mMethodMap) {
                         if (mCurMethod != null) {
@@ -1964,6 +1965,20 @@
         return mCurrentSubtype;
     }
 
+    public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
+        synchronized (mMethodMap) {
+            if (subtype != null && mCurMethodId != null) {
+                InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+                int subtypeId = getSubtypeIdFromHashCode(imi, subtype.hashCode());
+                if (subtypeId != NOT_A_SUBTYPE_ID) {
+                    setInputMethodLocked(mCurMethodId, subtypeId);
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     /**
      * Utility class for putting and getting settings for InputMethod
      * TODO: Move all putters and getters of settings to this class.