CursorAnchorInfoCompatWrapper.java revision 8c42bf54af9afe44eade9f0c36cfd2136d20e2f6
1/*
2 * Copyright (C) 2014 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
17package com.android.inputmethod.compat;
18
19import android.graphics.Matrix;
20import android.graphics.RectF;
21
22import com.android.inputmethod.annotations.UsedForTesting;
23
24@UsedForTesting
25public final class CursorAnchorInfoCompatWrapper {
26
27    /**
28     * The insertion marker or character bounds have at least one visible region.
29     */
30    public static final int FLAG_HAS_VISIBLE_REGION = 0x01;
31
32    /**
33     * The insertion marker or character bounds have at least one invisible (clipped) region.
34     */
35    public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
36
37    // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
38    private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
39    private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterRectMethod;
40    private static final CompatUtils.ToIntMethodWrapper sGetCharacterRectFlagsMethod;
41    private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
42    private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
43    private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
44    private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBottomMethod;
45    private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod;
46    private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod;
47    private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod;
48    private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod;
49
50    private static int COMPOSING_TEXT_START_DEFAULT = -1;
51    static {
52        sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
53                "android.view.inputmethod.CursorAnchorInfo");
54        sGetCharacterRectMethod = sCursorAnchorInfoClass.getMethod(
55                "getCharacterRect", (RectF)null, int.class);
56        sGetCharacterRectFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
57                "getCharacterRectFlags", 0, int.class);
58        sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
59                "getComposingText", (CharSequence)null);
60        sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
61                "getComposingTextStart", COMPOSING_TEXT_START_DEFAULT);
62        sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
63                "getInsertionMarkerBaseline", 0.0f);
64        sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
65                "getInsertionMarkerBottom", 0.0f);
66        sGetInsertionMarkerHorizontalMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
67                "getInsertionMarkerHorizontal", 0.0f);
68        sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
69                "getInsertionMarkerTop", 0.0f);
70        sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null);
71        sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
72                "getInsertionMarkerFlags", 0);
73    }
74
75    @UsedForTesting
76    public static boolean isAvailable() {
77        return sCursorAnchorInfoClass.exists();
78    }
79
80    private Object mInstance;
81
82    private CursorAnchorInfoCompatWrapper(final Object instance) {
83        mInstance = instance;
84    }
85
86    @UsedForTesting
87    public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
88        if (!isAvailable()) {
89            return new CursorAnchorInfoCompatWrapper(null);
90        }
91        return new CursorAnchorInfoCompatWrapper(instance);
92    }
93
94    private static final class FakeHolder {
95        static CursorAnchorInfoCompatWrapper sInstance = new CursorAnchorInfoCompatWrapper(null);
96    }
97
98    @UsedForTesting
99    public static CursorAnchorInfoCompatWrapper getFake() {
100        return FakeHolder.sInstance;
101    }
102
103    public CharSequence getComposingText() {
104        return sGetComposingTextMethod.invoke(mInstance);
105    }
106
107    public int getComposingTextStart() {
108        return sGetComposingTextStartMethod.invoke(mInstance);
109    }
110
111    public Matrix getMatrix() {
112        return sGetMatrixMethod.invoke(mInstance);
113    }
114
115    public RectF getCharacterRect(final int index) {
116        return sGetCharacterRectMethod.invoke(mInstance, index);
117    }
118
119    public int getCharacterRectFlags(final int index) {
120        return sGetCharacterRectFlagsMethod.invoke(mInstance, index);
121    }
122
123    public float getInsertionMarkerBaseline() {
124        return sGetInsertionMarkerBaselineMethod.invoke(mInstance);
125    }
126
127    public float getInsertionMarkerBottom() {
128        return sGetInsertionMarkerBottomMethod.invoke(mInstance);
129    }
130
131    public float getInsertionMarkerHorizontal() {
132        return sGetInsertionMarkerHorizontalMethod.invoke(mInstance);
133    }
134
135    public float getInsertionMarkerTop() {
136        return sGetInsertionMarkerTopMethod.invoke(mInstance);
137    }
138
139    public int getInsertionMarkerFlags() {
140        return sGetInsertionMarkerFlagsMethod.invoke(mInstance);
141    }
142}
143