• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin;
18 
19 import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
20 
21 import android.content.Context;
22 import android.view.inputmethod.InputMethodInfo;
23 import android.view.inputmethod.InputMethodManager;
24 import android.view.inputmethod.InputMethodSubtype;
25 
26 import java.util.Collections;
27 import java.util.List;
28 
29 /**
30  * Utility class for Input Method Framework
31  */
32 public final class ImfUtils {
ImfUtils()33     private ImfUtils() {
34         // This utility class is not publicly instantiable.
35     }
36 
37     private static InputMethodManager sInputMethodManager;
38 
getInputMethodManager(Context context)39     public static InputMethodManager getInputMethodManager(Context context) {
40         if (sInputMethodManager == null) {
41             sInputMethodManager = (InputMethodManager)context.getSystemService(
42                     Context.INPUT_METHOD_SERVICE);
43         }
44         return sInputMethodManager;
45     }
46 
47     private static InputMethodInfo sInputMethodInfoOfThisIme;
48 
getInputMethodInfoOfThisIme(Context context)49     public static InputMethodInfo getInputMethodInfoOfThisIme(Context context) {
50         if (sInputMethodInfoOfThisIme == null) {
51             final InputMethodManager imm = getInputMethodManager(context);
52             final String packageName = context.getPackageName();
53             for (final InputMethodInfo imi : imm.getInputMethodList()) {
54                 if (imi.getPackageName().equals(packageName))
55                     return imi;
56             }
57             throw new RuntimeException("Can not find input method id for " + packageName);
58         }
59         return sInputMethodInfoOfThisIme;
60     }
61 
getInputMethodIdOfThisIme(Context context)62     public static String getInputMethodIdOfThisIme(Context context) {
63         return getInputMethodInfoOfThisIme(context).getId();
64     }
65 
checkIfSubtypeBelongsToThisImeAndEnabled(Context context, InputMethodSubtype ims)66     public static boolean checkIfSubtypeBelongsToThisImeAndEnabled(Context context,
67             InputMethodSubtype ims) {
68         final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context);
69         final InputMethodManager imm = getInputMethodManager(context);
70         // TODO: Cache all subtypes of this IME for optimization
71         final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true);
72         for (final InputMethodSubtype subtype : subtypes) {
73             if (subtype.equals(ims)) {
74                 return true;
75             }
76         }
77         return false;
78     }
79 
checkIfSubtypeBelongsToThisIme(Context context, InputMethodSubtype ims)80     public static boolean checkIfSubtypeBelongsToThisIme(Context context,
81             InputMethodSubtype ims) {
82         final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context);
83         final int count = myImi.getSubtypeCount();
84         for (int i = 0; i < count; i++) {
85             final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
86             if (subtype.equals(ims)) {
87                 return true;
88             }
89         }
90         return false;
91     }
92 
getCurrentInputMethodSubtype(Context context, InputMethodSubtype defaultSubtype)93     public static InputMethodSubtype getCurrentInputMethodSubtype(Context context,
94             InputMethodSubtype defaultSubtype) {
95         final InputMethodManager imm = getInputMethodManager(context);
96         final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype();
97         return (currentSubtype != null) ? currentSubtype : defaultSubtype;
98     }
99 
hasMultipleEnabledIMEsOrSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes)100     public static boolean hasMultipleEnabledIMEsOrSubtypes(Context context,
101             final boolean shouldIncludeAuxiliarySubtypes) {
102         final InputMethodManager imm = getInputMethodManager(context);
103         final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
104         return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, enabledImis);
105     }
106 
hasMultipleEnabledSubtypesInThisIme(Context context, final boolean shouldIncludeAuxiliarySubtypes)107     public static boolean hasMultipleEnabledSubtypesInThisIme(Context context,
108             final boolean shouldIncludeAuxiliarySubtypes) {
109         final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context);
110         final List<InputMethodInfo> imiList = Collections.singletonList(myImi);
111         return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, imiList);
112     }
113 
hasMultipleEnabledSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes, List<InputMethodInfo> imiList)114     private static boolean hasMultipleEnabledSubtypes(Context context,
115             final boolean shouldIncludeAuxiliarySubtypes, List<InputMethodInfo> imiList) {
116         final InputMethodManager imm = getInputMethodManager(context);
117 
118         // Number of the filtered IMEs
119         int filteredImisCount = 0;
120 
121         for (InputMethodInfo imi : imiList) {
122             // We can return true immediately after we find two or more filtered IMEs.
123             if (filteredImisCount > 1) return true;
124             final List<InputMethodSubtype> subtypes =
125                     imm.getEnabledInputMethodSubtypeList(imi, true);
126             // IMEs that have no subtypes should be counted.
127             if (subtypes.isEmpty()) {
128                 ++filteredImisCount;
129                 continue;
130             }
131 
132             int auxCount = 0;
133             for (InputMethodSubtype subtype : subtypes) {
134                 if (subtype.isAuxiliary()) {
135                     ++auxCount;
136                 }
137             }
138             final int nonAuxCount = subtypes.size() - auxCount;
139 
140             // IMEs that have one or more non-auxiliary subtypes should be counted.
141             // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
142             // subtypes should be counted as well.
143             if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
144                 ++filteredImisCount;
145                 continue;
146             }
147         }
148 
149         if (filteredImisCount > 1) {
150             return true;
151         }
152         final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(null, true);
153         int keyboardCount = 0;
154         // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's
155         // both explicitly and implicitly enabled input method subtype.
156         // (The current IME should be LatinIME.)
157         for (InputMethodSubtype subtype : subtypes) {
158             if (KEYBOARD_MODE.equals(subtype.getMode())) {
159                 ++keyboardCount;
160             }
161         }
162         return keyboardCount > 1;
163     }
164 
findSubtypeByLocaleAndKeyboardLayoutSet( Context context, String localeString, String keyboardLayoutSetName)165     public static InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(
166             Context context, String localeString, String keyboardLayoutSetName) {
167         final InputMethodInfo imi = getInputMethodInfoOfThisIme(context);
168         final int count = imi.getSubtypeCount();
169         for (int i = 0; i < count; i++) {
170             final InputMethodSubtype subtype = imi.getSubtypeAt(i);
171             final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
172             if (localeString.equals(subtype.getLocale())
173                     && keyboardLayoutSetName.equals(layoutName)) {
174                 return subtype;
175             }
176         }
177         return null;
178     }
179 
setAdditionalInputMethodSubtypes(Context context, InputMethodSubtype[] subtypes)180     public static void setAdditionalInputMethodSubtypes(Context context,
181             InputMethodSubtype[] subtypes) {
182         final InputMethodManager imm = getInputMethodManager(context);
183         final String imiId = getInputMethodIdOfThisIme(context);
184         imm.setAdditionalInputMethodSubtypes(imiId, subtypes);
185     }
186 }
187