AccessibilityNodeInfoCompat.java revision 9dede51868bbbe16aadcd65e04860bea8ea50e05
1/* 2 * Copyright (C) 2011 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 androidx.core.view.accessibility; 18 19import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21import android.graphics.Rect; 22import android.os.Build; 23import android.os.Bundle; 24import android.text.InputType; 25import android.view.View; 26import android.view.accessibility.AccessibilityNodeInfo; 27 28import androidx.annotation.NonNull; 29import androidx.annotation.Nullable; 30import androidx.annotation.RestrictTo; 31import androidx.core.accessibilityservice.AccessibilityServiceInfoCompat; 32import androidx.core.os.BuildCompat; 33import androidx.core.view.ViewCompat; 34 35import java.util.ArrayList; 36import java.util.Collections; 37import java.util.List; 38 39/** 40 * Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo} in a backwards 41 * compatible fashion. 42 */ 43@SuppressWarnings("NewApi") 44public class AccessibilityNodeInfoCompat { 45 46 public static class AccessibilityActionCompat { 47 48 /** 49 * Action that gives input focus to the node. 50 */ 51 public static final AccessibilityActionCompat ACTION_FOCUS = 52 new AccessibilityActionCompat( 53 AccessibilityNodeInfoCompat.ACTION_FOCUS, null); 54 55 /** 56 * Action that clears input focus of the node. 57 */ 58 public static final AccessibilityActionCompat ACTION_CLEAR_FOCUS = 59 new AccessibilityActionCompat( 60 AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS, null); 61 62 /** 63 * Action that selects the node. 64 */ 65 public static final AccessibilityActionCompat ACTION_SELECT = 66 new AccessibilityActionCompat( 67 AccessibilityNodeInfoCompat.ACTION_SELECT, null); 68 69 /** 70 * Action that deselects the node. 71 */ 72 public static final AccessibilityActionCompat ACTION_CLEAR_SELECTION = 73 new AccessibilityActionCompat( 74 AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION, null); 75 76 /** 77 * Action that clicks on the node info. 78 */ 79 public static final AccessibilityActionCompat ACTION_CLICK = 80 new AccessibilityActionCompat( 81 AccessibilityNodeInfoCompat.ACTION_CLICK, null); 82 83 /** 84 * Action that long clicks on the node. 85 */ 86 public static final AccessibilityActionCompat ACTION_LONG_CLICK = 87 new AccessibilityActionCompat( 88 AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null); 89 90 /** 91 * Action that gives accessibility focus to the node. 92 */ 93 public static final AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS = 94 new AccessibilityActionCompat( 95 AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null); 96 97 /** 98 * Action that clears accessibility focus of the node. 99 */ 100 public static final AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS = 101 new AccessibilityActionCompat( 102 AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null); 103 104 /** 105 * Action that requests to go to the next entity in this node's text 106 * at a given movement granularity. For example, move to the next character, 107 * word, etc. 108 * <p> 109 * <strong>Arguments:</strong> 110 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 111 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}, 112 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 113 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br> 114 * <strong>Example:</strong> Move to the previous character and do not extend selection. 115 * <code><pre><p> 116 * Bundle arguments = new Bundle(); 117 * arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, 118 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER); 119 * arguments.putBoolean( 120 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); 121 * info.performAction( 122 * AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId(), 123 * arguments); 124 * </code></pre></p> 125 * </p> 126 * 127 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 128 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 129 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 130 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 131 * 132 * @see AccessibilityNodeInfoCompat#setMovementGranularities(int) 133 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 134 * @see AccessibilityNodeInfoCompat#getMovementGranularities() 135 * AccessibilityNodeInfoCompat.getMovementGranularities() 136 * 137 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER 138 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER 139 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD 140 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD 141 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE 142 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE 143 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH 144 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH 145 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE 146 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE 147 */ 148 public static final AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 149 new AccessibilityActionCompat( 150 AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, null); 151 152 /** 153 * Action that requests to go to the previous entity in this node's text 154 * at a given movement granularity. For example, move to the next character, 155 * word, etc. 156 * <p> 157 * <strong>Arguments:</strong> 158 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 159 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}, 160 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 161 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br> 162 * <strong>Example:</strong> Move to the next character and do not extend selection. 163 * <code><pre><p> 164 * Bundle arguments = new Bundle(); 165 * arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, 166 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER); 167 * arguments.putBoolean( 168 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false); 169 * info.performAction( 170 * AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId(), 171 * arguments); 172 * </code></pre></p> 173 * </p> 174 * 175 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 176 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 177 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 178 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 179 * 180 * @see AccessibilityNodeInfoCompat#setMovementGranularities(int) 181 * AccessibilityNodeInfoCompat.setMovementGranularities(int) 182 * @see AccessibilityNodeInfoCompat#getMovementGranularities() 183 * AccessibilityNodeInfoCompat.getMovementGranularities() 184 * 185 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER 186 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER 187 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD 188 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD 189 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE 190 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE 191 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH 192 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH 193 * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE 194 * AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE 195 */ 196 public static final AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 197 new AccessibilityActionCompat( 198 AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, null); 199 200 /** 201 * Action to move to the next HTML element of a given type. For example, move 202 * to the BUTTON, INPUT, TABLE, etc. 203 * <p> 204 * <strong>Arguments:</strong> 205 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING 206 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br> 207 * <strong>Example:</strong> 208 * <code><pre><p> 209 * Bundle arguments = new Bundle(); 210 * arguments.putString( 211 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON"); 212 * info.performAction( 213 * AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT.getId(), arguments); 214 * </code></pre></p> 215 * </p> 216 */ 217 public static final AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT = 218 new AccessibilityActionCompat( 219 AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT, null); 220 221 /** 222 * Action to move to the previous HTML element of a given type. For example, move 223 * to the BUTTON, INPUT, TABLE, etc. 224 * <p> 225 * <strong>Arguments:</strong> 226 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING 227 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br> 228 * <strong>Example:</strong> 229 * <code><pre><p> 230 * Bundle arguments = new Bundle(); 231 * arguments.putString( 232 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON"); 233 * info.performAction( 234 * AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT.getId(), arguments); 235 * </code></pre></p> 236 * </p> 237 */ 238 public static final AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT = 239 new AccessibilityActionCompat( 240 AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT, null); 241 242 /** 243 * Action to scroll the node content forward. 244 */ 245 public static final AccessibilityActionCompat ACTION_SCROLL_FORWARD = 246 new AccessibilityActionCompat( 247 AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null); 248 249 /** 250 * Action to scroll the node content backward. 251 */ 252 public static final AccessibilityActionCompat ACTION_SCROLL_BACKWARD = 253 new AccessibilityActionCompat( 254 AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null); 255 256 /** 257 * Action to copy the current selection to the clipboard. 258 */ 259 public static final AccessibilityActionCompat ACTION_COPY = 260 new AccessibilityActionCompat( 261 AccessibilityNodeInfoCompat.ACTION_COPY, null); 262 263 /** 264 * Action to paste the current clipboard content. 265 */ 266 public static final AccessibilityActionCompat ACTION_PASTE = 267 new AccessibilityActionCompat( 268 AccessibilityNodeInfoCompat.ACTION_PASTE, null); 269 270 /** 271 * Action to cut the current selection and place it to the clipboard. 272 */ 273 public static final AccessibilityActionCompat ACTION_CUT = 274 new AccessibilityActionCompat( 275 AccessibilityNodeInfoCompat.ACTION_CUT, null); 276 277 /** 278 * Action to set the selection. Performing this action with no arguments 279 * clears the selection. 280 * <p> 281 * <strong>Arguments:</strong> 282 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT 283 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT}, 284 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT 285 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT}<br> 286 * <strong>Example:</strong> 287 * <code><pre><p> 288 * Bundle arguments = new Bundle(); 289 * arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, 1); 290 * arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, 2); 291 * info.performAction(AccessibilityActionCompat.ACTION_SET_SELECTION.getId(), arguments); 292 * </code></pre></p> 293 * </p> 294 * 295 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT 296 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT 297 * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT 298 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT 299 */ 300 public static final AccessibilityActionCompat ACTION_SET_SELECTION = 301 new AccessibilityActionCompat( 302 AccessibilityNodeInfoCompat.ACTION_SET_SELECTION, null); 303 304 /** 305 * Action to expand an expandable node. 306 */ 307 public static final AccessibilityActionCompat ACTION_EXPAND = 308 new AccessibilityActionCompat( 309 AccessibilityNodeInfoCompat.ACTION_EXPAND, null); 310 311 /** 312 * Action to collapse an expandable node. 313 */ 314 public static final AccessibilityActionCompat ACTION_COLLAPSE = 315 new AccessibilityActionCompat( 316 AccessibilityNodeInfoCompat.ACTION_COLLAPSE, null); 317 318 /** 319 * Action to dismiss a dismissable node. 320 */ 321 public static final AccessibilityActionCompat ACTION_DISMISS = 322 new AccessibilityActionCompat( 323 AccessibilityNodeInfoCompat.ACTION_DISMISS, null); 324 325 /** 326 * Action that sets the text of the node. Performing the action without argument, 327 * using <code> null</code> or empty {@link CharSequence} will clear the text. This 328 * action will also put the cursor at the end of text. 329 * <p> 330 * <strong>Arguments:</strong> 331 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE 332 * AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br> 333 * <strong>Example:</strong> 334 * <code><pre><p> 335 * Bundle arguments = new Bundle(); 336 * arguments.putCharSequence(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, 337 * "android"); 338 * info.performAction(AccessibilityActionCompat.ACTION_SET_TEXT.getId(), arguments); 339 * </code></pre></p> 340 */ 341 public static final AccessibilityActionCompat ACTION_SET_TEXT = 342 new AccessibilityActionCompat( 343 AccessibilityNodeInfoCompat.ACTION_SET_TEXT, null); 344 345 /** 346 * Action that requests the node make its bounding rectangle visible 347 * on the screen, scrolling if necessary just enough. 348 * 349 * @see View#requestRectangleOnScreen(Rect) 350 */ 351 public static final AccessibilityActionCompat ACTION_SHOW_ON_SCREEN = 352 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 353 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_ON_SCREEN : null); 354 355 /** 356 * Action that scrolls the node to make the specified collection 357 * position visible on screen. 358 * <p> 359 * <strong>Arguments:</strong> 360 * <ul> 361 * <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_ROW_INT}</li> 362 * <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_COLUMN_INT}</li> 363 * <ul> 364 * 365 * @see AccessibilityNodeInfoCompat#getCollectionInfo() 366 */ 367 public static final AccessibilityActionCompat ACTION_SCROLL_TO_POSITION = 368 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 369 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_TO_POSITION 370 : null); 371 372 /** 373 * Action to scroll the node content up. 374 */ 375 public static final AccessibilityActionCompat ACTION_SCROLL_UP = 376 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 377 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP : null); 378 379 /** 380 * Action to scroll the node content left. 381 */ 382 public static final AccessibilityActionCompat ACTION_SCROLL_LEFT = 383 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 384 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_LEFT : null); 385 386 /** 387 * Action to scroll the node content down. 388 */ 389 public static final AccessibilityActionCompat ACTION_SCROLL_DOWN = 390 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 391 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN : null); 392 393 /** 394 * Action to scroll the node content right. 395 */ 396 public static final AccessibilityActionCompat ACTION_SCROLL_RIGHT = 397 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 398 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_RIGHT : null); 399 400 /** 401 * Action that context clicks the node. 402 */ 403 public static final AccessibilityActionCompat ACTION_CONTEXT_CLICK = 404 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23 405 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_CONTEXT_CLICK : null); 406 407 /** 408 * Action that sets progress between {@link RangeInfoCompat#getMin() RangeInfo.getMin()} and 409 * {@link RangeInfoCompat#getMax() RangeInfo.getMax()}. It should use the same value type as 410 * {@link RangeInfoCompat#getType() RangeInfo.getType()} 411 * <p> 412 * <strong>Arguments:</strong> 413 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_PROGRESS_VALUE} 414 * 415 * @see RangeInfoCompat 416 */ 417 public static final AccessibilityActionCompat ACTION_SET_PROGRESS = 418 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 24 419 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS : null); 420 421 /** 422 * Action to move a window to a new location. 423 * <p> 424 * <strong>Arguments:</strong> 425 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVE_WINDOW_X} 426 * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVE_WINDOW_Y} 427 */ 428 public static final AccessibilityActionCompat ACTION_MOVE_WINDOW = 429 new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 26 430 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW : null); 431 432 /** 433 * Action to show a tooltip. 434 */ 435 public static final AccessibilityActionCompat ACTION_SHOW_TOOLTIP = 436 new AccessibilityActionCompat(BuildCompat.isAtLeastP() 437 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_TOOLTIP : null); 438 439 /** 440 * Action to hide a tooltip. A node should expose this action only for views that are 441 * currently showing a tooltip. 442 */ 443 public static final AccessibilityActionCompat ACTION_HIDE_TOOLTIP = 444 new AccessibilityActionCompat(BuildCompat.isAtLeastP() 445 ? AccessibilityNodeInfo.AccessibilityAction.ACTION_HIDE_TOOLTIP : null); 446 447 final Object mAction; 448 449 /** 450 * Creates a new instance. 451 * 452 * @param actionId The action id. 453 * @param label The action label. 454 */ 455 public AccessibilityActionCompat(int actionId, CharSequence label) { 456 this(Build.VERSION.SDK_INT >= 21 457 ? new AccessibilityNodeInfo.AccessibilityAction(actionId, label) : null); 458 } 459 460 AccessibilityActionCompat(Object action) { 461 mAction = action; 462 } 463 464 /** 465 * Gets the id for this action. 466 * 467 * @return The action id. 468 */ 469 public int getId() { 470 if (Build.VERSION.SDK_INT >= 21) { 471 return ((AccessibilityNodeInfo.AccessibilityAction) mAction).getId(); 472 } else { 473 return 0; 474 } 475 } 476 477 /** 478 * Gets the label for this action. Its purpose is to describe the 479 * action to user. 480 * 481 * @return The label. 482 */ 483 public CharSequence getLabel() { 484 if (Build.VERSION.SDK_INT >= 21) { 485 return ((AccessibilityNodeInfo.AccessibilityAction) mAction).getLabel(); 486 } else { 487 return null; 488 } 489 } 490 } 491 492 /** 493 * Class with information if a node is a collection. 494 * <p> 495 * A collection of items has rows and columns and may be hierarchical. 496 * For example, a horizontal list is a collection with one column, as 497 * many rows as the list items, and is not hierarchical; A table is a 498 * collection with several rows, several columns, and is not hierarchical; 499 * A vertical tree is a hierarchical collection with one column and 500 * as many rows as the first level children. 501 * </p> 502 */ 503 public static class CollectionInfoCompat { 504 /** Selection mode where items are not selectable. */ 505 public static final int SELECTION_MODE_NONE = 0; 506 507 /** Selection mode where a single item may be selected. */ 508 public static final int SELECTION_MODE_SINGLE = 1; 509 510 /** Selection mode where multiple items may be selected. */ 511 public static final int SELECTION_MODE_MULTIPLE = 2; 512 513 final Object mInfo; 514 515 /** 516 * Returns a cached instance if such is available otherwise a new one. 517 * 518 * @param rowCount The number of rows. 519 * @param columnCount The number of columns. 520 * @param hierarchical Whether the collection is hierarchical. 521 * @param selectionMode The collection's selection mode, one of: 522 * <ul> 523 * <li>{@link #SELECTION_MODE_NONE} 524 * <li>{@link #SELECTION_MODE_SINGLE} 525 * <li>{@link #SELECTION_MODE_MULTIPLE} 526 * </ul> 527 * 528 * @return An instance. 529 */ 530 public static CollectionInfoCompat obtain(int rowCount, int columnCount, 531 boolean hierarchical, int selectionMode) { 532 if (Build.VERSION.SDK_INT >= 21) { 533 return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain( 534 rowCount, columnCount, hierarchical, selectionMode)); 535 } else if (Build.VERSION.SDK_INT >= 19) { 536 return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain( 537 rowCount, columnCount, hierarchical)); 538 } else { 539 return new CollectionInfoCompat(null); 540 } 541 } 542 543 /** 544 * Returns a cached instance if such is available otherwise a new one. 545 * 546 * @param rowCount The number of rows. 547 * @param columnCount The number of columns. 548 * @param hierarchical Whether the collection is hierarchical. 549 * 550 * @return An instance. 551 */ 552 public static CollectionInfoCompat obtain(int rowCount, int columnCount, 553 boolean hierarchical) { 554 if (Build.VERSION.SDK_INT >= 19) { 555 return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain( 556 rowCount, columnCount, hierarchical)); 557 } else { 558 return new CollectionInfoCompat(null); 559 } 560 } 561 562 CollectionInfoCompat(Object info) { 563 mInfo = info; 564 } 565 566 /** 567 * Gets the number of columns. 568 * 569 * @return The column count. 570 */ 571 public int getColumnCount() { 572 if (Build.VERSION.SDK_INT >= 19) { 573 return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getColumnCount(); 574 } else { 575 return 0; 576 } 577 } 578 579 /** 580 * Gets the number of rows. 581 * 582 * @return The row count. 583 */ 584 public int getRowCount() { 585 if (Build.VERSION.SDK_INT >= 19) { 586 return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getRowCount(); 587 } else { 588 return 0; 589 } 590 } 591 592 /** 593 * Gets if the collection is a hierarchically ordered. 594 * 595 * @return Whether the collection is hierarchical. 596 */ 597 public boolean isHierarchical() { 598 if (Build.VERSION.SDK_INT >= 19) { 599 return ((AccessibilityNodeInfo.CollectionInfo) mInfo).isHierarchical(); 600 } else { 601 return false; 602 } 603 } 604 605 /** 606 * Gets the collection's selection mode. 607 * 608 * @return The collection's selection mode, one of: 609 * <ul> 610 * <li>{@link #SELECTION_MODE_NONE} 611 * <li>{@link #SELECTION_MODE_SINGLE} 612 * <li>{@link #SELECTION_MODE_MULTIPLE} 613 * </ul> 614 */ 615 public int getSelectionMode() { 616 if (Build.VERSION.SDK_INT >= 21) { 617 return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getSelectionMode(); 618 } else { 619 return 0; 620 } 621 } 622 } 623 624 /** 625 * Class with information if a node is a collection item. 626 * <p> 627 * A collection item is contained in a collection, it starts at 628 * a given row and column in the collection, and spans one or 629 * more rows and columns. For example, a header of two related 630 * table columns starts at the first row and the first column, 631 * spans one row and two columns. 632 * </p> 633 */ 634 public static class CollectionItemInfoCompat { 635 636 final Object mInfo; 637 638 /** 639 * Returns a cached instance if such is available otherwise a new one. 640 * 641 * @param rowIndex The row index at which the item is located. 642 * @param rowSpan The number of rows the item spans. 643 * @param columnIndex The column index at which the item is located. 644 * @param columnSpan The number of columns the item spans. 645 * @param heading Whether the item is a heading. 646 * @param selected Whether the item is selected. 647 * @return An instance. 648 */ 649 public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan, 650 int columnIndex, int columnSpan, boolean heading, boolean selected) { 651 if (Build.VERSION.SDK_INT >= 21) { 652 return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain( 653 rowIndex, rowSpan, columnIndex, columnSpan, heading, selected)); 654 } else if (Build.VERSION.SDK_INT >= 19) { 655 return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain( 656 rowIndex, rowSpan, columnIndex, columnSpan, heading)); 657 } else { 658 return new CollectionItemInfoCompat(null); 659 } 660 } 661 662 /** 663 * Returns a cached instance if such is available otherwise a new one. 664 * 665 * @param rowIndex The row index at which the item is located. 666 * @param rowSpan The number of rows the item spans. 667 * @param columnIndex The column index at which the item is located. 668 * @param columnSpan The number of columns the item spans. 669 * @param heading Whether the item is a heading. 670 * @return An instance. 671 */ 672 public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan, 673 int columnIndex, int columnSpan, boolean heading) { 674 if (Build.VERSION.SDK_INT >= 19) { 675 return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain( 676 rowIndex, rowSpan, columnIndex, columnSpan, heading)); 677 } else { 678 return new CollectionItemInfoCompat(null); 679 } 680 } 681 682 CollectionItemInfoCompat(Object info) { 683 mInfo = info; 684 } 685 686 /** 687 * Gets the column index at which the item is located. 688 * 689 * @return The column index. 690 */ 691 public int getColumnIndex() { 692 if (Build.VERSION.SDK_INT >= 19) { 693 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnIndex(); 694 } else { 695 return 0; 696 } 697 } 698 699 /** 700 * Gets the number of columns the item spans. 701 * 702 * @return The column span. 703 */ 704 public int getColumnSpan() { 705 if (Build.VERSION.SDK_INT >= 19) { 706 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnSpan(); 707 } else { 708 return 0; 709 } 710 } 711 712 /** 713 * Gets the row index at which the item is located. 714 * 715 * @return The row index. 716 */ 717 public int getRowIndex() { 718 if (Build.VERSION.SDK_INT >= 19) { 719 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowIndex(); 720 } else { 721 return 0; 722 } 723 } 724 725 /** 726 * Gets the number of rows the item spans. 727 * 728 * @return The row span. 729 */ 730 public int getRowSpan() { 731 if (Build.VERSION.SDK_INT >= 19) { 732 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowSpan(); 733 } else { 734 return 0; 735 } 736 } 737 738 /** 739 * Gets if the collection item is a heading. For example, section 740 * heading, table header, etc. 741 * 742 * @return If the item is a heading. 743 */ 744 public boolean isHeading() { 745 if (Build.VERSION.SDK_INT >= 19) { 746 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isHeading(); 747 } else { 748 return false; 749 } 750 } 751 752 /** 753 * Gets if the collection item is selected. 754 * 755 * @return If the item is selected. 756 */ 757 public boolean isSelected() { 758 if (Build.VERSION.SDK_INT >= 21) { 759 return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isSelected(); 760 } else { 761 return false; 762 } 763 } 764 } 765 766 /** 767 * Class with information if a node is a range. 768 */ 769 public static class RangeInfoCompat { 770 /** Range type: integer. */ 771 public static final int RANGE_TYPE_INT = 0; 772 /** Range type: float. */ 773 public static final int RANGE_TYPE_FLOAT = 1; 774 /** Range type: percent with values from zero to one.*/ 775 public static final int RANGE_TYPE_PERCENT = 2; 776 777 /** 778 * Obtains a cached instance if such is available otherwise a new one. 779 * 780 * @param type The type of the range. 781 * @param min The min value. 782 * @param max The max value. 783 * @param current The current value. 784 * @return The instance 785 */ 786 public static RangeInfoCompat obtain(int type, float min, float max, float current) { 787 if (Build.VERSION.SDK_INT >= 19) { 788 return new RangeInfoCompat( 789 AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current)); 790 } else { 791 return new RangeInfoCompat(null); 792 } 793 } 794 795 final Object mInfo; 796 797 RangeInfoCompat(Object info) { 798 mInfo = info; 799 } 800 801 /** 802 * Gets the current value. 803 * 804 * @return The current value. 805 */ 806 public float getCurrent() { 807 if (Build.VERSION.SDK_INT >= 19) { 808 return ((AccessibilityNodeInfo.RangeInfo) mInfo).getCurrent(); 809 } else { 810 return 0; 811 } 812 } 813 814 /** 815 * Gets the max value. 816 * 817 * @return The max value. 818 */ 819 public float getMax() { 820 if (Build.VERSION.SDK_INT >= 19) { 821 return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMax(); 822 } else { 823 return 0; 824 } 825 } 826 827 /** 828 * Gets the min value. 829 * 830 * @return The min value. 831 */ 832 public float getMin() { 833 if (Build.VERSION.SDK_INT >= 19) { 834 return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMin(); 835 } else { 836 return 0; 837 } 838 } 839 840 /** 841 * Gets the range type. 842 * 843 * @return The range type. 844 * 845 * @see #RANGE_TYPE_INT 846 * @see #RANGE_TYPE_FLOAT 847 * @see #RANGE_TYPE_PERCENT 848 */ 849 public int getType() { 850 if (Build.VERSION.SDK_INT >= 19) { 851 return ((AccessibilityNodeInfo.RangeInfo) mInfo).getType(); 852 } else { 853 return RANGE_TYPE_INT; 854 } 855 } 856 } 857 858 private static final String ROLE_DESCRIPTION_KEY = 859 "AccessibilityNodeInfo.roleDescription"; 860 861 private static final String PANE_TITLE_KEY = 862 "androidx.view.accessibility.AccessibilityNodeInfoCompat.PANE_TITLE_KEY"; 863 864 private static final String TOOLTIP_TEXT_KEY = 865 "androidx.view.accessibility.AccessibilityNodeInfoCompat.TOOLTIP_TEXT_KEY"; 866 867 private static final String HINT_TEXT_KEY = 868 "androidx.view.accessibility.AccessibilityNodeInfoCompat.HINT_TEXT_KEY"; 869 870 private static final String BOOLEAN_PROPERTY_KEY = 871 "androidx.view.accessibility.AccessibilityNodeInfoCompat.BOOLEAN_PROPERTY_KEY"; 872 873 // These don't line up with the internal framework constants, since they are independent 874 // and we might as well get all 32 bits of utility here. 875 private static final int BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE = 0x00000001; 876 private static final int BOOLEAN_PROPERTY_IS_HEADING = 0x00000002; 877 private static final int BOOLEAN_PROPERTY_IS_SHOWING_HINT = 0x00000004; 878 879 private final AccessibilityNodeInfo mInfo; 880 881 /** 882 * androidx.customview.widget.ExploreByTouchHelper.HOST_ID = -1; 883 * 884 * @hide 885 */ 886 @RestrictTo(LIBRARY_GROUP) 887 public int mParentVirtualDescendantId = -1; 888 889 // Actions introduced in IceCreamSandwich 890 891 /** 892 * Action that focuses the node. 893 */ 894 public static final int ACTION_FOCUS = 0x00000001; 895 896 /** 897 * Action that unfocuses the node. 898 */ 899 public static final int ACTION_CLEAR_FOCUS = 0x00000002; 900 901 /** 902 * Action that selects the node. 903 */ 904 public static final int ACTION_SELECT = 0x00000004; 905 906 /** 907 * Action that unselects the node. 908 */ 909 public static final int ACTION_CLEAR_SELECTION = 0x00000008; 910 911 /** 912 * Action that clicks on the node info. 913 */ 914 public static final int ACTION_CLICK = 0x00000010; 915 916 /** 917 * Action that long clicks on the node. 918 */ 919 public static final int ACTION_LONG_CLICK = 0x00000020; 920 921 // Actions introduced in JellyBean 922 923 /** 924 * Action that gives accessibility focus to the node. 925 */ 926 public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040; 927 928 /** 929 * Action that clears accessibility focus of the node. 930 */ 931 public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080; 932 933 /** 934 * Action that requests to go to the next entity in this node's text 935 * at a given movement granularity. For example, move to the next character, 936 * word, etc. 937 * <p> 938 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<, 939 * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br> 940 * <strong>Example:</strong> Move to the previous character and do not extend selection. 941 * <code><pre><p> 942 * Bundle arguments = new Bundle(); 943 * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, 944 * AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER); 945 * arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, 946 * false); 947 * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments); 948 * </code></pre></p> 949 * </p> 950 * 951 * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 952 * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 953 * 954 * @see #setMovementGranularities(int) 955 * @see #getMovementGranularities() 956 * 957 * @see #MOVEMENT_GRANULARITY_CHARACTER 958 * @see #MOVEMENT_GRANULARITY_WORD 959 * @see #MOVEMENT_GRANULARITY_LINE 960 * @see #MOVEMENT_GRANULARITY_PARAGRAPH 961 * @see #MOVEMENT_GRANULARITY_PAGE 962 */ 963 public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 0x00000100; 964 965 /** 966 * Action that requests to go to the previous entity in this node's text 967 * at a given movement granularity. For example, move to the next character, 968 * word, etc. 969 * <p> 970 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<, 971 * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br> 972 * <strong>Example:</strong> Move to the next character and do not extend selection. 973 * <code><pre><p> 974 * Bundle arguments = new Bundle(); 975 * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, 976 * AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER); 977 * arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, 978 * false); 979 * info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, 980 * arguments); 981 * </code></pre></p> 982 * </p> 983 * 984 * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT 985 * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 986 * 987 * @see #setMovementGranularities(int) 988 * @see #getMovementGranularities() 989 * 990 * @see #MOVEMENT_GRANULARITY_CHARACTER 991 * @see #MOVEMENT_GRANULARITY_WORD 992 * @see #MOVEMENT_GRANULARITY_LINE 993 * @see #MOVEMENT_GRANULARITY_PARAGRAPH 994 * @see #MOVEMENT_GRANULARITY_PAGE 995 */ 996 public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 0x00000200; 997 998 /** 999 * Action to move to the next HTML element of a given type. For example, move 1000 * to the BUTTON, INPUT, TABLE, etc. 1001 * <p> 1002 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br> 1003 * <strong>Example:</strong> 1004 * <code><pre><p> 1005 * Bundle arguments = new Bundle(); 1006 * arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON"); 1007 * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT, arguments); 1008 * </code></pre></p> 1009 * </p> 1010 */ 1011 public static final int ACTION_NEXT_HTML_ELEMENT = 0x00000400; 1012 1013 /** 1014 * Action to move to the previous HTML element of a given type. For example, move 1015 * to the BUTTON, INPUT, TABLE, etc. 1016 * <p> 1017 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br> 1018 * <strong>Example:</strong> 1019 * <code><pre><p> 1020 * Bundle arguments = new Bundle(); 1021 * arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON"); 1022 * info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT, arguments); 1023 * </code></pre></p> 1024 * </p> 1025 */ 1026 public static final int ACTION_PREVIOUS_HTML_ELEMENT = 0x00000800; 1027 1028 /** 1029 * Action to scroll the node content forward. 1030 */ 1031 public static final int ACTION_SCROLL_FORWARD = 0x00001000; 1032 1033 /** 1034 * Action to scroll the node content backward. 1035 */ 1036 public static final int ACTION_SCROLL_BACKWARD = 0x00002000; 1037 1038 // Actions introduced in JellyBeanMr2 1039 1040 /** 1041 * Action to copy the current selection to the clipboard. 1042 */ 1043 public static final int ACTION_COPY = 0x00004000; 1044 1045 /** 1046 * Action to paste the current clipboard content. 1047 */ 1048 public static final int ACTION_PASTE = 0x00008000; 1049 1050 /** 1051 * Action to cut the current selection and place it to the clipboard. 1052 */ 1053 public static final int ACTION_CUT = 0x00010000; 1054 1055 /** 1056 * Action to set the selection. Performing this action with no arguments 1057 * clears the selection. 1058 * <p> 1059 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SELECTION_START_INT}, 1060 * {@link #ACTION_ARGUMENT_SELECTION_END_INT}<br> 1061 * <strong>Example:</strong> 1062 * <code><pre><p> 1063 * Bundle arguments = new Bundle(); 1064 * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1); 1065 * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2); 1066 * info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments); 1067 * </code></pre></p> 1068 * </p> 1069 * 1070 * @see #ACTION_ARGUMENT_SELECTION_START_INT 1071 * @see #ACTION_ARGUMENT_SELECTION_END_INT 1072 */ 1073 public static final int ACTION_SET_SELECTION = 0x00020000; 1074 1075 /** 1076 * Action to expand an expandable node. 1077 */ 1078 public static final int ACTION_EXPAND = 0x00040000; 1079 1080 /** 1081 * Action to collapse an expandable node. 1082 */ 1083 public static final int ACTION_COLLAPSE = 0x00080000; 1084 1085 /** 1086 * Action to dismiss a dismissable node. 1087 */ 1088 public static final int ACTION_DISMISS = 0x00100000; 1089 1090 /** 1091 * Action that sets the text of the node. Performing the action without argument, using <code> 1092 * null</code> or empty {@link CharSequence} will clear the text. This action will also put the 1093 * cursor at the end of text. 1094 * <p> 1095 * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br> 1096 * <strong>Example:</strong> 1097 * <code><pre><p> 1098 * Bundle arguments = new Bundle(); 1099 * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, 1100 * "android"); 1101 * info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments); 1102 * </code></pre></p> 1103 */ 1104 public static final int ACTION_SET_TEXT = 0x00200000; 1105 1106 // Action arguments 1107 1108 /** 1109 * Argument for which movement granularity to be used when traversing the node text. 1110 * <p> 1111 * <strong>Type:</strong> int<br> 1112 * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY}, 1113 * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY} 1114 * </p> 1115 */ 1116 public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = 1117 "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT"; 1118 1119 /** 1120 * Argument for which HTML element to get moving to the next/previous HTML element. 1121 * <p> 1122 * <strong>Type:</strong> String<br> 1123 * <strong>Actions:</strong> {@link #ACTION_NEXT_HTML_ELEMENT}, 1124 * {@link #ACTION_PREVIOUS_HTML_ELEMENT} 1125 * </p> 1126 */ 1127 public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = 1128 "ACTION_ARGUMENT_HTML_ELEMENT_STRING"; 1129 1130 /** 1131 * Argument for whether when moving at granularity to extend the selection 1132 * or to move it otherwise. 1133 * <p> 1134 * <strong>Type:</strong> boolean<br> 1135 * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY}, 1136 * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY} 1137 * </p> 1138 * 1139 * @see #ACTION_NEXT_AT_MOVEMENT_GRANULARITY 1140 * @see #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY 1141 */ 1142 public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = 1143 "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN"; 1144 1145 /** 1146 * Argument for specifying the selection start. 1147 * <p> 1148 * <strong>Type:</strong> int<br> 1149 * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION} 1150 * </p> 1151 * 1152 * @see #ACTION_SET_SELECTION 1153 */ 1154 public static final String ACTION_ARGUMENT_SELECTION_START_INT = 1155 "ACTION_ARGUMENT_SELECTION_START_INT"; 1156 1157 /** 1158 * Argument for specifying the selection end. 1159 * <p> 1160 * <strong>Type:</strong> int<br> 1161 * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION} 1162 * </p> 1163 * 1164 * @see #ACTION_SET_SELECTION 1165 */ 1166 public static final String ACTION_ARGUMENT_SELECTION_END_INT = 1167 "ACTION_ARGUMENT_SELECTION_END_INT"; 1168 1169 /** 1170 * Argument for specifying the text content to set 1171 * <p> 1172 * <strong>Type:</strong> CharSequence<br> 1173 * <strong>Actions:</strong> {@link #ACTION_SET_TEXT} 1174 * </p> 1175 * 1176 * @see #ACTION_SET_TEXT 1177 */ 1178 public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = 1179 "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE"; 1180 1181 /** 1182 * Argument for specifying the collection row to make visible on screen. 1183 * <p> 1184 * <strong>Type:</strong> int<br> 1185 * <strong>Actions:</strong> 1186 * <ul> 1187 * <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li> 1188 * </ul> 1189 * 1190 * @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION 1191 */ 1192 public static final String ACTION_ARGUMENT_ROW_INT = 1193 "android.view.accessibility.action.ARGUMENT_ROW_INT"; 1194 1195 /** 1196 * Argument for specifying the collection column to make visible on screen. 1197 * <p> 1198 * <strong>Type:</strong> int<br> 1199 * <strong>Actions:</strong> 1200 * <ul> 1201 * <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li> 1202 * </ul> 1203 * 1204 * @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION 1205 */ 1206 public static final String ACTION_ARGUMENT_COLUMN_INT = 1207 "android.view.accessibility.action.ARGUMENT_COLUMN_INT"; 1208 1209 /** 1210 * Argument for specifying the progress value to set. 1211 * <p> 1212 * <strong>Type:</strong> float<br> 1213 * <strong>Actions:</strong> 1214 * <ul> 1215 * <li>{@link AccessibilityActionCompat#ACTION_SET_PROGRESS}</li> 1216 * </ul> 1217 * 1218 * @see AccessibilityActionCompat#ACTION_SET_PROGRESS 1219 */ 1220 public static final String ACTION_ARGUMENT_PROGRESS_VALUE = 1221 "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE"; 1222 1223 /** 1224 * Argument for specifying the x coordinate to which to move a window. 1225 * <p> 1226 * <strong>Type:</strong> int<br> 1227 * <strong>Actions:</strong> 1228 * <ul> 1229 * <li>{@link AccessibilityActionCompat#ACTION_MOVE_WINDOW}</li> 1230 * </ul> 1231 * 1232 * @see AccessibilityActionCompat#ACTION_MOVE_WINDOW 1233 */ 1234 public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = 1235 "ACTION_ARGUMENT_MOVE_WINDOW_X"; 1236 1237 /** 1238 * Argument for specifying the y coordinate to which to move a window. 1239 * <p> 1240 * <strong>Type:</strong> int<br> 1241 * <strong>Actions:</strong> 1242 * <ul> 1243 * <li>{@link AccessibilityActionCompat#ACTION_MOVE_WINDOW}</li> 1244 * </ul> 1245 * 1246 * @see AccessibilityActionCompat#ACTION_MOVE_WINDOW 1247 */ 1248 public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = 1249 "ACTION_ARGUMENT_MOVE_WINDOW_Y"; 1250 1251 // Focus types 1252 1253 /** 1254 * The input focus. 1255 */ 1256 public static final int FOCUS_INPUT = 1; 1257 1258 /** 1259 * The accessibility focus. 1260 */ 1261 public static final int FOCUS_ACCESSIBILITY = 2; 1262 1263 // Movement granularities 1264 1265 /** 1266 * Movement granularity bit for traversing the text of a node by character. 1267 */ 1268 public static final int MOVEMENT_GRANULARITY_CHARACTER = 0x00000001; 1269 1270 /** 1271 * Movement granularity bit for traversing the text of a node by word. 1272 */ 1273 public static final int MOVEMENT_GRANULARITY_WORD = 0x00000002; 1274 1275 /** 1276 * Movement granularity bit for traversing the text of a node by line. 1277 */ 1278 public static final int MOVEMENT_GRANULARITY_LINE = 0x00000004; 1279 1280 /** 1281 * Movement granularity bit for traversing the text of a node by paragraph. 1282 */ 1283 public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 0x00000008; 1284 1285 /** 1286 * Movement granularity bit for traversing the text of a node by page. 1287 */ 1288 public static final int MOVEMENT_GRANULARITY_PAGE = 0x00000010; 1289 1290 /** 1291 * Creates a wrapper for info implementation. 1292 * 1293 * @param object The info to wrap. 1294 * @return A wrapper for if the object is not null, null otherwise. 1295 */ 1296 static AccessibilityNodeInfoCompat wrapNonNullInstance(Object object) { 1297 if (object != null) { 1298 return new AccessibilityNodeInfoCompat(object); 1299 } 1300 return null; 1301 } 1302 1303 /** 1304 * Creates a new instance wrapping an 1305 * {@link android.view.accessibility.AccessibilityNodeInfo}. 1306 * 1307 * @param info The info. 1308 * 1309 * @deprecated Use {@link #wrap(AccessibilityNodeInfo)} instead. 1310 */ 1311 @Deprecated 1312 public AccessibilityNodeInfoCompat(Object info) { 1313 mInfo = (AccessibilityNodeInfo) info; 1314 } 1315 1316 private AccessibilityNodeInfoCompat(AccessibilityNodeInfo info) { 1317 mInfo = info; 1318 } 1319 1320 /** 1321 * Creates a new instance wrapping an 1322 * {@link android.view.accessibility.AccessibilityNodeInfo}. 1323 * 1324 * @param info The info. 1325 */ 1326 public static AccessibilityNodeInfoCompat wrap(@NonNull AccessibilityNodeInfo info) { 1327 return new AccessibilityNodeInfoCompat(info); 1328 } 1329 1330 /** 1331 * @return The unwrapped {@link android.view.accessibility.AccessibilityNodeInfo}. 1332 */ 1333 public AccessibilityNodeInfo unwrap() { 1334 return mInfo; 1335 } 1336 1337 /** 1338 * @return The wrapped {@link android.view.accessibility.AccessibilityNodeInfo}. 1339 * 1340 * @deprecated Use {@link #unwrap()} instead. 1341 */ 1342 @Deprecated 1343 public Object getInfo() { 1344 return mInfo; 1345 } 1346 1347 /** 1348 * Returns a cached instance if such is available otherwise a new one and 1349 * sets the source. 1350 * 1351 * @return An instance. 1352 * @see #setSource(View) 1353 */ 1354 public static AccessibilityNodeInfoCompat obtain(View source) { 1355 return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain(source)); 1356 } 1357 1358 /** 1359 * Returns a cached instance if such is available otherwise a new one 1360 * and sets the source. 1361 * 1362 * @param root The root of the virtual subtree. 1363 * @param virtualDescendantId The id of the virtual descendant. 1364 * @return An instance. 1365 * 1366 * @see #setSource(View, int) 1367 */ 1368 public static AccessibilityNodeInfoCompat obtain(View root, int virtualDescendantId) { 1369 if (Build.VERSION.SDK_INT >= 16) { 1370 return AccessibilityNodeInfoCompat.wrapNonNullInstance( 1371 AccessibilityNodeInfo.obtain(root, virtualDescendantId)); 1372 } else { 1373 return null; 1374 } 1375 } 1376 1377 /** 1378 * Returns a cached instance if such is available otherwise a new one. 1379 * 1380 * @return An instance. 1381 */ 1382 public static AccessibilityNodeInfoCompat obtain() { 1383 return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain()); 1384 } 1385 1386 /** 1387 * Returns a cached instance if such is available or a new one is create. 1388 * The returned instance is initialized from the given <code>info</code>. 1389 * 1390 * @param info The other info. 1391 * @return An instance. 1392 */ 1393 public static AccessibilityNodeInfoCompat obtain(AccessibilityNodeInfoCompat info) { 1394 return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain(info.mInfo)); 1395 } 1396 1397 /** 1398 * Sets the source. 1399 * 1400 * @param source The info source. 1401 */ 1402 public void setSource(View source) { 1403 mInfo.setSource(source); 1404 } 1405 1406 /** 1407 * Sets the source to be a virtual descendant of the given <code>root</code>. 1408 * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root 1409 * is set as the source. 1410 * <p> 1411 * A virtual descendant is an imaginary View that is reported as a part of the view 1412 * hierarchy for accessibility purposes. This enables custom views that draw complex 1413 * content to report themselves as a tree of virtual views, thus conveying their 1414 * logical structure. 1415 * </p> 1416 * <p> 1417 * <strong>Note:</strong> Cannot be called from an 1418 * {@link android.accessibilityservice.AccessibilityService}. 1419 * This class is made immutable before being delivered to an AccessibilityService. 1420 * </p> 1421 * 1422 * @param root The root of the virtual subtree. 1423 * @param virtualDescendantId The id of the virtual descendant. 1424 */ 1425 public void setSource(View root, int virtualDescendantId) { 1426 if (Build.VERSION.SDK_INT >= 16) { 1427 mInfo.setSource(root, virtualDescendantId); 1428 } 1429 } 1430 1431 /** 1432 * Find the view that has the specified focus type. The search starts from 1433 * the view represented by this node info. 1434 * 1435 * @param focus The focus to find. One of {@link #FOCUS_INPUT} or 1436 * {@link #FOCUS_ACCESSIBILITY}. 1437 * @return The node info of the focused view or null. 1438 * 1439 * @see #FOCUS_INPUT 1440 * @see #FOCUS_ACCESSIBILITY 1441 */ 1442 public AccessibilityNodeInfoCompat findFocus(int focus) { 1443 if (Build.VERSION.SDK_INT >= 16) { 1444 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.findFocus(focus)); 1445 } else { 1446 return null; 1447 } 1448 } 1449 1450 /** 1451 * Searches for the nearest view in the specified direction that can take 1452 * input focus. 1453 * 1454 * @param direction The direction. Can be one of: 1455 * {@link View#FOCUS_DOWN}, 1456 * {@link View#FOCUS_UP}, 1457 * {@link View#FOCUS_LEFT}, 1458 * {@link View#FOCUS_RIGHT}, 1459 * {@link View#FOCUS_FORWARD}, 1460 * {@link View#FOCUS_BACKWARD}. 1461 * 1462 * @return The node info for the view that can take accessibility focus. 1463 */ 1464 public AccessibilityNodeInfoCompat focusSearch(int direction) { 1465 if (Build.VERSION.SDK_INT >= 16) { 1466 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.focusSearch(direction)); 1467 } else { 1468 return null; 1469 } 1470 } 1471 1472 /** 1473 * Gets the id of the window from which the info comes from. 1474 * 1475 * @return The window id. 1476 */ 1477 public int getWindowId() { 1478 return mInfo.getWindowId(); 1479 } 1480 1481 /** 1482 * Gets the number of children. 1483 * 1484 * @return The child count. 1485 */ 1486 public int getChildCount() { 1487 return mInfo.getChildCount(); 1488 } 1489 1490 /** 1491 * Get the child at given index. 1492 * <p> 1493 * <strong>Note:</strong> It is a client responsibility to recycle the 1494 * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} to 1495 * avoid creating of multiple instances. 1496 * </p> 1497 * 1498 * @param index The child index. 1499 * @return The child node. 1500 * @throws IllegalStateException If called outside of an 1501 * AccessibilityService. 1502 */ 1503 public AccessibilityNodeInfoCompat getChild(int index) { 1504 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getChild(index)); 1505 } 1506 1507 /** 1508 * Adds a child. 1509 * <p> 1510 * <strong>Note:</strong> Cannot be called from an 1511 * {@link android.accessibilityservice.AccessibilityService}. This class is 1512 * made immutable before being delivered to an AccessibilityService. 1513 * </p> 1514 * 1515 * @param child The child. 1516 * @throws IllegalStateException If called from an AccessibilityService. 1517 */ 1518 public void addChild(View child) { 1519 mInfo.addChild(child); 1520 } 1521 1522 /** 1523 * Adds a virtual child which is a descendant of the given <code>root</code>. 1524 * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root 1525 * is added as a child. 1526 * <p> 1527 * A virtual descendant is an imaginary View that is reported as a part of the view 1528 * hierarchy for accessibility purposes. This enables custom views that draw complex 1529 * content to report them selves as a tree of virtual views, thus conveying their 1530 * logical structure. 1531 * </p> 1532 * 1533 * @param root The root of the virtual subtree. 1534 * @param virtualDescendantId The id of the virtual child. 1535 */ 1536 public void addChild(View root, int virtualDescendantId) { 1537 if (Build.VERSION.SDK_INT >= 16) { 1538 mInfo.addChild(root, virtualDescendantId); 1539 } 1540 } 1541 1542 /** 1543 * Removes a child. If the child was not previously added to the node, 1544 * calling this method has no effect. 1545 * <p> 1546 * <strong>Note:</strong> Cannot be called from an 1547 * {@link android.accessibilityservice.AccessibilityService}. 1548 * This class is made immutable before being delivered to an AccessibilityService. 1549 * </p> 1550 * 1551 * @param child The child. 1552 * @return true if the child was present 1553 * 1554 * @throws IllegalStateException If called from an AccessibilityService. 1555 */ 1556 public boolean removeChild(View child) { 1557 if (Build.VERSION.SDK_INT >= 21) { 1558 return mInfo.removeChild(child); 1559 } else { 1560 return false; 1561 } 1562 } 1563 1564 /** 1565 * Removes a virtual child which is a descendant of the given 1566 * <code>root</code>. If the child was not previously added to the node, 1567 * calling this method has no effect. 1568 * 1569 * @param root The root of the virtual subtree. 1570 * @param virtualDescendantId The id of the virtual child. 1571 * @return true if the child was present 1572 * @see #addChild(View, int) 1573 */ 1574 public boolean removeChild(View root, int virtualDescendantId) { 1575 if (Build.VERSION.SDK_INT >= 21) { 1576 return mInfo.removeChild(root, virtualDescendantId); 1577 } else { 1578 return false; 1579 } 1580 } 1581 1582 /** 1583 * Gets the actions that can be performed on the node. 1584 * 1585 * @return The bit mask of with actions. 1586 * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS 1587 * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS 1588 * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT 1589 * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION 1590 */ 1591 public int getActions() { 1592 return mInfo.getActions(); 1593 } 1594 1595 /** 1596 * Adds an action that can be performed on the node. 1597 * <p> 1598 * <strong>Note:</strong> Cannot be called from an 1599 * {@link android.accessibilityservice.AccessibilityService}. This class is 1600 * made immutable before being delivered to an AccessibilityService. 1601 * </p> 1602 * 1603 * @param action The action. 1604 * @throws IllegalStateException If called from an AccessibilityService. 1605 */ 1606 public void addAction(int action) { 1607 mInfo.addAction(action); 1608 } 1609 1610 /** 1611 * Adds an action that can be performed on the node. 1612 * <p> 1613 * <strong>Note:</strong> Cannot be called from an 1614 * {@link android.accessibilityservice.AccessibilityService}. This class is 1615 * made immutable before being delivered to an AccessibilityService. 1616 * </p> 1617 * 1618 * @param action The action. 1619 * @throws IllegalStateException If called from an AccessibilityService. 1620 */ 1621 public void addAction(AccessibilityActionCompat action) { 1622 if (Build.VERSION.SDK_INT >= 21) { 1623 mInfo.addAction((AccessibilityNodeInfo.AccessibilityAction) action.mAction); 1624 } 1625 } 1626 1627 /** 1628 * Removes an action that can be performed on the node. If the action was 1629 * not already added to the node, calling this method has no effect. 1630 * <p> 1631 * <strong>Note:</strong> Cannot be called from an 1632 * {@link android.accessibilityservice.AccessibilityService}. 1633 * This class is made immutable before being delivered to an AccessibilityService. 1634 * </p> 1635 * 1636 * @param action The action to be removed. 1637 * @return The action removed from the list of actions. 1638 * 1639 * @throws IllegalStateException If called from an AccessibilityService. 1640 */ 1641 public boolean removeAction(AccessibilityActionCompat action) { 1642 if (Build.VERSION.SDK_INT >= 21) { 1643 return mInfo.removeAction((AccessibilityNodeInfo.AccessibilityAction) action.mAction); 1644 } else { 1645 return false; 1646 } 1647 } 1648 1649 /** 1650 * Performs an action on the node. 1651 * <p> 1652 * <strong>Note:</strong> An action can be performed only if the request is 1653 * made from an {@link android.accessibilityservice.AccessibilityService}. 1654 * </p> 1655 * 1656 * @param action The action to perform. 1657 * @return True if the action was performed. 1658 * @throws IllegalStateException If called outside of an 1659 * AccessibilityService. 1660 */ 1661 public boolean performAction(int action) { 1662 return mInfo.performAction(action); 1663 } 1664 1665 /** 1666 * Performs an action on the node. 1667 * <p> 1668 * <strong>Note:</strong> An action can be performed only if the request is made 1669 * from an {@link android.accessibilityservice.AccessibilityService}. 1670 * </p> 1671 * 1672 * @param action The action to perform. 1673 * @param arguments A bundle with additional arguments. 1674 * @return True if the action was performed. 1675 * 1676 * @throws IllegalStateException If called outside of an AccessibilityService. 1677 */ 1678 public boolean performAction(int action, Bundle arguments) { 1679 if (Build.VERSION.SDK_INT >= 16) { 1680 return mInfo.performAction(action, arguments); 1681 } else { 1682 return false; 1683 } 1684 } 1685 1686 /** 1687 * Sets the movement granularities for traversing the text of this node. 1688 * <p> 1689 * <strong>Note:</strong> Cannot be called from an 1690 * {@link android.accessibilityservice.AccessibilityService}. 1691 * This class is made immutable before being delivered to an AccessibilityService. 1692 * </p> 1693 * 1694 * @param granularities The bit mask with granularities. 1695 * 1696 * @throws IllegalStateException If called from an AccessibilityService. 1697 */ 1698 public void setMovementGranularities(int granularities) { 1699 if (Build.VERSION.SDK_INT >= 16) { 1700 mInfo.setMovementGranularities(granularities); 1701 } 1702 } 1703 1704 /** 1705 * Gets the movement granularities for traversing the text of this node. 1706 * 1707 * @return The bit mask with granularities. 1708 */ 1709 public int getMovementGranularities() { 1710 if (Build.VERSION.SDK_INT >= 16) { 1711 return mInfo.getMovementGranularities(); 1712 } else { 1713 return 0; 1714 } 1715 } 1716 1717 /** 1718 * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by text. The match 1719 * is case insensitive containment. The search is relative to this info i.e. this 1720 * info is the root of the traversed tree. 1721 * <p> 1722 * <strong>Note:</strong> It is a client responsibility to recycle the 1723 * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()} 1724 * to avoid creating of multiple instances. 1725 * </p> 1726 * 1727 * @param text The searched text. 1728 * @return A list of node info. 1729 */ 1730 public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) { 1731 List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>(); 1732 List<AccessibilityNodeInfo> infos = mInfo.findAccessibilityNodeInfosByText(text); 1733 final int infoCount = infos.size(); 1734 for (int i = 0; i < infoCount; i++) { 1735 AccessibilityNodeInfo info = infos.get(i); 1736 result.add(AccessibilityNodeInfoCompat.wrap(info)); 1737 } 1738 return result; 1739 } 1740 1741 /** 1742 * Gets the parent. 1743 * <p> 1744 * <strong>Note:</strong> It is a client responsibility to recycle the 1745 * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()} 1746 * to avoid creating of multiple instances. 1747 * </p> 1748 * 1749 * @return The parent. 1750 */ 1751 public AccessibilityNodeInfoCompat getParent() { 1752 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getParent()); 1753 } 1754 1755 /** 1756 * Sets the parent. 1757 * <p> 1758 * <strong>Note:</strong> Cannot be called from an 1759 * {@link android.accessibilityservice.AccessibilityService}. This class is 1760 * made immutable before being delivered to an AccessibilityService. 1761 * </p> 1762 * 1763 * @param parent The parent. 1764 * @throws IllegalStateException If called from an AccessibilityService. 1765 */ 1766 public void setParent(View parent) { 1767 mInfo.setParent(parent); 1768 } 1769 1770 /** 1771 * Sets the parent to be a virtual descendant of the given <code>root</code>. 1772 * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root 1773 * is set as the parent. 1774 * <p> 1775 * A virtual descendant is an imaginary View that is reported as a part of the view 1776 * hierarchy for accessibility purposes. This enables custom views that draw complex 1777 * content to report them selves as a tree of virtual views, thus conveying their 1778 * logical structure. 1779 * </p> 1780 * <p> 1781 * <strong>Note:</strong> Cannot be called from an 1782 * {@link android.accessibilityservice.AccessibilityService}. 1783 * This class is made immutable before being delivered to an AccessibilityService. 1784 * </p> 1785 * 1786 * @param root The root of the virtual subtree. 1787 * @param virtualDescendantId The id of the virtual descendant. 1788 */ 1789 public void setParent(View root, int virtualDescendantId) { 1790 mParentVirtualDescendantId = virtualDescendantId; 1791 if (Build.VERSION.SDK_INT >= 16) { 1792 mInfo.setParent(root, virtualDescendantId); 1793 } 1794 } 1795 1796 /** 1797 * Gets the node bounds in parent coordinates. 1798 * 1799 * @param outBounds The output node bounds. 1800 */ 1801 public void getBoundsInParent(Rect outBounds) { 1802 mInfo.getBoundsInParent(outBounds); 1803 } 1804 1805 /** 1806 * Sets the node bounds in parent coordinates. 1807 * <p> 1808 * <strong>Note:</strong> Cannot be called from an 1809 * {@link android.accessibilityservice.AccessibilityService}. This class is 1810 * made immutable before being delivered to an AccessibilityService. 1811 * </p> 1812 * 1813 * @param bounds The node bounds. 1814 * @throws IllegalStateException If called from an AccessibilityService. 1815 */ 1816 public void setBoundsInParent(Rect bounds) { 1817 mInfo.setBoundsInParent(bounds); 1818 } 1819 1820 /** 1821 * Gets the node bounds in screen coordinates. 1822 * 1823 * @param outBounds The output node bounds. 1824 */ 1825 public void getBoundsInScreen(Rect outBounds) { 1826 mInfo.getBoundsInScreen(outBounds); 1827 } 1828 1829 /** 1830 * Sets the node bounds in screen coordinates. 1831 * <p> 1832 * <strong>Note:</strong> Cannot be called from an 1833 * {@link android.accessibilityservice.AccessibilityService}. This class is 1834 * made immutable before being delivered to an AccessibilityService. 1835 * </p> 1836 * 1837 * @param bounds The node bounds. 1838 * @throws IllegalStateException If called from an AccessibilityService. 1839 */ 1840 public void setBoundsInScreen(Rect bounds) { 1841 mInfo.setBoundsInScreen(bounds); 1842 } 1843 1844 /** 1845 * Gets whether this node is checkable. 1846 * 1847 * @return True if the node is checkable. 1848 */ 1849 public boolean isCheckable() { 1850 return mInfo.isCheckable(); 1851 } 1852 1853 /** 1854 * Sets whether this node is checkable. 1855 * <p> 1856 * <strong>Note:</strong> Cannot be called from an 1857 * {@link android.accessibilityservice.AccessibilityService}. This class is 1858 * made immutable before being delivered to an AccessibilityService. 1859 * </p> 1860 * 1861 * @param checkable True if the node is checkable. 1862 * @throws IllegalStateException If called from an AccessibilityService. 1863 */ 1864 public void setCheckable(boolean checkable) { 1865 mInfo.setCheckable(checkable); 1866 } 1867 1868 /** 1869 * Gets whether this node is checked. 1870 * 1871 * @return True if the node is checked. 1872 */ 1873 public boolean isChecked() { 1874 return mInfo.isChecked(); 1875 } 1876 1877 /** 1878 * Sets whether this node is checked. 1879 * <p> 1880 * <strong>Note:</strong> Cannot be called from an 1881 * {@link android.accessibilityservice.AccessibilityService}. This class is 1882 * made immutable before being delivered to an AccessibilityService. 1883 * </p> 1884 * 1885 * @param checked True if the node is checked. 1886 * @throws IllegalStateException If called from an AccessibilityService. 1887 */ 1888 public void setChecked(boolean checked) { 1889 mInfo.setChecked(checked); 1890 } 1891 1892 /** 1893 * Gets whether this node is focusable. 1894 * 1895 * @return True if the node is focusable. 1896 */ 1897 public boolean isFocusable() { 1898 return mInfo.isFocusable(); 1899 } 1900 1901 /** 1902 * Sets whether this node is focusable. 1903 * <p> 1904 * <strong>Note:</strong> Cannot be called from an 1905 * {@link android.accessibilityservice.AccessibilityService}. This class is 1906 * made immutable before being delivered to an AccessibilityService. 1907 * </p> 1908 * 1909 * @param focusable True if the node is focusable. 1910 * @throws IllegalStateException If called from an AccessibilityService. 1911 */ 1912 public void setFocusable(boolean focusable) { 1913 mInfo.setFocusable(focusable); 1914 } 1915 1916 /** 1917 * Gets whether this node is focused. 1918 * 1919 * @return True if the node is focused. 1920 */ 1921 public boolean isFocused() { 1922 return mInfo.isFocused(); 1923 } 1924 1925 /** 1926 * Sets whether this node is focused. 1927 * <p> 1928 * <strong>Note:</strong> Cannot be called from an 1929 * {@link android.accessibilityservice.AccessibilityService}. This class is 1930 * made immutable before being delivered to an AccessibilityService. 1931 * </p> 1932 * 1933 * @param focused True if the node is focused. 1934 * @throws IllegalStateException If called from an AccessibilityService. 1935 */ 1936 public void setFocused(boolean focused) { 1937 mInfo.setFocused(focused); 1938 } 1939 1940 /** 1941 * Gets whether this node is visible to the user. 1942 * 1943 * @return Whether the node is visible to the user. 1944 */ 1945 public boolean isVisibleToUser() { 1946 if (Build.VERSION.SDK_INT >= 16) { 1947 return mInfo.isVisibleToUser(); 1948 } else { 1949 return false; 1950 } 1951 } 1952 1953 /** 1954 * Sets whether this node is visible to the user. 1955 * <p> 1956 * <strong>Note:</strong> Cannot be called from an 1957 * {@link android.accessibilityservice.AccessibilityService}. 1958 * This class is made immutable before being delivered to an AccessibilityService. 1959 * </p> 1960 * 1961 * @param visibleToUser Whether the node is visible to the user. 1962 * 1963 * @throws IllegalStateException If called from an AccessibilityService. 1964 */ 1965 public void setVisibleToUser(boolean visibleToUser) { 1966 if (Build.VERSION.SDK_INT >= 16) { 1967 mInfo.setVisibleToUser(visibleToUser); 1968 } 1969 } 1970 1971 /** 1972 * Gets whether this node is accessibility focused. 1973 * 1974 * @return True if the node is accessibility focused. 1975 */ 1976 public boolean isAccessibilityFocused() { 1977 if (Build.VERSION.SDK_INT >= 16) { 1978 return mInfo.isAccessibilityFocused(); 1979 } else { 1980 return false; 1981 } 1982 } 1983 1984 /** 1985 * Sets whether this node is accessibility focused. 1986 * <p> 1987 * <strong>Note:</strong> Cannot be called from an 1988 * {@link android.accessibilityservice.AccessibilityService}. 1989 * This class is made immutable before being delivered to an AccessibilityService. 1990 * </p> 1991 * 1992 * @param focused True if the node is accessibility focused. 1993 * 1994 * @throws IllegalStateException If called from an AccessibilityService. 1995 */ 1996 public void setAccessibilityFocused(boolean focused) { 1997 if (Build.VERSION.SDK_INT >= 16) { 1998 mInfo.setAccessibilityFocused(focused); 1999 } 2000 } 2001 2002 /** 2003 * Gets whether this node is selected. 2004 * 2005 * @return True if the node is selected. 2006 */ 2007 public boolean isSelected() { 2008 return mInfo.isSelected(); 2009 } 2010 2011 /** 2012 * Sets whether this node is selected. 2013 * <p> 2014 * <strong>Note:</strong> Cannot be called from an 2015 * {@link android.accessibilityservice.AccessibilityService}. This class is 2016 * made immutable before being delivered to an AccessibilityService. 2017 * </p> 2018 * 2019 * @param selected True if the node is selected. 2020 * @throws IllegalStateException If called from an AccessibilityService. 2021 */ 2022 public void setSelected(boolean selected) { 2023 mInfo.setSelected(selected); 2024 } 2025 2026 /** 2027 * Gets whether this node is clickable. 2028 * 2029 * @return True if the node is clickable. 2030 */ 2031 public boolean isClickable() { 2032 return mInfo.isClickable(); 2033 } 2034 2035 /** 2036 * Sets whether this node is clickable. 2037 * <p> 2038 * <strong>Note:</strong> Cannot be called from an 2039 * {@link android.accessibilityservice.AccessibilityService}. This class is 2040 * made immutable before being delivered to an AccessibilityService. 2041 * </p> 2042 * 2043 * @param clickable True if the node is clickable. 2044 * @throws IllegalStateException If called from an AccessibilityService. 2045 */ 2046 public void setClickable(boolean clickable) { 2047 mInfo.setClickable(clickable); 2048 } 2049 2050 /** 2051 * Gets whether this node is long clickable. 2052 * 2053 * @return True if the node is long clickable. 2054 */ 2055 public boolean isLongClickable() { 2056 return mInfo.isLongClickable(); 2057 } 2058 2059 /** 2060 * Sets whether this node is long clickable. 2061 * <p> 2062 * <strong>Note:</strong> Cannot be called from an 2063 * {@link android.accessibilityservice.AccessibilityService}. This class is 2064 * made immutable before being delivered to an AccessibilityService. 2065 * </p> 2066 * 2067 * @param longClickable True if the node is long clickable. 2068 * @throws IllegalStateException If called from an AccessibilityService. 2069 */ 2070 public void setLongClickable(boolean longClickable) { 2071 mInfo.setLongClickable(longClickable); 2072 } 2073 2074 /** 2075 * Gets whether this node is enabled. 2076 * 2077 * @return True if the node is enabled. 2078 */ 2079 public boolean isEnabled() { 2080 return mInfo.isEnabled(); 2081 } 2082 2083 /** 2084 * Sets whether this node is enabled. 2085 * <p> 2086 * <strong>Note:</strong> Cannot be called from an 2087 * {@link android.accessibilityservice.AccessibilityService}. This class is 2088 * made immutable before being delivered to an AccessibilityService. 2089 * </p> 2090 * 2091 * @param enabled True if the node is enabled. 2092 * @throws IllegalStateException If called from an AccessibilityService. 2093 */ 2094 public void setEnabled(boolean enabled) { 2095 mInfo.setEnabled(enabled); 2096 } 2097 2098 /** 2099 * Gets whether this node is a password. 2100 * 2101 * @return True if the node is a password. 2102 */ 2103 public boolean isPassword() { 2104 return mInfo.isPassword(); 2105 } 2106 2107 /** 2108 * Sets whether this node is a password. 2109 * <p> 2110 * <strong>Note:</strong> Cannot be called from an 2111 * {@link android.accessibilityservice.AccessibilityService}. This class is 2112 * made immutable before being delivered to an AccessibilityService. 2113 * </p> 2114 * 2115 * @param password True if the node is a password. 2116 * @throws IllegalStateException If called from an AccessibilityService. 2117 */ 2118 public void setPassword(boolean password) { 2119 mInfo.setPassword(password); 2120 } 2121 2122 /** 2123 * Gets if the node is scrollable. 2124 * 2125 * @return True if the node is scrollable, false otherwise. 2126 */ 2127 public boolean isScrollable() { 2128 return mInfo.isScrollable(); 2129 } 2130 2131 /** 2132 * Sets if the node is scrollable. 2133 * <p> 2134 * <strong>Note:</strong> Cannot be called from an 2135 * {@link android.accessibilityservice.AccessibilityService}. This class is 2136 * made immutable before being delivered to an AccessibilityService. 2137 * </p> 2138 * 2139 * @param scrollable True if the node is scrollable, false otherwise. 2140 * @throws IllegalStateException If called from an AccessibilityService. 2141 */ 2142 public void setScrollable(boolean scrollable) { 2143 mInfo.setScrollable(scrollable); 2144 } 2145 2146 /** 2147 * Returns whether the node originates from a view considered important for accessibility. 2148 * 2149 * @return {@code true} if the node originates from a view considered important for 2150 * accessibility, {@code false} otherwise 2151 * 2152 * @see View#isImportantForAccessibility() 2153 */ 2154 public boolean isImportantForAccessibility() { 2155 if (Build.VERSION.SDK_INT >= 24) { 2156 return mInfo.isImportantForAccessibility(); 2157 } else { 2158 return true; 2159 } 2160 } 2161 2162 /** 2163 * Sets whether the node is considered important for accessibility. 2164 * <p> 2165 * <strong>Note:</strong> Cannot be called from an 2166 * {@link android.accessibilityservice.AccessibilityService}. 2167 * This class is made immutable before being delivered to an AccessibilityService. 2168 * </p> 2169 * 2170 * @param important {@code true} if the node is considered important for accessibility, 2171 * {@code false} otherwise 2172 */ 2173 public void setImportantForAccessibility(boolean important) { 2174 if (Build.VERSION.SDK_INT >= 24) { 2175 mInfo.setImportantForAccessibility(important); 2176 } 2177 } 2178 2179 /** 2180 * Gets the package this node comes from. 2181 * 2182 * @return The package name. 2183 */ 2184 public CharSequence getPackageName() { 2185 return mInfo.getPackageName(); 2186 } 2187 2188 /** 2189 * Sets the package this node comes from. 2190 * <p> 2191 * <strong>Note:</strong> Cannot be called from an 2192 * {@link android.accessibilityservice.AccessibilityService}. This class is 2193 * made immutable before being delivered to an AccessibilityService. 2194 * </p> 2195 * 2196 * @param packageName The package name. 2197 * @throws IllegalStateException If called from an AccessibilityService. 2198 */ 2199 public void setPackageName(CharSequence packageName) { 2200 mInfo.setPackageName(packageName); 2201 } 2202 2203 /** 2204 * Gets the class this node comes from. 2205 * 2206 * @return The class name. 2207 */ 2208 public CharSequence getClassName() { 2209 return mInfo.getClassName(); 2210 } 2211 2212 /** 2213 * Sets the class this node comes from. 2214 * <p> 2215 * <strong>Note:</strong> Cannot be called from an 2216 * {@link android.accessibilityservice.AccessibilityService}. This class is 2217 * made immutable before being delivered to an AccessibilityService. 2218 * </p> 2219 * 2220 * @param className The class name. 2221 * @throws IllegalStateException If called from an AccessibilityService. 2222 */ 2223 public void setClassName(CharSequence className) { 2224 mInfo.setClassName(className); 2225 } 2226 2227 /** 2228 * Gets the text of this node. 2229 * 2230 * @return The text. 2231 */ 2232 public CharSequence getText() { 2233 return mInfo.getText(); 2234 } 2235 2236 /** 2237 * Sets the text of this node. 2238 * <p> 2239 * <strong>Note:</strong> Cannot be called from an 2240 * {@link android.accessibilityservice.AccessibilityService}. This class is 2241 * made immutable before being delivered to an AccessibilityService. 2242 * </p> 2243 * 2244 * @param text The text. 2245 * @throws IllegalStateException If called from an AccessibilityService. 2246 */ 2247 public void setText(CharSequence text) { 2248 mInfo.setText(text); 2249 } 2250 2251 /** 2252 * Gets the content description of this node. 2253 * 2254 * @return The content description. 2255 */ 2256 public CharSequence getContentDescription() { 2257 return mInfo.getContentDescription(); 2258 } 2259 2260 /** 2261 * Sets the content description of this node. 2262 * <p> 2263 * <strong>Note:</strong> Cannot be called from an 2264 * {@link android.accessibilityservice.AccessibilityService}. This class is 2265 * made immutable before being delivered to an AccessibilityService. 2266 * </p> 2267 * 2268 * @param contentDescription The content description. 2269 * @throws IllegalStateException If called from an AccessibilityService. 2270 */ 2271 public void setContentDescription(CharSequence contentDescription) { 2272 mInfo.setContentDescription(contentDescription); 2273 } 2274 2275 /** 2276 * Return an instance back to be reused. 2277 * <p> 2278 * <strong>Note:</strong> You must not touch the object after calling this function. 2279 * 2280 * @throws IllegalStateException If the info is already recycled. 2281 */ 2282 public void recycle() { 2283 mInfo.recycle(); 2284 } 2285 2286 /** 2287 * Sets the fully qualified resource name of the source view's id. 2288 * 2289 * <p> 2290 * <strong>Note:</strong> Cannot be called from an 2291 * {@link android.accessibilityservice.AccessibilityService}. 2292 * This class is made immutable before being delivered to an AccessibilityService. 2293 * </p> 2294 * 2295 * @param viewId The id resource name. 2296 */ 2297 public void setViewIdResourceName(String viewId) { 2298 if (Build.VERSION.SDK_INT >= 18) { 2299 mInfo.setViewIdResourceName(viewId); 2300 } 2301 } 2302 2303 /** 2304 * Gets the fully qualified resource name of the source view's id. 2305 * 2306 * <p> 2307 * <strong>Note:</strong> The primary usage of this API is for UI test automation 2308 * and in order to report the source view id of an {@link AccessibilityNodeInfoCompat} 2309 * the client has to set the {@link AccessibilityServiceInfoCompat#FLAG_REPORT_VIEW_IDS} 2310 * flag when configuring his {@link android.accessibilityservice.AccessibilityService}. 2311 * </p> 2312 * 2313 * @return The id resource name. 2314 */ 2315 public String getViewIdResourceName() { 2316 if (Build.VERSION.SDK_INT >= 18) { 2317 return mInfo.getViewIdResourceName(); 2318 } else { 2319 return null; 2320 } 2321 } 2322 2323 /** 2324 * Gets the node's live region mode. 2325 * <p> 2326 * A live region is a node that contains information that is important for 2327 * the user and when it changes the user should be notified. For example, 2328 * in a login screen with a TextView that displays an "incorrect password" 2329 * notification, that view should be marked as a live region with mode 2330 * {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_POLITE}. 2331 * <p> 2332 * It is the responsibility of the accessibility service to monitor 2333 * {@link AccessibilityEventCompat#TYPE_WINDOW_CONTENT_CHANGED} events 2334 * indicating changes to live region nodes and their children. 2335 * 2336 * @return The live region mode, or 2337 * {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is 2338 * not a live region. 2339 * @see ViewCompat#getAccessibilityLiveRegion(View) 2340 */ 2341 public int getLiveRegion() { 2342 if (Build.VERSION.SDK_INT >= 19) { 2343 return mInfo.getLiveRegion(); 2344 } else { 2345 return ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE; 2346 } 2347 } 2348 2349 /** 2350 * Sets the node's live region mode. 2351 * <p> 2352 * <strong>Note:</strong> Cannot be called from an 2353 * {@link android.accessibilityservice.AccessibilityService}. This class is 2354 * made immutable before being delivered to an AccessibilityService. 2355 * 2356 * @param mode The live region mode, or 2357 * {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is 2358 * not a live region. 2359 * @see ViewCompat#setAccessibilityLiveRegion(View, int) 2360 */ 2361 public void setLiveRegion(int mode) { 2362 if (Build.VERSION.SDK_INT >= 19) { 2363 mInfo.setLiveRegion(mode); 2364 } 2365 } 2366 2367 /** 2368 * Get the drawing order of the view corresponding it this node. 2369 * <p> 2370 * Drawing order is determined only within the node's parent, so this index is only relative 2371 * to its siblings. 2372 * <p> 2373 * In some cases, the drawing order is essentially simultaneous, so it is possible for two 2374 * siblings to return the same value. It is also possible that values will be skipped. 2375 * 2376 * @return The drawing position of the view corresponding to this node relative to its siblings. 2377 */ 2378 public int getDrawingOrder() { 2379 if (Build.VERSION.SDK_INT >= 24) { 2380 return mInfo.getDrawingOrder(); 2381 } else { 2382 return 0; 2383 } 2384 } 2385 2386 /** 2387 * Set the drawing order of the view corresponding it this node. 2388 * 2389 * <p> 2390 * <strong>Note:</strong> Cannot be called from an 2391 * {@link android.accessibilityservice.AccessibilityService}. 2392 * This class is made immutable before being delivered to an AccessibilityService. 2393 * </p> 2394 * @param drawingOrderInParent 2395 * @throws IllegalStateException If called from an AccessibilityService. 2396 */ 2397 public void setDrawingOrder(int drawingOrderInParent) { 2398 if (Build.VERSION.SDK_INT >= 24) { 2399 mInfo.setDrawingOrder(drawingOrderInParent); 2400 } 2401 } 2402 2403 /** 2404 * Gets the collection info if the node is a collection. A collection 2405 * child is always a collection item. 2406 * 2407 * @return The collection info. 2408 */ 2409 public CollectionInfoCompat getCollectionInfo() { 2410 if (Build.VERSION.SDK_INT >= 19) { 2411 AccessibilityNodeInfo.CollectionInfo info = mInfo.getCollectionInfo(); 2412 if (info != null) { 2413 return new CollectionInfoCompat(info); 2414 } 2415 } 2416 return null; 2417 } 2418 2419 public void setCollectionInfo(Object collectionInfo) { 2420 if (Build.VERSION.SDK_INT >= 19) { 2421 mInfo.setCollectionInfo((collectionInfo == null) ? null 2422 : (AccessibilityNodeInfo.CollectionInfo) ((CollectionInfoCompat) 2423 collectionInfo).mInfo); 2424 } 2425 2426 } 2427 2428 public void setCollectionItemInfo(Object collectionItemInfo) { 2429 if (Build.VERSION.SDK_INT >= 19) { 2430 mInfo.setCollectionItemInfo((collectionItemInfo == null) ? null 2431 : (AccessibilityNodeInfo.CollectionItemInfo) ((CollectionItemInfoCompat) 2432 collectionItemInfo).mInfo); 2433 } 2434 } 2435 2436 /** 2437 * Gets the collection item info if the node is a collection item. A collection 2438 * item is always a child of a collection. 2439 * 2440 * @return The collection item info. 2441 */ 2442 public CollectionItemInfoCompat getCollectionItemInfo() { 2443 if (Build.VERSION.SDK_INT >= 19) { 2444 AccessibilityNodeInfo.CollectionItemInfo info = mInfo.getCollectionItemInfo(); 2445 if (info != null) { 2446 return new CollectionItemInfoCompat(info); 2447 } 2448 } 2449 return null; 2450 } 2451 2452 /** 2453 * Gets the range info if this node is a range. 2454 * 2455 * @return The range. 2456 */ 2457 public RangeInfoCompat getRangeInfo() { 2458 if (Build.VERSION.SDK_INT >= 19) { 2459 AccessibilityNodeInfo.RangeInfo info = mInfo.getRangeInfo(); 2460 if (info != null) { 2461 return new RangeInfoCompat(info); 2462 } 2463 } 2464 return null; 2465 } 2466 2467 /** 2468 * Sets the range info if this node is a range. 2469 * <p> 2470 * <strong>Note:</strong> Cannot be called from an 2471 * {@link android.accessibilityservice.AccessibilityService}. 2472 * This class is made immutable before being delivered to an AccessibilityService. 2473 * </p> 2474 * 2475 * @param rangeInfo The range info. 2476 */ 2477 public void setRangeInfo(RangeInfoCompat rangeInfo) { 2478 if (Build.VERSION.SDK_INT >= 19) { 2479 mInfo.setRangeInfo((AccessibilityNodeInfo.RangeInfo) rangeInfo.mInfo); 2480 } 2481 } 2482 2483 /** 2484 * Gets the actions that can be performed on the node. 2485 * 2486 * @return A list of AccessibilityActions. 2487 */ 2488 @SuppressWarnings("unchecked") 2489 public List<AccessibilityActionCompat> getActionList() { 2490 List<Object> actions = null; 2491 if (Build.VERSION.SDK_INT >= 21) { 2492 actions = (List<Object>) (List<?>) mInfo.getActionList(); 2493 } 2494 if (actions != null) { 2495 List<AccessibilityActionCompat> result = new ArrayList<AccessibilityActionCompat>(); 2496 final int actionCount = actions.size(); 2497 for (int i = 0; i < actionCount; i++) { 2498 Object action = actions.get(i); 2499 result.add(new AccessibilityActionCompat(action)); 2500 } 2501 return result; 2502 } else { 2503 return Collections.<AccessibilityActionCompat>emptyList(); 2504 } 2505 } 2506 2507 /** 2508 * Sets if the content of this node is invalid. For example, 2509 * a date is not well-formed. 2510 * <p> 2511 * <strong>Note:</strong> Cannot be called from an 2512 * {@link android.accessibilityservice.AccessibilityService}. 2513 * This class is made immutable before being delivered to an AccessibilityService. 2514 * </p> 2515 * 2516 * @param contentInvalid If the node content is invalid. 2517 */ 2518 public void setContentInvalid(boolean contentInvalid) { 2519 if (Build.VERSION.SDK_INT >= 19) { 2520 mInfo.setContentInvalid(contentInvalid); 2521 } 2522 } 2523 2524 /** 2525 * Gets if the content of this node is invalid. For example, 2526 * a date is not well-formed. 2527 * 2528 * @return If the node content is invalid. 2529 */ 2530 public boolean isContentInvalid() { 2531 if (Build.VERSION.SDK_INT >= 19) { 2532 return mInfo.isContentInvalid(); 2533 } else { 2534 return false; 2535 } 2536 } 2537 2538 /** 2539 * Gets whether this node is context clickable. 2540 * 2541 * @return True if the node is context clickable. 2542 */ 2543 public boolean isContextClickable() { 2544 if (Build.VERSION.SDK_INT >= 23) { 2545 return mInfo.isContextClickable(); 2546 } else { 2547 return false; 2548 } 2549 } 2550 2551 /** 2552 * Sets whether this node is context clickable. 2553 * <p> 2554 * <strong>Note:</strong> Cannot be called from an 2555 * {@link android.accessibilityservice.AccessibilityService}. This class is made immutable 2556 * before being delivered to an AccessibilityService. 2557 * </p> 2558 * 2559 * @param contextClickable True if the node is context clickable. 2560 * @throws IllegalStateException If called from an AccessibilityService. 2561 */ 2562 public void setContextClickable(boolean contextClickable) { 2563 if (Build.VERSION.SDK_INT >= 23) { 2564 mInfo.setContextClickable(contextClickable); 2565 } 2566 } 2567 2568 /** 2569 * Gets the hint text of this node. Only applies to nodes where text can be entered. 2570 * 2571 * @return The hint text. 2572 */ 2573 public @Nullable CharSequence getHintText() { 2574 if (Build.VERSION.SDK_INT >= 26) { 2575 return mInfo.getHintText(); 2576 } else if (Build.VERSION.SDK_INT >= 19) { 2577 return mInfo.getExtras().getCharSequence(HINT_TEXT_KEY); 2578 } 2579 return null; 2580 } 2581 2582 /** 2583 * Sets the hint text of this node. Only applies to nodes where text can be entered. 2584 * <p>This method has no effect below API 19</p> 2585 * <p> 2586 * <strong>Note:</strong> Cannot be called from an 2587 * {@link android.accessibilityservice.AccessibilityService}. 2588 * This class is made immutable before being delivered to an AccessibilityService. 2589 * </p> 2590 * 2591 * @param hintText The hint text for this mode. 2592 * 2593 * @throws IllegalStateException If called from an AccessibilityService. 2594 */ 2595 public void setHintText(@Nullable CharSequence hintText) { 2596 if (Build.VERSION.SDK_INT >= 26) { 2597 mInfo.setHintText(hintText); 2598 } else if (Build.VERSION.SDK_INT >= 19) { 2599 mInfo.getExtras().putCharSequence(HINT_TEXT_KEY, hintText); 2600 } 2601 } 2602 2603 2604 /** 2605 * Sets the error text of this node. 2606 * <p> 2607 * <strong>Note:</strong> Cannot be called from an 2608 * {@link android.accessibilityservice.AccessibilityService}. 2609 * This class is made immutable before being delivered to an AccessibilityService. 2610 * </p> 2611 * 2612 * @param error The error text. 2613 * 2614 * @throws IllegalStateException If called from an AccessibilityService. 2615 */ 2616 public void setError(CharSequence error) { 2617 if (Build.VERSION.SDK_INT >= 21) { 2618 mInfo.setError(error); 2619 } 2620 } 2621 2622 /** 2623 * Gets the error text of this node. 2624 * 2625 * @return The error text. 2626 */ 2627 public CharSequence getError() { 2628 if (Build.VERSION.SDK_INT >= 21) { 2629 return mInfo.getError(); 2630 } else { 2631 return null; 2632 } 2633 } 2634 2635 /** 2636 * Sets the view for which the view represented by this info serves as a 2637 * label for accessibility purposes. 2638 * 2639 * @param labeled The view for which this info serves as a label. 2640 */ 2641 public void setLabelFor(View labeled) { 2642 if (Build.VERSION.SDK_INT >= 17) { 2643 mInfo.setLabelFor(labeled); 2644 } 2645 } 2646 2647 /** 2648 * Sets the view for which the view represented by this info serves as a 2649 * label for accessibility purposes. If <code>virtualDescendantId</code> 2650 * is {@link View#NO_ID} the root is set as the labeled. 2651 * <p> 2652 * A virtual descendant is an imaginary View that is reported as a part of the view 2653 * hierarchy for accessibility purposes. This enables custom views that draw complex 2654 * content to report themselves as a tree of virtual views, thus conveying their 2655 * logical structure. 2656 * </p> 2657 * 2658 * @param root The root whose virtual descendant serves as a label. 2659 * @param virtualDescendantId The id of the virtual descendant. 2660 */ 2661 public void setLabelFor(View root, int virtualDescendantId) { 2662 if (Build.VERSION.SDK_INT >= 17) { 2663 mInfo.setLabelFor(root, virtualDescendantId); 2664 } 2665 } 2666 2667 /** 2668 * Gets the node info for which the view represented by this info serves as 2669 * a label for accessibility purposes. 2670 * <p> 2671 * <strong>Note:</strong> It is a client responsibility to recycle the 2672 * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} 2673 * to avoid creating of multiple instances. 2674 * </p> 2675 * 2676 * @return The labeled info. 2677 */ 2678 public AccessibilityNodeInfoCompat getLabelFor() { 2679 if (Build.VERSION.SDK_INT >= 17) { 2680 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabelFor()); 2681 } else { 2682 return null; 2683 } 2684 } 2685 2686 /** 2687 * Sets the view which serves as the label of the view represented by 2688 * this info for accessibility purposes. 2689 * 2690 * @param label The view that labels this node's source. 2691 */ 2692 public void setLabeledBy(View label) { 2693 if (Build.VERSION.SDK_INT >= 17) { 2694 mInfo.setLabeledBy(label); 2695 } 2696 } 2697 2698 /** 2699 * Sets the view which serves as the label of the view represented by 2700 * this info for accessibility purposes. If <code>virtualDescendantId</code> 2701 * is {@link View#NO_ID} the root is set as the label. 2702 * <p> 2703 * A virtual descendant is an imaginary View that is reported as a part of the view 2704 * hierarchy for accessibility purposes. This enables custom views that draw complex 2705 * content to report themselves as a tree of virtual views, thus conveying their 2706 * logical structure. 2707 * </p> 2708 * <p> 2709 * <strong>Note:</strong> Cannot be called from an 2710 * {@link android.accessibilityservice.AccessibilityService}. 2711 * This class is made immutable before being delivered to an AccessibilityService. 2712 * </p> 2713 * 2714 * @param root The root whose virtual descendant labels this node's source. 2715 * @param virtualDescendantId The id of the virtual descendant. 2716 */ 2717 public void setLabeledBy(View root, int virtualDescendantId) { 2718 if (Build.VERSION.SDK_INT >= 17) { 2719 mInfo.setLabeledBy(root, virtualDescendantId); 2720 } 2721 } 2722 2723 /** 2724 * Gets the node info which serves as the label of the view represented by 2725 * this info for accessibility purposes. 2726 * <p> 2727 * <strong>Note:</strong> It is a client responsibility to recycle the 2728 * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} 2729 * to avoid creating of multiple instances. 2730 * </p> 2731 * 2732 * @return The label. 2733 */ 2734 public AccessibilityNodeInfoCompat getLabeledBy() { 2735 if (Build.VERSION.SDK_INT >= 17) { 2736 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabeledBy()); 2737 } else { 2738 return null; 2739 } 2740 } 2741 2742 /** 2743 * Gets if this node opens a popup or a dialog. 2744 * 2745 * @return If the the node opens a popup. 2746 */ 2747 public boolean canOpenPopup() { 2748 if (Build.VERSION.SDK_INT >= 19) { 2749 return mInfo.canOpenPopup(); 2750 } else { 2751 return false; 2752 } 2753 } 2754 2755 /** 2756 * Sets if this node opens a popup or a dialog. 2757 * <p> 2758 * <strong>Note:</strong> Cannot be called from an 2759 * {@link android.accessibilityservice.AccessibilityService}. 2760 * This class is made immutable before being delivered to an AccessibilityService. 2761 * </p> 2762 * 2763 * @param opensPopup If the the node opens a popup. 2764 */ 2765 public void setCanOpenPopup(boolean opensPopup) { 2766 if (Build.VERSION.SDK_INT >= 19) { 2767 mInfo.setCanOpenPopup(opensPopup); 2768 } 2769 } 2770 2771 /** 2772 * Finds {@link AccessibilityNodeInfoCompat}s by the fully qualified view id's resource 2773 * name where a fully qualified id is of the from "package:id/id_resource_name". 2774 * For example, if the target application's package is "foo.bar" and the id 2775 * resource name is "baz", the fully qualified resource id is "foo.bar:id/baz". 2776 * 2777 * <p> 2778 * <strong>Note:</strong> It is a client responsibility to recycle the 2779 * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} 2780 * to avoid creating of multiple instances. 2781 * </p> 2782 * <p> 2783 * <strong>Note:</strong> The primary usage of this API is for UI test automation 2784 * and in order to report the fully qualified view id if an 2785 * {@link AccessibilityNodeInfoCompat} the client has to set the 2786 * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS} 2787 * flag when configuring his {@link android.accessibilityservice.AccessibilityService}. 2788 * </p> 2789 * 2790 * @param viewId The fully qualified resource name of the view id to find. 2791 * @return A list of node info. 2792 */ 2793 public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(String viewId) { 2794 if (Build.VERSION.SDK_INT >= 18) { 2795 List<AccessibilityNodeInfo> nodes = mInfo.findAccessibilityNodeInfosByViewId(viewId); 2796 List<AccessibilityNodeInfoCompat> result = new ArrayList<>(); 2797 for (AccessibilityNodeInfo node : nodes) { 2798 result.add(AccessibilityNodeInfoCompat.wrap(node)); 2799 } 2800 return result; 2801 } else { 2802 return Collections.emptyList(); 2803 } 2804 } 2805 2806 /** 2807 * Gets an optional bundle with extra data. The bundle 2808 * is lazily created and never <code>null</code>. 2809 * <p> 2810 * <strong>Note:</strong> It is recommended to use the package 2811 * name of your application as a prefix for the keys to avoid 2812 * collisions which may confuse an accessibility service if the 2813 * same key has different meaning when emitted from different 2814 * applications. 2815 * </p> 2816 * 2817 * @return The bundle. 2818 */ 2819 public Bundle getExtras() { 2820 if (Build.VERSION.SDK_INT >= 19) { 2821 return mInfo.getExtras(); 2822 } else { 2823 return new Bundle(); 2824 } 2825 } 2826 2827 /** 2828 * Gets the input type of the source as defined by {@link InputType}. 2829 * 2830 * @return The input type. 2831 */ 2832 public int getInputType() { 2833 if (Build.VERSION.SDK_INT >= 19) { 2834 return mInfo.getInputType(); 2835 } else { 2836 return InputType.TYPE_NULL; 2837 } 2838 } 2839 2840 /** 2841 * Sets the input type of the source as defined by {@link InputType}. 2842 * <p> 2843 * <strong>Note:</strong> Cannot be called from an 2844 * {@link android.accessibilityservice.AccessibilityService}. 2845 * This class is made immutable before being delivered to an 2846 * AccessibilityService. 2847 * </p> 2848 * 2849 * @param inputType The input type. 2850 * 2851 * @throws IllegalStateException If called from an AccessibilityService. 2852 */ 2853 public void setInputType(int inputType) { 2854 if (Build.VERSION.SDK_INT >= 19) { 2855 mInfo.setInputType(inputType); 2856 } 2857 } 2858 2859 /** 2860 * Sets the maximum text length, or -1 for no limit. 2861 * <p> 2862 * Typically used to indicate that an editable text field has a limit on 2863 * the number of characters entered. 2864 * <p> 2865 * <strong>Note:</strong> Cannot be called from an 2866 * {@link android.accessibilityservice.AccessibilityService}. 2867 * This class is made immutable before being delivered to an AccessibilityService. 2868 * 2869 * @param max The maximum text length. 2870 * @see #getMaxTextLength() 2871 * 2872 * @throws IllegalStateException If called from an AccessibilityService. 2873 */ 2874 public void setMaxTextLength(int max) { 2875 if (Build.VERSION.SDK_INT >= 21) { 2876 mInfo.setMaxTextLength(max); 2877 } 2878 } 2879 2880 /** 2881 * Returns the maximum text length for this node. 2882 * 2883 * @return The maximum text length, or -1 for no limit. 2884 * @see #setMaxTextLength(int) 2885 */ 2886 public int getMaxTextLength() { 2887 if (Build.VERSION.SDK_INT >= 21) { 2888 return mInfo.getMaxTextLength(); 2889 } else { 2890 return -1; 2891 } 2892 } 2893 2894 /** 2895 * Sets the text selection start and end. 2896 * <p> 2897 * <strong>Note:</strong> Cannot be called from an 2898 * {@link android.accessibilityservice.AccessibilityService}. 2899 * This class is made immutable before being delivered to an AccessibilityService. 2900 * </p> 2901 * 2902 * @param start The text selection start. 2903 * @param end The text selection end. 2904 * 2905 * @throws IllegalStateException If called from an AccessibilityService. 2906 */ 2907 public void setTextSelection(int start, int end) { 2908 if (Build.VERSION.SDK_INT >= 18) { 2909 mInfo.setTextSelection(start, end); 2910 } 2911 } 2912 2913 /** 2914 * Gets the text selection start. 2915 * 2916 * @return The text selection start if there is selection or -1. 2917 */ 2918 public int getTextSelectionStart() { 2919 if (Build.VERSION.SDK_INT >= 18) { 2920 return mInfo.getTextSelectionStart(); 2921 } else { 2922 return -1; 2923 } 2924 } 2925 2926 /** 2927 * Gets the text selection end. 2928 * 2929 * @return The text selection end if there is selection or -1. 2930 */ 2931 public int getTextSelectionEnd() { 2932 if (Build.VERSION.SDK_INT >= 18) { 2933 return mInfo.getTextSelectionEnd(); 2934 } else { 2935 return -1; 2936 } 2937 } 2938 2939 /** 2940 * Gets the node before which this one is visited during traversal. A screen-reader 2941 * must visit the content of this node before the content of the one it precedes. 2942 * 2943 * @return The succeeding node if such or <code>null</code>. 2944 * 2945 * @see #setTraversalBefore(android.view.View) 2946 * @see #setTraversalBefore(android.view.View, int) 2947 */ 2948 public AccessibilityNodeInfoCompat getTraversalBefore() { 2949 if (Build.VERSION.SDK_INT >= 22) { 2950 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getTraversalBefore()); 2951 } else { 2952 return null; 2953 } 2954 } 2955 2956 /** 2957 * Sets the view before whose node this one should be visited during traversal. A 2958 * screen-reader must visit the content of this node before the content of the one 2959 * it precedes. 2960 * <p> 2961 * <strong>Note:</strong> Cannot be called from an 2962 * {@link android.accessibilityservice.AccessibilityService}. 2963 * This class is made immutable before being delivered to an AccessibilityService. 2964 * </p> 2965 * 2966 * @param view The view providing the preceding node. 2967 * 2968 * @see #getTraversalBefore() 2969 */ 2970 public void setTraversalBefore(View view) { 2971 if (Build.VERSION.SDK_INT >= 22) { 2972 mInfo.setTraversalBefore(view); 2973 } 2974 } 2975 2976 /** 2977 * Sets the node before which this one is visited during traversal. A screen-reader 2978 * must visit the content of this node before the content of the one it precedes. 2979 * The successor is a virtual descendant of the given <code>root</code>. If 2980 * <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root is set 2981 * as the successor. 2982 * <p> 2983 * A virtual descendant is an imaginary View that is reported as a part of the view 2984 * hierarchy for accessibility purposes. This enables custom views that draw complex 2985 * content to report them selves as a tree of virtual views, thus conveying their 2986 * logical structure. 2987 * </p> 2988 * <p> 2989 * <strong>Note:</strong> Cannot be called from an 2990 * {@link android.accessibilityservice.AccessibilityService}. 2991 * This class is made immutable before being delivered to an AccessibilityService. 2992 * </p> 2993 * 2994 * @param root The root of the virtual subtree. 2995 * @param virtualDescendantId The id of the virtual descendant. 2996 */ 2997 public void setTraversalBefore(View root, int virtualDescendantId) { 2998 if (Build.VERSION.SDK_INT >= 22) { 2999 mInfo.setTraversalBefore(root, virtualDescendantId); 3000 } 3001 } 3002 3003 /** 3004 * Gets the node after which this one is visited in accessibility traversal. 3005 * A screen-reader must visit the content of the other node before the content 3006 * of this one. 3007 * 3008 * @return The succeeding node if such or <code>null</code>. 3009 * 3010 * @see #setTraversalAfter(android.view.View) 3011 * @see #setTraversalAfter(android.view.View, int) 3012 */ 3013 public AccessibilityNodeInfoCompat getTraversalAfter() { 3014 if (Build.VERSION.SDK_INT >= 22) { 3015 return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getTraversalAfter()); 3016 } else { 3017 return null; 3018 } 3019 } 3020 3021 /** 3022 * Sets the view whose node is visited after this one in accessibility traversal. 3023 * A screen-reader must visit the content of the other node before the content 3024 * of this one. 3025 * <p> 3026 * <strong>Note:</strong> Cannot be called from an 3027 * {@link android.accessibilityservice.AccessibilityService}. 3028 * This class is made immutable before being delivered to an AccessibilityService. 3029 * </p> 3030 * 3031 * @param view The previous view. 3032 * 3033 * @see #getTraversalAfter() 3034 */ 3035 public void setTraversalAfter(View view) { 3036 if (Build.VERSION.SDK_INT >= 22) { 3037 mInfo.setTraversalAfter(view); 3038 } 3039 } 3040 3041 /** 3042 * Sets the node after which this one is visited in accessibility traversal. 3043 * A screen-reader must visit the content of the other node before the content 3044 * of this one. If <code>virtualDescendantId</code> equals to {@link View#NO_ID} 3045 * the root is set as the predecessor. 3046 * <p> 3047 * A virtual descendant is an imaginary View that is reported as a part of the view 3048 * hierarchy for accessibility purposes. This enables custom views that draw complex 3049 * content to report them selves as a tree of virtual views, thus conveying their 3050 * logical structure. 3051 * </p> 3052 * <p> 3053 * <strong>Note:</strong> Cannot be called from an 3054 * {@link android.accessibilityservice.AccessibilityService}. 3055 * This class is made immutable before being delivered to an AccessibilityService. 3056 * </p> 3057 * 3058 * @param root The root of the virtual subtree. 3059 * @param virtualDescendantId The id of the virtual descendant. 3060 */ 3061 public void setTraversalAfter(View root, int virtualDescendantId) { 3062 if (Build.VERSION.SDK_INT >= 22) { 3063 mInfo.setTraversalAfter(root, virtualDescendantId); 3064 } 3065 } 3066 3067 /** 3068 * Gets the window to which this node belongs. 3069 * 3070 * @return The window. 3071 * 3072 * @see android.accessibilityservice.AccessibilityService#getWindows() 3073 */ 3074 public AccessibilityWindowInfoCompat getWindow() { 3075 if (Build.VERSION.SDK_INT >= 21) { 3076 return AccessibilityWindowInfoCompat.wrapNonNullInstance(mInfo.getWindow()); 3077 } else { 3078 return null; 3079 } 3080 } 3081 3082 /** 3083 * Gets if the node can be dismissed. 3084 * 3085 * @return If the node can be dismissed. 3086 */ 3087 public boolean isDismissable() { 3088 if (Build.VERSION.SDK_INT >= 19) { 3089 return mInfo.isDismissable(); 3090 } else { 3091 return false; 3092 } 3093 } 3094 3095 /** 3096 * Sets if the node can be dismissed. 3097 * <p> 3098 * <strong>Note:</strong> Cannot be called from an 3099 * {@link android.accessibilityservice.AccessibilityService}. 3100 * This class is made immutable before being delivered to an AccessibilityService. 3101 * </p> 3102 * 3103 * @param dismissable If the node can be dismissed. 3104 */ 3105 public void setDismissable(boolean dismissable) { 3106 if (Build.VERSION.SDK_INT >= 19) { 3107 mInfo.setDismissable(dismissable); 3108 } 3109 } 3110 3111 /** 3112 * Gets if the node is editable. 3113 * 3114 * @return True if the node is editable, false otherwise. 3115 */ 3116 public boolean isEditable() { 3117 if (Build.VERSION.SDK_INT >= 18) { 3118 return mInfo.isEditable(); 3119 } else { 3120 return false; 3121 } 3122 } 3123 3124 /** 3125 * Sets whether this node is editable. 3126 * <p> 3127 * <strong>Note:</strong> Cannot be called from an 3128 * {@link android.accessibilityservice.AccessibilityService}. 3129 * This class is made immutable before being delivered to an AccessibilityService. 3130 * </p> 3131 * 3132 * @param editable True if the node is editable. 3133 * 3134 * @throws IllegalStateException If called from an AccessibilityService. 3135 */ 3136 public void setEditable(boolean editable) { 3137 if (Build.VERSION.SDK_INT >= 18) { 3138 mInfo.setEditable(editable); 3139 } 3140 } 3141 3142 /** 3143 * Gets if the node is a multi line editable text. 3144 * 3145 * @return True if the node is multi line. 3146 */ 3147 public boolean isMultiLine() { 3148 if (Build.VERSION.SDK_INT >= 19) { 3149 return mInfo.isMultiLine(); 3150 } else { 3151 return false; 3152 } 3153 } 3154 3155 /** 3156 * Sets if the node is a multi line editable text. 3157 * <p> 3158 * <strong>Note:</strong> Cannot be called from an 3159 * {@link android.accessibilityservice.AccessibilityService}. 3160 * This class is made immutable before being delivered to an AccessibilityService. 3161 * </p> 3162 * 3163 * @param multiLine True if the node is multi line. 3164 */ 3165 public void setMultiLine(boolean multiLine) { 3166 if (Build.VERSION.SDK_INT >= 19) { 3167 mInfo.setMultiLine(multiLine); 3168 } 3169 } 3170 3171 /** 3172 * Gets the tooltip text of this node. 3173 * 3174 * @return The tooltip text. 3175 */ 3176 @Nullable 3177 public CharSequence getTooltipText() { 3178 if (BuildCompat.isAtLeastP()) { 3179 return mInfo.getTooltipText(); 3180 } else if (Build.VERSION.SDK_INT >= 19) { 3181 return mInfo.getExtras().getCharSequence(TOOLTIP_TEXT_KEY); 3182 } 3183 return null; 3184 } 3185 3186 /** 3187 * Sets the tooltip text of this node. 3188 * <p>This method has no effect below API 19</p> 3189 * <p> 3190 * <strong>Note:</strong> Cannot be called from an 3191 * {@link android.accessibilityservice.AccessibilityService}. 3192 * This class is made immutable before being delivered to an AccessibilityService. 3193 * </p> 3194 * 3195 * @param tooltipText The tooltip text. 3196 * 3197 * @throws IllegalStateException If called from an AccessibilityService. 3198 */ 3199 public void setTooltipText(@Nullable CharSequence tooltipText) { 3200 if (BuildCompat.isAtLeastP()) { 3201 mInfo.setTooltipText(tooltipText); 3202 } else if (Build.VERSION.SDK_INT >= 19) { 3203 mInfo.getExtras().putCharSequence(TOOLTIP_TEXT_KEY, tooltipText); 3204 } 3205 } 3206 3207 /** 3208 * If this node represents a visually distinct region of the screen that may update separately 3209 * from the rest of the window, it is considered a pane. Set the pane title to indicate that 3210 * the node is a pane, and to provide a title for it. 3211 * <p>This method has no effect below API 19</p> 3212 * <p> 3213 * <strong>Note:</strong> Cannot be called from an 3214 * {@link android.accessibilityservice.AccessibilityService}. 3215 * This class is made immutable before being delivered to an AccessibilityService. 3216 * </p> 3217 * @param paneTitle The title of the window represented by this node. 3218 */ 3219 public void setPaneTitle(@Nullable CharSequence paneTitle) { 3220 if (BuildCompat.isAtLeastP()) { 3221 mInfo.setPaneTitle(paneTitle); 3222 } else if (Build.VERSION.SDK_INT >= 19) { 3223 mInfo.getExtras().putCharSequence(PANE_TITLE_KEY, paneTitle); 3224 } 3225 } 3226 3227 /** 3228 * Get the title of the pane represented by this node. 3229 * 3230 * @return The title of the pane represented by this node, or {@code null} if this node does 3231 * not represent a pane. 3232 */ 3233 public @Nullable CharSequence getPaneTitle() { 3234 if (BuildCompat.isAtLeastP()) { 3235 return mInfo.getPaneTitle(); 3236 } else if (Build.VERSION.SDK_INT >= 19) { 3237 return mInfo.getExtras().getCharSequence(PANE_TITLE_KEY); 3238 } 3239 return null; 3240 } 3241 3242 /** 3243 * Returns whether the node is explicitly marked as a focusable unit by a screen reader. Note 3244 * that {@code false} indicates that it is not explicitly marked, not that the node is not 3245 * a focusable unit. Screen readers should generally use other signals, such as 3246 * {@link #isFocusable()}, or the presence of text in a node, to determine what should receive 3247 * focus. 3248 * 3249 * @return {@code true} if the node is specifically marked as a focusable unit for screen 3250 * readers, {@code false} otherwise. 3251 */ 3252 public boolean isScreenReaderFocusable() { 3253 if (BuildCompat.isAtLeastP()) { 3254 return mInfo.isScreenReaderFocusable(); 3255 } 3256 return getBooleanProperty(BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE); 3257 } 3258 3259 /** 3260 * Sets whether the node should be considered a focusable unit by a screen reader. 3261 * <p>This method has no effect below API 19</p> 3262 * <p> 3263 * <strong>Note:</strong> Cannot be called from an 3264 * {@link android.accessibilityservice.AccessibilityService}. 3265 * This class is made immutable before being delivered to an AccessibilityService. 3266 * </p> 3267 * 3268 * @param screenReaderFocusable {@code true} if the node is a focusable unit for screen readers, 3269 * {@code false} otherwise. 3270 */ 3271 public void setScreenReaderFocusable(boolean screenReaderFocusable) { 3272 if (BuildCompat.isAtLeastP()) { 3273 mInfo.setScreenReaderFocusable(screenReaderFocusable); 3274 } else { 3275 setBooleanProperty(BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE, screenReaderFocusable); 3276 } 3277 } 3278 3279 /** 3280 * Returns whether the node's text represents a hint for the user to enter text. It should only 3281 * be {@code true} if the node has editable text. 3282 * 3283 * @return {@code true} if the text in the node represents a hint to the user, {@code false} 3284 * otherwise. 3285 */ 3286 public boolean isShowingHintText() { 3287 if (Build.VERSION.SDK_INT >= 26) { 3288 return mInfo.isShowingHintText(); 3289 } 3290 return getBooleanProperty(BOOLEAN_PROPERTY_IS_SHOWING_HINT); 3291 } 3292 3293 /** 3294 * Sets whether the node's text represents a hint for the user to enter text. It should only 3295 * be {@code true} if the node has editable text. 3296 * <p>This method has no effect below API 19</p> 3297 * <p> 3298 * <strong>Note:</strong> Cannot be called from an 3299 * {@link android.accessibilityservice.AccessibilityService}. 3300 * This class is made immutable before being delivered to an AccessibilityService. 3301 * </p> 3302 * 3303 * @param showingHintText {@code true} if the text in the node represents a hint to the user, 3304 * {@code false} otherwise. 3305 */ 3306 public void setShowingHintText(boolean showingHintText) { 3307 if (Build.VERSION.SDK_INT >= 26) { 3308 mInfo.setShowingHintText(showingHintText); 3309 } else { 3310 setBooleanProperty(BOOLEAN_PROPERTY_IS_SHOWING_HINT, showingHintText); 3311 } 3312 } 3313 3314 /** 3315 * Returns whether node represents a heading. 3316 * 3317 * @return {@code true} if the node is a heading, {@code false} otherwise. 3318 */ 3319 public boolean isHeading() { 3320 return getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING); 3321 } 3322 3323 /** 3324 * Sets whether the node represents a heading. 3325 * <p>This method has no effect below API 19</p> 3326 * <p> 3327 * <strong>Note:</strong> Cannot be called from an 3328 * {@link android.accessibilityservice.AccessibilityService}. 3329 * This class is made immutable before being delivered to an AccessibilityService. 3330 * </p> 3331 * 3332 * @param isHeading {@code true} if the node is a heading, {@code false} otherwise. 3333 */ 3334 public void setHeading(boolean isHeading) { 3335 setBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING, isHeading); 3336 } 3337 3338 /** 3339 * Refreshes this info with the latest state of the view it represents. 3340 * <p> 3341 * <strong>Note:</strong> If this method returns false this info is obsolete 3342 * since it represents a view that is no longer in the view tree and should 3343 * be recycled. 3344 * </p> 3345 * @return Whether the refresh succeeded. 3346 */ 3347 public boolean refresh() { 3348 if (Build.VERSION.SDK_INT >= 18) { 3349 return mInfo.refresh(); 3350 } else { 3351 return false; 3352 } 3353 } 3354 3355 /** 3356 * Gets the custom role description. 3357 * @return The role description. 3358 */ 3359 public @Nullable CharSequence getRoleDescription() { 3360 if (Build.VERSION.SDK_INT >= 19) { 3361 return mInfo.getExtras().getCharSequence(ROLE_DESCRIPTION_KEY); 3362 } else { 3363 return null; 3364 } 3365 } 3366 3367 /** 3368 * Sets the custom role description. 3369 * 3370 * <p> 3371 * The role description allows you to customize the name for the view's semantic 3372 * role. For example, if you create a custom subclass of {@link android.view.View} 3373 * to display a menu bar, you could assign it the role description of "menu bar". 3374 * </p> 3375 * <p> 3376 * <strong>Warning:</strong> For consistency with other applications, you should 3377 * not use the role description to force accessibility services to describe 3378 * standard views (such as buttons or checkboxes) using specific wording. For 3379 * example, you should not set a role description of "check box" or "tick box" for 3380 * a standard {@link android.widget.CheckBox}. Instead let accessibility services 3381 * decide what feedback to provide. 3382 * </p> 3383 * <p> 3384 * <strong>Note:</strong> Cannot be called from an 3385 * {@link android.accessibilityservice.AccessibilityService}. 3386 * This class is made immutable before being delivered to an AccessibilityService. 3387 * </p> 3388 * 3389 * @param roleDescription The role description. 3390 */ 3391 public void setRoleDescription(@Nullable CharSequence roleDescription) { 3392 if (Build.VERSION.SDK_INT >= 19) { 3393 mInfo.getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription); 3394 } 3395 } 3396 3397 @Override 3398 public int hashCode() { 3399 return (mInfo == null) ? 0 : mInfo.hashCode(); 3400 } 3401 3402 @Override 3403 public boolean equals(Object obj) { 3404 if (this == obj) { 3405 return true; 3406 } 3407 if (obj == null) { 3408 return false; 3409 } 3410 if (getClass() != obj.getClass()) { 3411 return false; 3412 } 3413 AccessibilityNodeInfoCompat other = (AccessibilityNodeInfoCompat) obj; 3414 if (mInfo == null) { 3415 if (other.mInfo != null) { 3416 return false; 3417 } 3418 } else if (!mInfo.equals(other.mInfo)) { 3419 return false; 3420 } 3421 return true; 3422 } 3423 3424 @Override 3425 public String toString() { 3426 StringBuilder builder = new StringBuilder(); 3427 builder.append(super.toString()); 3428 3429 Rect bounds = new Rect(); 3430 3431 getBoundsInParent(bounds); 3432 builder.append("; boundsInParent: " + bounds); 3433 3434 getBoundsInScreen(bounds); 3435 builder.append("; boundsInScreen: " + bounds); 3436 3437 builder.append("; packageName: ").append(getPackageName()); 3438 builder.append("; className: ").append(getClassName()); 3439 builder.append("; text: ").append(getText()); 3440 builder.append("; contentDescription: ").append(getContentDescription()); 3441 builder.append("; viewId: ").append(getViewIdResourceName()); 3442 3443 builder.append("; checkable: ").append(isCheckable()); 3444 builder.append("; checked: ").append(isChecked()); 3445 builder.append("; focusable: ").append(isFocusable()); 3446 builder.append("; focused: ").append(isFocused()); 3447 builder.append("; selected: ").append(isSelected()); 3448 builder.append("; clickable: ").append(isClickable()); 3449 builder.append("; longClickable: ").append(isLongClickable()); 3450 builder.append("; enabled: ").append(isEnabled()); 3451 builder.append("; password: ").append(isPassword()); 3452 builder.append("; scrollable: " + isScrollable()); 3453 3454 builder.append("; ["); 3455 for (int actionBits = getActions(); actionBits != 0;) { 3456 final int action = 1 << Integer.numberOfTrailingZeros(actionBits); 3457 actionBits &= ~action; 3458 builder.append(getActionSymbolicName(action)); 3459 if (actionBits != 0) { 3460 builder.append(", "); 3461 } 3462 } 3463 builder.append("]"); 3464 3465 return builder.toString(); 3466 } 3467 3468 private void setBooleanProperty(int property, boolean value) { 3469 Bundle extras = getExtras(); 3470 if (extras != null) { 3471 int booleanProperties = extras.getInt(BOOLEAN_PROPERTY_KEY, 0); 3472 booleanProperties &= ~property; 3473 booleanProperties |= (value) ? property : 0; 3474 extras.putInt(BOOLEAN_PROPERTY_KEY, booleanProperties); 3475 } 3476 } 3477 3478 private boolean getBooleanProperty(int property) { 3479 Bundle extras = getExtras(); 3480 if (extras == null) return false; 3481 return (extras.getInt(BOOLEAN_PROPERTY_KEY, 0) & property) == property; 3482 } 3483 3484 private static String getActionSymbolicName(int action) { 3485 switch (action) { 3486 case ACTION_FOCUS: 3487 return "ACTION_FOCUS"; 3488 case ACTION_CLEAR_FOCUS: 3489 return "ACTION_CLEAR_FOCUS"; 3490 case ACTION_SELECT: 3491 return "ACTION_SELECT"; 3492 case ACTION_CLEAR_SELECTION: 3493 return "ACTION_CLEAR_SELECTION"; 3494 case ACTION_CLICK: 3495 return "ACTION_CLICK"; 3496 case ACTION_LONG_CLICK: 3497 return "ACTION_LONG_CLICK"; 3498 case ACTION_ACCESSIBILITY_FOCUS: 3499 return "ACTION_ACCESSIBILITY_FOCUS"; 3500 case ACTION_CLEAR_ACCESSIBILITY_FOCUS: 3501 return "ACTION_CLEAR_ACCESSIBILITY_FOCUS"; 3502 case ACTION_NEXT_AT_MOVEMENT_GRANULARITY: 3503 return "ACTION_NEXT_AT_MOVEMENT_GRANULARITY"; 3504 case ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: 3505 return "ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY"; 3506 case ACTION_NEXT_HTML_ELEMENT: 3507 return "ACTION_NEXT_HTML_ELEMENT"; 3508 case ACTION_PREVIOUS_HTML_ELEMENT: 3509 return "ACTION_PREVIOUS_HTML_ELEMENT"; 3510 case ACTION_SCROLL_FORWARD: 3511 return "ACTION_SCROLL_FORWARD"; 3512 case ACTION_SCROLL_BACKWARD: 3513 return "ACTION_SCROLL_BACKWARD"; 3514 case ACTION_CUT: 3515 return "ACTION_CUT"; 3516 case ACTION_COPY: 3517 return "ACTION_COPY"; 3518 case ACTION_PASTE: 3519 return "ACTION_PASTE"; 3520 case ACTION_SET_SELECTION: 3521 return "ACTION_SET_SELECTION"; 3522 default: 3523 return"ACTION_UNKNOWN"; 3524 } 3525 } 3526} 3527