Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 610f1dc8 authored by satok's avatar satok
Browse files

Use reflections for classes related to InputMethodSubtype

Change-Id: Ica53ce879c2b4c5eb47f757fb788a795a881c30e
parent 0a7cf81c
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
/*
 * 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.android.inputmethod.compat;

import android.util.Log;

public abstract class AbstractCompatWrapper {
    private static final String TAG = AbstractCompatWrapper.class.getSimpleName();
    protected final Object mObj;

    public AbstractCompatWrapper(Object obj) {
        if (obj == null) {
            Log.e(TAG, "Invalid input to AbstructCompatWrapper");
        }
        mObj = obj;
    }

    public Object getOriginalObject() {
        return mObj;
    }
}
+56 −0
Original line number Diff line number Diff line
@@ -18,8 +18,15 @@ package com.android.inputmethod.compat;

import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class CompatUtils {
    private static final String TAG = CompatUtils.class.getSimpleName();
    private static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
    // TODO: Can these be constants instead of literal String constants?
    private static final String INPUT_METHOD_SUBTYPE_SETTINGS =
@@ -48,4 +55,53 @@ public class CompatUtils {
        }
        return intent;
    }

    public static Class<?> getClass(String className) {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    public static Method getMethod(Class<?> targetClass, String name,
            Class<?>... parameterTypes) {
        try {
            return targetClass.getMethod(name, parameterTypes);
        } catch (SecurityException e) {
            // ignore
            return null;
        } catch (NoSuchMethodException e) {
            // ignore
            return null;
        }
    }

    public static Object invoke(
            Object receiver, Object defaultValue, Method method, Object... args) {
        if (receiver == null || method == null) return defaultValue;
        try {
            return method.invoke(receiver, args);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Exception in invoke: IllegalArgmentException");
            return defaultValue;
        } catch (IllegalAccessException e) {
            Log.e(TAG, "Exception in invoke: IllegalAccessException");
            return defaultValue;
        } catch (InvocationTargetException e) {
            Log.e(TAG, "Exception in invoke: IllegalTargetException");
            return defaultValue;
        }
    }

    public static List<InputMethodSubtypeCompatWrapper> copyInputMethodSubtypeListToWrappler(
            Object listObject) {
        if (!(listObject instanceof List<?>)) return null;
        final List<InputMethodSubtypeCompatWrapper> subtypes =
                new ArrayList<InputMethodSubtypeCompatWrapper>();
        for (Object o: (List<?>)listObject) {
            subtypes.add(new InputMethodSubtypeCompatWrapper(o));
        }
        return subtypes;
    }
}
+115 −0
Original line number Diff line number Diff line
/*
 * 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.android.inputmethod.compat;

import android.content.Context;
import android.os.IBinder;
import android.util.Log;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// TODO: Override this class with the concrete implementation if we need to take care of the
// performance.
public class InputMethodManagerCompatWrapper {
    private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
    private static final Method METHOD_getCurrentInputMethodSubtype =
            CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype");
    private static final Method METHOD_getEnabledInputMethodSubtypeList =
            CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList",
                    InputMethodInfo.class, boolean.class);
    private static final Method METHOD_getShortcutInputMethodsAndSubtypes =
            CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes");
    private static final Method METHOD_setInputMethodAndSubtype =
            CompatUtils.getMethod(
                    InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class,
                    String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype);

    private static final InputMethodManagerCompatWrapper sInstance =
            new InputMethodManagerCompatWrapper();

    private InputMethodManager mImm;
    private InputMethodManagerCompatWrapper() {
    }

    public static InputMethodManagerCompatWrapper getInstance(Context context) {
        if (sInstance.mImm == null) {
            sInstance.init(context);
        }
        return sInstance;
    }

    private synchronized void init(Context context) {
        mImm = (InputMethodManager) context.getSystemService(
                Context.INPUT_METHOD_SERVICE);
    }

    public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() {
        return new InputMethodSubtypeCompatWrapper(
                CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype));
    }

    public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
            InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) {
        Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList,
                imi, allowsImplicitlySelectedSubtypes);
        return CompatUtils.copyInputMethodSubtypeListToWrappler((List<?>)retval);
    }

    public Map<InputMethodInfo, List<InputMethodSubtypeCompatWrapper>>
            getShortcutInputMethodsAndSubtypes() {
        Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
        if (!(retval instanceof Map)) return null;
        Map<InputMethodInfo, List<InputMethodSubtypeCompatWrapper>> shortcutMap =
                new HashMap<InputMethodInfo, List<InputMethodSubtypeCompatWrapper>>();
        final Map<?, ?> retvalMap = (Map<?, ?>)retval;
        for (Object key: retvalMap.keySet()) {
            if (!(key instanceof InputMethodInfo)) {
                Log.e(TAG, "Class type error.");
                return null;
            }
            shortcutMap.put((InputMethodInfo)key, CompatUtils.copyInputMethodSubtypeListToWrappler(
                    retvalMap.get(key)));
        }
        return shortcutMap;
    }

    public void setInputMethodAndSubtype(
            IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) {
        CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype,
                token, id, subtype.getOriginalObject());
    }

    public boolean switchToLastInputMethod(IBinder token) {
        if (mImm == null) return false;
        return mImm.switchToLastInputMethod(token);
    }

    public List<InputMethodInfo> getEnabledInputMethodList() {
        if (mImm == null) return null;
        return mImm.getEnabledInputMethodList();
    }

    public void showInputMethodPicker() {
        if (mImm == null) return;
        mImm.showInputMethodPicker();
    }
}
+93 −0
Original line number Diff line number Diff line
/*
 * 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.android.inputmethod.compat;

import com.android.inputmethod.latin.LatinImeLogger;

import android.util.Log;

import java.lang.reflect.Method;

// TODO: Override this class with the concrete implementation if we need to take care of the
// performance.
public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper {
    private static final boolean DBG = LatinImeLogger.sDBG;
    private static final String TAG = InputMethodSubtypeCompatWrapper.class.getSimpleName();

    public static final Class<?> CLASS_InputMethodSubtype =
            CompatUtils.getClass("android.view.inputmethod.InputMethodSubtype");
    private static final Method METHOD_getNameResId =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getNameResId");
    private static final Method METHOD_getIconResId =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getIconResId");
    private static final Method METHOD_getLocale =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getLocale");
    private static final Method METHOD_getMode =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getMode");
    private static final Method METHOD_getExtraValue =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValue");
    private static final Method METHOD_containsExtraValueKey =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "containsExtraValueKey", String.class);
    private static final Method METHOD_getExtraValueOf =
            CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class);

    public InputMethodSubtypeCompatWrapper(Object subtype) {
        super(CLASS_InputMethodSubtype.isInstance(subtype) ? subtype : null);
        if (DBG) {
            Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper");
        }
    }

    public int getNameResId() {
        return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId);
    }

    public int getIconResId() {
        return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId);
    }

    public String getLocale() {
        return (String)CompatUtils.invoke(mObj, null, METHOD_getLocale);
    }

    public String getMode() {
        return (String)CompatUtils.invoke(mObj, null, METHOD_getMode);
    }

    public String getExtraValue() {
        return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue);
    }

    public boolean containsExtraValueKey(String key) {
        return (Boolean)CompatUtils.invoke(mObj, null, METHOD_containsExtraValueKey, key);
    }

    public String getExtraValueOf(String key) {
        return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValueOf, key);
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof InputMethodSubtypeCompatWrapper) {
            InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o;
            return mObj.equals(subtype.getOriginalObject());
        } else {
            return mObj.equals(o);
        }
    }

}
+3 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.inputmethod.deprecated;

import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.deprecated.voice.FieldContext;
import com.android.inputmethod.deprecated.voice.Hints;
import com.android.inputmethod.deprecated.voice.SettingsUtil;
@@ -60,7 +61,6 @@ import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import java.util.ArrayList;
@@ -99,7 +99,7 @@ public class VoiceConnector implements VoiceInput.UiListener {
    private boolean mVoiceButtonOnPrimary;
    private boolean mVoiceInputHighlighted;

    private InputMethodManager mImm;
    private InputMethodManagerCompatWrapper mImm;
    private LatinIME mService;
    private AlertDialog mVoiceWarningDialog;
    private VoiceInput mVoiceInput;
@@ -123,7 +123,7 @@ public class VoiceConnector implements VoiceInput.UiListener {
    private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) {
        mService = service;
        mHandler = h;
        mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE);
        mImm = InputMethodManagerCompatWrapper.getInstance(service);
        mSubtypeSwitcher = SubtypeSwitcher.getInstance();
        if (VOICE_INSTALLED) {
            mVoiceInput = new VoiceInput(service, this);
Loading