InputConnectionCompatUtils.java revision 413aded6007032278120de0f43c4d520c269b53c
1413aded6007032278120de0f43c4d520c269b53cYohei Yukawa/*
2413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * Copyright (C) 2014 The Android Open Source Project
3413aded6007032278120de0f43c4d520c269b53cYohei Yukawa *
4413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * Licensed under the Apache License, Version 2.0 (the "License");
5413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * you may not use this file except in compliance with the License.
6413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * You may obtain a copy of the License at
7413aded6007032278120de0f43c4d520c269b53cYohei Yukawa *
8413aded6007032278120de0f43c4d520c269b53cYohei Yukawa *      http://www.apache.org/licenses/LICENSE-2.0
9413aded6007032278120de0f43c4d520c269b53cYohei Yukawa *
10413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * Unless required by applicable law or agreed to in writing, software
11413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * distributed under the License is distributed on an "AS IS" BASIS,
12413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * See the License for the specific language governing permissions and
14413aded6007032278120de0f43c4d520c269b53cYohei Yukawa * limitations under the License.
15413aded6007032278120de0f43c4d520c269b53cYohei Yukawa */
16413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
17413aded6007032278120de0f43c4d520c269b53cYohei Yukawapackage com.android.inputmethod.compat;
18413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
19413aded6007032278120de0f43c4d520c269b53cYohei Yukawaimport android.view.inputmethod.InputConnection;
20413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
21413aded6007032278120de0f43c4d520c269b53cYohei Yukawaimport java.lang.reflect.Constructor;
22413aded6007032278120de0f43c4d520c269b53cYohei Yukawaimport java.lang.reflect.Method;
23413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
24413aded6007032278120de0f43c4d520c269b53cYohei Yukawapublic final class InputConnectionCompatUtils {
25413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later.
26413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    private static Class<?> getCursorAnchorInfoRequestClass() {
27413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        try {
28413aded6007032278120de0f43c4d520c269b53cYohei Yukawa            return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest");
29413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        } catch (ClassNotFoundException e) {
30413aded6007032278120de0f43c4d520c269b53cYohei Yukawa            return null;
31413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        }
32413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    }
33413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
34413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    private static final Class<?> TYPE_CursorAnchorInfoRequest;
35413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    private static final Constructor<?> CONSTRUCTOR_CursorAnchorInfoRequest;
36413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    private static final Method METHOD_requestCursorAnchorInfo;
37413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    static {
38413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass();
39413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor(
40413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                TYPE_CursorAnchorInfoRequest, int.class, int.class);
41413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class,
42413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest);
43413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    }
44413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
45413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    public static boolean isRequestCursorAnchorInfoAvailable() {
46413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        return METHOD_requestCursorAnchorInfo != null &&
47413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                CONSTRUCTOR_CursorAnchorInfoRequest != null;
48413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    }
49413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
50413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    /**
51413aded6007032278120de0f43c4d520c269b53cYohei Yukawa     * A local copy of CursorAnchorInfoRequest.RESULT_NOT_HANDLED until the SDK becomes publicly
52413aded6007032278120de0f43c4d520c269b53cYohei Yukawa     * available.
53413aded6007032278120de0f43c4d520c269b53cYohei Yukawa     */
54413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    private final static int CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED = 0;
55413aded6007032278120de0f43c4d520c269b53cYohei Yukawa
56413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    public static int requestCursorAnchorInfo(final InputConnection inputConnection,
57413aded6007032278120de0f43c4d520c269b53cYohei Yukawa            final int type, final int flags) {
58413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        if (!isRequestCursorAnchorInfoAvailable()) {
59413aded6007032278120de0f43c4d520c269b53cYohei Yukawa             return CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED;
60413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        }
61413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        final Object requestObject = CompatUtils.newInstance(
62413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                CONSTRUCTOR_CursorAnchorInfoRequest, type, flags);
63413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        if (requestObject == null) {
64413aded6007032278120de0f43c4d520c269b53cYohei Yukawa            return CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED;
65413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        }
66413aded6007032278120de0f43c4d520c269b53cYohei Yukawa        return (Integer) CompatUtils.invoke(inputConnection,
67413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED /* defaultValue */,
68413aded6007032278120de0f43c4d520c269b53cYohei Yukawa                METHOD_requestCursorAnchorInfo, requestObject);
69413aded6007032278120de0f43c4d520c269b53cYohei Yukawa    }
70413aded6007032278120de0f43c4d520c269b53cYohei Yukawa}
71