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.view.textservice.TextInfo;
20 
21 import com.android.inputmethod.annotations.UsedForTesting;
22 
23 import java.lang.reflect.Constructor;
24 import java.lang.reflect.Method;
25 
26 @UsedForTesting
27 public final class TextInfoCompatUtils {
28     // Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later.
29     private static final Method TEXT_INFO_GET_CHAR_SEQUENCE =
30             CompatUtils.getMethod(TextInfo.class, "getCharSequence");
31     private static final Constructor<?> TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE =
32             CompatUtils.getConstructor(TextInfo.class, CharSequence.class, int.class, int.class,
33                     int.class, int.class);
34 
35     @UsedForTesting
isCharSequenceSupported()36     public static boolean isCharSequenceSupported() {
37         return TEXT_INFO_GET_CHAR_SEQUENCE != null &&
38                 TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null;
39     }
40 
41     @UsedForTesting
newInstance(CharSequence charSequence, int start, int end, int cookie, int sequenceNumber)42     public static TextInfo newInstance(CharSequence charSequence, int start, int end, int cookie,
43             int sequenceNumber) {
44         if (TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null) {
45             return (TextInfo) CompatUtils.newInstance(TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE,
46                     charSequence, start, end, cookie, sequenceNumber);
47         }
48         return new TextInfo(charSequence.subSequence(start, end).toString(), cookie,
49                 sequenceNumber);
50     }
51 
52     /**
53      * Returns the result of {@link TextInfo#getCharSequence()} when available. Otherwise returns
54      * the result of {@link TextInfo#getText()} as fall back.
55      * @param textInfo the instance for which {@link TextInfo#getCharSequence()} or
56      * {@link TextInfo#getText()} is called.
57      * @return the result of {@link TextInfo#getCharSequence()} when available. Otherwise returns
58      * the result of {@link TextInfo#getText()} as fall back. If {@code textInfo} is {@code null},
59      * returns {@code null}.
60      */
61     @UsedForTesting
getCharSequenceOrString(final TextInfo textInfo)62     public static CharSequence getCharSequenceOrString(final TextInfo textInfo) {
63         final CharSequence defaultValue = (textInfo == null ? null : textInfo.getText());
64         return (CharSequence) CompatUtils.invoke(textInfo, defaultValue,
65                 TEXT_INFO_GET_CHAR_SEQUENCE);
66     }
67 }
68