1 /*
2  * Copyright (C) 2022 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 android.view.inputmethod;
18 
19 import android.annotation.IntDef;
20 import android.annotation.Nullable;
21 import android.graphics.RectF;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.util.concurrent.Executor;
26 import java.util.function.Consumer;
27 
28 /**
29  * The object that holds the result of the
30  * {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} call.
31  *
32  * @see InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)
33  */
34 public final class TextBoundsInfoResult {
35     private final int mResultCode;
36     private final TextBoundsInfo mTextBoundsInfo;
37 
38     /**
39      * Result for {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} when the
40      * editor doesn't implement the method.
41      */
42     public static final int CODE_UNSUPPORTED = 0;
43 
44     /**
45      * Result for {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} when the
46      * editor successfully returns a {@link TextBoundsInfo}.
47      */
48     public static final int CODE_SUCCESS = 1;
49 
50     /**
51      * Result for {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} when the
52      * request failed. This result code is returned when the editor can't provide a valid
53      * {@link TextBoundsInfo}. (e.g. The editor view is not laid out.)
54      */
55     public static final int CODE_FAILED = 2;
56 
57     /**
58      * Result for {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} when the
59      * request is cancelled. This happens when the {@link InputConnection} is or becomes
60      * invalidated while requesting the
61      * {@link TextBoundsInfo}, for example because a new {@code InputConnection} was started, or
62      * due to {@link InputMethodManager#invalidateInput}.
63      */
64     public static final int CODE_CANCELLED = 3;
65 
66     /** @hide */
67     @IntDef(prefix = { "CODE_" }, value = {
68             CODE_UNSUPPORTED,
69             CODE_SUCCESS,
70             CODE_FAILED,
71             CODE_CANCELLED,
72     })
73     @Retention(RetentionPolicy.SOURCE)
74     public @interface ResultCode {}
75 
76     /**
77      * Create a {@link TextBoundsInfoResult} object with no {@link TextBoundsInfo}.
78      * The given {@code resultCode} can't be {@link #CODE_SUCCESS}.
79      * @param resultCode the result code of the
80      * {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} call.
81      */
TextBoundsInfoResult(@esultCode int resultCode)82     public TextBoundsInfoResult(@ResultCode int resultCode) {
83         this(resultCode, null);
84     }
85 
86     /**
87      * Create a {@link TextBoundsInfoResult} object.
88      *
89      * @param resultCode the result code of the
90      * {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} call.
91      * @param textBoundsInfo the returned {@link TextBoundsInfo} of the
92      * {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} call. It can't be
93      *                       null if the {@code resultCode} is {@link #CODE_SUCCESS}.
94      *
95      * @throws IllegalStateException if the resultCode is
96      * {@link #CODE_SUCCESS} but the given {@code textBoundsInfo}
97      * is null.
98      */
TextBoundsInfoResult(@esultCode int resultCode, @Nullable TextBoundsInfo textBoundsInfo)99     public TextBoundsInfoResult(@ResultCode int resultCode,
100             @Nullable TextBoundsInfo textBoundsInfo) {
101         if (resultCode == CODE_SUCCESS && textBoundsInfo == null) {
102             throw new IllegalStateException("TextBoundsInfo must be provided when the resultCode "
103                     + "is CODE_SUCCESS.");
104         }
105         mResultCode = resultCode;
106         mTextBoundsInfo = textBoundsInfo;
107     }
108 
109     /**
110      * Return the result code of the
111      * {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)} call.
112      * Its value is one of the {@link #CODE_UNSUPPORTED}, {@link #CODE_SUCCESS},
113      * {@link #CODE_FAILED} and {@link #CODE_CANCELLED}.
114      */
115     @ResultCode
getResultCode()116     public int getResultCode() {
117         return mResultCode;
118     }
119 
120     /**
121      * Return the {@link TextBoundsInfo} provided by the editor. It is non-null if the
122      * {@code resultCode} is {@link #CODE_SUCCESS}.
123      * Otherwise, it can be null in the following conditions:
124      * <ul>
125      *    <li>the editor doesn't support
126      *      {@link InputConnection#requestTextBoundsInfo(RectF, Executor, Consumer)}.</li>
127      *    <li>the editor doesn't have the text bounds information at the moment. (e.g. the editor
128      *    view is not laid out yet.) </li>
129      *    <li> the {@link InputConnection} is or become inactive during the request. </li>
130      * <ul/>
131      */
132     @Nullable
getTextBoundsInfo()133     public TextBoundsInfo getTextBoundsInfo() {
134         return  mTextBoundsInfo;
135     }
136 }
137