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 com.example.android.sampleinputmethodaccessibilityservice; 18 19 import android.view.inputmethod.EditorInfo; 20 21 import androidx.annotation.NonNull; 22 import androidx.annotation.Nullable; 23 24 final class EditorInfoUtil { 25 /** 26 * Not intended to be instantiated. 27 */ EditorInfoUtil()28 private EditorInfoUtil() { 29 } 30 dump(@ullable EditorInfo editorInfo)31 static String dump(@Nullable EditorInfo editorInfo) { 32 if (editorInfo == null) { 33 return "null"; 34 } 35 final StringBuilder sb = new StringBuilder(); 36 dump(sb, editorInfo); 37 return sb.toString(); 38 } 39 dump(@onNull StringBuilder sb, @NonNull EditorInfo editorInfo)40 static void dump(@NonNull StringBuilder sb, @NonNull EditorInfo editorInfo) { 41 sb.append("packageName=").append(editorInfo.packageName).append("\n") 42 .append("inputType="); 43 dumpInputType(sb, editorInfo.inputType); 44 sb.append("\n"); 45 sb.append("imeOptions="); 46 dumpImeOptions(sb, editorInfo.imeOptions); 47 sb.append("\n"); 48 sb.append("initialSelection=(").append(editorInfo.initialSelStart) 49 .append(",").append(editorInfo.initialSelEnd).append(")"); 50 sb.append("\n"); 51 sb.append("initialCapsMode="); 52 dumpCapsMode(sb, editorInfo.initialCapsMode); 53 sb.append("\n"); 54 } 55 dumpInputType(@onNull StringBuilder sb, int inputType)56 static void dumpInputType(@NonNull StringBuilder sb, int inputType) { 57 final int inputClass = inputType & EditorInfo.TYPE_MASK_CLASS; 58 final int inputVariation = inputType & EditorInfo.TYPE_MASK_VARIATION; 59 final int inputFlags = inputType & EditorInfo.TYPE_MASK_FLAGS; 60 switch (inputClass) { 61 case EditorInfo.TYPE_NULL: 62 sb.append("Null"); 63 break; 64 case EditorInfo.TYPE_CLASS_TEXT: { 65 sb.append("Text"); 66 switch (inputVariation) { 67 case EditorInfo.TYPE_TEXT_VARIATION_NORMAL: 68 break; 69 case EditorInfo.TYPE_TEXT_VARIATION_URI: 70 sb.append(":URI"); 71 break; 72 case EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS: 73 sb.append(":EMAIL_ADDRESS"); 74 break; 75 case EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT: 76 sb.append(":EMAIL_SUBJECT"); 77 break; 78 case EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE: 79 sb.append(":SHORT_MESSAGE"); 80 break; 81 case EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE: 82 sb.append(":LONG_MESSAGE"); 83 break; 84 case EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME: 85 sb.append(":PERSON_NAME"); 86 break; 87 case EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS: 88 sb.append(":POSTAL_ADDRESS"); 89 break; 90 case EditorInfo.TYPE_TEXT_VARIATION_PASSWORD: 91 sb.append(":PASSWORD"); 92 break; 93 case EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD: 94 sb.append(":VISIBLE_PASSWORD"); 95 break; 96 case EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT: 97 sb.append(":WEB_EDIT_TEXT"); 98 break; 99 case EditorInfo.TYPE_TEXT_VARIATION_FILTER: 100 sb.append(":FILTER"); 101 break; 102 case EditorInfo.TYPE_TEXT_VARIATION_PHONETIC: 103 sb.append(":PHONETIC"); 104 break; 105 case EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS: 106 sb.append(":WEB_EMAIL_ADDRESS"); 107 break; 108 case EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD: 109 sb.append(":WEB_PASSWORD"); 110 break; 111 default: 112 sb.append(":UNKNOWN=").append(inputVariation); 113 break; 114 } 115 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) { 116 sb.append("|CAP_CHARACTERS"); 117 } 118 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS) != 0) { 119 sb.append("|CAP_WORDS"); 120 } 121 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) { 122 sb.append("|CAP_SENTENCES"); 123 } 124 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0) { 125 sb.append("|AUTO_CORRECT"); 126 } 127 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { 128 sb.append("|AUTO_COMPLETE"); 129 } 130 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) != 0) { 131 sb.append("|MULTI_LINE"); 132 } 133 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { 134 sb.append("|NO_SUGGESTIONS"); 135 } 136 if ((inputFlags & EditorInfo.TYPE_TEXT_FLAG_ENABLE_TEXT_CONVERSION_SUGGESTIONS) 137 != 0) { 138 sb.append("|ENABLE_TEXT_CONVERSION_SUGGESTIONS"); 139 } 140 break; 141 } 142 case EditorInfo.TYPE_CLASS_NUMBER: { 143 sb.append("Number"); 144 switch (inputVariation) { 145 case EditorInfo.TYPE_NUMBER_VARIATION_NORMAL: 146 sb.append(":NORMAL"); 147 break; 148 case EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD: 149 sb.append(":PASSWORD"); 150 break; 151 default: 152 sb.append(":UNKNOWN=").append(inputVariation); 153 break; 154 } 155 if ((inputFlags & EditorInfo.TYPE_NUMBER_FLAG_SIGNED) != 0) { 156 sb.append("|SIGNED"); 157 } 158 if ((inputFlags & EditorInfo.TYPE_NUMBER_FLAG_DECIMAL) != 0) { 159 sb.append("|DECIMAL"); 160 } 161 break; 162 } 163 case EditorInfo.TYPE_CLASS_PHONE: 164 sb.append("Phone"); 165 break; 166 case EditorInfo.TYPE_CLASS_DATETIME: { 167 sb.append("DateTime"); 168 switch (inputVariation) { 169 case EditorInfo.TYPE_DATETIME_VARIATION_NORMAL: 170 sb.append(":NORMAL"); 171 break; 172 case EditorInfo.TYPE_DATETIME_VARIATION_DATE: 173 sb.append(":DATE"); 174 break; 175 case EditorInfo.TYPE_DATETIME_VARIATION_TIME: 176 sb.append(":TIME"); 177 break; 178 default: 179 sb.append(":UNKNOWN=").append(inputVariation); 180 break; 181 } 182 break; 183 } 184 default: 185 sb.append("UnknownClass=").append(inputClass); 186 if (inputVariation != 0) { 187 sb.append(":variation=").append(inputVariation); 188 } 189 if (inputFlags != 0) { 190 sb.append("|flags=0x").append(Integer.toHexString(inputFlags)); 191 } 192 break; 193 } 194 } 195 dumpImeOptions(@onNull StringBuilder sb, int imeOptions)196 static void dumpImeOptions(@NonNull StringBuilder sb, int imeOptions) { 197 final int action = imeOptions & EditorInfo.IME_MASK_ACTION; 198 final int flags = imeOptions & ~EditorInfo.IME_MASK_ACTION; 199 sb.append("Action:"); 200 switch (action) { 201 case EditorInfo.IME_ACTION_UNSPECIFIED: 202 sb.append("UNSPECIFIED"); 203 break; 204 case EditorInfo.IME_ACTION_NONE: 205 sb.append("NONE"); 206 break; 207 case EditorInfo.IME_ACTION_GO: 208 sb.append("GO"); 209 break; 210 case EditorInfo.IME_ACTION_SEARCH: 211 sb.append("SEARCH"); 212 break; 213 case EditorInfo.IME_ACTION_SEND: 214 sb.append("SEND"); 215 break; 216 case EditorInfo.IME_ACTION_NEXT: 217 sb.append("NEXT"); 218 break; 219 case EditorInfo.IME_ACTION_DONE: 220 sb.append("DONE"); 221 break; 222 case EditorInfo.IME_ACTION_PREVIOUS: 223 sb.append("PREVIOUS"); 224 break; 225 default: 226 sb.append("UNKNOWN=").append(action); 227 break; 228 } 229 if ((flags & EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING) != 0) { 230 sb.append("|NO_PERSONALIZED_LEARNING"); 231 } 232 if ((flags & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) { 233 sb.append("|NO_FULLSCREEN"); 234 } 235 if ((flags & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0) { 236 sb.append("|NAVIGATE_PREVIOUS"); 237 } 238 if ((flags & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0) { 239 sb.append("|NAVIGATE_NEXT"); 240 } 241 if ((flags & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0) { 242 sb.append("|NO_EXTRACT_UI"); 243 } 244 if ((flags & EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION) != 0) { 245 sb.append("|NO_ACCESSORY_ACTION"); 246 } 247 if ((flags & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) { 248 sb.append("|NO_ENTER_ACTION"); 249 } 250 if ((flags & EditorInfo.IME_FLAG_FORCE_ASCII) != 0) { 251 sb.append("|FORCE_ASCII"); 252 } 253 } 254 dumpCapsMode(@onNull StringBuilder sb, int capsMode)255 static void dumpCapsMode(@NonNull StringBuilder sb, int capsMode) { 256 if (capsMode == 0) { 257 sb.append("none"); 258 return; 259 } 260 boolean addSeparator = false; 261 if ((capsMode & EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) { 262 sb.append("CHARACTERS"); 263 addSeparator = true; 264 } 265 if ((capsMode & EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS) != 0) { 266 if (addSeparator) { 267 sb.append('|'); 268 } 269 sb.append("WORDS"); 270 addSeparator = true; 271 } 272 if ((capsMode & EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) { 273 if (addSeparator) { 274 sb.append('|'); 275 } 276 sb.append("SENTENCES"); 277 } 278 } 279 } 280