AccessibilityNodeInfoCompat.java revision f3ed7c56e6c409d27c60f7d74c026906593c21d4
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.view.View;
23
24import java.util.ArrayList;
25import java.util.Collections;
26import java.util.List;
27
28/**
29 * Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo}
30 * introduced after API level 4 in a backwards compatible fashion.
31 */
32public class AccessibilityNodeInfoCompat {
33
34    static interface AccessibilityNodeInfoImpl {
35        public Object obtain();
36        public Object obtain(View source);
37        public Object obtain(Object info);
38        public Object obtain(View root, int virtualDescendantId);
39        public void setSource(Object info, View source);
40        public void setSource(Object info, View root, int virtualDescendantId);
41        public Object findFocus(Object info, int focus);
42        public Object focusSearch(Object info, int direction);
43        public int getWindowId(Object info);
44        public int getChildCount(Object info);
45        public Object getChild(Object info, int index);
46        public void addChild(Object info, View child);
47        public void addChild(Object info, View child, int virtualDescendantId);
48        public int getActions(Object info);
49        public void addAction(Object info, int action);
50        public boolean performAction(Object info, int action);
51        public boolean performAction(Object info, int action, Bundle arguments);
52        public void setMovementGranularities(Object info, int granularities);
53        public int getMovementGranularities(Object info);
54        public List<Object> findAccessibilityNodeInfosByText(Object info, String text);
55        public Object getParent(Object info);
56        public void setParent(Object info, View root, int virtualDescendantId);
57        public void setParent(Object info, View parent);
58        public void getBoundsInParent(Object info, Rect outBounds);
59        public void setBoundsInParent(Object info, Rect bounds);
60        public void getBoundsInScreen(Object info, Rect outBounds);
61        public void setBoundsInScreen(Object info, Rect bounds);
62        public boolean isCheckable(Object info);
63        public void setCheckable(Object info, boolean checkable);
64        public boolean isChecked(Object info);
65        public void setChecked(Object info, boolean checked);
66        public boolean isFocusable(Object info);
67        public void setFocusable(Object info, boolean focusable);
68        public boolean isFocused(Object info);
69        public void setFocused(Object info, boolean focused);
70        public boolean isVisibleToUser(Object info);
71        public void setVisibleToUser(Object info, boolean visibleToUser);
72        public boolean isAccessibilityFocused(Object info);
73        public void setAccessibilityFocused(Object info, boolean focused);
74        public boolean isSelected(Object info);
75        public void setSelected(Object info, boolean selected);
76        public boolean isClickable(Object info);
77        public void setClickable(Object info, boolean clickable);
78        public boolean isLongClickable(Object info);
79        public void setLongClickable(Object info, boolean longClickable);
80        public boolean isEnabled(Object info);
81        public void setEnabled(Object info, boolean enabled);
82        public boolean isPassword(Object info);
83        public void setPassword(Object info, boolean password);
84        public boolean isScrollable(Object info);
85        public void setScrollable(Object info, boolean scrollable);
86        public CharSequence getPackageName(Object info);
87        public void setPackageName(Object info, CharSequence packageName);
88        public CharSequence getClassName(Object info);
89        public void setClassName(Object info, CharSequence className);
90        public CharSequence getText(Object info);
91        public void setText(Object info, CharSequence text);
92        public CharSequence getContentDescription(Object info);
93        public void setContentDescription(Object info, CharSequence contentDescription);
94        public void recycle(Object info);
95    }
96
97    static class AccessibilityNodeInfoStubImpl implements AccessibilityNodeInfoImpl {
98        @Override
99        public Object obtain() {
100            return null;
101        }
102
103        @Override
104        public Object obtain(View source) {
105            return null;
106        }
107
108        @Override
109        public Object obtain(View root, int virtualDescendantId) {
110            return null;
111        }
112
113        @Override
114        public Object obtain(Object info) {
115            return null;
116        }
117
118        @Override
119        public void addAction(Object info, int action) {
120
121        }
122
123        @Override
124        public void addChild(Object info, View child) {
125
126        }
127
128        @Override
129        public void addChild(Object info, View child, int virtualDescendantId) {
130
131        }
132
133        @Override
134        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
135            return Collections.emptyList();
136        }
137
138        @Override
139        public int getActions(Object info) {
140            return 0;
141        }
142
143        @Override
144        public void getBoundsInParent(Object info, Rect outBounds) {
145
146        }
147
148        @Override
149        public void getBoundsInScreen(Object info, Rect outBounds) {
150
151        }
152
153        @Override
154        public Object getChild(Object info, int index) {
155            return null;
156        }
157
158        @Override
159        public int getChildCount(Object info) {
160            return 0;
161        }
162
163        @Override
164        public CharSequence getClassName(Object info) {
165            return null;
166        }
167
168        @Override
169        public CharSequence getContentDescription(Object info) {
170            return null;
171        }
172
173        @Override
174        public CharSequence getPackageName(Object info) {
175            return null;
176        }
177
178        @Override
179        public Object getParent(Object info) {
180            return null;
181        }
182
183        @Override
184        public CharSequence getText(Object info) {
185            return null;
186        }
187
188        @Override
189        public int getWindowId(Object info) {
190            return 0;
191        }
192
193        @Override
194        public boolean isCheckable(Object info) {
195            return false;
196        }
197
198        @Override
199        public boolean isChecked(Object info) {
200            return false;
201        }
202
203        @Override
204        public boolean isClickable(Object info) {
205            return false;
206        }
207
208        @Override
209        public boolean isEnabled(Object info) {
210            return false;
211        }
212
213        @Override
214        public boolean isFocusable(Object info) {
215            return false;
216        }
217
218        @Override
219        public boolean isFocused(Object info) {
220            return false;
221        }
222
223        @Override
224        public boolean isVisibleToUser(Object info) {
225            return false;
226        }
227
228        @Override
229        public boolean isAccessibilityFocused(Object info) {
230            return false;
231        }
232
233        @Override
234        public boolean isLongClickable(Object info) {
235            return false;
236        }
237
238        @Override
239        public boolean isPassword(Object info) {
240            return false;
241        }
242
243        @Override
244        public boolean isScrollable(Object info) {
245            return false;
246        }
247
248        @Override
249        public boolean isSelected(Object info) {
250            return false;
251        }
252
253        @Override
254        public boolean performAction(Object info, int action) {
255            return false;
256        }
257
258        @Override
259        public boolean performAction(Object info, int action, Bundle arguments) {
260            return false;
261        }
262
263        @Override
264        public void setMovementGranularities(Object info, int granularities) {
265
266        }
267
268        @Override
269        public int getMovementGranularities(Object info) {
270            return 0;
271        }
272
273        @Override
274        public void setBoundsInParent(Object info, Rect bounds) {
275
276        }
277
278        @Override
279        public void setBoundsInScreen(Object info, Rect bounds) {
280
281        }
282
283        @Override
284        public void setCheckable(Object info, boolean checkable) {
285
286        }
287
288        @Override
289        public void setChecked(Object info, boolean checked) {
290
291        }
292
293        @Override
294        public void setClassName(Object info, CharSequence className) {
295
296        }
297
298        @Override
299        public void setClickable(Object info, boolean clickable) {
300
301        }
302
303        @Override
304        public void setContentDescription(Object info, CharSequence contentDescription) {
305
306        }
307
308        @Override
309        public void setEnabled(Object info, boolean enabled) {
310
311        }
312
313        @Override
314        public void setFocusable(Object info, boolean focusable) {
315
316        }
317
318        @Override
319        public void setFocused(Object info, boolean focused) {
320
321        }
322
323        @Override
324        public void setVisibleToUser(Object info, boolean visibleToUser) {
325
326        }
327
328        @Override
329        public void setAccessibilityFocused(Object info, boolean focused) {
330
331        }
332
333        @Override
334        public void setLongClickable(Object info, boolean longClickable) {
335
336        }
337
338        @Override
339        public void setPackageName(Object info, CharSequence packageName) {
340
341        }
342
343        @Override
344        public void setParent(Object info, View parent) {
345
346        }
347
348        @Override
349        public void setPassword(Object info, boolean password) {
350
351        }
352
353        @Override
354        public void setScrollable(Object info, boolean scrollable) {
355
356        }
357
358        @Override
359        public void setSelected(Object info, boolean selected) {
360
361        }
362
363        @Override
364        public void setSource(Object info, View source) {
365
366        }
367
368        @Override
369        public void setSource(Object info, View root, int virtualDescendantId) {
370
371        }
372
373        @Override
374        public Object findFocus(Object info, int focus) {
375            return null;
376        }
377
378        @Override
379        public Object focusSearch(Object info, int direction) {
380            return null;
381        }
382
383        @Override
384        public void setText(Object info, CharSequence text) {
385
386        }
387
388        @Override
389        public void recycle(Object info) {
390
391        }
392
393        @Override
394        public void setParent(Object info, View root, int virtualDescendantId) {
395
396        }
397    }
398
399    static class AccessibilityNodeInfoIcsImpl extends AccessibilityNodeInfoStubImpl {
400        @Override
401        public Object obtain() {
402            return AccessibilityNodeInfoCompatIcs.obtain();
403        }
404
405        @Override
406        public Object obtain(View source) {
407            return AccessibilityNodeInfoCompatIcs.obtain(source);
408        }
409
410        @Override
411        public Object obtain(Object info) {
412            return AccessibilityNodeInfoCompatIcs.obtain(info);
413        }
414
415        @Override
416        public void addAction(Object info, int action) {
417            AccessibilityNodeInfoCompatIcs.addAction(info, action);
418        }
419
420        @Override
421        public void addChild(Object info, View child) {
422            AccessibilityNodeInfoCompatIcs.addChild(info, child);
423        }
424
425        @Override
426        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
427            return AccessibilityNodeInfoCompatIcs.findAccessibilityNodeInfosByText(info, text);
428        }
429
430        @Override
431        public int getActions(Object info) {
432            return AccessibilityNodeInfoCompatIcs.getActions(info);
433        }
434
435        @Override
436        public void getBoundsInParent(Object info, Rect outBounds) {
437            AccessibilityNodeInfoCompatIcs.getBoundsInParent(info, outBounds);
438        }
439
440        @Override
441        public void getBoundsInScreen(Object info, Rect outBounds) {
442            AccessibilityNodeInfoCompatIcs.getBoundsInScreen(info, outBounds);
443        }
444
445        @Override
446        public Object getChild(Object info, int index) {
447            return AccessibilityNodeInfoCompatIcs.getChild(info, index);
448        }
449
450        @Override
451        public int getChildCount(Object info) {
452            return AccessibilityNodeInfoCompatIcs.getChildCount(info);
453        }
454
455        @Override
456        public CharSequence getClassName(Object info) {
457            return AccessibilityNodeInfoCompatIcs.getClassName(info);
458        }
459
460        @Override
461        public CharSequence getContentDescription(Object info) {
462            return AccessibilityNodeInfoCompatIcs.getContentDescription(info);
463        }
464
465        @Override
466        public CharSequence getPackageName(Object info) {
467            return AccessibilityNodeInfoCompatIcs.getPackageName(info);
468        }
469
470        @Override
471        public Object getParent(Object info) {
472            return AccessibilityNodeInfoCompatIcs.getParent(info);
473        }
474
475        @Override
476        public CharSequence getText(Object info) {
477            return AccessibilityNodeInfoCompatIcs.getText(info);
478        }
479
480        @Override
481        public int getWindowId(Object info) {
482            return AccessibilityNodeInfoCompatIcs.getWindowId(info);
483        }
484
485        @Override
486        public boolean isCheckable(Object info) {
487            return AccessibilityNodeInfoCompatIcs.isCheckable(info);
488        }
489
490        @Override
491        public boolean isChecked(Object info) {
492            return AccessibilityNodeInfoCompatIcs.isChecked(info);
493        }
494
495        @Override
496        public boolean isClickable(Object info) {
497            return AccessibilityNodeInfoCompatIcs.isClickable(info);
498        }
499
500        @Override
501        public boolean isEnabled(Object info) {
502            return AccessibilityNodeInfoCompatIcs.isEnabled(info);
503        }
504
505        @Override
506        public boolean isFocusable(Object info) {
507            return AccessibilityNodeInfoCompatIcs.isFocusable(info);
508        }
509
510        @Override
511        public boolean isFocused(Object info) {
512            return AccessibilityNodeInfoCompatIcs.isFocused(info);
513        }
514
515        @Override
516        public boolean isLongClickable(Object info) {
517            return AccessibilityNodeInfoCompatIcs.isLongClickable(info);
518        }
519
520        @Override
521        public boolean isPassword(Object info) {
522            return AccessibilityNodeInfoCompatIcs.isPassword(info);
523        }
524
525        @Override
526        public boolean isScrollable(Object info) {
527            return AccessibilityNodeInfoCompatIcs.isScrollable(info);
528        }
529
530        @Override
531        public boolean isSelected(Object info) {
532            return AccessibilityNodeInfoCompatIcs.isSelected(info);
533        }
534
535        @Override
536        public boolean performAction(Object info, int action) {
537            return AccessibilityNodeInfoCompatIcs.performAction(info, action);
538        }
539
540        @Override
541        public void setBoundsInParent(Object info, Rect bounds) {
542            AccessibilityNodeInfoCompatIcs.setBoundsInParent(info, bounds);
543        }
544
545        @Override
546        public void setBoundsInScreen(Object info, Rect bounds) {
547            AccessibilityNodeInfoCompatIcs.setBoundsInScreen(info, bounds);
548        }
549
550        @Override
551        public void setCheckable(Object info, boolean checkable) {
552            AccessibilityNodeInfoCompatIcs.setCheckable(info, checkable);
553        }
554
555        @Override
556        public void setChecked(Object info, boolean checked) {
557            AccessibilityNodeInfoCompatIcs.setChecked(info, checked);
558        }
559
560        @Override
561        public void setClassName(Object info, CharSequence className) {
562            AccessibilityNodeInfoCompatIcs.setClassName(info, className);
563        }
564
565        @Override
566        public void setClickable(Object info, boolean clickable) {
567            AccessibilityNodeInfoCompatIcs.setClickable(info, clickable);
568        }
569
570        @Override
571        public void setContentDescription(Object info, CharSequence contentDescription) {
572            AccessibilityNodeInfoCompatIcs.setContentDescription(info, contentDescription);
573        }
574
575        @Override
576        public void setEnabled(Object info, boolean enabled) {
577            AccessibilityNodeInfoCompatIcs.setEnabled(info, enabled);
578        }
579
580        @Override
581        public void setFocusable(Object info, boolean focusable) {
582            AccessibilityNodeInfoCompatIcs.setFocusable(info, focusable);
583        }
584
585        @Override
586        public void setFocused(Object info, boolean focused) {
587            AccessibilityNodeInfoCompatIcs.setFocused(info, focused);
588        }
589
590        @Override
591        public void setLongClickable(Object info, boolean longClickable) {
592            AccessibilityNodeInfoCompatIcs.setLongClickable(info, longClickable);
593        }
594
595        @Override
596        public void setPackageName(Object info, CharSequence packageName) {
597            AccessibilityNodeInfoCompatIcs.setPackageName(info, packageName);
598        }
599
600        @Override
601        public void setParent(Object info, View parent) {
602            AccessibilityNodeInfoCompatIcs.setParent(info, parent);
603        }
604
605        @Override
606        public void setPassword(Object info, boolean password) {
607            AccessibilityNodeInfoCompatIcs.setPassword(info, password);
608        }
609
610        @Override
611        public void setScrollable(Object info, boolean scrollable) {
612            AccessibilityNodeInfoCompatIcs.setScrollable(info, scrollable);
613        }
614
615        @Override
616        public void setSelected(Object info, boolean selected) {
617            AccessibilityNodeInfoCompatIcs.setSelected(info, selected);
618        }
619
620        @Override
621        public void setSource(Object info, View source) {
622            AccessibilityNodeInfoCompatIcs.setSource(info, source);
623        }
624
625        @Override
626        public void setText(Object info, CharSequence text) {
627            AccessibilityNodeInfoCompatIcs.setText(info, text);
628        }
629
630        @Override
631        public void recycle(Object info) {
632            AccessibilityNodeInfoCompatIcs.recycle(info);
633        }
634    }
635
636    static class AccessibilityNodeInfoJellybeanImpl extends AccessibilityNodeInfoIcsImpl {
637        @Override
638        public Object obtain(View root, int virtualDescendantId) {
639            return AccessibilityNodeInfoCompatJellyBean.obtain(root, virtualDescendantId);
640        }
641
642        @Override
643        public Object findFocus(Object info, int focus) {
644            return AccessibilityNodeInfoCompatJellyBean.findFocus(info, focus);
645        }
646
647        @Override
648        public Object focusSearch(Object info, int direction) {
649            return AccessibilityNodeInfoCompatJellyBean.focusSearch(info, direction);
650        }
651
652        @Override
653        public void addChild(Object info, View child, int virtualDescendantId) {
654            AccessibilityNodeInfoCompatJellyBean.addChild(info, child, virtualDescendantId);
655        }
656
657        @Override
658        public void setSource(Object info, View root, int virtualDescendantId) {
659            AccessibilityNodeInfoCompatJellyBean.setSource(info, root, virtualDescendantId);
660        }
661
662        @Override
663        public boolean isVisibleToUser(Object info) {
664            return AccessibilityNodeInfoCompatJellyBean.isVisibleToUser(info);
665        }
666
667        @Override
668        public void setVisibleToUser(Object info, boolean visibleToUser) {
669            AccessibilityNodeInfoCompatJellyBean.setVisibleToUser(info, visibleToUser);
670        }
671
672        @Override
673        public boolean isAccessibilityFocused(Object info) {
674            return AccessibilityNodeInfoCompatJellyBean.isAccessibilityFocused(info);
675        }
676
677        @Override
678        public void setAccessibilityFocused(Object info, boolean focused) {
679            AccessibilityNodeInfoCompatJellyBean.setAccesibilityFocused(info, focused);
680        }
681
682        @Override
683        public boolean performAction(Object info, int action, Bundle arguments) {
684            return AccessibilityNodeInfoCompatJellyBean.performAction(info, action, arguments);
685        }
686
687        @Override
688        public void setMovementGranularities(Object info, int granularities) {
689            AccessibilityNodeInfoCompatJellyBean.setMovementGranularities(info, granularities);
690        }
691
692        @Override
693        public int getMovementGranularities(Object info) {
694            return AccessibilityNodeInfoCompatJellyBean.getMovementGranularities(info);
695        }
696
697        @Override
698        public void setParent(Object info, View root, int virtualDescendantId) {
699            AccessibilityNodeInfoCompatJellyBean.setParent(info, root, virtualDescendantId);
700        }
701    }
702
703    static {
704        if (Build.VERSION.SDK_INT >= 16) { // JellyBean
705            IMPL = new AccessibilityNodeInfoJellybeanImpl();
706        } else if (Build.VERSION.SDK_INT >= 14) { // ICS
707            IMPL = new AccessibilityNodeInfoIcsImpl();
708        } else {
709            IMPL = new AccessibilityNodeInfoStubImpl();
710        }
711    }
712
713    private static final AccessibilityNodeInfoImpl IMPL;
714
715    private final Object mInfo;
716
717    // Actions.
718
719    /**
720     * Action that focuses the node.
721     */
722    public static final int ACTION_FOCUS = 0x00000001;
723
724    /**
725     * Action that unfocuses the node.
726     */
727    public static final int ACTION_CLEAR_FOCUS = 0x00000002;
728
729    /**
730     * Action that selects the node.
731     */
732    public static final int ACTION_SELECT = 0x00000004;
733
734    /**
735     * Action that unselects the node.
736     */
737    public static final int ACTION_CLEAR_SELECTION = 0x00000008;
738
739    /**
740     * Action that clicks on the node info.
741     */
742    public static final int ACTION_CLICK = 0x00000010;
743
744    /**
745     * Action that long clicks on the node.
746     */
747    public static final int ACTION_LONG_CLICK = 0x00000020;
748
749    /**
750     * Action that gives accessibility focus to the node.
751     */
752    public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
753
754    /**
755     * Action that clears accessibility focus of the node.
756     */
757    public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
758
759    /**
760     * Action that requests to go to the next entity in this node's text
761     * at a given movement granularity. For example, move to the next character,
762     * word, etc.
763     * <p>
764     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<br>
765     * <strong>Example:</strong>
766     * <code><pre><p>
767     *   Bundle arguments = new Bundle();
768     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
769     *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
770     *   info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
771     * </code></pre></p>
772     * </p>
773     *
774     * @see #setMovementGranularities(int)
775     * @see #getMovementGranularities()
776     *
777     * @see #MOVEMENT_GRANULARITY_CHARACTER
778     * @see #MOVEMENT_GRANULARITY_WORD
779     * @see #MOVEMENT_GRANULARITY_LINE
780     * @see #MOVEMENT_GRANULARITY_PARAGRAPH
781     * @see #MOVEMENT_GRANULARITY_PAGE
782     */
783    public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 0x00000100;
784
785    /**
786     * Action that requests to go to the previous entity in this node's text
787     * at a given movement granularity. For example, move to the next character,
788     * word, etc.
789     * <p>
790     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<br>
791     * <strong>Example:</strong>
792     * <code><pre><p>
793     *   Bundle arguments = new Bundle();
794     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
795     *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
796     *   info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
797     *           arguments);
798     * </code></pre></p>
799     * </p>
800     *
801     * @see #setMovementGranularities(int)
802     * @see #getMovementGranularities()
803     *
804     * @see #MOVEMENT_GRANULARITY_CHARACTER
805     * @see #MOVEMENT_GRANULARITY_WORD
806     * @see #MOVEMENT_GRANULARITY_LINE
807     * @see #MOVEMENT_GRANULARITY_PARAGRAPH
808     * @see #MOVEMENT_GRANULARITY_PAGE
809     */
810    public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 0x00000200;
811
812    /**
813     * Action to move to the next HTML element of a given type. For example, move
814     * to the BUTTON, INPUT, TABLE, etc.
815     * <p>
816     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
817     * <strong>Example:</strong>
818     * <code><pre><p>
819     *   Bundle arguments = new Bundle();
820     *   arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
821     *   info.performAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT, arguments);
822     * </code></pre></p>
823     * </p>
824     */
825    public static final int ACTION_NEXT_HTML_ELEMENT = 0x00000400;
826
827    /**
828     * Action to move to the previous HTML element of a given type. For example, move
829     * to the BUTTON, INPUT, TABLE, etc.
830     * <p>
831     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
832     * <strong>Example:</strong>
833     * <code><pre><p>
834     *   Bundle arguments = new Bundle();
835     *   arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
836     *   info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT, arguments);
837     * </code></pre></p>
838     * </p>
839     */
840    public static final int ACTION_PREVIOUS_HTML_ELEMENT = 0x00000800;
841
842    /**
843     * Action to scroll the node content forward.
844     */
845    public static final int ACTION_SCROLL_FORWARD = 0x00001000;
846
847    /**
848     * Action to scroll the node content backward.
849     */
850    public static final int ACTION_SCROLL_BACKWARD = 0x00002000;
851
852    /**
853     * Argument for which movement granularity to be used when traversing the node text.
854     * <p>
855     * <strong>Type:</strong> int<br>
856     * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
857     * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
858     * </p>
859     */
860    public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT =
861        "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
862
863    /**
864     * Argument for which HTML element to get moving to the next/previous HTML element.
865     * <p>
866     * <strong>Type:</strong> String<br>
867     * <strong>Actions:</strong> {@link #ACTION_NEXT_HTML_ELEMENT},
868     *         {@link #ACTION_PREVIOUS_HTML_ELEMENT}
869     * </p>
870     */
871    public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING =
872        "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
873
874    /**
875     * The input focus.
876     */
877    public static final int FOCUS_INPUT = 1;
878
879    /**
880     * The accessibility focus.
881     */
882    public static final int FOCUS_ACCESSIBILITY = 2;
883
884    // Movement granularities
885
886    /**
887     * Movement granularity bit for traversing the text of a node by character.
888     */
889    public static final int MOVEMENT_GRANULARITY_CHARACTER = 0x00000001;
890
891    /**
892     * Movement granularity bit for traversing the text of a node by word.
893     */
894    public static final int MOVEMENT_GRANULARITY_WORD = 0x00000002;
895
896    /**
897     * Movement granularity bit for traversing the text of a node by line.
898     */
899    public static final int MOVEMENT_GRANULARITY_LINE = 0x00000004;
900
901    /**
902     * Movement granularity bit for traversing the text of a node by paragraph.
903     */
904    public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 0x00000008;
905
906    /**
907     * Movement granularity bit for traversing the text of a node by page.
908     */
909    public static final int MOVEMENT_GRANULARITY_PAGE = 0x00000010;
910
911    /**
912     * Creates a wrapper for info implementation.
913     *
914     * @param object The info to wrap.
915     * @return A wrapper for if the object is not null, null otherwise.
916     */
917    static AccessibilityNodeInfoCompat wrapNonNullInstance(Object object) {
918        if (object != null) {
919            return new AccessibilityNodeInfoCompat(object);
920        }
921        return null;
922    }
923
924    /**
925     * Creates a new instance wrapping an
926     * {@link android.view.accessibility.AccessibilityNodeInfo}.
927     *
928     * @param info The info.
929     */
930    public AccessibilityNodeInfoCompat(Object info) {
931        mInfo = info;
932    }
933
934    /**
935     * @return The wrapped {@link android.view.accessibility.AccessibilityNodeInfo}.
936     */
937    public Object getInfo() {
938        return mInfo;
939    }
940
941    /**
942     * Returns a cached instance if such is available otherwise a new one and
943     * sets the source.
944     *
945     * @return An instance.
946     * @see #setSource(View)
947     */
948    public static AccessibilityNodeInfoCompat obtain(View source) {
949        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain(source));
950    }
951
952    /**
953     * Returns a cached instance if such is available otherwise a new one
954     * and sets the source.
955     *
956     * @param root The root of the virtual subtree.
957     * @param virtualDescendantId The id of the virtual descendant.
958     * @return An instance.
959     *
960     * @see #setSource(View, int)
961     */
962    public static AccessibilityNodeInfoCompat obtain(View root, int virtualDescendantId) {
963        return AccessibilityNodeInfoCompat.wrapNonNullInstance(
964                IMPL.obtain(root, virtualDescendantId));
965    }
966
967    /**
968     * Returns a cached instance if such is available otherwise a new one.
969     *
970     * @return An instance.
971     */
972    public static AccessibilityNodeInfoCompat obtain() {
973        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain());
974    }
975
976    /**
977     * Returns a cached instance if such is available or a new one is create.
978     * The returned instance is initialized from the given <code>info</code>.
979     *
980     * @param info The other info.
981     * @return An instance.
982     */
983    public static AccessibilityNodeInfoCompat obtain(AccessibilityNodeInfoCompat info) {
984        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.obtain(info.mInfo));
985    }
986
987    /**
988     * Sets the source.
989     *
990     * @param source The info source.
991     */
992    public void setSource(View source) {
993        IMPL.setSource(mInfo, source);
994    }
995
996    /**
997     * Sets the source to be a virtual descendant of the given <code>root</code>.
998     * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
999     * is set as the source.
1000     * <p>
1001     * A virtual descendant is an imaginary View that is reported as a part of the view
1002     * hierarchy for accessibility purposes. This enables custom views that draw complex
1003     * content to report themselves as a tree of virtual views, thus conveying their
1004     * logical structure.
1005     * </p>
1006     * <p>
1007     *   <strong>Note:</strong> Cannot be called from an
1008     *   {@link android.accessibilityservice.AccessibilityService}.
1009     *   This class is made immutable before being delivered to an AccessibilityService.
1010     * </p>
1011     *
1012     * @param root The root of the virtual subtree.
1013     * @param virtualDescendantId The id of the virtual descendant.
1014     */
1015    public void setSource(View root, int virtualDescendantId) {
1016        IMPL.setSource(mInfo, root, virtualDescendantId);
1017    }
1018
1019    /**
1020     * Find the view that has the specified focus type. The search starts from
1021     * the view represented by this node info.
1022     *
1023     * @param focus The focus to find. One of {@link #FOCUS_INPUT} or
1024     *         {@link #FOCUS_ACCESSIBILITY}.
1025     * @return The node info of the focused view or null.
1026     *
1027     * @see #FOCUS_INPUT
1028     * @see #FOCUS_ACCESSIBILITY
1029     */
1030    public AccessibilityNodeInfoCompat findFocus(int focus) {
1031        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.findFocus(mInfo, focus));
1032    }
1033
1034    /**
1035     * Searches for the nearest view in the specified direction that can take
1036     * focus.
1037     *
1038     * @param direction The direction. Can be one of:
1039     *     {@link View#FOCUS_DOWN},
1040     *     {@link View#FOCUS_UP},
1041     *     {@link View#FOCUS_LEFT},
1042     *     {@link View#FOCUS_RIGHT},
1043     *     {@link View#FOCUS_FORWARD},
1044     *     {@link View#FOCUS_BACKWARD},
1045     *     {@link View#ACCESSIBILITY_FOCUS_FORWARD},
1046     *     {@link View#ACCESSIBILITY_FOCUS_BACKWARD},
1047     *     {@link View#ACCESSIBILITY_FOCUS_UP},
1048     *     {@link View#ACCESSIBILITY_FOCUS_RIGHT},
1049     *     {@link View#ACCESSIBILITY_FOCUS_DOWN},
1050     *     {@link View#ACCESSIBILITY_FOCUS_LEFT}.
1051     *
1052     * @return The node info for the view that can take accessibility focus.
1053     */
1054    public AccessibilityNodeInfoCompat focusSearch(int direction) {
1055        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.focusSearch(mInfo, direction));
1056    }
1057
1058    /**
1059     * Gets the id of the window from which the info comes from.
1060     *
1061     * @return The window id.
1062     */
1063    public int getWindowId() {
1064        return IMPL.getWindowId(mInfo);
1065    }
1066
1067    /**
1068     * Gets the number of children.
1069     *
1070     * @return The child count.
1071     */
1072    public int getChildCount() {
1073        return IMPL.getChildCount(mInfo);
1074    }
1075
1076    /**
1077     * Get the child at given index.
1078     * <p>
1079     * <strong>Note:</strong> It is a client responsibility to recycle the
1080     * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} to
1081     * avoid creating of multiple instances.
1082     * </p>
1083     *
1084     * @param index The child index.
1085     * @return The child node.
1086     * @throws IllegalStateException If called outside of an
1087     *             AccessibilityService.
1088     */
1089    public AccessibilityNodeInfoCompat getChild(int index) {
1090        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getChild(mInfo, index));
1091    }
1092
1093    /**
1094     * Adds a child.
1095     * <p>
1096     * <strong>Note:</strong> Cannot be called from an
1097     * {@link android.accessibilityservice.AccessibilityService}. This class is
1098     * made immutable before being delivered to an AccessibilityService.
1099     * </p>
1100     *
1101     * @param child The child.
1102     * @throws IllegalStateException If called from an AccessibilityService.
1103     */
1104    public void addChild(View child) {
1105        IMPL.addChild(mInfo, child);
1106    }
1107
1108    /**
1109     * Adds a virtual child which is a descendant of the given <code>root</code>.
1110     * If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
1111     * is added as a child.
1112     * <p>
1113     * A virtual descendant is an imaginary View that is reported as a part of the view
1114     * hierarchy for accessibility purposes. This enables custom views that draw complex
1115     * content to report them selves as a tree of virtual views, thus conveying their
1116     * logical structure.
1117     * </p>
1118     *
1119     * @param root The root of the virtual subtree.
1120     * @param virtualDescendantId The id of the virtual child.
1121     */
1122    public void addChild(View root, int virtualDescendantId) {
1123        IMPL.addChild(mInfo, root, virtualDescendantId);
1124    }
1125
1126    /**
1127     * Gets the actions that can be performed on the node.
1128     *
1129     * @return The bit mask of with actions.
1130     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS
1131     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
1132     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT
1133     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
1134     */
1135    public int getActions() {
1136        return IMPL.getActions(mInfo);
1137    }
1138
1139    /**
1140     * Adds an action that can be performed on the node.
1141     * <p>
1142     * <strong>Note:</strong> Cannot be called from an
1143     * {@link android.accessibilityservice.AccessibilityService}. This class is
1144     * made immutable before being delivered to an AccessibilityService.
1145     * </p>
1146     *
1147     * @param action The action.
1148     * @throws IllegalStateException If called from an AccessibilityService.
1149     */
1150    public void addAction(int action) {
1151        IMPL.addAction(mInfo, action);
1152    }
1153
1154    /**
1155     * Performs an action on the node.
1156     * <p>
1157     * <strong>Note:</strong> An action can be performed only if the request is
1158     * made from an {@link android.accessibilityservice.AccessibilityService}.
1159     * </p>
1160     *
1161     * @param action The action to perform.
1162     * @return True if the action was performed.
1163     * @throws IllegalStateException If called outside of an
1164     *             AccessibilityService.
1165     */
1166    public boolean performAction(int action) {
1167        return IMPL.performAction(mInfo, action);
1168    }
1169
1170    /**
1171     * Performs an action on the node.
1172     * <p>
1173     *   <strong>Note:</strong> An action can be performed only if the request is made
1174     *   from an {@link android.accessibilityservice.AccessibilityService}.
1175     * </p>
1176     *
1177     * @param action The action to perform.
1178     * @param arguments A bundle with additional arguments.
1179     * @return True if the action was performed.
1180     *
1181     * @throws IllegalStateException If called outside of an AccessibilityService.
1182     */
1183    public boolean performAction(int action, Bundle arguments) {
1184        return IMPL.performAction(mInfo, action, arguments);
1185    }
1186
1187    /**
1188     * Sets the movement granularities for traversing the text of this node.
1189     * <p>
1190     *   <strong>Note:</strong> Cannot be called from an
1191     *   {@link android.accessibilityservice.AccessibilityService}.
1192     *   This class is made immutable before being delivered to an AccessibilityService.
1193     * </p>
1194     *
1195     * @param granularities The bit mask with granularities.
1196     *
1197     * @throws IllegalStateException If called from an AccessibilityService.
1198     */
1199    public void setMovementGranularities(int granularities) {
1200        IMPL.setMovementGranularities(mInfo, granularities);
1201    }
1202
1203    /**
1204     * Gets the movement granularities for traversing the text of this node.
1205     *
1206     * @return The bit mask with granularities.
1207     */
1208    public int getMovementGranularities() {
1209        return IMPL.getMovementGranularities(mInfo);
1210    }
1211
1212    /**
1213     * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by text. The match
1214     * is case insensitive containment. The search is relative to this info i.e. this
1215     * info is the root of the traversed tree.
1216     * <p>
1217     * <strong>Note:</strong> It is a client responsibility to recycle the
1218     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
1219     * to avoid creating of multiple instances.
1220     * </p>
1221     *
1222     * @param text The searched text.
1223     * @return A list of node info.
1224     */
1225    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
1226        List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>();
1227        List<Object> infos = IMPL.findAccessibilityNodeInfosByText(mInfo, text);
1228        final int infoCount = infos.size();
1229        for (int i = 0; i < infoCount; i++) {
1230            Object info = infos.get(i);
1231            result.add(new AccessibilityNodeInfoCompat(info));
1232        }
1233        return result;
1234    }
1235
1236    /**
1237     * Gets the parent.
1238     * <p>
1239     * <strong>Note:</strong> It is a client responsibility to recycle the
1240     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
1241     * to avoid creating of multiple instances.
1242     * </p>
1243     *
1244     * @return The parent.
1245     */
1246    public AccessibilityNodeInfoCompat getParent() {
1247        return AccessibilityNodeInfoCompat.wrapNonNullInstance(IMPL.getParent(mInfo));
1248    }
1249
1250    /**
1251     * Sets the parent.
1252     * <p>
1253     * <strong>Note:</strong> Cannot be called from an
1254     * {@link android.accessibilityservice.AccessibilityService}. This class is
1255     * made immutable before being delivered to an AccessibilityService.
1256     * </p>
1257     *
1258     * @param parent The parent.
1259     * @throws IllegalStateException If called from an AccessibilityService.
1260     */
1261    public void setParent(View parent) {
1262        IMPL.setParent(mInfo, parent);
1263    }
1264
1265    /**
1266     * Sets the parent to be a virtual descendant of the given <code>root</code>.
1267     * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
1268     * is set as the parent.
1269     * <p>
1270     * A virtual descendant is an imaginary View that is reported as a part of the view
1271     * hierarchy for accessibility purposes. This enables custom views that draw complex
1272     * content to report them selves as a tree of virtual views, thus conveying their
1273     * logical structure.
1274     * </p>
1275     * <p>
1276     *   <strong>Note:</strong> Cannot be called from an
1277     *   {@link android.accessibilityservice.AccessibilityService}.
1278     *   This class is made immutable before being delivered to an AccessibilityService.
1279     * </p>
1280     *
1281     * @param root The root of the virtual subtree.
1282     * @param virtualDescendantId The id of the virtual descendant.
1283     */
1284    public void setParent(View root, int virtualDescendantId) {
1285        IMPL.setParent(mInfo, root, virtualDescendantId);
1286    }
1287
1288    /**
1289     * Gets the node bounds in parent coordinates.
1290     *
1291     * @param outBounds The output node bounds.
1292     */
1293    public void getBoundsInParent(Rect outBounds) {
1294        IMPL.getBoundsInParent(mInfo, outBounds);
1295    }
1296
1297    /**
1298     * Sets the node bounds in parent coordinates.
1299     * <p>
1300     * <strong>Note:</strong> Cannot be called from an
1301     * {@link android.accessibilityservice.AccessibilityService}. This class is
1302     * made immutable before being delivered to an AccessibilityService.
1303     * </p>
1304     *
1305     * @param bounds The node bounds.
1306     *@throws IllegalStateException If called from an AccessibilityService.
1307     */
1308    public void setBoundsInParent(Rect bounds) {
1309        IMPL.setBoundsInParent(mInfo, bounds);
1310    }
1311
1312    /**
1313     * Gets the node bounds in screen coordinates.
1314     *
1315     * @param outBounds The output node bounds.
1316     */
1317    public void getBoundsInScreen(Rect outBounds) {
1318        IMPL.getBoundsInScreen(mInfo, outBounds);
1319    }
1320
1321    /**
1322     * Sets the node bounds in screen coordinates.
1323     * <p>
1324     * <strong>Note:</strong> Cannot be called from an
1325     * {@link android.accessibilityservice.AccessibilityService}. This class is
1326     * made immutable before being delivered to an AccessibilityService.
1327     * </p>
1328     *
1329     * @param bounds The node bounds.
1330     * @throws IllegalStateException If called from an AccessibilityService.
1331     */
1332    public void setBoundsInScreen(Rect bounds) {
1333        IMPL.setBoundsInScreen(mInfo, bounds);
1334    }
1335
1336    /**
1337     * Gets whether this node is checkable.
1338     *
1339     * @return True if the node is checkable.
1340     */
1341    public boolean isCheckable() {
1342        return IMPL.isCheckable(mInfo);
1343    }
1344
1345    /**
1346     * Sets whether this node is checkable.
1347     * <p>
1348     * <strong>Note:</strong> Cannot be called from an
1349     * {@link android.accessibilityservice.AccessibilityService}. This class is
1350     * made immutable before being delivered to an AccessibilityService.
1351     * </p>
1352     *
1353     * @param checkable True if the node is checkable.
1354     * @throws IllegalStateException If called from an AccessibilityService.
1355     */
1356    public void setCheckable(boolean checkable) {
1357        IMPL.setCheckable(mInfo, checkable);
1358    }
1359
1360    /**
1361     * Gets whether this node is checked.
1362     *
1363     * @return True if the node is checked.
1364     */
1365    public boolean isChecked() {
1366        return IMPL.isChecked(mInfo);
1367    }
1368
1369    /**
1370     * Sets whether this node is checked.
1371     * <p>
1372     * <strong>Note:</strong> Cannot be called from an
1373     * {@link android.accessibilityservice.AccessibilityService}. This class is
1374     * made immutable before being delivered to an AccessibilityService.
1375     * </p>
1376     *
1377     * @param checked True if the node is checked.
1378     * @throws IllegalStateException If called from an AccessibilityService.
1379     */
1380    public void setChecked(boolean checked) {
1381        IMPL.setChecked(mInfo, checked);
1382    }
1383
1384    /**
1385     * Gets whether this node is focusable.
1386     *
1387     * @return True if the node is focusable.
1388     */
1389    public boolean isFocusable() {
1390        return IMPL.isFocusable(mInfo);
1391    }
1392
1393    /**
1394     * Sets whether this node is focusable.
1395     * <p>
1396     * <strong>Note:</strong> Cannot be called from an
1397     * {@link android.accessibilityservice.AccessibilityService}. This class is
1398     * made immutable before being delivered to an AccessibilityService.
1399     * </p>
1400     *
1401     * @param focusable True if the node is focusable.
1402     * @throws IllegalStateException If called from an AccessibilityService.
1403     */
1404    public void setFocusable(boolean focusable) {
1405        IMPL.setFocusable(mInfo, focusable);
1406    }
1407
1408    /**
1409     * Gets whether this node is focused.
1410     *
1411     * @return True if the node is focused.
1412     */
1413    public boolean isFocused() {
1414        return IMPL.isFocused(mInfo);
1415    }
1416
1417    /**
1418     * Sets whether this node is focused.
1419     * <p>
1420     * <strong>Note:</strong> Cannot be called from an
1421     * {@link android.accessibilityservice.AccessibilityService}. This class is
1422     * made immutable before being delivered to an AccessibilityService.
1423     * </p>
1424     *
1425     * @param focused True if the node is focused.
1426     * @throws IllegalStateException If called from an AccessibilityService.
1427     */
1428    public void setFocused(boolean focused) {
1429        IMPL.setFocused(mInfo, focused);
1430    }
1431
1432    /**
1433     * Sets whether this node is visible to the user.
1434     *
1435     * @return Whether the node is visible to the user.
1436     */
1437    public boolean isVisibleToUser() {
1438        return IMPL.isVisibleToUser(mInfo);
1439    }
1440
1441    /**
1442     * Sets whether this node is visible to the user.
1443     * <p>
1444     *   <strong>Note:</strong> Cannot be called from an
1445     *   {@link android.accessibilityservice.AccessibilityService}.
1446     *   This class is made immutable before being delivered to an AccessibilityService.
1447     * </p>
1448     *
1449     * @param visibleToUser Whether the node is visible to the user.
1450     *
1451     * @throws IllegalStateException If called from an AccessibilityService.
1452     */
1453    public void setVisibleToUser(boolean visibleToUser) {
1454        IMPL.setVisibleToUser(mInfo, visibleToUser);
1455    }
1456
1457    /**
1458     * Gets whether this node is accessibility focused.
1459     *
1460     * @return True if the node is accessibility focused.
1461     */
1462    public boolean isAccessibilityFocused() {
1463        return IMPL.isAccessibilityFocused(mInfo);
1464    }
1465
1466    /**
1467     * Sets whether this node is accessibility focused.
1468     * <p>
1469     *   <strong>Note:</strong> Cannot be called from an
1470     *   {@link android.accessibilityservice.AccessibilityService}.
1471     *   This class is made immutable before being delivered to an AccessibilityService.
1472     * </p>
1473     *
1474     * @param focused True if the node is accessibility focused.
1475     *
1476     * @throws IllegalStateException If called from an AccessibilityService.
1477     */
1478    public void setAccessibilityFocused(boolean focused) {
1479        IMPL.setAccessibilityFocused(mInfo, focused);
1480    }
1481
1482    /**
1483     * Gets whether this node is selected.
1484     *
1485     * @return True if the node is selected.
1486     */
1487    public boolean isSelected() {
1488        return IMPL.isSelected(mInfo);
1489    }
1490
1491    /**
1492     * Sets whether this node is selected.
1493     * <p>
1494     * <strong>Note:</strong> Cannot be called from an
1495     * {@link android.accessibilityservice.AccessibilityService}. This class is
1496     * made immutable before being delivered to an AccessibilityService.
1497     * </p>
1498     *
1499     * @param selected True if the node is selected.
1500     * @throws IllegalStateException If called from an AccessibilityService.
1501     */
1502    public void setSelected(boolean selected) {
1503        IMPL.setSelected(mInfo, selected);
1504    }
1505
1506    /**
1507     * Gets whether this node is clickable.
1508     *
1509     * @return True if the node is clickable.
1510     */
1511    public boolean isClickable() {
1512        return IMPL.isClickable(mInfo);
1513    }
1514
1515    /**
1516     * Sets whether this node is clickable.
1517     * <p>
1518     * <strong>Note:</strong> Cannot be called from an
1519     * {@link android.accessibilityservice.AccessibilityService}. This class is
1520     * made immutable before being delivered to an AccessibilityService.
1521     * </p>
1522     *
1523     * @param clickable True if the node is clickable.
1524     * @throws IllegalStateException If called from an AccessibilityService.
1525     */
1526    public void setClickable(boolean clickable) {
1527        IMPL.setClickable(mInfo, clickable);
1528    }
1529
1530    /**
1531     * Gets whether this node is long clickable.
1532     *
1533     * @return True if the node is long clickable.
1534     */
1535    public boolean isLongClickable() {
1536        return IMPL.isLongClickable(mInfo);
1537    }
1538
1539    /**
1540     * Sets whether this node is long clickable.
1541     * <p>
1542     * <strong>Note:</strong> Cannot be called from an
1543     * {@link android.accessibilityservice.AccessibilityService}. This class is
1544     * made immutable before being delivered to an AccessibilityService.
1545     * </p>
1546     *
1547     * @param longClickable True if the node is long clickable.
1548     * @throws IllegalStateException If called from an AccessibilityService.
1549     */
1550    public void setLongClickable(boolean longClickable) {
1551        IMPL.setLongClickable(mInfo, longClickable);
1552    }
1553
1554    /**
1555     * Gets whether this node is enabled.
1556     *
1557     * @return True if the node is enabled.
1558     */
1559    public boolean isEnabled() {
1560        return IMPL.isEnabled(mInfo);
1561    }
1562
1563    /**
1564     * Sets whether this node is enabled.
1565     * <p>
1566     * <strong>Note:</strong> Cannot be called from an
1567     * {@link android.accessibilityservice.AccessibilityService}. This class is
1568     * made immutable before being delivered to an AccessibilityService.
1569     * </p>
1570     *
1571     * @param enabled True if the node is enabled.
1572     * @throws IllegalStateException If called from an AccessibilityService.
1573     */
1574    public void setEnabled(boolean enabled) {
1575        IMPL.setEnabled(mInfo, enabled);
1576    }
1577
1578    /**
1579     * Gets whether this node is a password.
1580     *
1581     * @return True if the node is a password.
1582     */
1583    public boolean isPassword() {
1584        return IMPL.isPassword(mInfo);
1585    }
1586
1587    /**
1588     * Sets whether this node is a password.
1589     * <p>
1590     * <strong>Note:</strong> Cannot be called from an
1591     * {@link android.accessibilityservice.AccessibilityService}. This class is
1592     * made immutable before being delivered to an AccessibilityService.
1593     * </p>
1594     *
1595     * @param password True if the node is a password.
1596     * @throws IllegalStateException If called from an AccessibilityService.
1597     */
1598    public void setPassword(boolean password) {
1599        IMPL.setPassword(mInfo, password);
1600    }
1601
1602    /**
1603     * Gets if the node is scrollable.
1604     *
1605     * @return True if the node is scrollable, false otherwise.
1606     */
1607    public boolean isScrollable() {
1608        return IMPL.isScrollable(mInfo);
1609    }
1610
1611    /**
1612     * Sets if the node is scrollable.
1613     * <p>
1614     * <strong>Note:</strong> Cannot be called from an
1615     * {@link android.accessibilityservice.AccessibilityService}. This class is
1616     * made immutable before being delivered to an AccessibilityService.
1617     * </p>
1618     *
1619     * @param scrollable True if the node is scrollable, false otherwise.
1620     * @throws IllegalStateException If called from an AccessibilityService.
1621     */
1622    public void setScrollable(boolean scrollable) {
1623        IMPL.setScrollable(mInfo, scrollable);
1624    }
1625
1626    /**
1627     * Gets the package this node comes from.
1628     *
1629     * @return The package name.
1630     */
1631    public CharSequence getPackageName() {
1632        return IMPL.getPackageName(mInfo);
1633    }
1634
1635    /**
1636     * Sets the package this node comes from.
1637     * <p>
1638     * <strong>Note:</strong> Cannot be called from an
1639     * {@link android.accessibilityservice.AccessibilityService}. This class is
1640     * made immutable before being delivered to an AccessibilityService.
1641     * </p>
1642     *
1643     * @param packageName The package name.
1644     * @throws IllegalStateException If called from an AccessibilityService.
1645     */
1646    public void setPackageName(CharSequence packageName) {
1647        IMPL.setPackageName(mInfo, packageName);
1648    }
1649
1650    /**
1651     * Gets the class this node comes from.
1652     *
1653     * @return The class name.
1654     */
1655    public CharSequence getClassName() {
1656        return IMPL.getClassName(mInfo);
1657    }
1658
1659    /**
1660     * Sets the class this node comes from.
1661     * <p>
1662     * <strong>Note:</strong> Cannot be called from an
1663     * {@link android.accessibilityservice.AccessibilityService}. This class is
1664     * made immutable before being delivered to an AccessibilityService.
1665     * </p>
1666     *
1667     * @param className The class name.
1668     * @throws IllegalStateException If called from an AccessibilityService.
1669     */
1670    public void setClassName(CharSequence className) {
1671        IMPL.setClassName(mInfo, className);
1672    }
1673
1674    /**
1675     * Gets the text of this node.
1676     *
1677     * @return The text.
1678     */
1679    public CharSequence getText() {
1680        return IMPL.getText(mInfo);
1681    }
1682
1683    /**
1684     * Sets the text of this node.
1685     * <p>
1686     * <strong>Note:</strong> Cannot be called from an
1687     * {@link android.accessibilityservice.AccessibilityService}. This class is
1688     * made immutable before being delivered to an AccessibilityService.
1689     * </p>
1690     *
1691     * @param text The text.
1692     * @throws IllegalStateException If called from an AccessibilityService.
1693     */
1694    public void setText(CharSequence text) {
1695        IMPL.setText(mInfo, text);
1696    }
1697
1698    /**
1699     * Gets the content description of this node.
1700     *
1701     * @return The content description.
1702     */
1703    public CharSequence getContentDescription() {
1704        return IMPL.getContentDescription(mInfo);
1705    }
1706
1707    /**
1708     * Sets the content description of this node.
1709     * <p>
1710     * <strong>Note:</strong> Cannot be called from an
1711     * {@link android.accessibilityservice.AccessibilityService}. This class is
1712     * made immutable before being delivered to an AccessibilityService.
1713     * </p>
1714     *
1715     * @param contentDescription The content description.
1716     * @throws IllegalStateException If called from an AccessibilityService.
1717     */
1718    public void setContentDescription(CharSequence contentDescription) {
1719        IMPL.setContentDescription(mInfo, contentDescription);
1720    }
1721
1722    /**
1723     * Return an instance back to be reused.
1724     * <p>
1725     * <strong>Note:</strong> You must not touch the object after calling this function.
1726     *
1727     * @throws IllegalStateException If the info is already recycled.
1728     */
1729    public void recycle() {
1730        IMPL.recycle(mInfo);
1731    }
1732
1733    @Override
1734    public int hashCode() {
1735        return (mInfo == null) ? 0 : mInfo.hashCode();
1736    }
1737
1738    @Override
1739    public boolean equals(Object obj) {
1740        if (this == obj) {
1741            return true;
1742        }
1743        if (obj == null) {
1744            return false;
1745        }
1746        if (getClass() != obj.getClass()) {
1747            return false;
1748        }
1749        AccessibilityNodeInfoCompat other = (AccessibilityNodeInfoCompat) obj;
1750        if (mInfo == null) {
1751            if (other.mInfo != null) {
1752                return false;
1753            }
1754        } else if (!mInfo.equals(other.mInfo)) {
1755            return false;
1756        }
1757        return true;
1758    }
1759}
1760