• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.internal.inputmethod;
18 
19 import android.annotation.AnyThread;
20 import android.annotation.NonNull;
21 import android.view.WindowManager;
22 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
23 
24 import java.util.StringJoiner;
25 
26 /**
27  * Provides useful methods for debugging.
28  */
29 public final class InputMethodDebug {
30 
31     /**
32      * Not intended to be instantiated.
33      */
InputMethodDebug()34     private InputMethodDebug() {
35     }
36 
37     /**
38      * Converts {@link StartInputReason} to {@link String} for debug logging.
39      *
40      * @param reason integer constant for {@link StartInputReason}.
41      * @return {@link String} message corresponds for the given {@code reason}.
42      */
startInputReasonToString(@tartInputReason int reason)43     public static String startInputReasonToString(@StartInputReason int reason) {
44         switch (reason) {
45             case StartInputReason.UNSPECIFIED:
46                 return "UNSPECIFIED";
47             case StartInputReason.WINDOW_FOCUS_GAIN:
48                 return "WINDOW_FOCUS_GAIN";
49             case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION:
50                 return "WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION";
51             case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION:
52                 return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION";
53             case StartInputReason.APP_CALLED_RESTART_INPUT_API:
54                 return "APP_CALLED_RESTART_INPUT_API";
55             case StartInputReason.CHECK_FOCUS:
56                 return "CHECK_FOCUS";
57             case StartInputReason.BOUND_TO_IMMS:
58                 return "BOUND_TO_IMMS";
59             case StartInputReason.UNBOUND_FROM_IMMS:
60                 return "UNBOUND_FROM_IMMS";
61             case StartInputReason.ACTIVATED_BY_IMMS:
62                 return "ACTIVATED_BY_IMMS";
63             case StartInputReason.DEACTIVATED_BY_IMMS:
64                 return "DEACTIVATED_BY_IMMS";
65             case StartInputReason.SESSION_CREATED_BY_IME:
66                 return "SESSION_CREATED_BY_IME";
67             case StartInputReason.BOUND_ACCESSIBILITY_SESSION_TO_IMMS:
68                 return "BOUND_ACCESSIBILITY_SESSION_TO_IMMS";
69             default:
70                 return "Unknown=" + reason;
71         }
72     }
73 
74     /**
75      * Converts {@link UnbindReason} to {@link String} for debug logging.
76      *
77      * @param reason integer constant for {@link UnbindReason}.
78      * @return {@link String} message corresponds for the given {@code reason}.
79      */
unbindReasonToString(@nbindReason int reason)80     public static String unbindReasonToString(@UnbindReason int reason) {
81         switch (reason) {
82             case UnbindReason.UNSPECIFIED:
83                 return "UNSPECIFIED";
84             case UnbindReason.SWITCH_CLIENT:
85                 return "SWITCH_CLIENT";
86             case UnbindReason.SWITCH_IME:
87                 return "SWITCH_IME";
88             case UnbindReason.DISCONNECT_IME:
89                 return "DISCONNECT_IME";
90             case UnbindReason.NO_IME:
91                 return "NO_IME";
92             case UnbindReason.SWITCH_IME_FAILED:
93                 return "SWITCH_IME_FAILED";
94             case UnbindReason.SWITCH_USER:
95                 return "SWITCH_USER";
96             case UnbindReason.ACCESSIBILITY_SERVICE_DISABLED:
97                 return "ACCESSIBILITY_SERVICE_DISABLED";
98             default:
99                 return "Unknown=" + reason;
100         }
101     }
102 
103     /**
104      * Converts {@link SoftInputModeFlags} to {@link String} for debug logging.
105      *
106      * @param softInputMode integer constant for {@link SoftInputModeFlags}.
107      * @return {@link String} message corresponds for the given {@code softInputMode}.
108      */
softInputModeToString(@oftInputModeFlags int softInputMode)109     public static String softInputModeToString(@SoftInputModeFlags int softInputMode) {
110         final StringJoiner joiner = new StringJoiner("|");
111         final int state = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
112         final int adjust = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
113         final boolean isForwardNav =
114                 (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
115 
116         switch (state) {
117             case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
118                 joiner.add("STATE_UNSPECIFIED");
119                 break;
120             case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
121                 joiner.add("STATE_UNCHANGED");
122                 break;
123             case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
124                 joiner.add("STATE_HIDDEN");
125                 break;
126             case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
127                 joiner.add("STATE_ALWAYS_HIDDEN");
128                 break;
129             case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
130                 joiner.add("STATE_VISIBLE");
131                 break;
132             case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
133                 joiner.add("STATE_ALWAYS_VISIBLE");
134                 break;
135             default:
136                 joiner.add("STATE_UNKNOWN(" + state + ")");
137                 break;
138         }
139 
140         switch (adjust) {
141             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
142                 joiner.add("ADJUST_UNSPECIFIED");
143                 break;
144             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
145                 joiner.add("ADJUST_RESIZE");
146                 break;
147             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN:
148                 joiner.add("ADJUST_PAN");
149                 break;
150             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
151                 joiner.add("ADJUST_NOTHING");
152                 break;
153             default:
154                 joiner.add("ADJUST_UNKNOWN(" + adjust + ")");
155                 break;
156         }
157 
158         if (isForwardNav) {
159             // This is a special bit that is set by the system only during the window navigation.
160             joiner.add("IS_FORWARD_NAVIGATION");
161         }
162 
163         return joiner.setEmptyValue("(none)").toString();
164     }
165 
166     /**
167      * Converts {@link StartInputFlags} to {@link String} for debug logging.
168      *
169      * @param startInputFlags integer constant for {@link StartInputFlags}.
170      * @return {@link String} message corresponds for the given {@code startInputFlags}.
171      */
startInputFlagsToString(@tartInputFlags int startInputFlags)172     public static String startInputFlagsToString(@StartInputFlags int startInputFlags) {
173         final StringJoiner joiner = new StringJoiner("|");
174         if ((startInputFlags & StartInputFlags.VIEW_HAS_FOCUS) != 0) {
175             joiner.add("VIEW_HAS_FOCUS");
176         }
177         if ((startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) {
178             joiner.add("IS_TEXT_EDITOR");
179         }
180         if ((startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0) {
181             joiner.add("INITIAL_CONNECTION");
182         }
183 
184         return joiner.setEmptyValue("(none)").toString();
185     }
186 
187 
188     /**
189      * Converts {@link SoftInputShowHideReason} to {@link String} for history dump.
190      */
softInputDisplayReasonToString(@oftInputShowHideReason int reason)191     public static String softInputDisplayReasonToString(@SoftInputShowHideReason int reason) {
192         switch (reason) {
193             case SoftInputShowHideReason.SHOW_SOFT_INPUT:
194                 return "SHOW_SOFT_INPUT";
195             case SoftInputShowHideReason.ATTACH_NEW_INPUT:
196                 return "ATTACH_NEW_INPUT";
197             case SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME:
198                 return "SHOW_SOFT_INPUT_FROM_IME";
199             case SoftInputShowHideReason.HIDE_SOFT_INPUT:
200                 return "HIDE_SOFT_INPUT";
201             case SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME:
202                 return "HIDE_SOFT_INPUT_FROM_IME";
203             case SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV:
204                 return "SHOW_AUTO_EDITOR_FORWARD_NAV";
205             case SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV:
206                 return "SHOW_STATE_VISIBLE_FORWARD_NAV";
207             case SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE:
208                 return "SHOW_STATE_ALWAYS_VISIBLE";
209             case SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE:
210                 return "SHOW_SETTINGS_ON_CHANGE";
211             case SoftInputShowHideReason.HIDE_SWITCH_USER:
212                 return "HIDE_SWITCH_USER";
213             case SoftInputShowHideReason.HIDE_INVALID_USER:
214                 return "HIDE_INVALID_USER";
215             case SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW:
216                 return "HIDE_UNSPECIFIED_WINDOW";
217             case SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV:
218                 return "HIDE_STATE_HIDDEN_FORWARD_NAV";
219             case SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE:
220                 return "HIDE_ALWAYS_HIDDEN_STATE";
221             case SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND:
222                 return "HIDE_RESET_SHELL_COMMAND";
223             case SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE:
224                 return "HIDE_SETTINGS_ON_CHANGE";
225             case SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME:
226                 return "HIDE_POWER_BUTTON_GO_HOME";
227             case SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED:
228                 return "HIDE_DOCKED_STACK_ATTACHED";
229             case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION:
230                 return "HIDE_RECENTS_ANIMATION";
231             case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR:
232                 return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR";
233             case SoftInputShowHideReason.HIDE_REMOVE_CLIENT:
234                 return "HIDE_REMOVE_CLIENT";
235             case SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY:
236                 return "SHOW_RESTORE_IME_VISIBILITY";
237             case SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT:
238                 return "SHOW_TOGGLE_SOFT_INPUT";
239             case SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT:
240                 return "HIDE_TOGGLE_SOFT_INPUT";
241             case SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API:
242                 return "SHOW_SOFT_INPUT_BY_INSETS_API";
243             case SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE:
244                 return "HIDE_DISPLAY_IME_POLICY_HIDE";
245             case SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API:
246                 return "HIDE_SOFT_INPUT_BY_INSETS_API";
247             case SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_BACK_KEY:
248                 return "HIDE_SOFT_INPUT_BY_BACK_KEY";
249             case SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT:
250                 return "HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT";
251             case SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED:
252                 return "HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED";
253             case SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION:
254                 return "HIDE_SOFT_INPUT_IMM_DEPRECATION";
255             default:
256                 return "Unknown=" + reason;
257         }
258     }
259 
260     /**
261      * Return a fixed size string of the object.
262      * TODO(b/151575861): Take & return with StringBuilder to make more memory efficient.
263      */
264     @NonNull
265     @AnyThread
objToString(Object obj)266     public static String objToString(Object obj) {
267         if (obj == null) {
268             return "null";
269         }
270         StringBuilder sb = new StringBuilder(64);
271         sb.setLength(0);
272         sb.append(obj.getClass().getName());
273         sb.append("@");
274         sb.append(Integer.toHexString(obj.hashCode()));
275         return sb.toString();
276     }
277 }
278