Enable VoiceInput even if there is no shortcut subtype supported
Change-Id: I1d455348f56d73ecb942f22c2bbd03f240b489a6main
parent
a1f9cdd6f5
commit
7429009838
|
@ -16,8 +16,13 @@
|
||||||
|
|
||||||
package com.android.inputmethod.compat;
|
package com.android.inputmethod.compat;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
|
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||||
|
import com.android.inputmethod.latin.Utils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.inputmethod.InputMethodInfo;
|
import android.view.inputmethod.InputMethodInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
@ -27,6 +32,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
// TODO: Override this class with the concrete implementation if we need to take care of the
|
// TODO: Override this class with the concrete implementation if we need to take care of the
|
||||||
|
@ -50,7 +56,15 @@ public class InputMethodManagerCompatWrapper {
|
||||||
private static final InputMethodManagerCompatWrapper sInstance =
|
private static final InputMethodManagerCompatWrapper sInstance =
|
||||||
new InputMethodManagerCompatWrapper();
|
new InputMethodManagerCompatWrapper();
|
||||||
|
|
||||||
|
// For the compatibility, IMM will create dummy subtypes if subtypes are not found.
|
||||||
|
// This is required to be false if the current behavior is broken. For now, it's ok to be true.
|
||||||
|
private static final boolean ALLOW_DUMMY_SUBTYPE = true;
|
||||||
|
private static final boolean HAS_VOICE_FUNCTION = true;
|
||||||
|
private static final String VOICE_MODE = "voice";
|
||||||
|
private static final String KEYBOARD_MODE = "keyboard";
|
||||||
|
|
||||||
private InputMethodManager mImm;
|
private InputMethodManager mImm;
|
||||||
|
private String mLatinImePackageName;
|
||||||
private InputMethodManagerCompatWrapper() {
|
private InputMethodManagerCompatWrapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,28 +78,82 @@ public class InputMethodManagerCompatWrapper {
|
||||||
private synchronized void init(Context context) {
|
private synchronized void init(Context context) {
|
||||||
mImm = (InputMethodManager) context.getSystemService(
|
mImm = (InputMethodManager) context.getSystemService(
|
||||||
Context.INPUT_METHOD_SERVICE);
|
Context.INPUT_METHOD_SERVICE);
|
||||||
|
if (context instanceof LatinIME) {
|
||||||
|
mLatinImePackageName = context.getPackageName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() {
|
public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() {
|
||||||
return new InputMethodSubtypeCompatWrapper(
|
Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype);
|
||||||
CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype));
|
return new InputMethodSubtypeCompatWrapper(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
|
public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
|
||||||
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
|
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
|
||||||
Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList,
|
Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList,
|
||||||
(imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes);
|
(imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes);
|
||||||
// Returns an empty list
|
if (retval == null || !(retval instanceof List) || ((List<?>)retval).isEmpty()) {
|
||||||
if (retval == null)
|
if (!ALLOW_DUMMY_SUBTYPE) {
|
||||||
return Collections.emptyList();
|
// Returns an empty list
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
// Creates dummy subtypes
|
||||||
|
List<InputMethodSubtypeCompatWrapper> subtypeList =
|
||||||
|
new ArrayList<InputMethodSubtypeCompatWrapper>();
|
||||||
|
InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE);
|
||||||
|
InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
|
||||||
|
if (keyboardSubtype != null) {
|
||||||
|
subtypeList.add(keyboardSubtype);
|
||||||
|
}
|
||||||
|
if (voiceSubtype != null) {
|
||||||
|
subtypeList.add(voiceSubtype);
|
||||||
|
}
|
||||||
|
return subtypeList;
|
||||||
|
}
|
||||||
return CompatUtils.copyInputMethodSubtypeListToWrapper((List<?>)retval);
|
return CompatUtils.copyInputMethodSubtypeListToWrapper((List<?>)retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() {
|
||||||
|
if (TextUtils.isEmpty(mLatinImePackageName))
|
||||||
|
return null;
|
||||||
|
return Utils.getInputMethodInfo(this, mLatinImePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
|
||||||
|
if (VOICE_MODE.equals(mode) && !HAS_VOICE_FUNCTION)
|
||||||
|
return null;
|
||||||
|
Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale();
|
||||||
|
if (inputLocale == null)
|
||||||
|
return null;
|
||||||
|
return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, "");
|
||||||
|
}
|
||||||
|
|
||||||
public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
|
public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
|
||||||
getShortcutInputMethodsAndSubtypes() {
|
getShortcutInputMethodsAndSubtypes() {
|
||||||
Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
|
Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
|
||||||
// Returns an empty map
|
if (retval == null || !(retval instanceof Map) || ((Map<?, ?>)retval).isEmpty()) {
|
||||||
if (!(retval instanceof Map)) return Collections.emptyMap();
|
if (!ALLOW_DUMMY_SUBTYPE) {
|
||||||
|
// Returns an empty map
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
// Creates dummy subtypes
|
||||||
|
InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo();
|
||||||
|
InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
|
||||||
|
if (imi != null && voiceSubtype != null) {
|
||||||
|
Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
|
||||||
|
shortcutMap =
|
||||||
|
new HashMap<InputMethodInfoCompatWrapper,
|
||||||
|
List<InputMethodSubtypeCompatWrapper>>();
|
||||||
|
List<InputMethodSubtypeCompatWrapper> subtypeList =
|
||||||
|
new ArrayList<InputMethodSubtypeCompatWrapper>();
|
||||||
|
subtypeList.add(voiceSubtype);
|
||||||
|
shortcutMap.put(imi, subtypeList);
|
||||||
|
return shortcutMap;
|
||||||
|
} else {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap =
|
Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap =
|
||||||
new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>();
|
new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>();
|
||||||
final Map<?, ?> retvalMap = (Map<?, ?>)retval;
|
final Map<?, ?> retvalMap = (Map<?, ?>)retval;
|
||||||
|
@ -107,6 +175,9 @@ public class InputMethodManagerCompatWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean switchToLastInputMethod(IBinder token) {
|
public boolean switchToLastInputMethod(IBinder token) {
|
||||||
|
if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token);
|
return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
// TODO: Override this class with the concrete implementation if we need to take care of the
|
// TODO: Override this class with the concrete implementation if we need to take care of the
|
||||||
// performance.
|
// performance.
|
||||||
|
@ -48,35 +49,65 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper
|
||||||
private static final Method METHOD_getExtraValueOf =
|
private static final Method METHOD_getExtraValueOf =
|
||||||
CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class);
|
CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class);
|
||||||
|
|
||||||
|
private final int mDummyNameResId;
|
||||||
|
private final int mDummyIconResId;
|
||||||
|
private final String mDummyLocale;
|
||||||
|
private final String mDummyMode;
|
||||||
|
private final String mDummyExtraValues;
|
||||||
|
|
||||||
public InputMethodSubtypeCompatWrapper(Object subtype) {
|
public InputMethodSubtypeCompatWrapper(Object subtype) {
|
||||||
super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype))
|
super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype))
|
||||||
? subtype : null);
|
? subtype : null);
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper");
|
Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper");
|
||||||
}
|
}
|
||||||
|
mDummyNameResId = 0;
|
||||||
|
mDummyIconResId = 0;
|
||||||
|
mDummyLocale = DEFAULT_LOCALE;
|
||||||
|
mDummyMode = DEFAULT_MODE;
|
||||||
|
mDummyExtraValues = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor for creating a dummy subtype.
|
||||||
|
public InputMethodSubtypeCompatWrapper(int nameResId, int iconResId, String locale,
|
||||||
|
String mode, String extraValues) {
|
||||||
|
super(null);
|
||||||
|
if (DBG) {
|
||||||
|
Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper");
|
||||||
|
}
|
||||||
|
mDummyNameResId = nameResId;
|
||||||
|
mDummyIconResId = iconResId;
|
||||||
|
mDummyLocale = locale != null ? locale : "";
|
||||||
|
mDummyMode = mode != null ? mode : "";
|
||||||
|
mDummyExtraValues = extraValues != null ? extraValues : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNameResId() {
|
public int getNameResId() {
|
||||||
|
if (mObj == null) return mDummyNameResId;
|
||||||
return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId);
|
return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIconResId() {
|
public int getIconResId() {
|
||||||
|
if (mObj == null) return mDummyIconResId;
|
||||||
return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId);
|
return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLocale() {
|
public String getLocale() {
|
||||||
|
if (mObj == null) return mDummyLocale;
|
||||||
final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale);
|
final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale);
|
||||||
if (TextUtils.isEmpty(s)) return DEFAULT_LOCALE;
|
if (TextUtils.isEmpty(s)) return DEFAULT_LOCALE;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMode() {
|
public String getMode() {
|
||||||
|
if (mObj == null) return mDummyMode;
|
||||||
String s = (String)CompatUtils.invoke(mObj, null, METHOD_getMode);
|
String s = (String)CompatUtils.invoke(mObj, null, METHOD_getMode);
|
||||||
if (TextUtils.isEmpty(s)) return DEFAULT_MODE;
|
if (TextUtils.isEmpty(s)) return DEFAULT_MODE;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExtraValue() {
|
public String getExtraValue() {
|
||||||
|
if (mObj == null) return mDummyExtraValues;
|
||||||
return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue);
|
return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +123,32 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o instanceof InputMethodSubtypeCompatWrapper) {
|
if (o instanceof InputMethodSubtypeCompatWrapper) {
|
||||||
InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o;
|
InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o;
|
||||||
|
if (mObj == null) {
|
||||||
|
// easy check of dummy subtypes
|
||||||
|
return (mDummyNameResId == subtype.mDummyNameResId
|
||||||
|
&& mDummyIconResId == subtype.mDummyIconResId
|
||||||
|
&& mDummyLocale.equals(subtype.mDummyLocale)
|
||||||
|
&& mDummyMode.equals(subtype.mDummyMode)
|
||||||
|
&& mDummyExtraValues.equals(subtype.mDummyExtraValues));
|
||||||
|
}
|
||||||
return mObj.equals(subtype.getOriginalObject());
|
return mObj.equals(subtype.getOriginalObject());
|
||||||
} else {
|
} else {
|
||||||
return mObj.equals(o);
|
return mObj.equals(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (mObj == null) {
|
||||||
|
return hashCodeInternal(mDummyNameResId, mDummyIconResId, mDummyLocale,
|
||||||
|
mDummyMode, mDummyExtraValues);
|
||||||
|
}
|
||||||
|
return mObj.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int hashCodeInternal(int nameResId, int iconResId, String locale,
|
||||||
|
String mode, String extraValue) {
|
||||||
|
return Arrays
|
||||||
|
.hashCode(new Object[] { nameResId, iconResId, locale, mode, extraValue });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,8 @@ public class VoiceProxy implements VoiceInput.UiListener {
|
||||||
private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE =
|
private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE =
|
||||||
"has_used_voice_input_unsupported_locale";
|
"has_used_voice_input_unsupported_locale";
|
||||||
private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6;
|
private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6;
|
||||||
|
// TODO: Adjusted on phones for now
|
||||||
|
private static final int RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP = 244;
|
||||||
|
|
||||||
private static final String TAG = VoiceProxy.class.getSimpleName();
|
private static final String TAG = VoiceProxy.class.getSimpleName();
|
||||||
private static final boolean DEBUG = LatinImeLogger.sDBG;
|
private static final boolean DEBUG = LatinImeLogger.sDBG;
|
||||||
|
@ -99,6 +101,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
|
||||||
private boolean mVoiceButtonOnPrimary;
|
private boolean mVoiceButtonOnPrimary;
|
||||||
private boolean mVoiceInputHighlighted;
|
private boolean mVoiceInputHighlighted;
|
||||||
|
|
||||||
|
private int mMinimumVoiceRecognitionViewHeightPixel;
|
||||||
private InputMethodManagerCompatWrapper mImm;
|
private InputMethodManagerCompatWrapper mImm;
|
||||||
private LatinIME mService;
|
private LatinIME mService;
|
||||||
private AlertDialog mVoiceWarningDialog;
|
private AlertDialog mVoiceWarningDialog;
|
||||||
|
@ -107,6 +110,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
|
||||||
private Hints mHints;
|
private Hints mHints;
|
||||||
private UIHandler mHandler;
|
private UIHandler mHandler;
|
||||||
private SubtypeSwitcher mSubtypeSwitcher;
|
private SubtypeSwitcher mSubtypeSwitcher;
|
||||||
|
|
||||||
// For each word, a list of potential replacements, usually from voice.
|
// For each word, a list of potential replacements, usually from voice.
|
||||||
private final Map<String, List<CharSequence>> mWordToSuggestions =
|
private final Map<String, List<CharSequence>> mWordToSuggestions =
|
||||||
new HashMap<String, List<CharSequence>>();
|
new HashMap<String, List<CharSequence>>();
|
||||||
|
@ -123,6 +127,8 @@ public class VoiceProxy implements VoiceInput.UiListener {
|
||||||
private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) {
|
private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) {
|
||||||
mService = service;
|
mService = service;
|
||||||
mHandler = h;
|
mHandler = h;
|
||||||
|
mMinimumVoiceRecognitionViewHeightPixel = Utils.dipToPixel(
|
||||||
|
Utils.getDipScale(service), RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP);
|
||||||
mImm = InputMethodManagerCompatWrapper.getInstance(service);
|
mImm = InputMethodManagerCompatWrapper.getInstance(service);
|
||||||
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
||||||
if (VOICE_INSTALLED) {
|
if (VOICE_INSTALLED) {
|
||||||
|
@ -542,7 +548,11 @@ public class VoiceProxy implements VoiceInput.UiListener {
|
||||||
mService.getResources().getDisplayMetrics().heightPixels;
|
mService.getResources().getDisplayMetrics().heightPixels;
|
||||||
final int currentHeight = popupLayout.getLayoutParams().height;
|
final int currentHeight = popupLayout.getLayoutParams().height;
|
||||||
final int keyboardHeight = keyboardView.getHeight();
|
final int keyboardHeight = keyboardView.getHeight();
|
||||||
if (keyboardHeight > currentHeight || keyboardHeight
|
if (mMinimumVoiceRecognitionViewHeightPixel > keyboardHeight
|
||||||
|
|| mMinimumVoiceRecognitionViewHeightPixel > currentHeight) {
|
||||||
|
popupLayout.getLayoutParams().height =
|
||||||
|
mMinimumVoiceRecognitionViewHeightPixel;
|
||||||
|
} else if (keyboardHeight > currentHeight || keyboardHeight
|
||||||
> (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) {
|
> (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) {
|
||||||
popupLayout.getLayoutParams().height = keyboardHeight;
|
popupLayout.getLayoutParams().height = keyboardHeight;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ import java.util.Locale;
|
||||||
* plays beeps, shows errors, etc.
|
* plays beeps, shows errors, etc.
|
||||||
*/
|
*/
|
||||||
public class RecognitionView {
|
public class RecognitionView {
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static final String TAG = "RecognitionView";
|
private static final String TAG = "RecognitionView";
|
||||||
|
|
||||||
private Handler mUiHandler; // Reference to UI thread
|
private Handler mUiHandler; // Reference to UI thread
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class SubtypeSwitcher {
|
||||||
final String newLocale;
|
final String newLocale;
|
||||||
final String newMode;
|
final String newMode;
|
||||||
final String oldMode = getCurrentSubtypeMode();
|
final String oldMode = getCurrentSubtypeMode();
|
||||||
if (newSubtype == null || !newSubtype.hasOriginalObject()) {
|
if (newSubtype == null) {
|
||||||
// Normally, newSubtype shouldn't be null. But just in case newSubtype was null,
|
// Normally, newSubtype shouldn't be null. But just in case newSubtype was null,
|
||||||
// fallback to the default locale.
|
// fallback to the default locale.
|
||||||
Log.w(TAG, "Couldn't get the current subtype.");
|
Log.w(TAG, "Couldn't get the current subtype.");
|
||||||
|
@ -539,6 +539,11 @@ public class SubtypeSwitcher {
|
||||||
return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode());
|
return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDummyVoiceMode() {
|
||||||
|
return mCurrentSubtype != null && mCurrentSubtype.getOriginalObject() == null
|
||||||
|
&& VOICE_MODE.equals(getCurrentSubtypeMode());
|
||||||
|
}
|
||||||
|
|
||||||
private void triggerVoiceIME() {
|
private void triggerVoiceIME() {
|
||||||
if (!mService.isInputViewShown()) return;
|
if (!mService.isInputViewShown()) return;
|
||||||
VoiceProxy.getInstance().startListening(false,
|
VoiceProxy.getInstance().startListening(false,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
|
||||||
import com.android.inputmethod.compat.InputTypeCompatUtils;
|
import com.android.inputmethod.compat.InputTypeCompatUtils;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -110,9 +111,14 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) {
|
public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) {
|
||||||
|
return getInputMethodInfo(imm, packageName).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputMethodInfoCompatWrapper getInputMethodInfo(
|
||||||
|
InputMethodManagerCompatWrapper imm, String packageName) {
|
||||||
for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) {
|
for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) {
|
||||||
if (imi.getPackageName().equals(packageName))
|
if (imi.getPackageName().equals(packageName))
|
||||||
return imi.getId();
|
return imi;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Can not find input method id for " + packageName);
|
throw new RuntimeException("Can not find input method id for " + packageName);
|
||||||
}
|
}
|
||||||
|
@ -601,4 +607,14 @@ public class Utils {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float getDipScale(Context context) {
|
||||||
|
final float scale = context.getResources().getDisplayMetrics().density;
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert pixel to DIP */
|
||||||
|
public static int dipToPixel(float scale, int dip) {
|
||||||
|
return (int) ((float) dip * scale + 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue