• 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             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      */
unbindReasonToString(@nbindReason int reason)78     public static String unbindReasonToString(@UnbindReason int reason) {
79         switch (reason) {
80             case UnbindReason.UNSPECIFIED:
81                 return "UNSPECIFIED";
82             case UnbindReason.SWITCH_CLIENT:
83                 return "SWITCH_CLIENT";
84             case UnbindReason.SWITCH_IME:
85                 return "SWITCH_IME";
86             case UnbindReason.DISCONNECT_IME:
87                 return "DISCONNECT_IME";
88             case UnbindReason.NO_IME:
89                 return "NO_IME";
90             case UnbindReason.SWITCH_IME_FAILED:
91                 return "SWITCH_IME_FAILED";
92             case UnbindReason.SWITCH_USER:
93                 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      */
softInputModeToString(@oftInputModeFlags int softInputMode)105     public static String softInputModeToString(@SoftInputModeFlags int softInputMode) {
106         final StringJoiner joiner = new StringJoiner("|");
107         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:
114                 joiner.add("STATE_UNSPECIFIED");
115                 break;
116             case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
117                 joiner.add("STATE_UNCHANGED");
118                 break;
119             case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
120                 joiner.add("STATE_HIDDEN");
121                 break;
122             case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
123                 joiner.add("STATE_ALWAYS_HIDDEN");
124                 break;
125             case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
126                 joiner.add("STATE_VISIBLE");
127                 break;
128             case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
129                 joiner.add("STATE_ALWAYS_VISIBLE");
130                 break;
131             default:
132                 joiner.add("STATE_UNKNOWN(" + state + ")");
133                 break;
134         }
135 
136         switch (adjust) {
137             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
138                 joiner.add("ADJUST_UNSPECIFIED");
139                 break;
140             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
141                 joiner.add("ADJUST_RESIZE");
142                 break;
143             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN:
144                 joiner.add("ADJUST_PAN");
145                 break;
146             case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
147                 joiner.add("ADJUST_NOTHING");
148                 break;
149             default:
150                 joiner.add("ADJUST_UNKNOWN(" + adjust + ")");
151                 break;
152         }
153 
154         if (isForwardNav) {
155             // This is a special bit that is set by the system only during the window navigation.
156             joiner.add("IS_FORWARD_NAVIGATION");
157         }
158 
159         return joiner.setEmptyValue("(none)").toString();
160     }
161 
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      */
startInputFlagsToString(@tartInputFlags int startInputFlags)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         }
176         if ((startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0) {
177             joiner.add("INITIAL_CONNECTION");
178         }
179 
180         return joiner.setEmptyValue("(none)").toString();
181     }
182 
183 
184     /**
185      * Converts {@link SoftInputShowHideReason} to {@link String} for history dump.
186      */
softInputDisplayReasonToString(@oftInputShowHideReason int reason)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             case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR:
228                 return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR";
229             case SoftInputShowHideReason.HIDE_REMOVE_CLIENT:
230                 return "HIDE_REMOVE_CLIENT";
231             case SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY:
232                 return "SHOW_RESTORE_IME_VISIBILITY";
233             case SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT:
234                 return "SHOW_TOGGLE_SOFT_INPUT";
235             case SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT:
236                 return "HIDE_TOGGLE_SOFT_INPUT";
237             case SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API:
238                 return "SHOW_SOFT_INPUT_BY_INSETS_API";
239             default:
240                 return "Unknown=" + reason;
241         }
242     }
243 
244     /**
245      * Return a fixed size string of the object.
246      * TODO(b/151575861): Take & return with StringBuilder to make more memory efficient.
247      */
248     @NonNull
249     @AnyThread
objToString(Object obj)250     public static String objToString(Object obj) {
251         if (obj == null) {
252             return "null";
253         }
254         StringBuilder sb = new StringBuilder(64);
255         sb.setLength(0);
256         sb.append(obj.getClass().getName());
257         sb.append("@");
258         sb.append(Integer.toHexString(obj.hashCode()));
259         return sb.toString();
260     }
261 }
262