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 android.support.v4.view.accessibility;
18
19import android.graphics.Rect;
20import android.os.Build;
21import android.os.Bundle;
22import android.support.annotation.Nullable;
23import android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat;
24import android.support.v4.view.ViewCompat;
25import android.text.InputType;
26import android.view.View;
27
28import java.util.ArrayList;
29import java.util.Collections;
30import java.util.List;
31
32/**
33 * Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo}
34 * introduced after API level 4 in a backwards compatible fashion.
35 */
36public class AccessibilityNodeInfoCompat {
37
38    public static class AccessibilityActionCompat {
39
40        /**
41         * Action that gives input focus to the node.
42         */
43        public static final AccessibilityActionCompat ACTION_FOCUS =
44                new AccessibilityActionCompat(
45                        AccessibilityNodeInfoCompat.ACTION_FOCUS, null);
46
47        /**
48         * Action that clears input focus of the node.
49         */
50        public static final AccessibilityActionCompat ACTION_CLEAR_FOCUS =
51                new AccessibilityActionCompat(
52                        AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS, null);
53
54        /**
55         *  Action that selects the node.
56         */
57        public static final AccessibilityActionCompat ACTION_SELECT =
58                new AccessibilityActionCompat(
59                        AccessibilityNodeInfoCompat.ACTION_SELECT, null);
60
61        /**
62         * Action that deselects the node.
63         */
64        public static final AccessibilityActionCompat ACTION_CLEAR_SELECTION =
65                new AccessibilityActionCompat(
66                        AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION, null);
67
68        /**
69         * Action that clicks on the node info.
70         */
71        public static final AccessibilityActionCompat ACTION_CLICK =
72                new AccessibilityActionCompat(
73                        AccessibilityNodeInfoCompat.ACTION_CLICK, null);
74
75        /**
76         * Action that long clicks on the node.
77         */
78        public static final AccessibilityActionCompat ACTION_LONG_CLICK =
79                new AccessibilityActionCompat(
80                        AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null);
81
82        /**
83         * Action that gives accessibility focus to the node.
84         */
85        public static final AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS =
86                new AccessibilityActionCompat(
87                        AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null);
88
89        /**
90         * Action that clears accessibility focus of the node.
91         */
92        public static final AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS =
93                new AccessibilityActionCompat(
94                        AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
95
96        /**
97         * Action that requests to go to the next entity in this node's text
98         * at a given movement granularity. For example, move to the next character,
99         * word, etc.
100         * <p>
101         * <strong>Arguments:</strong>
102         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
103         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT},
104         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
105         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
106         * <strong>Example:</strong> Move to the previous character and do not extend selection.
107         * <code><pre><p>
108         *   Bundle arguments = new Bundle();
109         *   arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
110         *           AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER);
111         *   arguments.putBoolean(
112         *           AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false);
113         *   info.performAction(
114         *           AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId(),
115         *           arguments);
116         * </code></pre></p>
117         * </p>
118         *
119         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
120         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
121         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
122         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
123         *
124         * @see AccessibilityNodeInfoCompat#setMovementGranularities(int)
125         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
126         * @see AccessibilityNodeInfoCompat#getMovementGranularities()
127         *  AccessibilityNodeInfoCompat.getMovementGranularities()
128         *
129         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER
130         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER
131         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD
132         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD
133         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE
134         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE
135         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH
136         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH
137         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE
138         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE
139         */
140        public static final AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY =
141                new AccessibilityActionCompat(
142                        AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, null);
143
144        /**
145         * Action that requests to go to the previous entity in this node's text
146         * at a given movement granularity. For example, move to the next character,
147         * word, etc.
148         * <p>
149         * <strong>Arguments:</strong>
150         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
151         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT},
152         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
153         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
154         * <strong>Example:</strong> Move to the next character and do not extend selection.
155         * <code><pre><p>
156         *   Bundle arguments = new Bundle();
157         *   arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
158         *           AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER);
159         *   arguments.putBoolean(
160         *           AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false);
161         *   info.performAction(
162         *           AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId(),
163         *           arguments);
164         * </code></pre></p>
165         * </p>
166         *
167         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
168         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
169         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
170         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
171         *
172         * @see AccessibilityNodeInfoCompat#setMovementGranularities(int)
173         *   AccessibilityNodeInfoCompat.setMovementGranularities(int)
174         * @see AccessibilityNodeInfoCompat#getMovementGranularities()
175         *  AccessibilityNodeInfoCompat.getMovementGranularities()
176         *
177         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER
178         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER
179         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD
180         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD
181         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE
182         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE
183         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH
184         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH
185         * @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE
186         *  AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE
187         */
188        public static final AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY =
189                new AccessibilityActionCompat(
190                        AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, null);
191
192        /**
193         * Action to move to the next HTML element of a given type. For example, move
194         * to the BUTTON, INPUT, TABLE, etc.
195         * <p>
196         * <strong>Arguments:</strong>
197         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING
198         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
199         * <strong>Example:</strong>
200         * <code><pre><p>
201         *   Bundle arguments = new Bundle();
202         *   arguments.putString(
203         *           AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
204         *   info.performAction(
205         *           AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT.getId(), arguments);
206         * </code></pre></p>
207         * </p>
208         */
209        public static final AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT =
210                new AccessibilityActionCompat(
211                        AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT, null);
212
213        /**
214         * Action to move to the previous HTML element of a given type. For example, move
215         * to the BUTTON, INPUT, TABLE, etc.
216         * <p>
217         * <strong>Arguments:</strong>
218         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING
219         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
220         * <strong>Example:</strong>
221         * <code><pre><p>
222         *   Bundle arguments = new Bundle();
223         *   arguments.putString(
224         *           AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
225         *   info.performAction(
226         *           AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT.getId(), arguments);
227         * </code></pre></p>
228         * </p>
229         */
230        public static final AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT =
231                new AccessibilityActionCompat(
232                        AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT, null);
233
234        /**
235         * Action to scroll the node content forward.
236         */
237        public static final AccessibilityActionCompat ACTION_SCROLL_FORWARD =
238                new AccessibilityActionCompat(
239                        AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
240
241        /**
242         * Action to scroll the node content backward.
243         */
244        public static final AccessibilityActionCompat ACTION_SCROLL_BACKWARD =
245                new AccessibilityActionCompat(
246                        AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
247
248        /**
249         * Action to copy the current selection to the clipboard.
250         */
251        public static final AccessibilityActionCompat ACTION_COPY =
252                new AccessibilityActionCompat(
253                        AccessibilityNodeInfoCompat.ACTION_COPY, null);
254
255        /**
256         * Action to paste the current clipboard content.
257         */
258        public static final AccessibilityActionCompat ACTION_PASTE =
259                new AccessibilityActionCompat(
260                        AccessibilityNodeInfoCompat.ACTION_PASTE, null);
261
262        /**
263         * Action to cut the current selection and place it to the clipboard.
264         */
265        public static final AccessibilityActionCompat ACTION_CUT =
266                new AccessibilityActionCompat(
267                        AccessibilityNodeInfoCompat.ACTION_CUT, null);
268
269        /**
270         * Action to set the selection. Performing this action with no arguments
271         * clears the selection.
272         * <p>
273         * <strong>Arguments:</strong>
274         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT
275         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT},
276         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT
277         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT}<br>
278         * <strong>Example:</strong>
279         * <code><pre><p>
280         *   Bundle arguments = new Bundle();
281         *   arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, 1);
282         *   arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, 2);
283         *   info.performAction(AccessibilityActionCompat.ACTION_SET_SELECTION.getId(), arguments);
284         * </code></pre></p>
285         * </p>
286         *
287         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT
288         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT
289         * @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT
290         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT
291         */
292        public static final AccessibilityActionCompat ACTION_SET_SELECTION =
293                new AccessibilityActionCompat(
294                        AccessibilityNodeInfoCompat.ACTION_SET_SELECTION, null);
295
296        /**
297         * Action to expand an expandable node.
298         */
299        public static final AccessibilityActionCompat ACTION_EXPAND =
300                new AccessibilityActionCompat(
301                        AccessibilityNodeInfoCompat.ACTION_EXPAND, null);
302
303        /**
304         * Action to collapse an expandable node.
305         */
306        public static final AccessibilityActionCompat ACTION_COLLAPSE =
307                new AccessibilityActionCompat(
308                        AccessibilityNodeInfoCompat.ACTION_COLLAPSE, null);
309
310        /**
311         * Action to dismiss a dismissable node.
312         */
313        public static final AccessibilityActionCompat ACTION_DISMISS =
314                new AccessibilityActionCompat(
315                        AccessibilityNodeInfoCompat.ACTION_DISMISS, null);
316
317        /**
318         * Action that sets the text of the node. Performing the action without argument,
319         * using <code> null</code> or empty {@link CharSequence} will clear the text. This
320         * action will also put the cursor at the end of text.
321         * <p>
322         * <strong>Arguments:</strong>
323         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
324         *  AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
325         * <strong>Example:</strong>
326         * <code><pre><p>
327         *   Bundle arguments = new Bundle();
328         *   arguments.putCharSequence(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
329         *       "android");
330         *   info.performAction(AccessibilityActionCompat.ACTION_SET_TEXT.getId(), arguments);
331         * </code></pre></p>
332         */
333        public static final AccessibilityActionCompat ACTION_SET_TEXT =
334                new AccessibilityActionCompat(
335                        AccessibilityNodeInfoCompat.ACTION_SET_TEXT, null);
336
337        /**
338         * Action that requests the node make its bounding rectangle visible
339         * on the screen, scrolling if necessary just enough.
340         *
341         * @see View#requestRectangleOnScreen(Rect)
342         */
343        public static final AccessibilityActionCompat ACTION_SHOW_ON_SCREEN =
344                new AccessibilityActionCompat(IMPL.getActionShowOnScreen());
345
346        /**
347         * Action that scrolls the node to make the specified collection
348         * position visible on screen.
349         * <p>
350         * <strong>Arguments:</strong>
351         * <ul>
352         *     <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_ROW_INT}</li>
353         *     <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_COLUMN_INT}</li>
354         * <ul>
355         *
356         * @see AccessibilityNodeInfoCompat#getCollectionInfo()
357         */
358        public static final AccessibilityActionCompat ACTION_SCROLL_TO_POSITION =
359                new AccessibilityActionCompat(IMPL.getActionScrollToPosition());
360
361        /**
362         * Action to scroll the node content up.
363         */
364        public static final AccessibilityActionCompat ACTION_SCROLL_UP =
365                new AccessibilityActionCompat(IMPL.getActionScrollUp());
366
367        /**
368         * Action to scroll the node content left.
369         */
370        public static final AccessibilityActionCompat ACTION_SCROLL_LEFT =
371                new AccessibilityActionCompat(IMPL.getActionScrollLeft());
372
373        /**
374         * Action to scroll the node content down.
375         */
376        public static final AccessibilityActionCompat ACTION_SCROLL_DOWN =
377                new AccessibilityActionCompat(IMPL.getActionScrollDown());
378
379        /**
380         * Action to scroll the node content right.
381         */
382        public static final AccessibilityActionCompat ACTION_SCROLL_RIGHT =
383                new AccessibilityActionCompat(IMPL.getActionScrollRight());
384
385        /**
386         * Action that context clicks the node.
387         */
388        public static final AccessibilityActionCompat ACTION_CONTEXT_CLICK =
389                new AccessibilityActionCompat(IMPL.getActionContextClick());
390
391        /**
392         * Action that sets progress between {@link  RangeInfoCompat#getMin() RangeInfo.getMin()} and
393         * {@link  RangeInfoCompat#getMax() RangeInfo.getMax()}. It should use the same value type as
394         * {@link RangeInfoCompat#getType() RangeInfo.getType()}
395         * <p>
396         * <strong>Arguments:</strong>
397         * {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_PROGRESS_VALUE}
398         *
399         * @see RangeInfoCompat
400         */
401        public static final AccessibilityActionCompat ACTION_SET_PROGRESS =
402                new AccessibilityActionCompat(IMPL.getActionSetProgress());
403
404        final Object mAction;
405
406        /**
407         * Creates a new instance.
408         *
409         * @param actionId The action id.
410         * @param label The action label.
411         */
412        public AccessibilityActionCompat(int actionId, CharSequence label) {
413            this(IMPL.newAccessibilityAction(actionId, label));
414        }
415
416        AccessibilityActionCompat(Object action) {
417            mAction = action;
418        }
419
420        /**
421         * Gets the id for this action.
422         *
423         * @return The action id.
424         */
425        public int getId() {
426            return IMPL.getAccessibilityActionId(mAction);
427        }
428
429        /**
430         * Gets the label for this action. Its purpose is to describe the
431         * action to user.
432         *
433         * @return The label.
434         */
435        public CharSequence getLabel() {
436            return IMPL.getAccessibilityActionLabel(mAction);
437        }
438    }
439
440    /**
441     * Class with information if a node is a collection.
442     * <p>
443     * A collection of items has rows and columns and may be hierarchical.
444     * For example, a horizontal list is a collection with one column, as
445     * many rows as the list items, and is not hierarchical; A table is a
446     * collection with several rows, several columns, and is not hierarchical;
447     * A vertical tree is a hierarchical collection with one column and
448     * as many rows as the first level children.
449     * </p>
450     */
451    public static class CollectionInfoCompat {
452        /** Selection mode where items are not selectable. */
453        public static final int SELECTION_MODE_NONE = 0;
454
455        /** Selection mode where a single item may be selected. */
456        public static final int SELECTION_MODE_SINGLE = 1;
457
458        /** Selection mode where multiple items may be selected. */
459        public static final int SELECTION_MODE_MULTIPLE = 2;
460
461        final Object mInfo;
462
463        /**
464         * Returns a cached instance if such is available otherwise a new one.
465         *
466         * @param rowCount The number of rows.
467         * @param columnCount The number of columns.
468         * @param hierarchical Whether the collection is hierarchical.
469         * @param selectionMode The collection's selection mode, one of:
470         *            <ul>
471         *            <li>{@link #SELECTION_MODE_NONE}
472         *            <li>{@link #SELECTION_MODE_SINGLE}
473         *            <li>{@link #SELECTION_MODE_MULTIPLE}
474         *            </ul>
475         *
476         * @return An instance.
477         */
478        public static CollectionInfoCompat obtain(int rowCount, int columnCount,
479                boolean hierarchical, int selectionMode) {
480            return new CollectionInfoCompat(IMPL.obtainCollectionInfo(rowCount, columnCount,
481                    hierarchical, selectionMode));
482        }
483
484        /**
485         * Returns a cached instance if such is available otherwise a new one.
486         *
487         * @param rowCount The number of rows.
488         * @param columnCount The number of columns.
489         * @param hierarchical Whether the collection is hierarchical.
490         *
491         * @return An instance.
492         */
493        public static CollectionInfoCompat obtain(int rowCount, int columnCount,
494                boolean hierarchical) {
495            return new CollectionInfoCompat(IMPL.obtainCollectionInfo(rowCount, columnCount,
496                    hierarchical));
497        }
498
499        CollectionInfoCompat(Object info) {
500            mInfo = info;
501        }
502
503        /**
504         * Gets the number of columns.
505         *
506         * @return The column count.
507         */
508        public int getColumnCount() {
509            return IMPL.getCollectionInfoColumnCount(mInfo);
510        }
511
512        /**
513         * Gets the number of rows.
514         *
515         * @return The row count.
516         */
517        public int getRowCount() {
518            return IMPL.getCollectionInfoRowCount(mInfo);
519        }
520
521        /**
522         * Gets if the collection is a hierarchically ordered.
523         *
524         * @return Whether the collection is hierarchical.
525         */
526        public boolean isHierarchical() {
527            return IMPL.isCollectionInfoHierarchical(mInfo);
528        }
529
530        /**
531         * Gets the collection's selection mode.
532         *
533         * @return The collection's selection mode, one of:
534         *         <ul>
535         *         <li>{@link #SELECTION_MODE_NONE}
536         *         <li>{@link #SELECTION_MODE_SINGLE}
537         *         <li>{@link #SELECTION_MODE_MULTIPLE}
538         *         </ul>
539         */
540        public int getSelectionMode() {
541            return IMPL.getCollectionInfoSelectionMode(mInfo);
542        }
543    }
544
545    /**
546     * Class with information if a node is a collection item.
547     * <p>
548     * A collection item is contained in a collection, it starts at
549     * a given row and column in the collection, and spans one or
550     * more rows and columns. For example, a header of two related
551     * table columns starts at the first row and the first column,
552     * spans one row and two columns.
553     * </p>
554     */
555    public static class CollectionItemInfoCompat {
556
557        final Object mInfo;
558
559        /**
560         * Returns a cached instance if such is available otherwise a new one.
561         *
562         * @param rowIndex The row index at which the item is located.
563         * @param rowSpan The number of rows the item spans.
564         * @param columnIndex The column index at which the item is located.
565         * @param columnSpan The number of columns the item spans.
566         * @param heading Whether the item is a heading.
567         * @param selected Whether the item is selected.
568         * @return An instance.
569         */
570        public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
571                int columnIndex, int columnSpan, boolean heading, boolean selected) {
572            return new CollectionItemInfoCompat(IMPL.obtainCollectionItemInfo(rowIndex, rowSpan,
573                    columnIndex, columnSpan, heading, selected));
574        }
575
576        /**
577         * Returns a cached instance if such is available otherwise a new one.
578         *
579         * @param rowIndex The row index at which the item is located.
580         * @param rowSpan The number of rows the item spans.
581         * @param columnIndex The column index at which the item is located.
582         * @param columnSpan The number of columns the item spans.
583         * @param heading Whether the item is a heading.
584         * @return An instance.
585         */
586        public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
587                int columnIndex, int columnSpan, boolean heading) {
588            return new CollectionItemInfoCompat(IMPL.obtainCollectionItemInfo(rowIndex, rowSpan,
589                    columnIndex, columnSpan, heading));
590        }
591
592        CollectionItemInfoCompat(Object info) {
593            mInfo = info;
594        }
595
596        /**
597         * Gets the column index at which the item is located.
598         *
599         * @return The column index.
600         */
601        public int getColumnIndex() {
602            return IMPL.getCollectionItemColumnIndex(mInfo);
603        }
604
605        /**
606         * Gets the number of columns the item spans.
607         *
608         * @return The column span.
609         */
610        public int getColumnSpan() {
611            return IMPL.getCollectionItemColumnSpan(mInfo);
612        }
613
614        /**
615         * Gets the row index at which the item is located.
616         *
617         * @return The row index.
618         */
619        public int getRowIndex() {
620            return IMPL.getCollectionItemRowIndex(mInfo);
621        }
622
623        /**
624         * Gets the number of rows the item spans.
625         *
626         * @return The row span.
627         */
628        public int getRowSpan() {
629            return IMPL.getCollectionItemRowSpan(mInfo);
630        }
631
632        /**
633         * Gets if the collection item is a heading. For example, section
634         * heading, table header, etc.
635         *
636         * @return If the item is a heading.
637         */
638        public boolean isHeading() {
639            return IMPL.isCollectionItemHeading(mInfo);
640        }
641
642        /**
643         * Gets if the collection item is selected.
644         *
645         * @return If the item is selected.
646         */
647        public boolean isSelected() {
648            return IMPL.isCollectionItemSelected(mInfo);
649        }
650    }
651
652    /**
653     * Class with information if a node is a range.
654     */
655    public static class RangeInfoCompat {
656        /** Range type: integer. */
657        public static final int RANGE_TYPE_INT = 0;
658        /** Range type: float. */
659        public static final int RANGE_TYPE_FLOAT = 1;
660        /** Range type: percent with values from zero to one.*/
661        public static final int RANGE_TYPE_PERCENT = 2;
662
663        /**
664         * Obtains a cached instance if such is available otherwise a new one.
665         *
666         * @param type The type of the range.
667         * @param min The min value.
668         * @param max The max value.
669         * @param current The current value.
670         * @return The instance
671         */
672        public static RangeInfoCompat obtain(int type, float min, float max, float current) {
673            return new RangeInfoCompat(IMPL.obtainRangeInfo(type, min, max, current));
674        }
675
676        final Object mInfo;
677
678        RangeInfoCompat(Object info) {
679            mInfo = info;
680        }
681
682        /**
683         * Gets the current value.
684         *
685         * @return The current value.
686         */
687        public float getCurrent() {
688            return AccessibilityNodeInfoCompatKitKat.RangeInfo.getCurrent(mInfo);
689        }
690
691        /**
692         * Gets the max value.
693         *
694         * @return The max value.
695         */
696        public float getMax() {
697            return AccessibilityNodeInfoCompatKitKat.RangeInfo.getMax(mInfo);
698        }
699
700        /**
701         * Gets the min value.
702         *
703         * @return The min value.
704         */
705        public float getMin() {
706            return AccessibilityNodeInfoCompatKitKat.RangeInfo.getMin(mInfo);
707        }
708
709        /**
710         * Gets the range type.
711         *
712         * @return The range type.
713         *
714         * @see #RANGE_TYPE_INT
715         * @see #RANGE_TYPE_FLOAT
716         * @see #RANGE_TYPE_PERCENT
717         */
718        public int getType() {
719            return AccessibilityNodeInfoCompatKitKat.RangeInfo.getType(mInfo);
720        }
721    }
722
723    interface AccessibilityNodeInfoImpl {
724        Object newAccessibilityAction(int actionId, CharSequence label);
725        Object obtain();
726        Object obtain(View source);
727        Object obtain(Object info);
728        Object obtain(View root, int virtualDescendantId);
729        void setSource(Object info, View source);
730        void setSource(Object info, View root, int virtualDescendantId);
731        Object findFocus(Object info, int focus);
732        Object focusSearch(Object info, int direction);
733        int getWindowId(Object info);
734        int getChildCount(Object info);
735        Object getChild(Object info, int index);
736        void addChild(Object info, View child);
737        void addChild(Object info, View child, int virtualDescendantId);
738        boolean removeChild(Object info, View child);
739        boolean removeChild(Object info, View root, int virtualDescendantId);
740        int getActions(Object info);
741        void addAction(Object info, int action);
742        void addAction(Object info, Object action);
743        boolean removeAction(Object info, Object action);
744        int getAccessibilityActionId(Object action);
745        CharSequence getAccessibilityActionLabel(Object action);
746        boolean performAction(Object info, int action);
747        boolean performAction(Object info, int action, Bundle arguments);
748        void setMovementGranularities(Object info, int granularities);
749        int getMovementGranularities(Object info);
750        List<Object> findAccessibilityNodeInfosByText(Object info, String text);
751        Object getParent(Object info);
752        void setParent(Object info, View root, int virtualDescendantId);
753        void setParent(Object info, View parent);
754        void getBoundsInParent(Object info, Rect outBounds);
755        void setBoundsInParent(Object info, Rect bounds);
756        void getBoundsInScreen(Object info, Rect outBounds);
757        void setBoundsInScreen(Object info, Rect bounds);
758        boolean isCheckable(Object info);
759        void setCheckable(Object info, boolean checkable);
760        boolean isChecked(Object info);
761        void setChecked(Object info, boolean checked);
762        boolean isFocusable(Object info);
763        void setFocusable(Object info, boolean focusable);
764        boolean isFocused(Object info);
765        void setFocused(Object info, boolean focused);
766        boolean isVisibleToUser(Object info);
767        void setVisibleToUser(Object info, boolean visibleToUser);
768        boolean isAccessibilityFocused(Object info);
769        void setAccessibilityFocused(Object info, boolean focused);
770        boolean isSelected(Object info);
771        void setSelected(Object info, boolean selected);
772        boolean isClickable(Object info);
773        void setClickable(Object info, boolean clickable);
774        boolean isLongClickable(Object info);
775        void setLongClickable(Object info, boolean longClickable);
776        boolean isEnabled(Object info);
777        void setEnabled(Object info, boolean enabled);
778        boolean isPassword(Object info);
779        void setPassword(Object info, boolean password);
780        boolean isScrollable(Object info);
781        void setScrollable(Object info, boolean scrollable);
782        CharSequence getPackageName(Object info);
783        void setPackageName(Object info, CharSequence packageName);
784        CharSequence getClassName(Object info);
785        void setClassName(Object info, CharSequence className);
786        CharSequence getText(Object info);
787        void setText(Object info, CharSequence text);
788        CharSequence getContentDescription(Object info);
789        void setContentDescription(Object info, CharSequence contentDescription);
790        void recycle(Object info);
791        String getViewIdResourceName(Object info);
792        void setViewIdResourceName(Object info, String viewId);
793        int getLiveRegion(Object info);
794        void setLiveRegion(Object info, int mode);
795        Object getCollectionInfo(Object info);
796        void setCollectionInfo(Object info, Object collectionInfo);
797        Object getCollectionItemInfo(Object info);
798        void setCollectionItemInfo(Object info, Object collectionItemInfo);
799        Object getRangeInfo(Object info);
800        void setRangeInfo(Object info, Object rangeInfo);
801        List<Object> getActionList(Object info);
802        Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical,
803                int selectionMode);
804        Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical);
805        int getCollectionInfoColumnCount(Object info);
806        int getCollectionInfoRowCount(Object info);
807        boolean isCollectionInfoHierarchical(Object info);
808        int getCollectionInfoSelectionMode(Object info);
809        Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
810                int columnSpan, boolean heading, boolean selected);
811        Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
812                int columnSpan, boolean heading);
813        int getCollectionItemColumnIndex(Object info);
814        int getCollectionItemColumnSpan(Object info);
815        int getCollectionItemRowIndex(Object info);
816        int getCollectionItemRowSpan(Object info);
817        boolean isCollectionItemHeading(Object info);
818        boolean isCollectionItemSelected(Object info);
819        Object obtainRangeInfo(int type, float min, float max, float current);
820        Object getTraversalBefore(Object info);
821        void setTraversalBefore(Object info, View view);
822        void setTraversalBefore(Object info, View root, int virtualDescendantId);
823        Object getTraversalAfter(Object info);
824        void setTraversalAfter(Object info, View view);
825        void setTraversalAfter(Object info, View root, int virtualDescendantId);
826        void setContentInvalid(Object info, boolean contentInvalid);
827        boolean isContentInvalid(Object info);
828        void setError(Object info, CharSequence error);
829        CharSequence getError(Object info);
830        void setLabelFor(Object info, View labeled);
831        void setLabelFor(Object info, View root, int virtualDescendantId);
832        Object getLabelFor(Object info);
833        void setLabeledBy(Object info, View labeled);
834        void setLabeledBy(Object info, View root, int virtualDescendantId);
835        Object getLabeledBy(Object info);
836        boolean canOpenPopup(Object info);
837        void setCanOpenPopup(Object info, boolean opensPopup);
838        List<Object> findAccessibilityNodeInfosByViewId(Object info, String viewId);
839        Bundle getExtras(Object info);
840        int getInputType(Object info);
841        void setInputType(Object info, int inputType);
842        void setMaxTextLength(Object info, int max);
843        int getMaxTextLength(Object info);
844        void setTextSelection(Object info, int start, int end);
845        int getTextSelectionStart(Object info);
846        int getTextSelectionEnd(Object info);
847        Object getWindow(Object info);
848        boolean isDismissable(Object info);
849        void setDismissable(Object info, boolean dismissable);
850        boolean isEditable(Object info);
851        void setEditable(Object info, boolean editable);
852        int getDrawingOrder(Object info);
853        void setDrawingOrder(Object info, int drawingOrderInParent);
854        boolean isImportantForAccessibility(Object info);
855        void setImportantForAccessibility(Object info, boolean importantForAccessibility);
856        boolean isMultiLine(Object info);
857        void setMultiLine(Object info, boolean multiLine);
858        boolean refresh(Object info);
859        CharSequence getRoleDescription(Object info);
860        void setRoleDescription(Object info, CharSequence roleDescription);
861        Object getActionScrollToPosition();
862        Object getActionSetProgress();
863        boolean isContextClickable(Object info);
864        void setContextClickable(Object info, boolean contextClickable);
865        Object getActionShowOnScreen();
866        Object getActionScrollUp();
867        Object getActionScrollDown();
868        Object getActionScrollLeft();
869        Object getActionScrollRight();
870        Object getActionContextClick();
871    }
872
873    static class AccessibilityNodeInfoStubImpl implements AccessibilityNodeInfoImpl {
874        @Override
875        public Object newAccessibilityAction(int actionId, CharSequence label) {
876            return null;
877        }
878
879        @Override
880        public Object obtain() {
881            return null;
882        }
883
884        @Override
885        public Object obtain(View source) {
886            return null;
887        }
888
889        @Override
890        public Object obtain(View root, int virtualDescendantId) {
891            return null;
892        }
893
894        @Override
895        public Object obtain(Object info) {
896            return null;
897        }
898
899        @Override
900        public void addAction(Object info, int action) {
901
902        }
903
904        @Override
905        public void addAction(Object info, Object action) {
906
907        }
908
909        @Override
910        public boolean removeAction(Object info, Object action) {
911            return false;
912        }
913
914        @Override
915        public int getAccessibilityActionId(Object action) {
916            return 0;
917        }
918
919        @Override
920        public CharSequence getAccessibilityActionLabel(Object action) {
921            return null;
922        }
923
924        @Override
925        public void addChild(Object info, View child) {
926
927        }
928
929        @Override
930        public void addChild(Object info, View child, int virtualDescendantId) {
931
932        }
933
934        @Override
935        public boolean removeChild(Object info, View child) {
936            return false;
937        }
938
939        @Override
940        public boolean removeChild(Object info, View root, int virtualDescendantId) {
941            return false;
942        }
943
944        @Override
945        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
946            return Collections.emptyList();
947        }
948
949        @Override
950        public int getActions(Object info) {
951            return 0;
952        }
953
954        @Override
955        public void getBoundsInParent(Object info, Rect outBounds) {
956
957        }
958
959        @Override
960        public void getBoundsInScreen(Object info, Rect outBounds) {
961
962        }
963
964        @Override
965        public Object getChild(Object info, int index) {
966            return null;
967        }
968
969        @Override
970        public int getChildCount(Object info) {
971            return 0;
972        }
973
974        @Override
975        public CharSequence getClassName(Object info) {
976            return null;
977        }
978
979        @Override
980        public CharSequence getContentDescription(Object info) {
981            return null;
982        }
983
984        @Override
985        public CharSequence getPackageName(Object info) {
986            return null;
987        }
988
989        @Override
990        public Object getParent(Object info) {
991            return null;
992        }
993
994        @Override
995        public CharSequence getText(Object info) {
996            return null;
997        }
998
999        @Override
1000        public int getWindowId(Object info) {
1001            return 0;
1002        }
1003
1004        @Override
1005        public boolean isCheckable(Object info) {
1006            return false;
1007        }
1008
1009        @Override
1010        public boolean isChecked(Object info) {
1011            return false;
1012        }
1013
1014        @Override
1015        public boolean isClickable(Object info) {
1016            return false;
1017        }
1018
1019        @Override
1020        public boolean isEnabled(Object info) {
1021            return false;
1022        }
1023
1024        @Override
1025        public boolean isFocusable(Object info) {
1026            return false;
1027        }
1028
1029        @Override
1030        public boolean isFocused(Object info) {
1031            return false;
1032        }
1033
1034        @Override
1035        public boolean isVisibleToUser(Object info) {
1036            return false;
1037        }
1038
1039        @Override
1040        public boolean isAccessibilityFocused(Object info) {
1041            return false;
1042        }
1043
1044        @Override
1045        public boolean isLongClickable(Object info) {
1046            return false;
1047        }
1048
1049        @Override
1050        public boolean isPassword(Object info) {
1051            return false;
1052        }
1053
1054        @Override
1055        public boolean isScrollable(Object info) {
1056            return false;
1057        }
1058
1059        @Override
1060        public boolean isSelected(Object info) {
1061            return false;
1062        }
1063
1064        @Override
1065        public boolean performAction(Object info, int action) {
1066            return false;
1067        }
1068
1069        @Override
1070        public boolean performAction(Object info, int action, Bundle arguments) {
1071            return false;
1072        }
1073
1074        @Override
1075        public void setMovementGranularities(Object info, int granularities) {
1076
1077        }
1078
1079        @Override
1080        public int getMovementGranularities(Object info) {
1081            return 0;
1082        }
1083
1084        @Override
1085        public void setBoundsInParent(Object info, Rect bounds) {
1086
1087        }
1088
1089        @Override
1090        public void setBoundsInScreen(Object info, Rect bounds) {
1091
1092        }
1093
1094        @Override
1095        public void setCheckable(Object info, boolean checkable) {
1096
1097        }
1098
1099        @Override
1100        public void setChecked(Object info, boolean checked) {
1101
1102        }
1103
1104        @Override
1105        public void setClassName(Object info, CharSequence className) {
1106
1107        }
1108
1109        @Override
1110        public void setClickable(Object info, boolean clickable) {
1111
1112        }
1113
1114        @Override
1115        public void setContentDescription(Object info, CharSequence contentDescription) {
1116
1117        }
1118
1119        @Override
1120        public void setEnabled(Object info, boolean enabled) {
1121
1122        }
1123
1124        @Override
1125        public void setFocusable(Object info, boolean focusable) {
1126
1127        }
1128
1129        @Override
1130        public void setFocused(Object info, boolean focused) {
1131
1132        }
1133
1134        @Override
1135        public void setVisibleToUser(Object info, boolean visibleToUser) {
1136
1137        }
1138
1139        @Override
1140        public void setAccessibilityFocused(Object info, boolean focused) {
1141
1142        }
1143
1144        @Override
1145        public void setLongClickable(Object info, boolean longClickable) {
1146
1147        }
1148
1149        @Override
1150        public void setPackageName(Object info, CharSequence packageName) {
1151
1152        }
1153
1154        @Override
1155        public void setParent(Object info, View parent) {
1156
1157        }
1158
1159        @Override
1160        public void setPassword(Object info, boolean password) {
1161
1162        }
1163
1164        @Override
1165        public void setScrollable(Object info, boolean scrollable) {
1166
1167        }
1168
1169        @Override
1170        public void setSelected(Object info, boolean selected) {
1171
1172        }
1173
1174        @Override
1175        public void setSource(Object info, View source) {
1176
1177        }
1178
1179        @Override
1180        public void setSource(Object info, View root, int virtualDescendantId) {
1181
1182        }
1183
1184        @Override
1185        public Object findFocus(Object info, int focus) {
1186            return null;
1187        }
1188
1189        @Override
1190        public Object focusSearch(Object info, int direction) {
1191            return null;
1192        }
1193
1194        @Override
1195        public void setText(Object info, CharSequence text) {
1196
1197        }
1198
1199        @Override
1200        public void recycle(Object info) {
1201
1202        }
1203
1204        @Override
1205        public void setParent(Object info, View root, int virtualDescendantId) {
1206
1207        }
1208
1209        @Override
1210        public String getViewIdResourceName(Object info) {
1211            return null;
1212        }
1213
1214        @Override
1215        public void setViewIdResourceName(Object info, String viewId) {
1216
1217        }
1218
1219        @Override
1220        public int getLiveRegion(Object info) {
1221            return ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE;
1222        }
1223
1224        @Override
1225        public void setLiveRegion(Object info, int mode) {
1226            // No-op
1227        }
1228
1229        @Override
1230        public Object getCollectionInfo(Object info) {
1231            return null;
1232        }
1233
1234        @Override
1235        public void setCollectionInfo(Object info, Object collectionInfo) {
1236        }
1237
1238        @Override
1239        public Object getCollectionItemInfo(Object info) {
1240            return null;
1241        }
1242
1243        @Override
1244        public void setCollectionItemInfo(Object info, Object collectionItemInfo) {
1245        }
1246
1247        @Override
1248        public Object getRangeInfo(Object info) {
1249            return null;
1250        }
1251
1252        @Override
1253        public void setRangeInfo(Object info, Object rangeInfo) {
1254        }
1255
1256        @Override
1257        public List<Object> getActionList(Object info) {
1258            return null;
1259        }
1260
1261        @Override
1262        public Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical,
1263                int selectionMode) {
1264            return null;
1265        }
1266
1267        @Override
1268        public Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical) {
1269            return null;
1270        }
1271
1272        @Override
1273        public int getCollectionInfoColumnCount(Object info) {
1274            return 0;
1275        }
1276
1277        @Override
1278        public int getCollectionInfoRowCount(Object info) {
1279            return 0;
1280        }
1281
1282        @Override
1283        public boolean isCollectionInfoHierarchical(Object info) {
1284            return false;
1285        }
1286
1287        @Override
1288        public Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
1289                int columnSpan, boolean heading, boolean selected) {
1290            return null;
1291        }
1292
1293        @Override
1294        public Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
1295                int columnSpan, boolean heading) {
1296            return null;
1297        }
1298
1299        @Override
1300        public int getCollectionItemColumnIndex(Object info) {
1301            return 0;
1302        }
1303
1304        @Override
1305        public int getCollectionItemColumnSpan(Object info) {
1306            return 0;
1307        }
1308
1309        @Override
1310        public int getCollectionItemRowIndex(Object info) {
1311            return 0;
1312        }
1313
1314        @Override
1315        public int getCollectionItemRowSpan(Object info) {
1316            return 0;
1317        }
1318
1319        @Override
1320        public boolean isCollectionItemHeading(Object info) {
1321            return false;
1322        }
1323
1324        @Override
1325        public boolean isCollectionItemSelected(Object info) {
1326            return false;
1327        }
1328
1329        @Override
1330        public Object obtainRangeInfo(int type, float min, float max, float current) {
1331            return null;
1332        }
1333
1334        @Override
1335        public Object getTraversalBefore(Object info) {
1336            return null;
1337        }
1338
1339        @Override
1340        public void setTraversalBefore(Object info, View view) {
1341        }
1342
1343        @Override
1344        public void setTraversalBefore(Object info, View root, int virtualDescendantId) {
1345        }
1346
1347        @Override
1348        public Object getTraversalAfter(Object info) {
1349            return null;
1350        }
1351
1352        @Override
1353        public void setTraversalAfter(Object info, View view) {
1354        }
1355
1356        @Override
1357        public void setTraversalAfter(Object info, View root, int virtualDescendantId) {
1358        }
1359
1360        @Override
1361        public void setContentInvalid(Object info, boolean contentInvalid) {
1362        }
1363
1364        @Override
1365        public boolean isContentInvalid(Object info) {
1366            return false;
1367        }
1368
1369        @Override
1370        public void setError(Object info, CharSequence error) {
1371        }
1372
1373        @Override
1374        public CharSequence getError(Object info) {
1375            return null;
1376        }
1377
1378        @Override
1379        public void setLabelFor(Object info, View labeled) {
1380        }
1381
1382        @Override
1383        public void setLabelFor(Object info, View root, int virtualDescendantId) {
1384        }
1385
1386        @Override
1387        public Object getLabelFor(Object info) {
1388            return null;
1389        }
1390
1391        @Override
1392        public void setLabeledBy(Object info, View labeled) {
1393        }
1394
1395        @Override
1396        public void setLabeledBy(Object info, View root, int virtualDescendantId) {
1397        }
1398
1399        @Override
1400        public Object getLabeledBy(Object info){
1401            return null;
1402        }
1403
1404        @Override
1405        public boolean canOpenPopup(Object info) {
1406            return false;
1407        }
1408
1409        @Override
1410        public void setCanOpenPopup(Object info, boolean opensPopup) {
1411        }
1412
1413        @Override
1414        public List<Object> findAccessibilityNodeInfosByViewId(Object info, String viewId) {
1415            return  Collections.emptyList();
1416        }
1417
1418        @Override
1419        public Bundle getExtras(Object info) {
1420            return new Bundle();
1421        }
1422
1423        @Override
1424        public int getInputType(Object info) {
1425            return InputType.TYPE_NULL;
1426        }
1427
1428        @Override
1429        public void setInputType(Object info, int inputType) {
1430        }
1431
1432        @Override
1433        public void setMaxTextLength(Object info, int max) {
1434        }
1435
1436        @Override
1437        public int getMaxTextLength(Object info) {
1438            return -1;
1439        }
1440
1441        @Override
1442        public void setTextSelection(Object info, int start, int end) {
1443        }
1444
1445        @Override
1446        public int getTextSelectionStart(Object info) {
1447            return -1;
1448        }
1449
1450        @Override
1451        public int getTextSelectionEnd(Object info) {
1452            return -1;
1453        }
1454
1455        @Override
1456        public Object getWindow(Object info) {
1457            return null;
1458        }
1459
1460        @Override
1461        public boolean isDismissable(Object info) {
1462            return false;
1463        }
1464
1465        @Override
1466        public void setDismissable(Object info, boolean dismissable) {
1467        }
1468
1469        @Override
1470        public boolean isEditable(Object info) {
1471            return false;
1472        }
1473
1474        @Override
1475        public void setEditable(Object info, boolean editable) {
1476        }
1477
1478        @Override
1479        public boolean isMultiLine(Object info) {
1480            return false;
1481        }
1482
1483        @Override
1484        public void setMultiLine(Object info, boolean multiLine) {
1485        }
1486
1487        @Override
1488        public boolean refresh(Object info) {
1489            return false;
1490        }
1491
1492        @Override
1493        public CharSequence getRoleDescription(Object info) {
1494            return null;
1495        }
1496
1497        @Override
1498        public void setRoleDescription(Object info, CharSequence roleDescription) {
1499        }
1500
1501        @Override
1502        public Object getActionScrollToPosition() {
1503            return null;
1504        }
1505
1506        @Override
1507        public Object getActionSetProgress() {
1508            return null;
1509        }
1510
1511        @Override
1512        public boolean isContextClickable(Object info) {
1513            return false;
1514        }
1515
1516        @Override
1517        public void setContextClickable(Object info, boolean contextClickable) {
1518            // Do nothing.
1519        }
1520
1521        @Override
1522        public Object getActionShowOnScreen() {
1523            return null;
1524        }
1525
1526        @Override
1527        public Object getActionScrollUp() {
1528            return null;
1529        }
1530
1531        @Override
1532        public Object getActionScrollDown() {
1533            return null;
1534        }
1535
1536        @Override
1537        public Object getActionScrollLeft() {
1538            return null;
1539        }
1540
1541        @Override
1542        public Object getActionScrollRight() {
1543            return null;
1544        }
1545
1546        @Override
1547        public Object getActionContextClick() {
1548            return null;
1549        }
1550
1551        @Override
1552        public int getCollectionInfoSelectionMode(Object info) {
1553            return 0;
1554        }
1555
1556        @Override
1557        public int getDrawingOrder(Object info) {
1558            return 0;
1559        }
1560
1561        @Override
1562        public void setDrawingOrder(Object info, int drawingOrderInParent) {
1563        }
1564
1565        @Override
1566        public boolean isImportantForAccessibility(Object info) {
1567            return true;
1568        }
1569
1570        @Override
1571        public void setImportantForAccessibility(Object info, boolean importantForAccessibility) {
1572        }
1573    }
1574
1575    static class AccessibilityNodeInfoIcsImpl extends AccessibilityNodeInfoStubImpl {
1576        @Override
1577        public Object obtain() {
1578            return AccessibilityNodeInfoCompatIcs.obtain();
1579        }
1580
1581        @Override
1582        public Object obtain(View source) {
1583            return AccessibilityNodeInfoCompatIcs.obtain(source);
1584        }
1585
1586        @Override
1587        public Object obtain(Object info) {
1588            return AccessibilityNodeInfoCompatIcs.obtain(info);
1589        }
1590
1591        @Override
1592        public void addAction(Object info, int action) {
1593            AccessibilityNodeInfoCompatIcs.addAction(info, action);
1594        }
1595
1596        @Override
1597        public void addChild(Object info, View child) {
1598            AccessibilityNodeInfoCompatIcs.addChild(info, child);
1599        }
1600
1601        @Override
1602        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
1603            return AccessibilityNodeInfoCompatIcs.findAccessibilityNodeInfosByText(info, text);
1604        }
1605
1606        @Override
1607        public int getActions(Object info) {
1608            return AccessibilityNodeInfoCompatIcs.getActions(info);
1609        }
1610
1611        @Override
1612        public void getBoundsInParent(Object info, Rect outBounds) {
1613            AccessibilityNodeInfoCompatIcs.getBoundsInParent(info, outBounds);
1614        }
1615
1616        @Override
1617        public void getBoundsInScreen(Object info, Rect outBounds) {
1618            AccessibilityNodeInfoCompatIcs.getBoundsInScreen(info, outBounds);
1619        }
1620
1621        @Override
1622        public Object getChild(Object info, int index) {
1623            return AccessibilityNodeInfoCompatIcs.getChild(info, index);
1624        }
1625
1626        @Override
1627        public int getChildCount(Object info) {
1628            return AccessibilityNodeInfoCompatIcs.getChildCount(info);
1629        }
1630
1631        @Override
1632        public CharSequence getClassName(Object info) {
1633            return AccessibilityNodeInfoCompatIcs.getClassName(info);
1634        }
1635
1636        @Override
1637        public CharSequence getContentDescription(Object info) {
1638            return AccessibilityNodeInfoCompatIcs.getContentDescription(info);
1639        }
1640
1641        @Override
1642        public CharSequence getPackageName(Object info) {
1643            return AccessibilityNodeInfoCompatIcs.getPackageName(info);
1644        }
1645
1646        @Override
1647        public Object getParent(Object info) {
1648            return AccessibilityNodeInfoCompatIcs.getParent(info);
1649        }
1650
1651        @Override
1652        public CharSequence getText(Object info) {
1653            return AccessibilityNodeInfoCompatIcs.getText(info);
1654        }
1655
1656        @Override
1657        public int getWindowId(Object info) {
1658            return AccessibilityNodeInfoCompatIcs.getWindowId(info);
1659        }
1660
1661        @Override
1662        public boolean isCheckable(Object info) {
1663            return AccessibilityNodeInfoCompatIcs.isCheckable(info);
1664        }
1665
1666        @Override
1667        public boolean isChecked(Object info) {
1668            return AccessibilityNodeInfoCompatIcs.isChecked(info);
1669        }
1670
1671        @Override
1672        public boolean isClickable(Object info) {
1673            return AccessibilityNodeInfoCompatIcs.isClickable(info);
1674        }
1675
1676        @Override
1677        public boolean isEnabled(Object info) {
1678            return AccessibilityNodeInfoCompatIcs.isEnabled(info);
1679        }
1680
1681        @Override
1682        public boolean isFocusable(Object info) {
1683            return AccessibilityNodeInfoCompatIcs.isFocusable(info);
1684        }
1685
1686        @Override
1687        public boolean isFocused(Object info) {
1688            return AccessibilityNodeInfoCompatIcs.isFocused(info);
1689        }
1690
1691        @Override
1692        public boolean isLongClickable(Object info) {
1693            return AccessibilityNodeInfoCompatIcs.isLongClickable(info);
1694        }
1695
1696        @Override
1697        public boolean isPassword(Object info) {
1698            return AccessibilityNodeInfoCompatIcs.isPassword(info);
1699        }
1700
1701        @Override
1702        public boolean isScrollable(Object info) {
1703            return AccessibilityNodeInfoCompatIcs.isScrollable(info);
1704        }
1705
1706        @Override
1707        public boolean isSelected(Object info) {
1708            return AccessibilityNodeInfoCompatIcs.isSelected(info);
1709        }
1710
1711        @Override
1712        public boolean performAction(Object info, int action) {
1713            return AccessibilityNodeInfoCompatIcs.performAction(info, action);
1714        }
1715
1716        @Override
1717        public void setBoundsInParent(Object info, Rect bounds) {
1718            AccessibilityNodeInfoCompatIcs.setBoundsInParent(info, bounds);
1719        }
1720
1721        @Override
1722        public void setBoundsInScreen(Object info, Rect bounds) {
1723            AccessibilityNodeInfoCompatIcs.setBoundsInScreen(info, bounds);
1724        }
1725
1726        @Override
1727        public void setCheckable(Object info, boolean checkable) {
1728            AccessibilityNodeInfoCompatIcs.setCheckable(info, checkable);
1729        }
1730
1731        @Override
1732        public void setChecked(Object info, boolean checked) {
1733            AccessibilityNodeInfoCompatIcs.setChecked(info, checked);
1734        }
1735
1736        @Override
1737        public void setClassName(Object info, CharSequence className) {
1738            AccessibilityNodeInfoCompatIcs.setClassName(info, className);
1739        }
1740
1741        @Override
1742        public void setClickable(Object info, boolean clickable) {
1743            AccessibilityNodeInfoCompatIcs.setClickable(info, clickable);
1744        }
1745
1746        @Override
1747        public void setContentDescription(Object info, CharSequence contentDescription) {
1748            AccessibilityNodeInfoCompatIcs.setContentDescription(info, contentDescription);
1749        }
1750
1751        @Override
1752        public void setEnabled(Object info, boolean enabled) {
1753            AccessibilityNodeInfoCompatIcs.setEnabled(info, enabled);
1754        }
1755
1756        @Override
1757        public void setFocusable(Object info, boolean focusable) {
1758            AccessibilityNodeInfoCompatIcs.setFocusable(info, focusable);
1759        }
1760
1761        @Override
1762        public void setFocused(Object info, boolean focused) {
1763            AccessibilityNodeInfoCompatIcs.setFocused(info, focused);
1764        }
1765
1766        @Override
1767        public void setLongClickable(Object info, boolean longClickable) {
1768            AccessibilityNodeInfoCompatIcs.setLongClickable(info, longClickable);
1769        }
1770
1771        @Override
1772        public void setPackageName(Object info, CharSequence packageName) {
1773            AccessibilityNodeInfoCompatIcs.setPackageName(info, packageName);
1774        }
1775
1776        @Override
1777        public void setParent(Object info, View parent) {
1778            AccessibilityNodeInfoCompatIcs.setParent(info, parent);
1779        }
1780
1781        @Override
1782        public void setPassword(Object info, boolean password) {
1783            AccessibilityNodeInfoCompatIcs.setPassword(info, password);
1784        }
1785
1786        @Override
1787        public void setScrollable(Object info, boolean scrollable) {
1788            AccessibilityNodeInfoCompatIcs.setScrollable(info, scrollable);
1789        }
1790
1791        @Override
1792        public void setSelected(Object info, boolean selected) {
1793            AccessibilityNodeInfoCompatIcs.setSelected(info, selected);
1794        }
1795
1796        @Override
1797        public void setSource(Object info, View source) {
1798            AccessibilityNodeInfoCompatIcs.setSource(info, source);
1799        }
1800
1801        @Override
1802        public void setText(Object info, CharSequence text) {
1803            AccessibilityNodeInfoCompatIcs.setText(info, text);
1804        }
1805
1806        @Override
1807        public void recycle(Object info) {
1808            AccessibilityNodeInfoCompatIcs.recycle(info);
1809        }
1810    }
1811
1812    static class AccessibilityNodeInfoJellybeanImpl extends AccessibilityNodeInfoIcsImpl {
1813        @Override
1814        public Object obtain(View root, int virtualDescendantId) {
1815            return AccessibilityNodeInfoCompatJellyBean.obtain(root, virtualDescendantId);
1816        }
1817
1818        @Override
1819        public Object findFocus(Object info, int focus) {
1820            return AccessibilityNodeInfoCompatJellyBean.findFocus(info, focus);
1821        }
1822
1823        @Override
1824        public Object focusSearch(Object info, int direction) {
1825            return AccessibilityNodeInfoCompatJellyBean.focusSearch(info, direction);
1826        }
1827
1828        @Override
1829        public void addChild(Object info, View child, int virtualDescendantId) {
1830            AccessibilityNodeInfoCompatJellyBean.addChild(info, child, virtualDescendantId);
1831        }
1832
1833        @Override
1834        public void setSource(Object info, View root, int virtualDescendantId) {
1835            AccessibilityNodeInfoCompatJellyBean.setSource(info, root, virtualDescendantId);
1836        }
1837
1838        @Override
1839        public boolean isVisibleToUser(Object info) {
1840            return AccessibilityNodeInfoCompatJellyBean.isVisibleToUser(info);
1841        }
1842
1843        @Override
1844        public void setVisibleToUser(Object info, boolean visibleToUser) {
1845            AccessibilityNodeInfoCompatJellyBean.setVisibleToUser(info, visibleToUser);
1846        }
1847
1848        @Override
1849        public boolean isAccessibilityFocused(Object info) {
1850            return AccessibilityNodeInfoCompatJellyBean.isAccessibilityFocused(info);
1851        }
1852
1853        @Override
1854        public void setAccessibilityFocused(Object info, boolean focused) {
1855            AccessibilityNodeInfoCompatJellyBean.setAccesibilityFocused(info, focused);
1856        }
1857
1858        @Override
1859        public boolean performAction(Object info, int action, Bundle arguments) {
1860            return AccessibilityNodeInfoCompatJellyBean.performAction(info, action, arguments);
1861        }
1862
1863        @Override
1864        public void setMovementGranularities(Object info, int granularities) {
1865            AccessibilityNodeInfoCompatJellyBean.setMovementGranularities(info, granularities);
1866        }
1867
1868        @Override
1869        public int getMovementGranularities(Object info) {
1870            return AccessibilityNodeInfoCompatJellyBean.getMovementGranularities(info);
1871        }
1872
1873        @Override
1874        public void setParent(Object info, View root, int virtualDescendantId) {
1875            AccessibilityNodeInfoCompatJellyBean.setParent(info, root, virtualDescendantId);
1876        }
1877    }
1878
1879    static class AccessibilityNodeInfoJellybeanMr1Impl extends AccessibilityNodeInfoJellybeanImpl {
1880
1881        @Override
1882        public void setLabelFor(Object info, View labeled) {
1883            AccessibilityNodeInfoCompatJellybeanMr1.setLabelFor(info, labeled);
1884        }
1885
1886        @Override
1887        public void setLabelFor(Object info, View root, int virtualDescendantId) {
1888            AccessibilityNodeInfoCompatJellybeanMr1.setLabelFor(info, root, virtualDescendantId);
1889        }
1890
1891        @Override
1892        public Object getLabelFor(Object info) {
1893            return AccessibilityNodeInfoCompatJellybeanMr1.getLabelFor(info);
1894        }
1895
1896        @Override
1897        public void setLabeledBy(Object info, View labeled) {
1898            AccessibilityNodeInfoCompatJellybeanMr1.setLabeledBy(info, labeled);
1899        }
1900
1901        @Override
1902        public void setLabeledBy(Object info, View root, int virtualDescendantId) {
1903            AccessibilityNodeInfoCompatJellybeanMr1.setLabeledBy(info, root, virtualDescendantId);
1904        }
1905
1906        @Override
1907        public Object getLabeledBy(Object info) {
1908            return AccessibilityNodeInfoCompatJellybeanMr1.getLabeledBy(info);
1909        }
1910    }
1911
1912    static class AccessibilityNodeInfoJellybeanMr2Impl extends
1913            AccessibilityNodeInfoJellybeanMr1Impl {
1914
1915        @Override
1916        public String getViewIdResourceName(Object info) {
1917            return AccessibilityNodeInfoCompatJellybeanMr2.getViewIdResourceName(info);
1918        }
1919
1920        @Override
1921        public void setViewIdResourceName(Object info, String viewId) {
1922            AccessibilityNodeInfoCompatJellybeanMr2.setViewIdResourceName(info, viewId);
1923        }
1924
1925        @Override
1926        public List<Object> findAccessibilityNodeInfosByViewId(Object info, String viewId) {
1927            return AccessibilityNodeInfoCompatJellybeanMr2.findAccessibilityNodeInfosByViewId(info,
1928                    viewId);
1929        }
1930
1931        @Override
1932        public void setTextSelection(Object info, int start, int end) {
1933            AccessibilityNodeInfoCompatJellybeanMr2.setTextSelection(info, start, end);
1934        }
1935
1936        @Override
1937        public int getTextSelectionStart(Object info) {
1938            return AccessibilityNodeInfoCompatJellybeanMr2.getTextSelectionStart(info);
1939        }
1940
1941        @Override
1942        public int getTextSelectionEnd(Object info) {
1943            return AccessibilityNodeInfoCompatJellybeanMr2.getTextSelectionEnd(info);
1944        }
1945
1946        @Override
1947        public boolean isEditable(Object info) {
1948            return AccessibilityNodeInfoCompatJellybeanMr2.isEditable(info);
1949        }
1950
1951        @Override
1952        public void setEditable(Object info, boolean editable) {
1953            AccessibilityNodeInfoCompatJellybeanMr2.setEditable(info, editable);
1954        }
1955
1956        @Override
1957        public boolean refresh(Object info) {
1958            return AccessibilityNodeInfoCompatJellybeanMr2.refresh(info);
1959        }
1960    }
1961
1962    static class AccessibilityNodeInfoKitKatImpl extends AccessibilityNodeInfoJellybeanMr2Impl {
1963        @Override
1964        public int getLiveRegion(Object info) {
1965            return AccessibilityNodeInfoCompatKitKat.getLiveRegion(info);
1966        }
1967
1968        @Override
1969        public void setLiveRegion(Object info, int mode) {
1970            AccessibilityNodeInfoCompatKitKat.setLiveRegion(info, mode);
1971        }
1972
1973        @Override
1974        public Object getCollectionInfo(Object info) {
1975            return AccessibilityNodeInfoCompatKitKat.getCollectionInfo(info);
1976        }
1977
1978        @Override
1979        public void setCollectionInfo(Object info, Object collectionInfo) {
1980            AccessibilityNodeInfoCompatKitKat.setCollectionInfo(info, collectionInfo);
1981        }
1982
1983        @Override
1984        public Object obtainCollectionInfo(int rowCount, int columnCount,
1985                boolean hierarchical, int selectionMode) {
1986            return AccessibilityNodeInfoCompatKitKat.obtainCollectionInfo(rowCount, columnCount,
1987                    hierarchical, selectionMode);
1988        }
1989
1990        @Override
1991        public Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical) {
1992            return AccessibilityNodeInfoCompatKitKat.obtainCollectionInfo(rowCount, columnCount,
1993                    hierarchical);
1994        }
1995
1996        @Override
1997        public Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
1998                int columnSpan, boolean heading, boolean selected) {
1999            return AccessibilityNodeInfoCompatKitKat
2000                    .obtainCollectionItemInfo(rowIndex, rowSpan, columnIndex, columnSpan, heading);
2001        }
2002
2003        @Override
2004        public Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
2005                int columnSpan, boolean heading) {
2006            return AccessibilityNodeInfoCompatKitKat
2007                    .obtainCollectionItemInfo(rowIndex, rowSpan, columnIndex, columnSpan, heading);
2008        }
2009
2010        @Override
2011        public int getCollectionInfoColumnCount(Object info) {
2012            return AccessibilityNodeInfoCompatKitKat.CollectionInfo.getColumnCount(info);
2013        }
2014
2015        @Override
2016        public int getCollectionInfoRowCount(Object info) {
2017            return AccessibilityNodeInfoCompatKitKat.CollectionInfo.getRowCount(info);
2018        }
2019
2020        @Override
2021        public boolean isCollectionInfoHierarchical(Object info) {
2022            return AccessibilityNodeInfoCompatKitKat.CollectionInfo.isHierarchical(info);
2023        }
2024
2025        @Override
2026        public Object getCollectionItemInfo(Object info) {
2027            return AccessibilityNodeInfoCompatKitKat.getCollectionItemInfo(info);
2028        }
2029
2030        @Override
2031        public Object getRangeInfo(Object info) {
2032            return AccessibilityNodeInfoCompatKitKat.getRangeInfo(info);
2033        }
2034
2035        @Override
2036        public void setRangeInfo(Object info, Object rangeInfo) {
2037            AccessibilityNodeInfoCompatKitKat.setRangeInfo(info, rangeInfo);
2038        }
2039
2040        @Override
2041        public int getCollectionItemColumnIndex(Object info) {
2042            return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getColumnIndex(info);
2043        }
2044
2045        @Override
2046        public int getCollectionItemColumnSpan(Object info) {
2047            return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getColumnSpan(info);
2048        }
2049
2050        @Override
2051        public int getCollectionItemRowIndex(Object info) {
2052            return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getRowIndex(info);
2053        }
2054
2055        @Override
2056        public int getCollectionItemRowSpan(Object info) {
2057            return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getRowSpan(info);
2058        }
2059
2060        @Override
2061        public boolean isCollectionItemHeading(Object info) {
2062            return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.isHeading(info);
2063        }
2064
2065        @Override
2066        public void setCollectionItemInfo(Object info, Object collectionItemInfo) {
2067            AccessibilityNodeInfoCompatKitKat.setCollectionItemInfo(info, collectionItemInfo);
2068        }
2069
2070        @Override
2071        public Object obtainRangeInfo(int type, float min, float max, float current) {
2072            return AccessibilityNodeInfoCompatKitKat.obtainRangeInfo(type, min, max, current);
2073        }
2074
2075        @Override
2076        public void setContentInvalid(Object info, boolean contentInvalid) {
2077            AccessibilityNodeInfoCompatKitKat.setContentInvalid(info, contentInvalid);
2078        }
2079
2080        @Override
2081        public boolean isContentInvalid(Object info) {
2082            return AccessibilityNodeInfoCompatKitKat.isContentInvalid(info);
2083        }
2084
2085        @Override
2086        public boolean canOpenPopup(Object info) {
2087            return AccessibilityNodeInfoCompatKitKat.canOpenPopup(info);
2088        }
2089
2090        @Override
2091        public void setCanOpenPopup(Object info, boolean opensPopup) {
2092            AccessibilityNodeInfoCompatKitKat.setCanOpenPopup(info, opensPopup);
2093        }
2094
2095        @Override
2096        public Bundle getExtras(Object info) {
2097            return AccessibilityNodeInfoCompatKitKat.getExtras(info);
2098        }
2099
2100        @Override
2101        public int getInputType(Object info) {
2102            return AccessibilityNodeInfoCompatKitKat.getInputType(info);
2103        }
2104
2105        @Override
2106        public void setInputType(Object info, int inputType) {
2107            AccessibilityNodeInfoCompatKitKat.setInputType(info, inputType);
2108        }
2109
2110        @Override
2111        public boolean isDismissable(Object info) {
2112            return AccessibilityNodeInfoCompatKitKat.isDismissable(info);
2113        }
2114
2115        @Override
2116        public void setDismissable(Object info, boolean dismissable) {
2117            AccessibilityNodeInfoCompatKitKat.setDismissable(info, dismissable);
2118        }
2119
2120        @Override
2121        public boolean isMultiLine(Object info) {
2122            return AccessibilityNodeInfoCompatKitKat.isMultiLine(info);
2123        }
2124
2125        @Override
2126        public void setMultiLine(Object info, boolean multiLine) {
2127            AccessibilityNodeInfoCompatKitKat.setMultiLine(info, multiLine);
2128        }
2129
2130        @Override
2131        public CharSequence getRoleDescription(Object info) {
2132            return AccessibilityNodeInfoCompatKitKat.getRoleDescription(info);
2133        }
2134
2135        @Override
2136        public void setRoleDescription(Object info, CharSequence roleDescription) {
2137            AccessibilityNodeInfoCompatKitKat.setRoleDescription(info, roleDescription);
2138        }
2139    }
2140
2141    static class AccessibilityNodeInfoApi21Impl extends AccessibilityNodeInfoKitKatImpl {
2142        @Override
2143        public Object newAccessibilityAction(int actionId, CharSequence label) {
2144            return AccessibilityNodeInfoCompatApi21.newAccessibilityAction(actionId, label);
2145        }
2146
2147        @Override
2148        public List<Object> getActionList(Object info) {
2149            return AccessibilityNodeInfoCompatApi21.getActionList(info);
2150        }
2151
2152        @Override
2153        public Object obtainCollectionInfo(int rowCount, int columnCount, boolean hierarchical,
2154                int selectionMode) {
2155            return AccessibilityNodeInfoCompatApi21.obtainCollectionInfo(rowCount, columnCount,
2156                    hierarchical, selectionMode);
2157        }
2158
2159        @Override
2160        public void addAction(Object info, Object action) {
2161            AccessibilityNodeInfoCompatApi21.addAction(info, action);
2162        }
2163
2164        @Override
2165        public boolean removeAction(Object info, Object action) {
2166            return AccessibilityNodeInfoCompatApi21.removeAction(info, action);
2167        }
2168
2169        @Override
2170        public int getAccessibilityActionId(Object action) {
2171            return AccessibilityNodeInfoCompatApi21.getAccessibilityActionId(action);
2172        }
2173
2174        @Override
2175        public CharSequence getAccessibilityActionLabel(Object action) {
2176            return AccessibilityNodeInfoCompatApi21.getAccessibilityActionLabel(action);
2177        }
2178
2179        @Override
2180        public Object obtainCollectionItemInfo(int rowIndex, int rowSpan, int columnIndex,
2181                int columnSpan, boolean heading, boolean selected) {
2182            return AccessibilityNodeInfoCompatApi21.obtainCollectionItemInfo(rowIndex, rowSpan,
2183                    columnIndex, columnSpan, heading, selected);
2184        }
2185
2186        @Override
2187        public boolean isCollectionItemSelected(Object info) {
2188            return AccessibilityNodeInfoCompatApi21.CollectionItemInfo.isSelected(info);
2189        }
2190
2191        @Override
2192        public CharSequence getError(Object info) {
2193            return AccessibilityNodeInfoCompatApi21.getError(info);
2194        }
2195
2196        @Override
2197        public void setError(Object info, CharSequence error) {
2198            AccessibilityNodeInfoCompatApi21.setError(info, error);
2199        }
2200
2201        @Override
2202        public void setMaxTextLength(Object info, int max) {
2203            AccessibilityNodeInfoCompatApi21.setMaxTextLength(info, max);
2204        }
2205
2206        @Override
2207        public int getMaxTextLength(Object info) {
2208            return AccessibilityNodeInfoCompatApi21.getMaxTextLength(info);
2209        }
2210
2211        @Override
2212        public Object getWindow(Object info) {
2213            return AccessibilityNodeInfoCompatApi21.getWindow(info);
2214        }
2215
2216        @Override
2217        public boolean removeChild(Object info, View child) {
2218            return AccessibilityNodeInfoCompatApi21.removeChild(info, child);
2219        }
2220
2221        @Override
2222        public boolean removeChild(Object info, View root, int virtualDescendantId) {
2223            return AccessibilityNodeInfoCompatApi21.removeChild(info, root, virtualDescendantId);
2224        }
2225
2226        @Override
2227        public int getCollectionInfoSelectionMode(Object info) {
2228            return AccessibilityNodeInfoCompatApi21.CollectionInfo.getSelectionMode(info);
2229        }
2230    }
2231
2232    static class AccessibilityNodeInfoApi22Impl extends AccessibilityNodeInfoApi21Impl {
2233        @Override
2234        public Object getTraversalBefore(Object info) {
2235            return AccessibilityNodeInfoCompatApi22.getTraversalBefore(info);
2236        }
2237
2238        @Override
2239        public void setTraversalBefore(Object info, View view) {
2240            AccessibilityNodeInfoCompatApi22.setTraversalBefore(info, view);
2241        }
2242
2243        @Override
2244        public void setTraversalBefore(Object info, View root, int virtualDescendantId) {
2245            AccessibilityNodeInfoCompatApi22.setTraversalBefore(info, root, virtualDescendantId);
2246        }
2247
2248        @Override
2249        public Object getTraversalAfter(Object info) {
2250            return AccessibilityNodeInfoCompatApi22.getTraversalAfter(info);
2251        }
2252
2253        @Override
2254        public void setTraversalAfter(Object info, View view) {
2255            AccessibilityNodeInfoCompatApi22.setTraversalAfter(info, view);
2256        }
2257
2258        @Override
2259        public void setTraversalAfter(Object info, View root, int virtualDescendantId) {
2260            AccessibilityNodeInfoCompatApi22.setTraversalAfter(info, root, virtualDescendantId);
2261        }
2262    }
2263
2264    static class AccessibilityNodeInfoApi23Impl extends AccessibilityNodeInfoApi22Impl {
2265        @Override
2266        public Object getActionScrollToPosition() {
2267            return AccessibilityNodeInfoCompatApi23.getActionScrollToPosition();
2268        }
2269
2270        @Override
2271        public Object getActionShowOnScreen() {
2272            return AccessibilityNodeInfoCompatApi23.getActionShowOnScreen();
2273        }
2274
2275        @Override
2276        public Object getActionScrollUp() {
2277            return AccessibilityNodeInfoCompatApi23.getActionScrollUp();
2278        }
2279
2280        @Override
2281        public Object getActionScrollDown() {
2282            return AccessibilityNodeInfoCompatApi23.getActionScrollDown();
2283        }
2284
2285        @Override
2286        public Object getActionScrollLeft() {
2287            return AccessibilityNodeInfoCompatApi23.getActionScrollLeft();
2288        }
2289
2290        @Override
2291        public Object getActionScrollRight() {
2292            return AccessibilityNodeInfoCompatApi23.getActionScrollRight();
2293        }
2294
2295        @Override
2296        public Object getActionContextClick() {
2297            return AccessibilityNodeInfoCompatApi23.getActionContextClick();
2298        }
2299
2300        @Override
2301        public boolean isContextClickable(Object info) {
2302            return AccessibilityNodeInfoCompatApi23.isContextClickable(info);
2303        }
2304
2305        @Override
2306        public void setContextClickable(Object info, boolean contextClickable) {
2307            AccessibilityNodeInfoCompatApi23.setContextClickable(info, contextClickable);
2308        }
2309    }
2310
2311    static class AccessibilityNodeInfoApi24Impl extends AccessibilityNodeInfoApi23Impl {
2312        @Override
2313        public Object getActionSetProgress() {
2314            return AccessibilityNodeInfoCompatApi24.getActionSetProgress();
2315        }
2316
2317        @Override
2318        public int getDrawingOrder(Object info) {
2319            return AccessibilityNodeInfoCompatApi24.getDrawingOrder(info);
2320        }
2321
2322        @Override
2323        public void setDrawingOrder(Object info, int drawingOrderInParent) {
2324            AccessibilityNodeInfoCompatApi24.setDrawingOrder(info, drawingOrderInParent);
2325        }
2326
2327        @Override
2328        public boolean isImportantForAccessibility(Object info) {
2329            return AccessibilityNodeInfoCompatApi24.isImportantForAccessibility(info);
2330        }
2331
2332        @Override
2333        public void setImportantForAccessibility(Object info, boolean importantForAccessibility) {
2334            AccessibilityNodeInfoCompatApi24.setImportantForAccessibility(
2335                    info, importantForAccessibility);
2336        }
2337
2338    }
2339
2340    static {
2341        if (Build.VERSION.SDK_INT >= 24) {
2342            IMPL = new AccessibilityNodeInfoApi24Impl();
2343        } else if (Build.VERSION.SDK_INT >= 23) {
2344            IMPL = new AccessibilityNodeInfoApi23Impl();
2345        } else if (Build.VERSION.SDK_INT >= 22) {
2346            IMPL = new AccessibilityNodeInfoApi22Impl();
2347        } else if (Build.VERSION.SDK_INT >= 21) {
2348            IMPL = new AccessibilityNodeInfoApi21Impl();
2349        } else if (Build.VERSION.SDK_INT >= 19) { // KitKat
2350            IMPL = new AccessibilityNodeInfoKitKatImpl();
2351        } else if (Build.VERSION.SDK_INT >= 18) { // JellyBean MR2
2352            IMPL = new AccessibilityNodeInfoJellybeanMr2Impl();
2353        } else if (Build.VERSION.SDK_INT >= 17) { // JellyBean MR1
2354            IMPL = new AccessibilityNodeInfoJellybeanMr1Impl();
2355        } else if (Build.VERSION.SDK_INT >= 16) { // JellyBean
2356            IMPL = new AccessibilityNodeInfoJellybeanImpl();
2357        } else if (Build.VERSION.SDK_INT >= 14) { // ICS
2358            IMPL = new AccessibilityNodeInfoIcsImpl();
2359        } else {
2360            IMPL = new AccessibilityNodeInfoStubImpl();
2361        }
2362    }
2363
2364    static final AccessibilityNodeInfoImpl IMPL;
2365
2366    private final Object mInfo;
2367
2368    // Actions introduced in IceCreamSandwich
2369
2370    /**
2371     * Action that focuses the node.
2372     */
2373    public static final int ACTION_FOCUS = 0x00000001;
2374
2375    /**
2376     * Action that unfocuses the node.
2377     */
2378    public static final int ACTION_CLEAR_FOCUS = 0x00000002;
2379
2380    /**
2381     * Action that selects the node.
2382     */
2383    public static final int ACTION_SELECT = 0x00000004;
2384
2385    /**
2386     * Action that unselects the node.
2387     */
2388    public static final int ACTION_CLEAR_SELECTION = 0x00000008;
2389
2390    /**
2391     * Action that clicks on the node info.
2392     */
2393    public static final int ACTION_CLICK = 0x00000010;
2394
2395    /**
2396     * Action that long clicks on the node.
2397     */
2398    public static final int ACTION_LONG_CLICK = 0x00000020;
2399
2400    // Actions introduced in JellyBean
2401
2402    /**
2403     * Action that gives accessibility focus to the node.
2404     */
2405    public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
2406
2407    /**
2408     * Action that clears accessibility focus of the node.
2409     */
2410    public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
2411
2412    /**
2413     * Action that requests to go to the next entity in this node's text
2414     * at a given movement granularity. For example, move to the next character,
2415     * word, etc.
2416     * <p>
2417     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
2418     * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
2419     * <strong>Example:</strong> Move to the previous character and do not extend selection.
2420     * <code><pre><p>
2421     *   Bundle arguments = new Bundle();
2422     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
2423     *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
2424     *   arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
2425     *           false);
2426     *   info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
2427     * </code></pre></p>
2428     * </p>
2429     *
2430     * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
2431     * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
2432     *
2433     * @see #setMovementGranularities(int)
2434     * @see #getMovementGranularities()
2435     *
2436     * @see #MOVEMENT_GRANULARITY_CHARACTER
2437     * @see #MOVEMENT_GRANULARITY_WORD
2438     * @see #MOVEMENT_GRANULARITY_LINE
2439     * @see #MOVEMENT_GRANULARITY_PARAGRAPH
2440     * @see #MOVEMENT_GRANULARITY_PAGE
2441     */
2442    public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 0x00000100;
2443
2444    /**
2445     * Action that requests to go to the previous entity in this node's text
2446     * at a given movement granularity. For example, move to the next character,
2447     * word, etc.
2448     * <p>
2449     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
2450     * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
2451     * <strong>Example:</strong> Move to the next character and do not extend selection.
2452     * <code><pre><p>
2453     *   Bundle arguments = new Bundle();
2454     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
2455     *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
2456     *   arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
2457     *           false);
2458     *   info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
2459     *           arguments);
2460     * </code></pre></p>
2461     * </p>
2462     *
2463     * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
2464     * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
2465     *
2466     * @see #setMovementGranularities(int)
2467     * @see #getMovementGranularities()
2468     *
2469     * @see #MOVEMENT_GRANULARITY_CHARACTER
2470     * @see #MOVEMENT_GRANULARITY_WORD
2471     * @see #MOVEMENT_GRANULARITY_LINE
2472     * @see #MOVEMENT_GRANULARITY_PARAGRAPH
2473     * @see #MOVEMENT_GRANULARITY_PAGE
2474     */
2475    public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 0x00000200;
2476
2477    /**
2478     * Action to move to the next HTML element of a given type. For example, move
2479     * to the BUTTON, INPUT, TABLE, etc.
2480     * <p>
2481     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
2482     * <strong>Example:</strong>
2483     * <code><pre><p>
2484     *   Bundle arguments = new Bundle();
2485     *   arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
2486     *   info.performAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT, arguments);
2487     * </code></pre></p>
2488     * </p>
2489     */
2490    public static final int ACTION_NEXT_HTML_ELEMENT = 0x00000400;
2491
2492    /**
2493     * Action to move to the previous HTML element of a given type. For example, move
2494     * to the BUTTON, INPUT, TABLE, etc.
2495     * <p>
2496     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
2497     * <strong>Example:</strong>
2498     * <code><pre><p>
2499     *   Bundle arguments = new Bundle();
2500     *   arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
2501     *   info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT, arguments);
2502     * </code></pre></p>
2503     * </p>
2504     */
2505    public static final int ACTION_PREVIOUS_HTML_ELEMENT = 0x00000800;
2506
2507    /**
2508     * Action to scroll the node content forward.
2509     */
2510    public static final int ACTION_SCROLL_FORWARD = 0x00001000;
2511
2512    /**
2513     * Action to scroll the node content backward.
2514     */
2515    public static final int ACTION_SCROLL_BACKWARD = 0x00002000;
2516
2517    // Actions introduced in JellyBeanMr2
2518
2519    /**
2520     * Action to copy the current selection to the clipboard.
2521     */
2522    public static final int ACTION_COPY = 0x00004000;
2523
2524    /**
2525     * Action to paste the current clipboard content.
2526     */
2527    public static final int ACTION_PASTE = 0x00008000;
2528
2529    /**
2530     * Action to cut the current selection and place it to the clipboard.
2531     */
2532    public static final int ACTION_CUT = 0x00010000;
2533
2534    /**
2535     * Action to set the selection. Performing this action with no arguments
2536     * clears the selection.
2537     * <p>
2538     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SELECTION_START_INT},
2539     * {@link #ACTION_ARGUMENT_SELECTION_END_INT}<br>
2540     * <strong>Example:</strong>
2541     * <code><pre><p>
2542     *   Bundle arguments = new Bundle();
2543     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1);
2544     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2);
2545     *   info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments);
2546     * </code></pre></p>
2547     * </p>
2548     *
2549     * @see #ACTION_ARGUMENT_SELECTION_START_INT
2550     * @see #ACTION_ARGUMENT_SELECTION_END_INT
2551     */
2552    public static final int ACTION_SET_SELECTION = 0x00020000;
2553
2554    /**
2555     * Action to expand an expandable node.
2556     */
2557    public static final int ACTION_EXPAND = 0x00040000;
2558
2559    /**
2560     * Action to collapse an expandable node.
2561     */
2562    public static final int ACTION_COLLAPSE = 0x00080000;
2563
2564    /**
2565     * Action to dismiss a dismissable node.
2566     */
2567    public static final int ACTION_DISMISS = 0x00100000;
2568
2569    /**
2570     * Action that sets the text of the node. Performing the action without argument, using <code>
2571     * null</code> or empty {@link CharSequence} will clear the text. This action will also put the
2572     * cursor at the end of text.
2573     * <p>
2574     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
2575     * <strong>Example:</strong>
2576     * <code><pre><p>
2577     *   Bundle arguments = new Bundle();
2578     *   arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
2579     *       "android");
2580     *   info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
2581     * </code></pre></p>
2582     */
2583    public static final int ACTION_SET_TEXT = 0x00200000;
2584
2585    // Action arguments
2586
2587    /**
2588     * Argument for which movement granularity to be used when traversing the node text.
2589     * <p>
2590     * <strong>Type:</strong> int<br>
2591     * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
2592     * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
2593     * </p>
2594     */
2595    public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT =
2596        "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
2597
2598    /**
2599     * Argument for which HTML element to get moving to the next/previous HTML element.
2600     * <p>
2601     * <strong>Type:</strong> String<br>
2602     * <strong>Actions:</strong> {@link #ACTION_NEXT_HTML_ELEMENT},
2603     *         {@link #ACTION_PREVIOUS_HTML_ELEMENT}
2604     * </p>
2605     */
2606    public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING =
2607        "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
2608
2609    /**
2610     * Argument for whether when moving at granularity to extend the selection
2611     * or to move it otherwise.
2612     * <p>
2613     * <strong>Type:</strong> boolean<br>
2614     * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
2615     * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
2616     * </p>
2617     *
2618     * @see #ACTION_NEXT_AT_MOVEMENT_GRANULARITY
2619     * @see #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
2620     */
2621    public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN =
2622            "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
2623
2624    /**
2625     * Argument for specifying the selection start.
2626     * <p>
2627     * <strong>Type:</strong> int<br>
2628     * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
2629     * </p>
2630     *
2631     * @see #ACTION_SET_SELECTION
2632     */
2633    public static final String ACTION_ARGUMENT_SELECTION_START_INT =
2634            "ACTION_ARGUMENT_SELECTION_START_INT";
2635
2636    /**
2637     * Argument for specifying the selection end.
2638     * <p>
2639     * <strong>Type:</strong> int<br>
2640     * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
2641     * </p>
2642     *
2643     * @see #ACTION_SET_SELECTION
2644     */
2645    public static final String ACTION_ARGUMENT_SELECTION_END_INT =
2646            "ACTION_ARGUMENT_SELECTION_END_INT";
2647
2648    /**
2649     * Argument for specifying the text content to set
2650     * <p>
2651     * <strong>Type:</strong> CharSequence<br>
2652     * <strong>Actions:</strong> {@link #ACTION_SET_TEXT}
2653     * </p>
2654     *
2655     * @see #ACTION_SET_TEXT
2656     */
2657    public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
2658            "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
2659
2660    /**
2661     * Argument for specifying the collection row to make visible on screen.
2662     * <p>
2663     * <strong>Type:</strong> int<br>
2664     * <strong>Actions:</strong>
2665     * <ul>
2666     *     <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
2667     * </ul>
2668     *
2669     * @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION
2670     */
2671    public static final String ACTION_ARGUMENT_ROW_INT =
2672            "android.view.accessibility.action.ARGUMENT_ROW_INT";
2673
2674    /**
2675     * Argument for specifying the collection column to make visible on screen.
2676     * <p>
2677     * <strong>Type:</strong> int<br>
2678     * <strong>Actions:</strong>
2679     * <ul>
2680     *     <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
2681     * </ul>
2682     *
2683     * @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION
2684     */
2685    public static final String ACTION_ARGUMENT_COLUMN_INT =
2686            "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
2687
2688    /**
2689     * Argument for specifying the progress value to set.
2690     * <p>
2691     * <strong>Type:</strong> float<br>
2692     * <strong>Actions:</strong>
2693     * <ul>
2694     *     <li>{@link AccessibilityActionCompat#ACTION_SET_PROGRESS}</li>
2695     * </ul>
2696     *
2697     * @see AccessibilityActionCompat#ACTION_SET_PROGRESS
2698     */
2699    public static final String ACTION_ARGUMENT_PROGRESS_VALUE =
2700            "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
2701
2702    // Focus types
2703
2704    /**
2705     * The input focus.
2706     */
2707    public static final int FOCUS_INPUT = 1;
2708
2709    /**
2710     * The accessibility focus.
2711     */
2712    public static final int FOCUS_ACCESSIBILITY = 2;
2713
2714    // Movement granularities
2715
2716    /**
2717     * Movement granularity bit for traversing the text of a node by character.
2718     */
2719    public static final int MOVEMENT_GRANULARITY_CHARACTER = 0x00000001;
2720
2721    /**
2722     * Movement granularity bit for traversing the text of a node by word.
2723     */
2724    public static final int MOVEMENT_GRANULARITY_WORD = 0x00000002;
2725
2726    /**
2727     * Movement granularity bit for traversing the text of a node by line.
2728     */
2729    public static final int MOVEMENT_GRANULARITY_LINE = 0x00000004;
2730
2731    /**
2732     * Movement granularity bit for traversing the text of a node by paragraph.
2733     */
2734    public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 0x00000008;
2735
2736    /**
2737     * Movement granularity bit for traversing the text of a node by page.
2738     */
2739    public static final int MOVEMENT_GRANULARITY_PAGE = 0x00000010;
2740
2741    /**
2742     * Creates a wrapper for info implementation.
2743     *
2744     * @param object The info to wrap.
2745     * @return A wrapper for if the object is not null, null otherwise.
2746     */
2747    static AccessibilityNodeInfoCompat wrapNonNullInstance(Object object) {
2748        if (object != null) {
2749            return new AccessibilityNodeInfoCompat(object);
2750        }
2751        return null;
2752    }
2753
2754    /**
2755     * Creates a new instance wrapping an
2756     * {@link android.view.accessibility.AccessibilityNodeInfo}.
2757     *
2758     * @param info The info.
2759     */
2760    public AccessibilityNodeInfoCompat(Object info) {
2761        mInfo = info;
2762    }
2763
2764    /**
2765     * @return The wrapped {@link android.view.accessibility.AccessibilityNodeInfo}.
2766     */
2767    public Object getInfo() {
2768        return mInfo;
2769    }
2770
2771    /**
2772     * Returns a cached instance if such is available otherwise a new one and
2773     * sets the source.
2774     *
2775     * @return An instance.
2776     * @see #setSource(View)
2777     */
2778    public static AccessibilityNodeInfoCompat obtain(View source) {
2779        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain(source));
2780    }
2781
2782    /**
2783     * Returns a cached instance if such is available otherwise a new one
2784     * and sets the source.
2785     *
2786     * @param root The root of the virtual subtree.
2787     * @param virtualDescendantId The id of the virtual descendant.
2788     * @return An instance.
2789     *
2790     * @see #setSource(View, int)
2791     */
2792    public static AccessibilityNodeInfoCompat obtain(View root, int virtualDescendantId) {
2793        return AccessibilityNodeInfoCompat.wrapNonNullInstance(
2794                IMPL.obtain(root, virtualDescendantId));
2795    }
2796
2797    /**
2798     * Returns a cached instance if such is available otherwise a new one.
2799     *
2800     * @return An instance.
2801     */
2802    public static AccessibilityNodeInfoCompat obtain() {
2803        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain());
2804    }
2805
2806    /**
2807     * Returns a cached instance if such is available or a new one is create.
2808     * The returned instance is initialized from the given <code>info</code>.
2809     *
2810     * @param info The other info.
2811     * @return An instance.
2812     */
2813    public static AccessibilityNodeInfoCompat obtain(AccessibilityNodeInfoCompat info) {
2814        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain(info.mInfo));
2815    }
2816
2817    /**
2818     * Sets the source.
2819     *
2820     * @param source The info source.
2821     */
2822    public void setSource(View source) {
2823        IMPL.setSource(mInfo, source);
2824    }
2825
2826    /**
2827     * Sets the source to be a virtual descendant of the given <code>root</code>.
2828     * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
2829     * is set as the source.
2830     * <p>
2831     * A virtual descendant is an imaginary View that is reported as a part of the view
2832     * hierarchy for accessibility purposes. This enables custom views that draw complex
2833     * content to report themselves as a tree of virtual views, thus conveying their
2834     * logical structure.
2835     * </p>
2836     * <p>
2837     *   <strong>Note:</strong> Cannot be called from an
2838     *   {@link android.accessibilityservice.AccessibilityService}.
2839     *   This class is made immutable before being delivered to an AccessibilityService.
2840     * </p>
2841     *
2842     * @param root The root of the virtual subtree.
2843     * @param virtualDescendantId The id of the virtual descendant.
2844     */
2845    public void setSource(View root, int virtualDescendantId) {
2846        IMPL.setSource(mInfo, root, virtualDescendantId);
2847    }
2848
2849    /**
2850     * Find the view that has the specified focus type. The search starts from
2851     * the view represented by this node info.
2852     *
2853     * @param focus The focus to find. One of {@link #FOCUS_INPUT} or
2854     *         {@link #FOCUS_ACCESSIBILITY}.
2855     * @return The node info of the focused view or null.
2856     *
2857     * @see #FOCUS_INPUT
2858     * @see #FOCUS_ACCESSIBILITY
2859     */
2860    public AccessibilityNodeInfoCompat findFocus(int focus) {
2861        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.findFocus(mInfo, focus));
2862    }
2863
2864    /**
2865     * Searches for the nearest view in the specified direction that can take
2866     * input focus.
2867     *
2868     * @param direction The direction. Can be one of:
2869     *     {@link View#FOCUS_DOWN},
2870     *     {@link View#FOCUS_UP},
2871     *     {@link View#FOCUS_LEFT},
2872     *     {@link View#FOCUS_RIGHT},
2873     *     {@link View#FOCUS_FORWARD},
2874     *     {@link View#FOCUS_BACKWARD}.
2875     *
2876     * @return The node info for the view that can take accessibility focus.
2877     */
2878    public AccessibilityNodeInfoCompat focusSearch(int direction) {
2879        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.focusSearch(mInfo, direction));
2880    }
2881
2882    /**
2883     * Gets the id of the window from which the info comes from.
2884     *
2885     * @return The window id.
2886     */
2887    public int getWindowId() {
2888        return IMPL.getWindowId(mInfo);
2889    }
2890
2891    /**
2892     * Gets the number of children.
2893     *
2894     * @return The child count.
2895     */
2896    public int getChildCount() {
2897        return IMPL.getChildCount(mInfo);
2898    }
2899
2900    /**
2901     * Get the child at given index.
2902     * <p>
2903     * <strong>Note:</strong> It is a client responsibility to recycle the
2904     * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} to
2905     * avoid creating of multiple instances.
2906     * </p>
2907     *
2908     * @param index The child index.
2909     * @return The child node.
2910     * @throws IllegalStateException If called outside of an
2911     *             AccessibilityService.
2912     */
2913    public AccessibilityNodeInfoCompat getChild(int index) {
2914        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getChild(mInfo, index));
2915    }
2916
2917    /**
2918     * Adds a child.
2919     * <p>
2920     * <strong>Note:</strong> Cannot be called from an
2921     * {@link android.accessibilityservice.AccessibilityService}. This class is
2922     * made immutable before being delivered to an AccessibilityService.
2923     * </p>
2924     *
2925     * @param child The child.
2926     * @throws IllegalStateException If called from an AccessibilityService.
2927     */
2928    public void addChild(View child) {
2929        IMPL.addChild(mInfo, child);
2930    }
2931
2932    /**
2933     * Adds a virtual child which is a descendant of the given <code>root</code>.
2934     * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
2935     * is added as a child.
2936     * <p>
2937     * A virtual descendant is an imaginary View that is reported as a part of the view
2938     * hierarchy for accessibility purposes. This enables custom views that draw complex
2939     * content to report them selves as a tree of virtual views, thus conveying their
2940     * logical structure.
2941     * </p>
2942     *
2943     * @param root The root of the virtual subtree.
2944     * @param virtualDescendantId The id of the virtual child.
2945     */
2946    public void addChild(View root, int virtualDescendantId) {
2947        IMPL.addChild(mInfo, root, virtualDescendantId);
2948    }
2949
2950    /**
2951     * Removes a child. If the child was not previously added to the node,
2952     * calling this method has no effect.
2953     * <p>
2954     * <strong>Note:</strong> Cannot be called from an
2955     * {@link android.accessibilityservice.AccessibilityService}.
2956     * This class is made immutable before being delivered to an AccessibilityService.
2957     * </p>
2958     *
2959     * @param child The child.
2960     * @return true if the child was present
2961     *
2962     * @throws IllegalStateException If called from an AccessibilityService.
2963     */
2964    public boolean removeChild(View child) {
2965        return IMPL.removeChild(mInfo, child);
2966    }
2967
2968    /**
2969     * Removes a virtual child which is a descendant of the given
2970     * <code>root</code>. If the child was not previously added to the node,
2971     * calling this method has no effect.
2972     *
2973     * @param root The root of the virtual subtree.
2974     * @param virtualDescendantId The id of the virtual child.
2975     * @return true if the child was present
2976     * @see #addChild(View, int)
2977     */
2978    public boolean removeChild(View root, int virtualDescendantId) {
2979        return IMPL.removeChild(mInfo, root, virtualDescendantId);
2980    }
2981
2982    /**
2983     * Gets the actions that can be performed on the node.
2984     *
2985     * @return The bit mask of with actions.
2986     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS
2987     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
2988     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT
2989     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
2990     */
2991    public int getActions() {
2992        return IMPL.getActions(mInfo);
2993    }
2994
2995    /**
2996     * Adds an action that can be performed on the node.
2997     * <p>
2998     * <strong>Note:</strong> Cannot be called from an
2999     * {@link android.accessibilityservice.AccessibilityService}. This class is
3000     * made immutable before being delivered to an AccessibilityService.
3001     * </p>
3002     *
3003     * @param action The action.
3004     * @throws IllegalStateException If called from an AccessibilityService.
3005     */
3006    public void addAction(int action) {
3007        IMPL.addAction(mInfo, action);
3008    }
3009
3010    /**
3011     * Adds an action that can be performed on the node.
3012     * <p>
3013     * <strong>Note:</strong> Cannot be called from an
3014     * {@link android.accessibilityservice.AccessibilityService}. This class is
3015     * made immutable before being delivered to an AccessibilityService.
3016     * </p>
3017     *
3018     * @param action The action.
3019     * @throws IllegalStateException If called from an AccessibilityService.
3020     */
3021    public void addAction(AccessibilityActionCompat action) {
3022        IMPL.addAction(mInfo, action.mAction);
3023    }
3024
3025    /**
3026     * Removes an action that can be performed on the node. If the action was
3027     * not already added to the node, calling this method has no effect.
3028     * <p>
3029     *   <strong>Note:</strong> Cannot be called from an
3030     *   {@link android.accessibilityservice.AccessibilityService}.
3031     *   This class is made immutable before being delivered to an AccessibilityService.
3032     * </p>
3033     *
3034     * @param action The action to be removed.
3035     * @return The action removed from the list of actions.
3036     *
3037     * @throws IllegalStateException If called from an AccessibilityService.
3038     */
3039    public boolean removeAction(AccessibilityActionCompat action) {
3040        return IMPL.removeAction(mInfo, action.mAction);
3041    }
3042
3043    /**
3044     * Performs an action on the node.
3045     * <p>
3046     * <strong>Note:</strong> An action can be performed only if the request is
3047     * made from an {@link android.accessibilityservice.AccessibilityService}.
3048     * </p>
3049     *
3050     * @param action The action to perform.
3051     * @return True if the action was performed.
3052     * @throws IllegalStateException If called outside of an
3053     *             AccessibilityService.
3054     */
3055    public boolean performAction(int action) {
3056        return IMPL.performAction(mInfo, action);
3057    }
3058
3059    /**
3060     * Performs an action on the node.
3061     * <p>
3062     *   <strong>Note:</strong> An action can be performed only if the request is made
3063     *   from an {@link android.accessibilityservice.AccessibilityService}.
3064     * </p>
3065     *
3066     * @param action The action to perform.
3067     * @param arguments A bundle with additional arguments.
3068     * @return True if the action was performed.
3069     *
3070     * @throws IllegalStateException If called outside of an AccessibilityService.
3071     */
3072    public boolean performAction(int action, Bundle arguments) {
3073        return IMPL.performAction(mInfo, action, arguments);
3074    }
3075
3076    /**
3077     * Sets the movement granularities for traversing the text of this node.
3078     * <p>
3079     *   <strong>Note:</strong> Cannot be called from an
3080     *   {@link android.accessibilityservice.AccessibilityService}.
3081     *   This class is made immutable before being delivered to an AccessibilityService.
3082     * </p>
3083     *
3084     * @param granularities The bit mask with granularities.
3085     *
3086     * @throws IllegalStateException If called from an AccessibilityService.
3087     */
3088    public void setMovementGranularities(int granularities) {
3089        IMPL.setMovementGranularities(mInfo, granularities);
3090    }
3091
3092    /**
3093     * Gets the movement granularities for traversing the text of this node.
3094     *
3095     * @return The bit mask with granularities.
3096     */
3097    public int getMovementGranularities() {
3098        return IMPL.getMovementGranularities(mInfo);
3099    }
3100
3101    /**
3102     * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by text. The match
3103     * is case insensitive containment. The search is relative to this info i.e. this
3104     * info is the root of the traversed tree.
3105     * <p>
3106     * <strong>Note:</strong> It is a client responsibility to recycle the
3107     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
3108     * to avoid creating of multiple instances.
3109     * </p>
3110     *
3111     * @param text The searched text.
3112     * @return A list of node info.
3113     */
3114    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
3115        List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>();
3116        List<Object> infos = IMPL.findAccessibilityNodeInfosByText(mInfo, text);
3117        final int infoCount = infos.size();
3118        for (int i = 0; i < infoCount; i++) {
3119            Object info = infos.get(i);
3120            result.add(new AccessibilityNodeInfoCompat(info));
3121        }
3122        return result;
3123    }
3124
3125    /**
3126     * Gets the parent.
3127     * <p>
3128     * <strong>Note:</strong> It is a client responsibility to recycle the
3129     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
3130     * to avoid creating of multiple instances.
3131     * </p>
3132     *
3133     * @return The parent.
3134     */
3135    public AccessibilityNodeInfoCompat getParent() {
3136        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getParent(mInfo));
3137    }
3138
3139    /**
3140     * Sets the parent.
3141     * <p>
3142     * <strong>Note:</strong> Cannot be called from an
3143     * {@link android.accessibilityservice.AccessibilityService}. This class is
3144     * made immutable before being delivered to an AccessibilityService.
3145     * </p>
3146     *
3147     * @param parent The parent.
3148     * @throws IllegalStateException If called from an AccessibilityService.
3149     */
3150    public void setParent(View parent) {
3151        IMPL.setParent(mInfo, parent);
3152    }
3153
3154    /**
3155     * Sets the parent to be a virtual descendant of the given <code>root</code>.
3156     * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
3157     * is set as the parent.
3158     * <p>
3159     * A virtual descendant is an imaginary View that is reported as a part of the view
3160     * hierarchy for accessibility purposes. This enables custom views that draw complex
3161     * content to report them selves as a tree of virtual views, thus conveying their
3162     * logical structure.
3163     * </p>
3164     * <p>
3165     *   <strong>Note:</strong> Cannot be called from an
3166     *   {@link android.accessibilityservice.AccessibilityService}.
3167     *   This class is made immutable before being delivered to an AccessibilityService.
3168     * </p>
3169     *
3170     * @param root The root of the virtual subtree.
3171     * @param virtualDescendantId The id of the virtual descendant.
3172     */
3173    public void setParent(View root, int virtualDescendantId) {
3174        IMPL.setParent(mInfo, root, virtualDescendantId);
3175    }
3176
3177    /**
3178     * Gets the node bounds in parent coordinates.
3179     *
3180     * @param outBounds The output node bounds.
3181     */
3182    public void getBoundsInParent(Rect outBounds) {
3183        IMPL.getBoundsInParent(mInfo, outBounds);
3184    }
3185
3186    /**
3187     * Sets the node bounds in parent coordinates.
3188     * <p>
3189     * <strong>Note:</strong> Cannot be called from an
3190     * {@link android.accessibilityservice.AccessibilityService}. This class is
3191     * made immutable before being delivered to an AccessibilityService.
3192     * </p>
3193     *
3194     * @param bounds The node bounds.
3195     *@throws IllegalStateException If called from an AccessibilityService.
3196     */
3197    public void setBoundsInParent(Rect bounds) {
3198        IMPL.setBoundsInParent(mInfo, bounds);
3199    }
3200
3201    /**
3202     * Gets the node bounds in screen coordinates.
3203     *
3204     * @param outBounds The output node bounds.
3205     */
3206    public void getBoundsInScreen(Rect outBounds) {
3207        IMPL.getBoundsInScreen(mInfo, outBounds);
3208    }
3209
3210    /**
3211     * Sets the node bounds in screen coordinates.
3212     * <p>
3213     * <strong>Note:</strong> Cannot be called from an
3214     * {@link android.accessibilityservice.AccessibilityService}. This class is
3215     * made immutable before being delivered to an AccessibilityService.
3216     * </p>
3217     *
3218     * @param bounds The node bounds.
3219     * @throws IllegalStateException If called from an AccessibilityService.
3220     */
3221    public void setBoundsInScreen(Rect bounds) {
3222        IMPL.setBoundsInScreen(mInfo, bounds);
3223    }
3224
3225    /**
3226     * Gets whether this node is checkable.
3227     *
3228     * @return True if the node is checkable.
3229     */
3230    public boolean isCheckable() {
3231        return IMPL.isCheckable(mInfo);
3232    }
3233
3234    /**
3235     * Sets whether this node is checkable.
3236     * <p>
3237     * <strong>Note:</strong> Cannot be called from an
3238     * {@link android.accessibilityservice.AccessibilityService}. This class is
3239     * made immutable before being delivered to an AccessibilityService.
3240     * </p>
3241     *
3242     * @param checkable True if the node is checkable.
3243     * @throws IllegalStateException If called from an AccessibilityService.
3244     */
3245    public void setCheckable(boolean checkable) {
3246        IMPL.setCheckable(mInfo, checkable);
3247    }
3248
3249    /**
3250     * Gets whether this node is checked.
3251     *
3252     * @return True if the node is checked.
3253     */
3254    public boolean isChecked() {
3255        return IMPL.isChecked(mInfo);
3256    }
3257
3258    /**
3259     * Sets whether this node is checked.
3260     * <p>
3261     * <strong>Note:</strong> Cannot be called from an
3262     * {@link android.accessibilityservice.AccessibilityService}. This class is
3263     * made immutable before being delivered to an AccessibilityService.
3264     * </p>
3265     *
3266     * @param checked True if the node is checked.
3267     * @throws IllegalStateException If called from an AccessibilityService.
3268     */
3269    public void setChecked(boolean checked) {
3270        IMPL.setChecked(mInfo, checked);
3271    }
3272
3273    /**
3274     * Gets whether this node is focusable.
3275     *
3276     * @return True if the node is focusable.
3277     */
3278    public boolean isFocusable() {
3279        return IMPL.isFocusable(mInfo);
3280    }
3281
3282    /**
3283     * Sets whether this node is focusable.
3284     * <p>
3285     * <strong>Note:</strong> Cannot be called from an
3286     * {@link android.accessibilityservice.AccessibilityService}. This class is
3287     * made immutable before being delivered to an AccessibilityService.
3288     * </p>
3289     *
3290     * @param focusable True if the node is focusable.
3291     * @throws IllegalStateException If called from an AccessibilityService.
3292     */
3293    public void setFocusable(boolean focusable) {
3294        IMPL.setFocusable(mInfo, focusable);
3295    }
3296
3297    /**
3298     * Gets whether this node is focused.
3299     *
3300     * @return True if the node is focused.
3301     */
3302    public boolean isFocused() {
3303        return IMPL.isFocused(mInfo);
3304    }
3305
3306    /**
3307     * Sets whether this node is focused.
3308     * <p>
3309     * <strong>Note:</strong> Cannot be called from an
3310     * {@link android.accessibilityservice.AccessibilityService}. This class is
3311     * made immutable before being delivered to an AccessibilityService.
3312     * </p>
3313     *
3314     * @param focused True if the node is focused.
3315     * @throws IllegalStateException If called from an AccessibilityService.
3316     */
3317    public void setFocused(boolean focused) {
3318        IMPL.setFocused(mInfo, focused);
3319    }
3320
3321    /**
3322     * Sets whether this node is visible to the user.
3323     *
3324     * @return Whether the node is visible to the user.
3325     */
3326    public boolean isVisibleToUser() {
3327        return IMPL.isVisibleToUser(mInfo);
3328    }
3329
3330    /**
3331     * Sets whether this node is visible to the user.
3332     * <p>
3333     *   <strong>Note:</strong> Cannot be called from an
3334     *   {@link android.accessibilityservice.AccessibilityService}.
3335     *   This class is made immutable before being delivered to an AccessibilityService.
3336     * </p>
3337     *
3338     * @param visibleToUser Whether the node is visible to the user.
3339     *
3340     * @throws IllegalStateException If called from an AccessibilityService.
3341     */
3342    public void setVisibleToUser(boolean visibleToUser) {
3343        IMPL.setVisibleToUser(mInfo, visibleToUser);
3344    }
3345
3346    /**
3347     * Gets whether this node is accessibility focused.
3348     *
3349     * @return True if the node is accessibility focused.
3350     */
3351    public boolean isAccessibilityFocused() {
3352        return IMPL.isAccessibilityFocused(mInfo);
3353    }
3354
3355    /**
3356     * Sets whether this node is accessibility focused.
3357     * <p>
3358     *   <strong>Note:</strong> Cannot be called from an
3359     *   {@link android.accessibilityservice.AccessibilityService}.
3360     *   This class is made immutable before being delivered to an AccessibilityService.
3361     * </p>
3362     *
3363     * @param focused True if the node is accessibility focused.
3364     *
3365     * @throws IllegalStateException If called from an AccessibilityService.
3366     */
3367    public void setAccessibilityFocused(boolean focused) {
3368        IMPL.setAccessibilityFocused(mInfo, focused);
3369    }
3370
3371    /**
3372     * Gets whether this node is selected.
3373     *
3374     * @return True if the node is selected.
3375     */
3376    public boolean isSelected() {
3377        return IMPL.isSelected(mInfo);
3378    }
3379
3380    /**
3381     * Sets whether this node is selected.
3382     * <p>
3383     * <strong>Note:</strong> Cannot be called from an
3384     * {@link android.accessibilityservice.AccessibilityService}. This class is
3385     * made immutable before being delivered to an AccessibilityService.
3386     * </p>
3387     *
3388     * @param selected True if the node is selected.
3389     * @throws IllegalStateException If called from an AccessibilityService.
3390     */
3391    public void setSelected(boolean selected) {
3392        IMPL.setSelected(mInfo, selected);
3393    }
3394
3395    /**
3396     * Gets whether this node is clickable.
3397     *
3398     * @return True if the node is clickable.
3399     */
3400    public boolean isClickable() {
3401        return IMPL.isClickable(mInfo);
3402    }
3403
3404    /**
3405     * Sets whether this node is clickable.
3406     * <p>
3407     * <strong>Note:</strong> Cannot be called from an
3408     * {@link android.accessibilityservice.AccessibilityService}. This class is
3409     * made immutable before being delivered to an AccessibilityService.
3410     * </p>
3411     *
3412     * @param clickable True if the node is clickable.
3413     * @throws IllegalStateException If called from an AccessibilityService.
3414     */
3415    public void setClickable(boolean clickable) {
3416        IMPL.setClickable(mInfo, clickable);
3417    }
3418
3419    /**
3420     * Gets whether this node is long clickable.
3421     *
3422     * @return True if the node is long clickable.
3423     */
3424    public boolean isLongClickable() {
3425        return IMPL.isLongClickable(mInfo);
3426    }
3427
3428    /**
3429     * Sets whether this node is long clickable.
3430     * <p>
3431     * <strong>Note:</strong> Cannot be called from an
3432     * {@link android.accessibilityservice.AccessibilityService}. This class is
3433     * made immutable before being delivered to an AccessibilityService.
3434     * </p>
3435     *
3436     * @param longClickable True if the node is long clickable.
3437     * @throws IllegalStateException If called from an AccessibilityService.
3438     */
3439    public void setLongClickable(boolean longClickable) {
3440        IMPL.setLongClickable(mInfo, longClickable);
3441    }
3442
3443    /**
3444     * Gets whether this node is enabled.
3445     *
3446     * @return True if the node is enabled.
3447     */
3448    public boolean isEnabled() {
3449        return IMPL.isEnabled(mInfo);
3450    }
3451
3452    /**
3453     * Sets whether this node is enabled.
3454     * <p>
3455     * <strong>Note:</strong> Cannot be called from an
3456     * {@link android.accessibilityservice.AccessibilityService}. This class is
3457     * made immutable before being delivered to an AccessibilityService.
3458     * </p>
3459     *
3460     * @param enabled True if the node is enabled.
3461     * @throws IllegalStateException If called from an AccessibilityService.
3462     */
3463    public void setEnabled(boolean enabled) {
3464        IMPL.setEnabled(mInfo, enabled);
3465    }
3466
3467    /**
3468     * Gets whether this node is a password.
3469     *
3470     * @return True if the node is a password.
3471     */
3472    public boolean isPassword() {
3473        return IMPL.isPassword(mInfo);
3474    }
3475
3476    /**
3477     * Sets whether this node is a password.
3478     * <p>
3479     * <strong>Note:</strong> Cannot be called from an
3480     * {@link android.accessibilityservice.AccessibilityService}. This class is
3481     * made immutable before being delivered to an AccessibilityService.
3482     * </p>
3483     *
3484     * @param password True if the node is a password.
3485     * @throws IllegalStateException If called from an AccessibilityService.
3486     */
3487    public void setPassword(boolean password) {
3488        IMPL.setPassword(mInfo, password);
3489    }
3490
3491    /**
3492     * Gets if the node is scrollable.
3493     *
3494     * @return True if the node is scrollable, false otherwise.
3495     */
3496    public boolean isScrollable() {
3497        return IMPL.isScrollable(mInfo);
3498    }
3499
3500    /**
3501     * Sets if the node is scrollable.
3502     * <p>
3503     * <strong>Note:</strong> Cannot be called from an
3504     * {@link android.accessibilityservice.AccessibilityService}. This class is
3505     * made immutable before being delivered to an AccessibilityService.
3506     * </p>
3507     *
3508     * @param scrollable True if the node is scrollable, false otherwise.
3509     * @throws IllegalStateException If called from an AccessibilityService.
3510     */
3511    public void setScrollable(boolean scrollable) {
3512        IMPL.setScrollable(mInfo, scrollable);
3513    }
3514
3515    /**
3516     * Returns whether the node originates from a view considered important for accessibility.
3517     *
3518     * @return {@code true} if the node originates from a view considered important for
3519     *         accessibility, {@code false} otherwise
3520     *
3521     * @see View#isImportantForAccessibility()
3522     */
3523    public boolean isImportantForAccessibility() {
3524        return IMPL.isImportantForAccessibility(mInfo);
3525    }
3526
3527    /**
3528     * Sets whether the node is considered important for accessibility.
3529     * <p>
3530     *   <strong>Note:</strong> Cannot be called from an
3531     *   {@link android.accessibilityservice.AccessibilityService}.
3532     *   This class is made immutable before being delivered to an AccessibilityService.
3533     * </p>
3534     *
3535     * @param important {@code true} if the node is considered important for accessibility,
3536     *                  {@code false} otherwise
3537     */
3538    public void setImportantForAccessibility(boolean important) {
3539        IMPL.setImportantForAccessibility(mInfo, important);
3540    }
3541
3542    /**
3543     * Gets the package this node comes from.
3544     *
3545     * @return The package name.
3546     */
3547    public CharSequence getPackageName() {
3548        return IMPL.getPackageName(mInfo);
3549    }
3550
3551    /**
3552     * Sets the package this node comes from.
3553     * <p>
3554     * <strong>Note:</strong> Cannot be called from an
3555     * {@link android.accessibilityservice.AccessibilityService}. This class is
3556     * made immutable before being delivered to an AccessibilityService.
3557     * </p>
3558     *
3559     * @param packageName The package name.
3560     * @throws IllegalStateException If called from an AccessibilityService.
3561     */
3562    public void setPackageName(CharSequence packageName) {
3563        IMPL.setPackageName(mInfo, packageName);
3564    }
3565
3566    /**
3567     * Gets the class this node comes from.
3568     *
3569     * @return The class name.
3570     */
3571    public CharSequence getClassName() {
3572        return IMPL.getClassName(mInfo);
3573    }
3574
3575    /**
3576     * Sets the class this node comes from.
3577     * <p>
3578     * <strong>Note:</strong> Cannot be called from an
3579     * {@link android.accessibilityservice.AccessibilityService}. This class is
3580     * made immutable before being delivered to an AccessibilityService.
3581     * </p>
3582     *
3583     * @param className The class name.
3584     * @throws IllegalStateException If called from an AccessibilityService.
3585     */
3586    public void setClassName(CharSequence className) {
3587        IMPL.setClassName(mInfo, className);
3588    }
3589
3590    /**
3591     * Gets the text of this node.
3592     *
3593     * @return The text.
3594     */
3595    public CharSequence getText() {
3596        return IMPL.getText(mInfo);
3597    }
3598
3599    /**
3600     * Sets the text of this node.
3601     * <p>
3602     * <strong>Note:</strong> Cannot be called from an
3603     * {@link android.accessibilityservice.AccessibilityService}. This class is
3604     * made immutable before being delivered to an AccessibilityService.
3605     * </p>
3606     *
3607     * @param text The text.
3608     * @throws IllegalStateException If called from an AccessibilityService.
3609     */
3610    public void setText(CharSequence text) {
3611        IMPL.setText(mInfo, text);
3612    }
3613
3614    /**
3615     * Gets the content description of this node.
3616     *
3617     * @return The content description.
3618     */
3619    public CharSequence getContentDescription() {
3620        return IMPL.getContentDescription(mInfo);
3621    }
3622
3623    /**
3624     * Sets the content description of this node.
3625     * <p>
3626     * <strong>Note:</strong> Cannot be called from an
3627     * {@link android.accessibilityservice.AccessibilityService}. This class is
3628     * made immutable before being delivered to an AccessibilityService.
3629     * </p>
3630     *
3631     * @param contentDescription The content description.
3632     * @throws IllegalStateException If called from an AccessibilityService.
3633     */
3634    public void setContentDescription(CharSequence contentDescription) {
3635        IMPL.setContentDescription(mInfo, contentDescription);
3636    }
3637
3638    /**
3639     * Return an instance back to be reused.
3640     * <p>
3641     * <strong>Note:</strong> You must not touch the object after calling this function.
3642     *
3643     * @throws IllegalStateException If the info is already recycled.
3644     */
3645    public void recycle() {
3646        IMPL.recycle(mInfo);
3647    }
3648
3649    /**
3650     * Sets the fully qualified resource name of the source view's id.
3651     *
3652     * <p>
3653     *   <strong>Note:</strong> Cannot be called from an
3654     *   {@link android.accessibilityservice.AccessibilityService}.
3655     *   This class is made immutable before being delivered to an AccessibilityService.
3656     * </p>
3657     *
3658     * @param viewId The id resource name.
3659     */
3660    public void setViewIdResourceName(String viewId) {
3661        IMPL.setViewIdResourceName(mInfo, viewId);
3662    }
3663
3664    /**
3665     * Gets the fully qualified resource name of the source view's id.
3666     *
3667     * <p>
3668     *   <strong>Note:</strong> The primary usage of this API is for UI test automation
3669     *   and in order to report the source view id of an {@link AccessibilityNodeInfoCompat}
3670     *   the client has to set the {@link AccessibilityServiceInfoCompat#FLAG_REPORT_VIEW_IDS}
3671     *   flag when configuring his {@link android.accessibilityservice.AccessibilityService}.
3672     * </p>
3673     *
3674     * @return The id resource name.
3675     */
3676    public String getViewIdResourceName() {
3677        return IMPL.getViewIdResourceName(mInfo);
3678    }
3679
3680    /**
3681     * Gets the node's live region mode.
3682     * <p>
3683     * A live region is a node that contains information that is important for
3684     * the user and when it changes the user should be notified. For example,
3685     * in a login screen with a TextView that displays an "incorrect password"
3686     * notification, that view should be marked as a live region with mode
3687     * {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_POLITE}.
3688     * <p>
3689     * It is the responsibility of the accessibility service to monitor
3690     * {@link AccessibilityEventCompat#TYPE_WINDOW_CONTENT_CHANGED} events
3691     * indicating changes to live region nodes and their children.
3692     *
3693     * @return The live region mode, or
3694     *         {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is
3695     *         not a live region.
3696     * @see ViewCompat#getAccessibilityLiveRegion(View)
3697     */
3698    public int getLiveRegion() {
3699        return IMPL.getLiveRegion(mInfo);
3700    }
3701
3702    /**
3703     * Sets the node's live region mode.
3704     * <p>
3705     * <strong>Note:</strong> Cannot be called from an
3706     * {@link android.accessibilityservice.AccessibilityService}. This class is
3707     * made immutable before being delivered to an AccessibilityService.
3708     *
3709     * @param mode The live region mode, or
3710     *        {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is
3711     *        not a live region.
3712     * @see ViewCompat#setAccessibilityLiveRegion(View, int)
3713     */
3714    public void setLiveRegion(int mode) {
3715        IMPL.setLiveRegion(mInfo, mode);
3716    }
3717
3718    /**
3719     * Get the drawing order of the view corresponding it this node.
3720     * <p>
3721     * Drawing order is determined only within the node's parent, so this index is only relative
3722     * to its siblings.
3723     * <p>
3724     * In some cases, the drawing order is essentially simultaneous, so it is possible for two
3725     * siblings to return the same value. It is also possible that values will be skipped.
3726     *
3727     * @return The drawing position of the view corresponding to this node relative to its siblings.
3728     */
3729    public int getDrawingOrder() {
3730        return IMPL.getDrawingOrder(mInfo);
3731    }
3732
3733    /**
3734     * Set the drawing order of the view corresponding it this node.
3735     *
3736     * <p>
3737     *   <strong>Note:</strong> Cannot be called from an
3738     *   {@link android.accessibilityservice.AccessibilityService}.
3739     *   This class is made immutable before being delivered to an AccessibilityService.
3740     * </p>
3741     * @param drawingOrderInParent
3742     * @throws IllegalStateException If called from an AccessibilityService.
3743     */
3744    public void setDrawingOrder(int drawingOrderInParent) {
3745        IMPL.setDrawingOrder(mInfo, drawingOrderInParent);
3746    }
3747
3748    /**
3749     * Gets the collection info if the node is a collection. A collection
3750     * child is always a collection item.
3751     *
3752     * @return The collection info.
3753     */
3754    public CollectionInfoCompat getCollectionInfo() {
3755        Object info = IMPL.getCollectionInfo(mInfo);
3756        if (info == null) return null;
3757        return new CollectionInfoCompat(info);
3758    }
3759
3760    public void setCollectionInfo(Object collectionInfo) {
3761        IMPL.setCollectionInfo(mInfo, ((CollectionInfoCompat) collectionInfo).mInfo);
3762    }
3763
3764    public void setCollectionItemInfo(Object collectionItemInfo) {
3765        IMPL.setCollectionItemInfo(mInfo, ((CollectionItemInfoCompat) collectionItemInfo).mInfo);
3766    }
3767
3768    /**
3769     * Gets the collection item info if the node is a collection item. A collection
3770     * item is always a child of a collection.
3771     *
3772     * @return The collection item info.
3773     */
3774    public CollectionItemInfoCompat getCollectionItemInfo() {
3775        Object info = IMPL.getCollectionItemInfo(mInfo);
3776        if (info == null) return null;
3777        return new CollectionItemInfoCompat(info);
3778    }
3779
3780    /**
3781     * Gets the range info if this node is a range.
3782     *
3783     * @return The range.
3784     */
3785    public RangeInfoCompat getRangeInfo() {
3786        Object info = IMPL.getRangeInfo(mInfo);
3787        if (info == null) return null;
3788        return new RangeInfoCompat(info);
3789    }
3790
3791    /**
3792     * Sets the range info if this node is a range.
3793     * <p>
3794     *   <strong>Note:</strong> Cannot be called from an
3795     *   {@link android.accessibilityservice.AccessibilityService}.
3796     *   This class is made immutable before being delivered to an AccessibilityService.
3797     * </p>
3798     *
3799     * @param rangeInfo The range info.
3800     */
3801    public void setRangeInfo(RangeInfoCompat rangeInfo) {
3802        IMPL.setRangeInfo(mInfo, rangeInfo.mInfo);
3803    }
3804
3805    /**
3806     * Gets the actions that can be performed on the node.
3807     *
3808     * @return A list of AccessibilityActions.
3809     */
3810    public List<AccessibilityActionCompat> getActionList() {
3811        List<Object> actions = IMPL.getActionList(mInfo);
3812        if (actions != null) {
3813            List<AccessibilityActionCompat> result = new ArrayList<AccessibilityActionCompat>();
3814            final int actionCount = actions.size();
3815            for (int i = 0; i < actionCount; i++) {
3816                Object action = actions.get(i);
3817                result.add(new AccessibilityActionCompat(action));
3818            }
3819            return result;
3820        } else {
3821            return Collections.<AccessibilityActionCompat>emptyList();
3822        }
3823    }
3824
3825    /**
3826     * Sets if the content of this node is invalid. For example,
3827     * a date is not well-formed.
3828     * <p>
3829     *   <strong>Note:</strong> Cannot be called from an
3830     *   {@link android.accessibilityservice.AccessibilityService}.
3831     *   This class is made immutable before being delivered to an AccessibilityService.
3832     * </p>
3833     *
3834     * @param contentInvalid If the node content is invalid.
3835     */
3836    public void setContentInvalid(boolean contentInvalid) {
3837        IMPL.setContentInvalid(mInfo, contentInvalid);
3838    }
3839
3840    /**
3841     * Gets if the content of this node is invalid. For example,
3842     * a date is not well-formed.
3843     *
3844     * @return If the node content is invalid.
3845     */
3846    public boolean isContentInvalid() {
3847        return IMPL.isContentInvalid(mInfo);
3848    }
3849
3850    /**
3851     * Gets whether this node is context clickable.
3852     *
3853     * @return True if the node is context clickable.
3854     */
3855    public boolean isContextClickable() {
3856        return IMPL.isContextClickable(mInfo);
3857    }
3858
3859    /**
3860     * Sets whether this node is context clickable.
3861     * <p>
3862     * <strong>Note:</strong> Cannot be called from an
3863     * {@link android.accessibilityservice.AccessibilityService}. This class is made immutable
3864     * before being delivered to an AccessibilityService.
3865     * </p>
3866     *
3867     * @param contextClickable True if the node is context clickable.
3868     * @throws IllegalStateException If called from an AccessibilityService.
3869     */
3870    public void setContextClickable(boolean contextClickable) {
3871        IMPL.setContextClickable(mInfo, contextClickable);
3872    }
3873
3874    /**
3875     * Sets the error text of this node.
3876     * <p>
3877     *   <strong>Note:</strong> Cannot be called from an
3878     *   {@link android.accessibilityservice.AccessibilityService}.
3879     *   This class is made immutable before being delivered to an AccessibilityService.
3880     * </p>
3881     *
3882     * @param error The error text.
3883     *
3884     * @throws IllegalStateException If called from an AccessibilityService.
3885     */
3886    public void setError(CharSequence error) {
3887        IMPL.setError(mInfo, error);
3888    }
3889
3890    /**
3891     * Gets the error text of this node.
3892     *
3893     * @return The error text.
3894     */
3895    public CharSequence getError() {
3896        return IMPL.getError(mInfo);
3897    }
3898
3899    /**
3900     * Sets the view for which the view represented by this info serves as a
3901     * label for accessibility purposes.
3902     *
3903     * @param labeled The view for which this info serves as a label.
3904     */
3905    public void setLabelFor(View labeled) {
3906        IMPL.setLabelFor(mInfo, labeled);
3907    }
3908
3909    /**
3910     * Sets the view for which the view represented by this info serves as a
3911     * label for accessibility purposes. If <code>virtualDescendantId</code>
3912     * is {@link View#NO_ID} the root is set as the labeled.
3913     * <p>
3914     * A virtual descendant is an imaginary View that is reported as a part of the view
3915     * hierarchy for accessibility purposes. This enables custom views that draw complex
3916     * content to report themselves as a tree of virtual views, thus conveying their
3917     * logical structure.
3918     * </p>
3919     *
3920     * @param root The root whose virtual descendant serves as a label.
3921     * @param virtualDescendantId The id of the virtual descendant.
3922     */
3923    public void setLabelFor(View root, int virtualDescendantId) {
3924        IMPL.setLabelFor(mInfo, root, virtualDescendantId);
3925    }
3926
3927    /**
3928     * Gets the node info for which the view represented by this info serves as
3929     * a label for accessibility purposes.
3930     * <p>
3931     *   <strong>Note:</strong> It is a client responsibility to recycle the
3932     *     received info by calling {@link AccessibilityNodeInfoCompat#recycle()}
3933     *     to avoid creating of multiple instances.
3934     * </p>
3935     *
3936     * @return The labeled info.
3937     */
3938    public AccessibilityNodeInfoCompat getLabelFor() {
3939        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getLabelFor(mInfo));
3940    }
3941
3942    /**
3943     * Sets the view which serves as the label of the view represented by
3944     * this info for accessibility purposes.
3945     *
3946     * @param label The view that labels this node's source.
3947     */
3948    public void setLabeledBy(View label) {
3949        IMPL.setLabeledBy(mInfo, label);
3950    }
3951
3952    /**
3953     * Sets the view which serves as the label of the view represented by
3954     * this info for accessibility purposes. If <code>virtualDescendantId</code>
3955     * is {@link View#NO_ID} the root is set as the label.
3956     * <p>
3957     * A virtual descendant is an imaginary View that is reported as a part of the view
3958     * hierarchy for accessibility purposes. This enables custom views that draw complex
3959     * content to report themselves as a tree of virtual views, thus conveying their
3960     * logical structure.
3961     * </p>
3962     * <p>
3963     *   <strong>Note:</strong> Cannot be called from an
3964     *   {@link android.accessibilityservice.AccessibilityService}.
3965     *   This class is made immutable before being delivered to an AccessibilityService.
3966     * </p>
3967     *
3968     * @param root The root whose virtual descendant labels this node's source.
3969     * @param virtualDescendantId The id of the virtual descendant.
3970     */
3971    public void setLabeledBy(View root, int virtualDescendantId) {
3972        IMPL.setLabeledBy(mInfo, root, virtualDescendantId);
3973    }
3974
3975    /**
3976     * Gets the node info which serves as the label of the view represented by
3977     * this info for accessibility purposes.
3978     * <p>
3979     *   <strong>Note:</strong> It is a client responsibility to recycle the
3980     *     received info by calling {@link AccessibilityNodeInfoCompat#recycle()}
3981     *     to avoid creating of multiple instances.
3982     * </p>
3983     *
3984     * @return The label.
3985     */
3986    public AccessibilityNodeInfoCompat getLabeledBy() {
3987        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getLabeledBy(mInfo));
3988    }
3989
3990    /**
3991     * Gets if this node opens a popup or a dialog.
3992     *
3993     * @return If the the node opens a popup.
3994     */
3995    public boolean canOpenPopup() {
3996        return IMPL.canOpenPopup(mInfo);
3997    }
3998
3999    /**
4000     * Sets if this node opens a popup or a dialog.
4001     * <p>
4002     *   <strong>Note:</strong> Cannot be called from an
4003     *   {@link android.accessibilityservice.AccessibilityService}.
4004     *   This class is made immutable before being delivered to an AccessibilityService.
4005     * </p>
4006     *
4007     * @param opensPopup If the the node opens a popup.
4008     */
4009    public void setCanOpenPopup(boolean opensPopup) {
4010        IMPL.setCanOpenPopup(mInfo, opensPopup);
4011    }
4012
4013    /**
4014     * Finds {@link AccessibilityNodeInfoCompat}s by the fully qualified view id's resource
4015     * name where a fully qualified id is of the from "package:id/id_resource_name".
4016     * For example, if the target application's package is "foo.bar" and the id
4017     * resource name is "baz", the fully qualified resource id is "foo.bar:id/baz".
4018     *
4019     * <p>
4020     *   <strong>Note:</strong> It is a client responsibility to recycle the
4021     *     received info by calling {@link AccessibilityNodeInfoCompat#recycle()}
4022     *     to avoid creating of multiple instances.
4023     * </p>
4024     * <p>
4025     *   <strong>Note:</strong> The primary usage of this API is for UI test automation
4026     *   and in order to report the fully qualified view id if an
4027     *   {@link AccessibilityNodeInfoCompat} the client has to set the
4028     *   {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
4029     *   flag when configuring his {@link android.accessibilityservice.AccessibilityService}.
4030     * </p>
4031     *
4032     * @param viewId The fully qualified resource name of the view id to find.
4033     * @return A list of node info.
4034     */
4035    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(String viewId) {
4036        List<Object> nodes = IMPL.findAccessibilityNodeInfosByViewId(mInfo, viewId);
4037        if (nodes != null) {
4038            List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>();
4039            for (Object node : nodes) {
4040                result.add(new AccessibilityNodeInfoCompat(node));
4041            }
4042            return result;
4043        } else {
4044            return Collections.emptyList();
4045        }
4046    }
4047
4048    /**
4049     * Gets an optional bundle with extra data. The bundle
4050     * is lazily created and never <code>null</code>.
4051     * <p>
4052     * <strong>Note:</strong> It is recommended to use the package
4053     * name of your application as a prefix for the keys to avoid
4054     * collisions which may confuse an accessibility service if the
4055     * same key has different meaning when emitted from different
4056     * applications.
4057     * </p>
4058     *
4059     * @return The bundle.
4060     */
4061    public Bundle getExtras() {
4062        return IMPL.getExtras(mInfo);
4063    }
4064
4065    /**
4066     * Gets the input type of the source as defined by {@link InputType}.
4067     *
4068     * @return The input type.
4069     */
4070    public int getInputType() {
4071        return IMPL.getInputType(mInfo);
4072    }
4073
4074    /**
4075     * Sets the input type of the source as defined by {@link InputType}.
4076     * <p>
4077     *   <strong>Note:</strong> Cannot be called from an
4078     *   {@link android.accessibilityservice.AccessibilityService}.
4079     *   This class is made immutable before being delivered to an
4080     *   AccessibilityService.
4081     * </p>
4082     *
4083     * @param inputType The input type.
4084     *
4085     * @throws IllegalStateException If called from an AccessibilityService.
4086     */
4087    public void setInputType(int inputType) {
4088        IMPL.setInputType(mInfo, inputType);
4089    }
4090
4091    /**
4092     * Sets the maximum text length, or -1 for no limit.
4093     * <p>
4094     * Typically used to indicate that an editable text field has a limit on
4095     * the number of characters entered.
4096     * <p>
4097     * <strong>Note:</strong> Cannot be called from an
4098     * {@link android.accessibilityservice.AccessibilityService}.
4099     * This class is made immutable before being delivered to an AccessibilityService.
4100     *
4101     * @param max The maximum text length.
4102     * @see #getMaxTextLength()
4103     *
4104     * @throws IllegalStateException If called from an AccessibilityService.
4105     */
4106    public void setMaxTextLength(int max) {
4107        IMPL.setMaxTextLength(mInfo, max);
4108    }
4109
4110    /**
4111     * Returns the maximum text length for this node.
4112     *
4113     * @return The maximum text length, or -1 for no limit.
4114     * @see #setMaxTextLength(int)
4115     */
4116    public int getMaxTextLength() {
4117        return IMPL.getMaxTextLength(mInfo);
4118    }
4119
4120    /**
4121     * Sets the text selection start and end.
4122     * <p>
4123     *   <strong>Note:</strong> Cannot be called from an
4124     *   {@link android.accessibilityservice.AccessibilityService}.
4125     *   This class is made immutable before being delivered to an AccessibilityService.
4126     * </p>
4127     *
4128     * @param start The text selection start.
4129     * @param end The text selection end.
4130     *
4131     * @throws IllegalStateException If called from an AccessibilityService.
4132     */
4133    public void setTextSelection(int start, int end) {
4134        IMPL.setTextSelection(mInfo, start, end);
4135    }
4136
4137    /**
4138     * Gets the text selection start.
4139     *
4140     * @return The text selection start if there is selection or -1.
4141     */
4142    public int getTextSelectionStart() {
4143        return IMPL.getTextSelectionStart(mInfo);
4144    }
4145
4146    /**
4147     * Gets the text selection end.
4148     *
4149     * @return The text selection end if there is selection or -1.
4150     */
4151    public int getTextSelectionEnd() {
4152        return IMPL.getTextSelectionEnd(mInfo);
4153    }
4154
4155    /**
4156     * Gets the node before which this one is visited during traversal. A screen-reader
4157     * must visit the content of this node before the content of the one it precedes.
4158     *
4159     * @return The succeeding node if such or <code>null</code>.
4160     *
4161     * @see #setTraversalBefore(android.view.View)
4162     * @see #setTraversalBefore(android.view.View, int)
4163     */
4164    public AccessibilityNodeInfoCompat getTraversalBefore() {
4165        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getTraversalBefore(mInfo));
4166    }
4167
4168    /**
4169     * Sets the view before whose node this one should be visited during traversal. A
4170     * screen-reader must visit the content of this node before the content of the one
4171     * it precedes.
4172     * <p>
4173     *   <strong>Note:</strong> Cannot be called from an
4174     *   {@link android.accessibilityservice.AccessibilityService}.
4175     *   This class is made immutable before being delivered to an AccessibilityService.
4176     * </p>
4177     *
4178     * @param view The view providing the preceding node.
4179     *
4180     * @see #getTraversalBefore()
4181     */
4182    public void setTraversalBefore(View view) {
4183        IMPL.setTraversalBefore(mInfo, view);
4184    }
4185
4186    /**
4187     * Sets the node before which this one is visited during traversal. A screen-reader
4188     * must visit the content of this node before the content of the one it precedes.
4189     * The successor is a virtual descendant of the given <code>root</code>. If
4190     * <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root is set
4191     * as the successor.
4192     * <p>
4193     * A virtual descendant is an imaginary View that is reported as a part of the view
4194     * hierarchy for accessibility purposes. This enables custom views that draw complex
4195     * content to report them selves as a tree of virtual views, thus conveying their
4196     * logical structure.
4197     * </p>
4198     * <p>
4199     *   <strong>Note:</strong> Cannot be called from an
4200     *   {@link android.accessibilityservice.AccessibilityService}.
4201     *   This class is made immutable before being delivered to an AccessibilityService.
4202     * </p>
4203     *
4204     * @param root The root of the virtual subtree.
4205     * @param virtualDescendantId The id of the virtual descendant.
4206     */
4207    public void setTraversalBefore(View root, int virtualDescendantId) {
4208        IMPL.setTraversalBefore(mInfo, root, virtualDescendantId);
4209    }
4210
4211    /**
4212     * Gets the node after which this one is visited in accessibility traversal.
4213     * A screen-reader must visit the content of the other node before the content
4214     * of this one.
4215     *
4216     * @return The succeeding node if such or <code>null</code>.
4217     *
4218     * @see #setTraversalAfter(android.view.View)
4219     * @see #setTraversalAfter(android.view.View, int)
4220     */
4221    public AccessibilityNodeInfoCompat getTraversalAfter() {
4222        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getTraversalAfter(mInfo));
4223    }
4224
4225    /**
4226     * Sets the view whose node is visited after this one in accessibility traversal.
4227     * A screen-reader must visit the content of the other node before the content
4228     * of this one.
4229     * <p>
4230     *   <strong>Note:</strong> Cannot be called from an
4231     *   {@link android.accessibilityservice.AccessibilityService}.
4232     *   This class is made immutable before being delivered to an AccessibilityService.
4233     * </p>
4234     *
4235     * @param view The previous view.
4236     *
4237     * @see #getTraversalAfter()
4238     */
4239    public void setTraversalAfter(View view) {
4240        IMPL.setTraversalAfter(mInfo, view);
4241    }
4242
4243    /**
4244     * Sets the node after which this one is visited in accessibility traversal.
4245     * A screen-reader must visit the content of the other node before the content
4246     * of this one. If <code>virtualDescendantId</code> equals to {@link View#NO_ID}
4247     * the root is set as the predecessor.
4248     * <p>
4249     * A virtual descendant is an imaginary View that is reported as a part of the view
4250     * hierarchy for accessibility purposes. This enables custom views that draw complex
4251     * content to report them selves as a tree of virtual views, thus conveying their
4252     * logical structure.
4253     * </p>
4254     * <p>
4255     *   <strong>Note:</strong> Cannot be called from an
4256     *   {@link android.accessibilityservice.AccessibilityService}.
4257     *   This class is made immutable before being delivered to an AccessibilityService.
4258     * </p>
4259     *
4260     * @param root The root of the virtual subtree.
4261     * @param virtualDescendantId The id of the virtual descendant.
4262     */
4263    public void setTraversalAfter(View root, int virtualDescendantId) {
4264        IMPL.setTraversalAfter(mInfo, root, virtualDescendantId);
4265    }
4266
4267    /**
4268     * Gets the window to which this node belongs.
4269     *
4270     * @return The window.
4271     *
4272     * @see android.accessibilityservice.AccessibilityService#getWindows()
4273     */
4274    public AccessibilityWindowInfoCompat getWindow() {
4275        return AccessibilityWindowInfoCompat.wrapNonNullInstance(IMPL.getWindow(mInfo));
4276    }
4277
4278    /**
4279     * Gets if the node can be dismissed.
4280     *
4281     * @return If the node can be dismissed.
4282     */
4283    public boolean isDismissable() {
4284        return IMPL.isDismissable(mInfo);
4285    }
4286
4287    /**
4288     * Sets if the node can be dismissed.
4289     * <p>
4290     *   <strong>Note:</strong> Cannot be called from an
4291     *   {@link android.accessibilityservice.AccessibilityService}.
4292     *   This class is made immutable before being delivered to an AccessibilityService.
4293     * </p>
4294     *
4295     * @param dismissable If the node can be dismissed.
4296     */
4297    public void setDismissable(boolean dismissable) {
4298        IMPL.setDismissable(mInfo, dismissable);
4299    }
4300
4301    /**
4302     * Gets if the node is editable.
4303     *
4304     * @return True if the node is editable, false otherwise.
4305     */
4306    public boolean isEditable() {
4307        return IMPL.isEditable(mInfo);
4308    }
4309
4310    /**
4311     * Sets whether this node is editable.
4312     * <p>
4313     *   <strong>Note:</strong> Cannot be called from an
4314     *   {@link android.accessibilityservice.AccessibilityService}.
4315     *   This class is made immutable before being delivered to an AccessibilityService.
4316     * </p>
4317     *
4318     * @param editable True if the node is editable.
4319     *
4320     * @throws IllegalStateException If called from an AccessibilityService.
4321     */
4322    public void setEditable(boolean editable) {
4323        IMPL.setEditable(mInfo, editable);
4324    }
4325
4326    /**
4327     * Gets if the node is a multi line editable text.
4328     *
4329     * @return True if the node is multi line.
4330     */
4331    public boolean isMultiLine() {
4332        return IMPL.isMultiLine(mInfo);
4333    }
4334
4335    /**
4336     * Sets if the node is a multi line editable text.
4337     * <p>
4338     *   <strong>Note:</strong> Cannot be called from an
4339     *   {@link android.accessibilityservice.AccessibilityService}.
4340     *   This class is made immutable before being delivered to an AccessibilityService.
4341     * </p>
4342     *
4343     * @param multiLine True if the node is multi line.
4344     */
4345    public void setMultiLine(boolean multiLine) {
4346        IMPL.setMultiLine(mInfo, multiLine);
4347    }
4348
4349    /**
4350     * Refreshes this info with the latest state of the view it represents.
4351     * <p>
4352     * <strong>Note:</strong> If this method returns false this info is obsolete
4353     * since it represents a view that is no longer in the view tree and should
4354     * be recycled.
4355     * </p>
4356     * @return Whether the refresh succeeded.
4357     */
4358    public boolean refresh() {
4359        return IMPL.refresh(mInfo);
4360    }
4361
4362    /**
4363     * Gets the custom role description.
4364     * @return The role description.
4365     */
4366    public @Nullable CharSequence getRoleDescription() {
4367        return IMPL.getRoleDescription(mInfo);
4368    }
4369
4370    /**
4371     * Sets the custom role description.
4372     *
4373     * <p>
4374     *   The role description allows you to customize the name for the view's semantic
4375     *   role. For example, if you create a custom subclass of {@link android.view.View}
4376     *   to display a menu bar, you could assign it the role description of "menu bar".
4377     * </p>
4378     * <p>
4379     *   <strong>Warning:</strong> For consistency with other applications, you should
4380     *   not use the role description to force accessibility services to describe
4381     *   standard views (such as buttons or checkboxes) using specific wording. For
4382     *   example, you should not set a role description of "check box" or "tick box" for
4383     *   a standard {@link android.widget.CheckBox}. Instead let accessibility services
4384     *   decide what feedback to provide.
4385     * </p>
4386     * <p>
4387     *   <strong>Note:</strong> Cannot be called from an
4388     *   {@link android.accessibilityservice.AccessibilityService}.
4389     *   This class is made immutable before being delivered to an AccessibilityService.
4390     * </p>
4391     *
4392     * @param roleDescription The role description.
4393     */
4394    public void setRoleDescription(@Nullable CharSequence roleDescription) {
4395        IMPL.setRoleDescription(mInfo, roleDescription);
4396    }
4397
4398    @Override
4399    public int hashCode() {
4400        return (mInfo == null) ? 0 : mInfo.hashCode();
4401    }
4402
4403    @Override
4404    public boolean equals(Object obj) {
4405        if (this == obj) {
4406            return true;
4407        }
4408        if (obj == null) {
4409            return false;
4410        }
4411        if (getClass() != obj.getClass()) {
4412            return false;
4413        }
4414        AccessibilityNodeInfoCompat other = (AccessibilityNodeInfoCompat) obj;
4415        if (mInfo == null) {
4416            if (other.mInfo != null) {
4417                return false;
4418            }
4419        } else if (!mInfo.equals(other.mInfo)) {
4420            return false;
4421        }
4422        return true;
4423    }
4424
4425    @Override
4426    public String toString() {
4427        StringBuilder builder = new StringBuilder();
4428        builder.append(super.toString());
4429
4430        Rect bounds = new Rect();
4431
4432        getBoundsInParent(bounds);
4433        builder.append("; boundsInParent: " + bounds);
4434
4435        getBoundsInScreen(bounds);
4436        builder.append("; boundsInScreen: " + bounds);
4437
4438        builder.append("; packageName: ").append(getPackageName());
4439        builder.append("; className: ").append(getClassName());
4440        builder.append("; text: ").append(getText());
4441        builder.append("; contentDescription: ").append(getContentDescription());
4442        builder.append("; viewId: ").append(getViewIdResourceName());
4443
4444        builder.append("; checkable: ").append(isCheckable());
4445        builder.append("; checked: ").append(isChecked());
4446        builder.append("; focusable: ").append(isFocusable());
4447        builder.append("; focused: ").append(isFocused());
4448        builder.append("; selected: ").append(isSelected());
4449        builder.append("; clickable: ").append(isClickable());
4450        builder.append("; longClickable: ").append(isLongClickable());
4451        builder.append("; enabled: ").append(isEnabled());
4452        builder.append("; password: ").append(isPassword());
4453        builder.append("; scrollable: " + isScrollable());
4454
4455        builder.append("; [");
4456        for (int actionBits = getActions(); actionBits != 0;) {
4457            final int action = 1 << Integer.numberOfTrailingZeros(actionBits);
4458            actionBits &= ~action;
4459            builder.append(getActionSymbolicName(action));
4460            if (actionBits != 0) {
4461                builder.append(", ");
4462            }
4463        }
4464        builder.append("]");
4465
4466        return builder.toString();
4467    }
4468
4469    private static String getActionSymbolicName(int action) {
4470        switch (action) {
4471            case ACTION_FOCUS:
4472                return "ACTION_FOCUS";
4473            case ACTION_CLEAR_FOCUS:
4474                return "ACTION_CLEAR_FOCUS";
4475            case ACTION_SELECT:
4476                return "ACTION_SELECT";
4477            case ACTION_CLEAR_SELECTION:
4478                return "ACTION_CLEAR_SELECTION";
4479            case ACTION_CLICK:
4480                return "ACTION_CLICK";
4481            case ACTION_LONG_CLICK:
4482                return "ACTION_LONG_CLICK";
4483            case ACTION_ACCESSIBILITY_FOCUS:
4484                return "ACTION_ACCESSIBILITY_FOCUS";
4485            case ACTION_CLEAR_ACCESSIBILITY_FOCUS:
4486                return "ACTION_CLEAR_ACCESSIBILITY_FOCUS";
4487            case ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
4488                return "ACTION_NEXT_AT_MOVEMENT_GRANULARITY";
4489            case ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
4490                return "ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY";
4491            case ACTION_NEXT_HTML_ELEMENT:
4492                return "ACTION_NEXT_HTML_ELEMENT";
4493            case ACTION_PREVIOUS_HTML_ELEMENT:
4494                return "ACTION_PREVIOUS_HTML_ELEMENT";
4495            case ACTION_SCROLL_FORWARD:
4496                return "ACTION_SCROLL_FORWARD";
4497            case ACTION_SCROLL_BACKWARD:
4498                return "ACTION_SCROLL_BACKWARD";
4499            case ACTION_CUT:
4500                return "ACTION_CUT";
4501            case ACTION_COPY:
4502                return "ACTION_COPY";
4503            case ACTION_PASTE:
4504                return "ACTION_PASTE";
4505            case ACTION_SET_SELECTION:
4506                return "ACTION_SET_SELECTION";
4507            default:
4508                return"ACTION_UNKNOWN";
4509        }
4510    }
4511}
4512