blob: a660493f4613b81a64429546e0785ba53b385ce8 [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";
Yohei Yukawa42194222018-10-21 20:14:40 -070049 case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY:
Yohei Yukawaa468d702018-10-21 11:42:34 -070050 return "WINDOW_FOCUS_GAIN_REPORT_ONLY";
Yohei Yukawa42194222018-10-21 20:14:40 -070051 case StartInputReason.APP_CALLED_RESTART_INPUT_API:
Yohei Yukawaa468d702018-10-21 11:42:34 -070052 return "APP_CALLED_RESTART_INPUT_API";
Yohei Yukawa42194222018-10-21 20:14:40 -070053 case StartInputReason.CHECK_FOCUS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070054 return "CHECK_FOCUS";
Yohei Yukawa42194222018-10-21 20:14:40 -070055 case StartInputReason.BOUND_TO_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070056 return "BOUND_TO_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070057 case StartInputReason.UNBOUND_FROM_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070058 return "UNBOUND_FROM_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070059 case StartInputReason.ACTIVATED_BY_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070060 return "ACTIVATED_BY_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070061 case StartInputReason.DEACTIVATED_BY_IMMS:
Yohei Yukawaa468d702018-10-21 11:42:34 -070062 return "DEACTIVATED_BY_IMMS";
Yohei Yukawa42194222018-10-21 20:14:40 -070063 case StartInputReason.SESSION_CREATED_BY_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070064 return "SESSION_CREATED_BY_IME";
65 default:
66 return "Unknown=" + reason;
67 }
68 }
69
70 /**
71 * Converts {@link UnbindReason} to {@link String} for debug logging.
72 *
73 * @param reason integer constant for {@link UnbindReason}.
74 * @return {@link String} message corresponds for the given {@code reason}.
75 */
76 public static String unbindReasonToString(@UnbindReason int reason) {
77 switch (reason) {
Yohei Yukawab7526452018-10-21 20:15:17 -070078 case UnbindReason.UNSPECIFIED:
Yohei Yukawaa468d702018-10-21 11:42:34 -070079 return "UNSPECIFIED";
Yohei Yukawab7526452018-10-21 20:15:17 -070080 case UnbindReason.SWITCH_CLIENT:
Yohei Yukawaa468d702018-10-21 11:42:34 -070081 return "SWITCH_CLIENT";
Yohei Yukawab7526452018-10-21 20:15:17 -070082 case UnbindReason.SWITCH_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070083 return "SWITCH_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070084 case UnbindReason.DISCONNECT_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070085 return "DISCONNECT_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070086 case UnbindReason.NO_IME:
Yohei Yukawaa468d702018-10-21 11:42:34 -070087 return "NO_IME";
Yohei Yukawab7526452018-10-21 20:15:17 -070088 case UnbindReason.SWITCH_IME_FAILED:
Yohei Yukawaa468d702018-10-21 11:42:34 -070089 return "SWITCH_IME_FAILED";
Yohei Yukawab7526452018-10-21 20:15:17 -070090 case UnbindReason.SWITCH_USER:
Yohei Yukawaa468d702018-10-21 11:42:34 -070091 return "SWITCH_USER";
92 default:
93 return "Unknown=" + reason;
94 }
95 }
96
97 /**
98 * Converts {@link SoftInputModeFlags} to {@link String} for debug logging.
99 *
100 * @param softInputMode integer constant for {@link SoftInputModeFlags}.
101 * @return {@link String} message corresponds for the given {@code softInputMode}.
102 */
103 public static String softInputModeToString(@SoftInputModeFlags int softInputMode) {
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700104 final StringJoiner joiner = new StringJoiner("|");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700105 final int state = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
106 final int adjust = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
107 final boolean isForwardNav =
108 (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
109
110 switch (state) {
111 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700112 joiner.add("STATE_UNSPECIFIED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700113 break;
114 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700115 joiner.add("STATE_UNCHANGED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700116 break;
117 case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700118 joiner.add("STATE_HIDDEN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700119 break;
120 case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700121 joiner.add("STATE_ALWAYS_HIDDEN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700122 break;
123 case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700124 joiner.add("STATE_VISIBLE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700125 break;
126 case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700127 joiner.add("STATE_ALWAYS_VISIBLE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700128 break;
129 default:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700130 joiner.add("STATE_UNKNOWN(" + state + ")");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700131 break;
132 }
133
134 switch (adjust) {
135 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700136 joiner.add("ADJUST_UNSPECIFIED");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700137 break;
138 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700139 joiner.add("ADJUST_RESIZE");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700140 break;
141 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700142 joiner.add("ADJUST_PAN");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700143 break;
144 case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700145 joiner.add("ADJUST_NOTHING");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700146 break;
147 default:
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700148 joiner.add("ADJUST_UNKNOWN(" + adjust + ")");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700149 break;
150 }
151
152 if (isForwardNav) {
153 // This is a special bit that is set by the system only during the window navigation.
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700154 joiner.add("IS_FORWARD_NAVIGATION");
Yohei Yukawaa468d702018-10-21 11:42:34 -0700155 }
156
Yohei Yukawa5e46a662018-10-31 14:31:35 -0700157 return joiner.setEmptyValue("(none)").toString();
Yohei Yukawaa468d702018-10-21 11:42:34 -0700158 }
Yohei Yukawa35fa6d52018-10-31 11:33:32 -0700159
160 /**
161 * Converts {@link StartInputFlags} to {@link String} for debug logging.
162 *
163 * @param startInputFlags integer constant for {@link StartInputFlags}.
164 * @return {@link String} message corresponds for the given {@code startInputFlags}.
165 */
166 public static String startInputFlagsToString(@StartInputFlags int startInputFlags) {
167 final StringJoiner joiner = new StringJoiner("|");
168 if ((startInputFlags & StartInputFlags.VIEW_HAS_FOCUS) != 0) {
169 joiner.add("VIEW_HAS_FOCUS");
170 }
171 if ((startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) {
172 joiner.add("IS_TEXT_EDITOR");
173 }
Yohei Yukawa35fa6d52018-10-31 11:33:32 -0700174 if ((startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0) {
175 joiner.add("INITIAL_CONNECTION");
176 }
177
178 return joiner.setEmptyValue("(none)").toString();
179 }
lumarkd85e1582019-12-29 20:20:41 +0800180
181
182 /**
183 * Converts {@link SoftInputShowHideReason} to {@link String} for history dump.
184 */
185 public static String softInputDisplayReasonToString(@SoftInputShowHideReason int reason) {
186 switch (reason) {
187 case SoftInputShowHideReason.SHOW_SOFT_INPUT:
188 return "SHOW_SOFT_INPUT";
189 case SoftInputShowHideReason.ATTACH_NEW_INPUT:
190 return "ATTACH_NEW_INPUT";
191 case SoftInputShowHideReason.SHOW_MY_SOFT_INPUT:
192 return "SHOW_MY_SOFT_INPUT";
193 case SoftInputShowHideReason.HIDE_SOFT_INPUT:
194 return "HIDE_SOFT_INPUT";
195 case SoftInputShowHideReason.HIDE_MY_SOFT_INPUT:
196 return "HIDE_MY_SOFT_INPUT";
197 case SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV:
198 return "SHOW_AUTO_EDITOR_FORWARD_NAV";
199 case SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV:
200 return "SHOW_STATE_VISIBLE_FORWARD_NAV";
201 case SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE:
202 return "SHOW_STATE_ALWAYS_VISIBLE";
203 case SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE:
204 return "SHOW_SETTINGS_ON_CHANGE";
205 case SoftInputShowHideReason.HIDE_SWITCH_USER:
206 return "HIDE_SWITCH_USER";
207 case SoftInputShowHideReason.HIDE_INVALID_USER:
208 return "HIDE_INVALID_USER";
209 case SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW:
210 return "HIDE_UNSPECIFIED_WINDOW";
211 case SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV:
212 return "HIDE_STATE_HIDDEN_FORWARD_NAV";
213 case SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE:
214 return "HIDE_ALWAYS_HIDDEN_STATE";
215 case SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND:
216 return "HIDE_RESET_SHELL_COMMAND";
217 case SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE:
218 return "HIDE_SETTINGS_ON_CHANGE";
219 case SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME:
220 return "HIDE_POWER_BUTTON_GO_HOME";
221 case SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED:
222 return "HIDE_DOCKED_STACK_ATTACHED";
223 case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION:
224 return "HIDE_RECENTS_ANIMATION";
225 default:
226 return "Unknown=" + reason;
227 }
228 }
229
230 /**
231 * Return a fixed size string of the object.
Anmol Gupta29f209d2020-03-11 11:34:46 -0700232 * TODO(b/151575861): Take & return with StringBuilder to make more memory efficient.
lumarkd85e1582019-12-29 20:20:41 +0800233 */
234 @NonNull
235 @AnyThread
236 public static String objToString(Object obj) {
237 if (obj == null) {
238 return "null";
239 }
240 StringBuilder sb = new StringBuilder(64);
241 sb.setLength(0);
242 sb.append(obj.getClass().getName());
243 sb.append("@");
244 sb.append(Integer.toHexString(obj.hashCode()));
245 return sb.toString();
246 }
Yohei Yukawaa468d702018-10-21 11:42:34 -0700247}