• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.inputmethod.compat;
18 
19 import android.graphics.Matrix;
20 import android.graphics.RectF;
21 
22 import com.android.inputmethod.annotations.UsedForTesting;
23 
24 @UsedForTesting
25 public 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     /**
38      * The insertion marker or character bounds is placed at right-to-left (RTL) character.
39      */
40     public static final int FLAG_IS_RTL = 0x04;
41 
42     // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
43     private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
44     private static final CompatUtils.ToIntMethodWrapper sGetSelectionStartMethod;
45     private static final CompatUtils.ToIntMethodWrapper sGetSelectionEndMethod;
46     private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterBoundsMethod;
47     private static final CompatUtils.ToIntMethodWrapper sGetCharacterBoundsFlagsMethod;
48     private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
49     private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
50     private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
51     private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBottomMethod;
52     private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod;
53     private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod;
54     private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod;
55     private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod;
56 
57     private static int INVALID_TEXT_INDEX = -1;
58     static {
59         sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
60                 "android.view.inputmethod.CursorAnchorInfo");
61         sGetSelectionStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
62                 "getSelectionStart", INVALID_TEXT_INDEX);
63         sGetSelectionEndMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
64                 "getSelectionEnd", INVALID_TEXT_INDEX);
65         sGetCharacterBoundsMethod = sCursorAnchorInfoClass.getMethod(
66                 "getCharacterBounds", (RectF)null, int.class);
67         sGetCharacterBoundsFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
68                 "getCharacterBoundsFlags", 0, int.class);
69         sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
70                 "getComposingText", (CharSequence)null);
71         sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
72                 "getComposingTextStart", INVALID_TEXT_INDEX);
73         sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
74                 "getInsertionMarkerBaseline", 0.0f);
75         sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
76                 "getInsertionMarkerBottom", 0.0f);
77         sGetInsertionMarkerHorizontalMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
78                 "getInsertionMarkerHorizontal", 0.0f);
79         sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
80                 "getInsertionMarkerTop", 0.0f);
81         sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null);
82         sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
83                 "getInsertionMarkerFlags", 0);
84     }
85 
86     @UsedForTesting
isAvailable()87     public boolean isAvailable() {
88         return sCursorAnchorInfoClass.exists() && mInstance != null;
89     }
90 
91     private Object mInstance;
92 
CursorAnchorInfoCompatWrapper(final Object instance)93     private CursorAnchorInfoCompatWrapper(final Object instance) {
94         mInstance = instance;
95     }
96 
97     @UsedForTesting
fromObject(final Object instance)98     public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
99         if (!sCursorAnchorInfoClass.exists()) {
100             return new CursorAnchorInfoCompatWrapper(null);
101         }
102         return new CursorAnchorInfoCompatWrapper(instance);
103     }
104 
105     private static final class FakeHolder {
106         static CursorAnchorInfoCompatWrapper sInstance = new CursorAnchorInfoCompatWrapper(null);
107     }
108 
109     @UsedForTesting
getFake()110     public static CursorAnchorInfoCompatWrapper getFake() {
111         return FakeHolder.sInstance;
112     }
113 
getSelectionStart()114     public int getSelectionStart() {
115         return sGetSelectionStartMethod.invoke(mInstance);
116     }
117 
getSelectionEnd()118     public int getSelectionEnd() {
119         return sGetSelectionEndMethod.invoke(mInstance);
120     }
121 
getComposingText()122     public CharSequence getComposingText() {
123         return sGetComposingTextMethod.invoke(mInstance);
124     }
125 
getComposingTextStart()126     public int getComposingTextStart() {
127         return sGetComposingTextStartMethod.invoke(mInstance);
128     }
129 
getMatrix()130     public Matrix getMatrix() {
131         return sGetMatrixMethod.invoke(mInstance);
132     }
133 
getCharacterBounds(final int index)134     public RectF getCharacterBounds(final int index) {
135         return sGetCharacterBoundsMethod.invoke(mInstance, index);
136     }
137 
getCharacterBoundsFlags(final int index)138     public int getCharacterBoundsFlags(final int index) {
139         return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index);
140     }
141 
getInsertionMarkerBaseline()142     public float getInsertionMarkerBaseline() {
143         return sGetInsertionMarkerBaselineMethod.invoke(mInstance);
144     }
145 
getInsertionMarkerBottom()146     public float getInsertionMarkerBottom() {
147         return sGetInsertionMarkerBottomMethod.invoke(mInstance);
148     }
149 
getInsertionMarkerHorizontal()150     public float getInsertionMarkerHorizontal() {
151         return sGetInsertionMarkerHorizontalMethod.invoke(mInstance);
152     }
153 
getInsertionMarkerTop()154     public float getInsertionMarkerTop() {
155         return sGetInsertionMarkerTopMethod.invoke(mInstance);
156     }
157 
getInsertionMarkerFlags()158     public int getInsertionMarkerFlags() {
159         return sGetInsertionMarkerFlagsMethod.invoke(mInstance);
160     }
161 }
162