blob: 085cdfcf946233f75de4b97770c027416f145bf6 [file] [log] [blame]
Yohei Yukawaa468d702018-10-21 11:42:34 -07001/*
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
17package com.android.internal.inputmethod;
18
lumarkd85e1582019-12-29 20:20:41 +080019import android.annotation.AnyThread;
20import android.annotation.NonNull;
Yohei Yukawaa468d702018-10-21 11:42:34 -070021import android.view.WindowManager;
22import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
23
Yohei Yukawa5e46a662018-10-31 14:31:35 -070024import java.util.StringJoiner;
25
Yohei Yukawaa468d702018-10-21 11:42:34 -070026/**
27 * Provides useful methods for debugging.
28 */
29public final class InputMethodDebug {
lumarkd85e1582019-12-29 20:20:41 +080030
Yohei Yukawaa468d702018-10-21 11:42:34 -070031 /**
32 * Not intended to be instantiated.
33 */
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 */
43 public static String startInputReasonToString(@StartInputReason int reason) {
44 switch (reason) {
Yohei Yukawa42194222018-10-21 20:14:40 -070045 case StartInputReason.UNSPECIFIED:
Yohei Yukawaa468d702018-10-21 11:42:34 -070046 return "UNSPECIFIED";
Yohei Yukawa42194222018-10-21 20:14:40 -070047 case StartInputReason.WINDOW_FOCUS_GAIN:
Yohei Yukawaa468d702018-10-21 11:42:34 -070048 return "WINDOW_FOCUS_GAIN";
Ming-Shin Lu48bfc312020-06-15 20:06:09 +080049 case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR:
50 return "WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR";
51 case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR:
52 return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR";
Yohei Yukawa42194222018-10-21 20:14:40 -070053 case StartInputReason.APP_CALLED_RESTART_INPUT_API:
Yohei Yukawaa468d702018-10-21 11:42:34 -070054 return "APP_CALLED_RESTART_INPUT_API";
Yohei Yukawa42194222018-10-21 20:14:40 -070055 case StartInputReason.CHECK_FOCUS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070056 return "CHECK_FOCUS";
Yohei Yukawa42194222018-10-21 20:14:40 -070057 case StartInputReason.BOUND_TO_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070058 return "BOUND_TO_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070059 case StartInputReason.UNBOUND_FROM_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070060 return "UNBOUND_FROM_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070061 case StartInputReason.ACTIVATED_BY_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070062 return "ACTIVATED_BY_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070063 case StartInputReason.DEACTIVATED_BY_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070064 return "DEACTIVATED_BY_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070065 case StartInputReason.SESSION_CREATED_BY_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070066 return "SESSION_CREATED_BY_IME";
67 default:
68 return "Unknown=" + reason;
69 }
70 }
71
72 /**
73 * Converts {@link UnbindReason} to {@link String} for debug logging.
74 *
75 * @param reason integer constant for {@link UnbindReason}.
76 * @return {@link String} message corresponds for the given {@code reason}.
77 */
78 public static String unbindReasonToString(@UnbindReason int reason) {
79 switch (reason) {
Yohei Yukawab7526452018-10-21 20:15:17 -070080 case UnbindReason.UNSPECIFIED:
Yohei Yukawaa468d702018-10-21 11:42:34 -070081 return "UNSPECIFIED";
Yohei Yukawab7526452018-10-21 20:15:17 -070082 case UnbindReason.SWITCH_CLIENT:
Yohei Yukawaa468d702018-10-21 11:42:34 -070083 return "SWITCH_CLIENT";
Yohei Yukawab7526452018-10-21 20:15:17 -070084 case UnbindReason.SWITCH_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070085 return "SWITCH_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070086 case UnbindReason.DISCONNECT_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070087 return "DISCONNECT_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070088 case UnbindReason.NO_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070089 return "NO_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070090 case UnbindReason.SWITCH_IME_FAILED:
Yohei Yukawaa468d702018-10-21 11:42:34 -070091 return "SWITCH_IME_FAILED";
Yohei Yukawab7526452018-10-21 20:15:17 -070092 case UnbindReason.SWITCH_USER:
Yohei Yukawaa468d702018-10-21 11:42:34 -070093 return "SWITCH_USER";
94 default:
95 return "Unknown=" + reason;
96 }
97 }
98
99 /**
100 * Converts {@link SoftInputModeFlags} to {@link String} for debug logging.
101 *
102 * @param softInputMode integer constant for {@link SoftInputModeFlags}.
103 * @return {@link String} message corresponds for the given {@code softInputMode}.
104 */
105 public static String softInputModeToString(@SoftInputModeFlags int softInputMode) {
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700106 final StringJoiner joiner = new StringJoiner("|");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700107 final int state = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
108 final int adjust = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
109 final boolean isForwardNav =
110 (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
111
112 switch (state) {
113 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700114 joiner.add("STATE_UNSPECIFIED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700115 break;
116 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700117 joiner.add("STATE_UNCHANGED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700118 break;
119 case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700120 joiner.add("STATE_HIDDEN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700121 break;
122 case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700123 joiner.add("STATE_ALWAYS_HIDDEN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700124 break;
125 case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700126 joiner.add("STATE_VISIBLE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700127 break;
128 case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700129 joiner.add("STATE_ALWAYS_VISIBLE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700130 break;
131 default:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700132 joiner.add("STATE_UNKNOWN(" + state + ")");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700133 break;
134 }
135
136 switch (adjust) {
137 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700138 joiner.add("ADJUST_UNSPECIFIED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700139 break;
140 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700141 joiner.add("ADJUST_RESIZE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700142 break;
143 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700144 joiner.add("ADJUST_PAN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700145 break;
146 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700147 joiner.add("ADJUST_NOTHING");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700148 break;
149 default:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700150 joiner.add("ADJUST_UNKNOWN(" + adjust + ")");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700151 break;
152 }
153
154 if (isForwardNav) {
155 // This is a special bit that is set by the system only during the window navigation.
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700156 joiner.add("IS_FORWARD_NAVIGATION");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700157 }
158
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700159 return joiner.setEmptyValue("(none)").toString();
Yohei Yukawaa468d702018-10-21 11:42:34 -0700160 }
Yohei Yukawa35fa6d52018-10-31 11:33:32 -0700161
162 /**
163 * Converts {@link StartInputFlags} to {@link String} for debug logging.
164 *
165 * @param startInputFlags integer constant for {@link StartInputFlags}.
166 * @return {@link String} message corresponds for the given {@code startInputFlags}.
167 */
168 public static String startInputFlagsToString(@StartInputFlags int startInputFlags) {
169 final StringJoiner joiner = new StringJoiner("|");
170 if ((startInputFlags & StartInputFlags.VIEW_HAS_FOCUS) != 0) {
171 joiner.add("VIEW_HAS_FOCUS");
172 }
173 if ((startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) {
174 joiner.add("IS_TEXT_EDITOR");
175 }
Yohei Yukawa35fa6d52018-10-31 11:33:32 -0700176 if ((startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0) {
177 joiner.add("INITIAL_CONNECTION");
178 }
179
180 return joiner.setEmptyValue("(none)").toString();
181 }
lumarkd85e1582019-12-29 20:20:41 +0800182
183
184 /**
185 * Converts {@link SoftInputShowHideReason} to {@link String} for history dump.
186 */
187 public static String softInputDisplayReasonToString(@SoftInputShowHideReason int reason) {
188 switch (reason) {
189 case SoftInputShowHideReason.SHOW_SOFT_INPUT:
190 return "SHOW_SOFT_INPUT";
191 case SoftInputShowHideReason.ATTACH_NEW_INPUT:
192 return "ATTACH_NEW_INPUT";
193 case SoftInputShowHideReason.SHOW_MY_SOFT_INPUT:
194 return "SHOW_MY_SOFT_INPUT";
195 case SoftInputShowHideReason.HIDE_SOFT_INPUT:
196 return "HIDE_SOFT_INPUT";
197 case SoftInputShowHideReason.HIDE_MY_SOFT_INPUT:
198 return "HIDE_MY_SOFT_INPUT";
199 case SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV:
200 return "SHOW_AUTO_EDITOR_FORWARD_NAV";
201 case SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV:
202 return "SHOW_STATE_VISIBLE_FORWARD_NAV";
203 case SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE:
204 return "SHOW_STATE_ALWAYS_VISIBLE";
205 case SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE:
206 return "SHOW_SETTINGS_ON_CHANGE";
207 case SoftInputShowHideReason.HIDE_SWITCH_USER:
208 return "HIDE_SWITCH_USER";
209 case SoftInputShowHideReason.HIDE_INVALID_USER:
210 return "HIDE_INVALID_USER";
211 case SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW:
212 return "HIDE_UNSPECIFIED_WINDOW";
213 case SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV:
214 return "HIDE_STATE_HIDDEN_FORWARD_NAV";
215 case SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE:
216 return "HIDE_ALWAYS_HIDDEN_STATE";
217 case SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND:
218 return "HIDE_RESET_SHELL_COMMAND";
219 case SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE:
220 return "HIDE_SETTINGS_ON_CHANGE";
221 case SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME:
222 return "HIDE_POWER_BUTTON_GO_HOME";
223 case SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED:
224 return "HIDE_DOCKED_STACK_ATTACHED";
225 case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION:
226 return "HIDE_RECENTS_ANIMATION";
227 default:
228 return "Unknown=" + reason;
229 }
230 }
231
232 /**
233 * Return a fixed size string of the object.
Anmol Gupta29f209d2020-03-11 11:34:46 -0700234 * TODO(b/151575861): Take & return with StringBuilder to make more memory efficient.
lumarkd85e1582019-12-29 20:20:41 +0800235 */
236 @NonNull
237 @AnyThread
238 public static String objToString(Object obj) {
239 if (obj == null) {
240 return "null";
241 }
242 StringBuilder sb = new StringBuilder(64);
243 sb.setLength(0);
244 sb.append(obj.getClass().getName());
245 sb.append("@");
246 sb.append(Integer.toHexString(obj.hashCode()));
247 return sb.toString();
248 }
Yohei Yukawaa468d702018-10-21 11:42:34 -0700249}