AccessibilityNodeInfoCompat.java revision c64858f808c159a8b144d22e3168459074cdc181
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.view.View;
22
23import java.util.ArrayList;
24import java.util.Collections;
25import java.util.List;
26
27/**
28 * Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo}
29 * introduced after API level 4 in a backwards compatible fashion.
30 */
31public class AccessibilityNodeInfoCompat {
32
33    static interface AccessibilityNodeInfoImpl {
34        public Object obtain();
35        public Object obtain(View source);
36        public Object obtain(Object info);
37        public void setSource(Object info, View source);
38        public int getWindowId(Object info);
39        public int getChildCount(Object info);
40        public AccessibilityNodeInfoCompat getChild(Object info, int index);
41        public void addChild(Object info, View child);
42        public int getActions(Object info);
43        public void addAction(Object info, int action);
44        public boolean performAction(Object info, int action);
45        public List<Object> findAccessibilityNodeInfosByText(Object info, String text);
46        public AccessibilityNodeInfoCompat getParent(Object info);
47        public void setParent(Object info, View parent);
48        public void getBoundsInParent(Object info, Rect outBounds);
49        public void setBoundsInParent(Object info, Rect bounds);
50        public void getBoundsInScreen(Object info, Rect outBounds);
51        public void setBoundsInScreen(Object info, Rect bounds);
52        public boolean isCheckable(Object info);
53        public void setCheckable(Object info, boolean checkable);
54        public boolean isChecked(Object info);
55        public void setChecked(Object info, boolean checked);
56        public boolean isFocusable(Object info);
57        public void setFocusable(Object info, boolean focusable);
58        public boolean isFocused(Object info);
59        public void setFocused(Object info, boolean focused);
60        public boolean isSelected(Object info);
61        public void setSelected(Object info, boolean selected);
62        public boolean isClickable(Object info);
63        public void setClickable(Object info, boolean clickable);
64        public boolean isLongClickable(Object info);
65        public void setLongClickable(Object info, boolean longClickable);
66        public boolean isEnabled(Object info);
67        public void setEnabled(Object info, boolean enabled);
68        public boolean isPassword(Object info);
69        public void setPassword(Object info, boolean password);
70        public boolean isScrollable(Object info);
71        public void setScrollable(Object info, boolean scrollable);
72        public CharSequence getPackageName(Object info);
73        public void setPackageName(Object info, CharSequence packageName);
74        public CharSequence getClassName(Object info);
75        public void setClassName(Object info, CharSequence className);
76        public CharSequence getText(Object info);
77        public void setText(Object info, CharSequence text);
78        public CharSequence getContentDescription(Object info);
79        public void setContentDescription(Object info, CharSequence contentDescription);
80        public void recycle(Object info);
81    }
82
83    static class AccessibilityNodeInfoStubImpl implements AccessibilityNodeInfoImpl {
84        public Object obtain() {
85            return null;
86        }
87
88        public Object obtain(View source) {
89            return null;
90        }
91
92        public Object obtain(Object info) {
93            return null;
94        }
95
96        public void addAction(Object info, int action) {
97
98        }
99
100        public void addChild(Object info, View child) {
101
102        }
103
104        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
105            return Collections.emptyList();
106        }
107
108        public int getActions(Object info) {
109            return 0;
110        }
111
112        public void getBoundsInParent(Object info, Rect outBounds) {
113
114        }
115
116        public void getBoundsInScreen(Object info, Rect outBounds) {
117
118        }
119
120        public AccessibilityNodeInfoCompat getChild(Object info, int index) {
121            return null;
122        }
123
124        public int getChildCount(Object info) {
125            return 0;
126        }
127
128        public CharSequence getClassName(Object info) {
129            return null;
130        }
131
132        public CharSequence getContentDescription(Object info) {
133            return null;
134        }
135
136        public CharSequence getPackageName(Object info) {
137            return null;
138        }
139
140        public AccessibilityNodeInfoCompat getParent(Object info) {
141            return null;
142        }
143
144        public CharSequence getText(Object info) {
145            return null;
146        }
147
148        public int getWindowId(Object info) {
149            return 0;
150        }
151
152        public boolean isCheckable(Object info) {
153            return false;
154        }
155
156        public boolean isChecked(Object info) {
157            return false;
158        }
159
160        public boolean isClickable(Object info) {
161            return false;
162        }
163
164        public boolean isEnabled(Object info) {
165            return false;
166        }
167
168        public boolean isFocusable(Object info) {
169            return false;
170        }
171
172        public boolean isFocused(Object info) {
173            return false;
174        }
175
176        public boolean isLongClickable(Object info) {
177            return false;
178        }
179
180        public boolean isPassword(Object info) {
181            return false;
182        }
183
184        public boolean isScrollable(Object info) {
185            return false;
186        }
187
188        public boolean isSelected(Object info) {
189            return false;
190        }
191
192        public boolean performAction(Object info, int action) {
193            return false;
194        }
195
196        public void setBoundsInParent(Object info, Rect bounds) {
197
198        }
199
200        public void setBoundsInScreen(Object info, Rect bounds) {
201
202        }
203
204        public void setCheckable(Object info, boolean checkable) {
205
206        }
207
208        public void setChecked(Object info, boolean checked) {
209
210        }
211
212        public void setClassName(Object info, CharSequence className) {
213
214        }
215
216        public void setClickable(Object info, boolean clickable) {
217
218        }
219
220        public void setContentDescription(Object info, CharSequence contentDescription) {
221
222        }
223
224        public void setEnabled(Object info, boolean enabled) {
225
226        }
227
228        public void setFocusable(Object info, boolean focusable) {
229
230        }
231
232        public void setFocused(Object info, boolean focused) {
233
234        }
235
236        public void setLongClickable(Object info, boolean longClickable) {
237
238        }
239
240        public void setPackageName(Object info, CharSequence packageName) {
241
242        }
243
244        public void setParent(Object info, View parent) {
245
246        }
247
248        public void setPassword(Object info, boolean password) {
249
250        }
251
252        public void setScrollable(Object info, boolean scrollable) {
253
254        }
255
256        public void setSelected(Object info, boolean selected) {
257
258        }
259
260        public void setSource(Object info, View source) {
261
262        }
263
264        public void setText(Object info, CharSequence text) {
265
266        }
267
268        public void recycle(Object info) {
269
270        }
271    }
272
273    static class AccessibilityNodeInfoIcsImpl extends AccessibilityNodeInfoStubImpl {
274        @Override
275        public Object obtain() {
276            return AccessibilityNodeInfoCompatIcs.obtain();
277        }
278
279        @Override
280        public Object obtain(View source) {
281            return AccessibilityNodeInfoCompatIcs.obtain(source);
282        }
283
284        @Override
285        public Object obtain(Object info) {
286            return AccessibilityNodeInfoCompatIcs.obtain(info);
287        }
288
289        @Override
290        public void addAction(Object info, int action) {
291            AccessibilityNodeInfoCompatIcs.addAction(info, action);
292        }
293
294        @Override
295        public void addChild(Object info, View child) {
296            AccessibilityNodeInfoCompatIcs.addChild(info, child);
297        }
298
299        @Override
300        public List<Object> findAccessibilityNodeInfosByText(Object info, String text) {
301            return AccessibilityNodeInfoCompatIcs.findAccessibilityNodeInfosByText(info, text);
302        }
303
304        @Override
305        public int getActions(Object info) {
306            return AccessibilityNodeInfoCompatIcs.getActions(info);
307        }
308
309        @Override
310        public void getBoundsInParent(Object info, Rect outBounds) {
311            AccessibilityNodeInfoCompatIcs.getBoundsInParent(info, outBounds);
312        }
313
314        @Override
315        public void getBoundsInScreen(Object info, Rect outBounds) {
316            AccessibilityNodeInfoCompatIcs.getBoundsInScreen(info, outBounds);
317        }
318
319        @Override
320        public AccessibilityNodeInfoCompat getChild(Object info, int index) {
321            return AccessibilityNodeInfoCompat.wrapNonNullInstance(
322                    AccessibilityNodeInfoCompatIcs.getChild(info, index));
323        }
324
325        @Override
326        public int getChildCount(Object info) {
327            return AccessibilityNodeInfoCompatIcs.getChildCount(info);
328        }
329
330        @Override
331        public CharSequence getClassName(Object info) {
332            return AccessibilityNodeInfoCompatIcs.getClassName(info);
333        }
334
335        @Override
336        public CharSequence getContentDescription(Object info) {
337            return AccessibilityNodeInfoCompatIcs.getContentDescription(info);
338        }
339
340        @Override
341        public CharSequence getPackageName(Object info) {
342            return AccessibilityNodeInfoCompatIcs.getPackageName(info);
343        }
344
345        @Override
346        public AccessibilityNodeInfoCompat getParent(Object info) {
347            return AccessibilityNodeInfoCompat.wrapNonNullInstance(
348                    AccessibilityNodeInfoCompatIcs.getParent(info));
349        }
350
351        @Override
352        public CharSequence getText(Object info) {
353            return AccessibilityNodeInfoCompatIcs.getText(info);
354        }
355
356        @Override
357        public int getWindowId(Object info) {
358            return AccessibilityNodeInfoCompatIcs.getWindowId(info);
359        }
360
361        @Override
362        public boolean isCheckable(Object info) {
363            return AccessibilityNodeInfoCompatIcs.isCheckable(info);
364        }
365
366        @Override
367        public boolean isChecked(Object info) {
368            return AccessibilityNodeInfoCompatIcs.isChecked(info);
369        }
370
371        @Override
372        public boolean isClickable(Object info) {
373            return AccessibilityNodeInfoCompatIcs.isClickable(info);
374        }
375
376        @Override
377        public boolean isEnabled(Object info) {
378            return AccessibilityNodeInfoCompatIcs.isEnabled(info);
379        }
380
381        @Override
382        public boolean isFocusable(Object info) {
383            return AccessibilityNodeInfoCompatIcs.isFocusable(info);
384        }
385
386        @Override
387        public boolean isFocused(Object info) {
388            return AccessibilityNodeInfoCompatIcs.isFocused(info);
389        }
390
391        @Override
392        public boolean isLongClickable(Object info) {
393            return AccessibilityNodeInfoCompatIcs.isLongClickable(info);
394        }
395
396        @Override
397        public boolean isPassword(Object info) {
398            return AccessibilityNodeInfoCompatIcs.isPassword(info);
399        }
400
401        @Override
402        public boolean isScrollable(Object info) {
403            return AccessibilityNodeInfoCompatIcs.isScrollable(info);
404        }
405
406        @Override
407        public boolean isSelected(Object info) {
408            return AccessibilityNodeInfoCompatIcs.isSelected(info);
409        }
410
411        @Override
412        public boolean performAction(Object info, int action) {
413            return AccessibilityNodeInfoCompatIcs.performAction(info, action);
414        }
415
416        @Override
417        public void setBoundsInParent(Object info, Rect bounds) {
418            AccessibilityNodeInfoCompatIcs.setBoundsInParent(info, bounds);
419        }
420
421        @Override
422        public void setBoundsInScreen(Object info, Rect bounds) {
423            AccessibilityNodeInfoCompatIcs.setBoundsInScreen(info, bounds);
424        }
425
426        @Override
427        public void setCheckable(Object info, boolean checkable) {
428            AccessibilityNodeInfoCompatIcs.setCheckable(info, checkable);
429        }
430
431        @Override
432        public void setChecked(Object info, boolean checked) {
433            AccessibilityNodeInfoCompatIcs.setChecked(info, checked);
434        }
435
436        @Override
437        public void setClassName(Object info, CharSequence className) {
438            AccessibilityNodeInfoCompatIcs.setClassName(info, className);
439        }
440
441        @Override
442        public void setClickable(Object info, boolean clickable) {
443            AccessibilityNodeInfoCompatIcs.setClickable(info, clickable);
444        }
445
446        @Override
447        public void setContentDescription(Object info, CharSequence contentDescription) {
448            AccessibilityNodeInfoCompatIcs.setContentDescription(info, contentDescription);
449        }
450
451        @Override
452        public void setEnabled(Object info, boolean enabled) {
453            AccessibilityNodeInfoCompatIcs.setEnabled(info, enabled);
454        }
455
456        @Override
457        public void setFocusable(Object info, boolean focusable) {
458            AccessibilityNodeInfoCompatIcs.setFocusable(info, focusable);
459        }
460
461        @Override
462        public void setFocused(Object info, boolean focused) {
463            AccessibilityNodeInfoCompatIcs.setFocused(info, focused);
464        }
465
466        @Override
467        public void setLongClickable(Object info, boolean longClickable) {
468            AccessibilityNodeInfoCompatIcs.setLongClickable(info, longClickable);
469        }
470
471        @Override
472        public void setPackageName(Object info, CharSequence packageName) {
473            AccessibilityNodeInfoCompatIcs.setPackageName(info, packageName);
474        }
475
476        @Override
477        public void setParent(Object info, View parent) {
478            AccessibilityNodeInfoCompatIcs.setParent(info, parent);
479        }
480
481        @Override
482        public void setPassword(Object info, boolean password) {
483            AccessibilityNodeInfoCompatIcs.setPassword(info, password);
484        }
485
486        @Override
487        public void setScrollable(Object info, boolean scrollable) {
488            AccessibilityNodeInfoCompatIcs.setScrollable(info, scrollable);
489        }
490
491        @Override
492        public void setSelected(Object info, boolean selected) {
493            AccessibilityNodeInfoCompatIcs.setSelected(info, selected);
494        }
495
496        @Override
497        public void setSource(Object info, View source) {
498            AccessibilityNodeInfoCompatIcs.setSource(info, source);
499        }
500
501        @Override
502        public void setText(Object info, CharSequence text) {
503            AccessibilityNodeInfoCompatIcs.setText(info, text);
504        }
505
506        @Override
507        public void recycle(Object info) {
508            AccessibilityNodeInfoCompatIcs.recycle(info);
509        }
510    }
511
512    static {
513        if (Build.VERSION.SDK_INT >= 14) { // ICS
514            IMPL = new AccessibilityNodeInfoIcsImpl();
515        } else {
516            IMPL = new AccessibilityNodeInfoStubImpl();
517        }
518    }
519
520    private static final AccessibilityNodeInfoImpl IMPL;
521
522    private final Object mInfo;
523
524    // Actions.
525
526    /**
527     * Action that focuses the node.
528     */
529    public static final int ACTION_FOCUS = 0x00000001;
530
531    /**
532     * Action that unfocuses the node.
533     */
534    public static final int ACTION_CLEAR_FOCUS = 0x00000002;
535
536    /**
537     * Action that selects the node.
538     */
539    public static final int ACTION_SELECT = 0x00000004;
540
541    /**
542     * Action that unselects the node.
543     */
544    public static final int ACTION_CLEAR_SELECTION = 0x00000008;
545
546    /**
547     * Creates a wrapper for info implementation.
548     *
549     * @param object The info to wrap.
550     * @return A wrapper for if the object is not null, null otherwise.
551     */
552    static AccessibilityNodeInfoCompat wrapNonNullInstance(Object object) {
553        if (object != null) {
554            return new AccessibilityNodeInfoCompat(object);
555        }
556        return null;
557    }
558
559    /*
560     * Hide constructor from clients.
561     */
562    public AccessibilityNodeInfoCompat(Object info) {
563        mInfo = info;
564    }
565
566    /**
567     * @return The wrapped actual implementation.
568     *
569     * @hide
570     */
571    public Object getImpl() {
572        return mInfo;
573    }
574
575    /**
576     * Returns a cached instance if such is available otherwise a new one and
577     * sets the source.
578     *
579     * @return An instance.
580     * @see #setSource(View)
581     */
582    public static AccessibilityNodeInfoCompat obtain(View source) {
583        return new AccessibilityNodeInfoCompat(IMPL.obtain(source));
584    }
585
586    /**
587     * Returns a cached instance if such is available otherwise a new one.
588     *
589     * @return An instance.
590     */
591    public static AccessibilityNodeInfoCompat obtain() {
592        return new AccessibilityNodeInfoCompat(IMPL.obtain());
593    }
594
595    /**
596     * Returns a cached instance if such is available or a new one is create.
597     * The returned instance is initialized from the given <code>info</code>.
598     *
599     * @param info The other info.
600     * @return An instance.
601     */
602    public static AccessibilityNodeInfoCompat obtain(AccessibilityNodeInfoCompat info) {
603        return new AccessibilityNodeInfoCompat(IMPL.obtain(info.mInfo));
604    }
605
606    /**
607     * Sets the source.
608     *
609     * @param source The info source.
610     */
611    public void setSource(View source) {
612        IMPL.setSource(mInfo, source);
613    }
614
615    /**
616     * Gets the id of the window from which the info comes from.
617     *
618     * @return The window id.
619     */
620    public int getWindowId() {
621        return IMPL.getWindowId(mInfo);
622    }
623
624    /**
625     * Gets the number of children.
626     *
627     * @return The child count.
628     */
629    public int getChildCount() {
630        return IMPL.getChildCount(mInfo);
631    }
632
633    /**
634     * Get the child at given index.
635     * <p>
636     * <strong>Note:</strong> It is a client responsibility to recycle the
637     * received info by calling {@link AccessibilityNodeInfoCompat#recycle()} to
638     * avoid creating of multiple instances.
639     * </p>
640     *
641     * @param index The child index.
642     * @return The child node.
643     * @throws IllegalStateException If called outside of an
644     *             AccessibilityService.
645     */
646    public AccessibilityNodeInfoCompat getChild(int index) {
647        return IMPL.getChild(mInfo, index);
648    }
649
650    /**
651     * Adds a child.
652     * <p>
653     * <strong>Note:</strong> Cannot be called from an
654     * {@link android.accessibilityservice.AccessibilityService}. This class is
655     * made immutable before being delivered to an AccessibilityService.
656     * </p>
657     *
658     * @param child The child.
659     * @throws IllegalStateException If called from an AccessibilityService.
660     */
661    public void addChild(View child) {
662        IMPL.addChild(mInfo, child);
663    }
664
665    /**
666     * Gets the actions that can be performed on the node.
667     *
668     * @return The bit mask of with actions.
669     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS
670     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
671     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT
672     * @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
673     */
674    public int getActions() {
675        return IMPL.getActions(mInfo);
676    }
677
678    /**
679     * Adds an action that can be performed on the node.
680     * <p>
681     * <strong>Note:</strong> Cannot be called from an
682     * {@link android.accessibilityservice.AccessibilityService}. This class is
683     * made immutable before being delivered to an AccessibilityService.
684     * </p>
685     *
686     * @param action The action.
687     * @throws IllegalStateException If called from an AccessibilityService.
688     */
689    public void addAction(int action) {
690        IMPL.addAction(mInfo, action);
691    }
692
693    /**
694     * Performs an action on the node.
695     * <p>
696     * <strong>Note:</strong> An action can be performed only if the request is
697     * made from an {@link android.accessibilityservice.AccessibilityService}.
698     * </p>
699     *
700     * @param action The action to perform.
701     * @return True if the action was performed.
702     * @throws IllegalStateException If called outside of an
703     *             AccessibilityService.
704     */
705    public boolean performAction(int action) {
706        return IMPL.performAction(mInfo, action);
707    }
708
709    /**
710     * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by text. The match
711     * is case insensitive containment. The search is relative to this info i.e. this
712     * info is the root of the traversed tree.
713     * <p>
714     * <strong>Note:</strong> It is a client responsibility to recycle the
715     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
716     * to avoid creating of multiple instances.
717     * </p>
718     *
719     * @param text The searched text.
720     * @return A list of node info.
721     */
722    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
723        List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>();
724        List<Object> infos = IMPL.findAccessibilityNodeInfosByText(mInfo, text);
725        final int infoCount = infos.size();
726        for (int i = 0; i < infoCount; i++) {
727            Object info = infos.get(i);
728            result.add(new AccessibilityNodeInfoCompat(info));
729        }
730        return result;
731    }
732
733    /**
734     * Gets the parent.
735     * <p>
736     * <strong>Note:</strong> It is a client responsibility to recycle the
737     * received info by calling {@link android.view.accessibility.AccessibilityNodeInfo#recycle()}
738     * to avoid creating of multiple instances.
739     * </p>
740     *
741     * @return The parent.
742     */
743    public AccessibilityNodeInfoCompat getParent() {
744        return IMPL.getParent(mInfo);
745    }
746
747    /**
748     * Sets the parent.
749     * <p>
750     * <strong>Note:</strong> Cannot be called from an
751     * {@link android.accessibilityservice.AccessibilityService}. This class is
752     * made immutable before being delivered to an AccessibilityService.
753     * </p>
754     *
755     * @param parent The parent.
756     * @throws IllegalStateException If called from an AccessibilityService.
757     */
758    public void setParent(View parent) {
759        IMPL.setParent(mInfo, parent);
760    }
761
762    /**
763     * Gets the node bounds in parent coordinates.
764     *
765     * @param outBounds The output node bounds.
766     */
767    public void getBoundsInParent(Rect outBounds) {
768        IMPL.getBoundsInParent(mInfo, outBounds);
769    }
770
771    /**
772     * Sets the node bounds in parent coordinates.
773     * <p>
774     * <strong>Note:</strong> Cannot be called from an
775     * {@link android.accessibilityservice.AccessibilityService}. This class is
776     * made immutable before being delivered to an AccessibilityService.
777     * </p>
778     *
779     * @param bounds The node bounds.
780     *@throws IllegalStateException If called from an AccessibilityService.
781     */
782    public void setBoundsInParent(Rect bounds) {
783        IMPL.setBoundsInParent(mInfo, bounds);
784    }
785
786    /**
787     * Gets the node bounds in screen coordinates.
788     *
789     * @param outBounds The output node bounds.
790     */
791    public void getBoundsInScreen(Rect outBounds) {
792        IMPL.getBoundsInScreen(mInfo, outBounds);
793    }
794
795    /**
796     * Sets the node bounds in screen coordinates.
797     * <p>
798     * <strong>Note:</strong> Cannot be called from an
799     * {@link android.accessibilityservice.AccessibilityService}. This class is
800     * made immutable before being delivered to an AccessibilityService.
801     * </p>
802     *
803     * @param bounds The node bounds.
804     * @throws IllegalStateException If called from an AccessibilityService.
805     */
806    public void setBoundsInScreen(Rect bounds) {
807        IMPL.setBoundsInParent(mInfo, bounds);
808    }
809
810    /**
811     * Gets whether this node is checkable.
812     *
813     * @return True if the node is checkable.
814     */
815    public boolean isCheckable() {
816        return IMPL.isCheckable(mInfo);
817    }
818
819    /**
820     * Sets whether this node is checkable.
821     * <p>
822     * <strong>Note:</strong> Cannot be called from an
823     * {@link android.accessibilityservice.AccessibilityService}. This class is
824     * made immutable before being delivered to an AccessibilityService.
825     * </p>
826     *
827     * @param checkable True if the node is checkable.
828     * @throws IllegalStateException If called from an AccessibilityService.
829     */
830    public void setCheckable(boolean checkable) {
831        IMPL.setCheckable(mInfo, checkable);
832    }
833
834    /**
835     * Gets whether this node is checked.
836     *
837     * @return True if the node is checked.
838     */
839    public boolean isChecked() {
840        return IMPL.isChecked(mInfo);
841    }
842
843    /**
844     * Sets whether this node is checked.
845     * <p>
846     * <strong>Note:</strong> Cannot be called from an
847     * {@link android.accessibilityservice.AccessibilityService}. This class is
848     * made immutable before being delivered to an AccessibilityService.
849     * </p>
850     *
851     * @param checked True if the node is checked.
852     * @throws IllegalStateException If called from an AccessibilityService.
853     */
854    public void setChecked(boolean checked) {
855        IMPL.setChecked(mInfo, checked);
856    }
857
858    /**
859     * Gets whether this node is focusable.
860     *
861     * @return True if the node is focusable.
862     */
863    public boolean isFocusable() {
864        return IMPL.isFocusable(mInfo);
865    }
866
867    /**
868     * Sets whether this node is focusable.
869     * <p>
870     * <strong>Note:</strong> Cannot be called from an
871     * {@link android.accessibilityservice.AccessibilityService}. This class is
872     * made immutable before being delivered to an AccessibilityService.
873     * </p>
874     *
875     * @param focusable True if the node is focusable.
876     * @throws IllegalStateException If called from an AccessibilityService.
877     */
878    public void setFocusable(boolean focusable) {
879        IMPL.setFocusable(mInfo, focusable);
880    }
881
882    /**
883     * Gets whether this node is focused.
884     *
885     * @return True if the node is focused.
886     */
887    public boolean isFocused() {
888        return IMPL.isFocused(mInfo);
889    }
890
891    /**
892     * Sets whether this node is focused.
893     * <p>
894     * <strong>Note:</strong> Cannot be called from an
895     * {@link android.accessibilityservice.AccessibilityService}. This class is
896     * made immutable before being delivered to an AccessibilityService.
897     * </p>
898     *
899     * @param focused True if the node is focused.
900     * @throws IllegalStateException If called from an AccessibilityService.
901     */
902    public void setFocused(boolean focused) {
903        IMPL.setFocused(mInfo, focused);
904    }
905
906    /**
907     * Gets whether this node is selected.
908     *
909     * @return True if the node is selected.
910     */
911    public boolean isSelected() {
912        return IMPL.isSelected(mInfo);
913    }
914
915    /**
916     * Sets whether this node is selected.
917     * <p>
918     * <strong>Note:</strong> Cannot be called from an
919     * {@link android.accessibilityservice.AccessibilityService}. This class is
920     * made immutable before being delivered to an AccessibilityService.
921     * </p>
922     *
923     * @param selected True if the node is selected.
924     * @throws IllegalStateException If called from an AccessibilityService.
925     */
926    public void setSelected(boolean selected) {
927        IMPL.setSelected(mInfo, selected);
928    }
929
930    /**
931     * Gets whether this node is clickable.
932     *
933     * @return True if the node is clickable.
934     */
935    public boolean isClickable() {
936        return IMPL.isClickable(mInfo);
937    }
938
939    /**
940     * Sets whether this node is clickable.
941     * <p>
942     * <strong>Note:</strong> Cannot be called from an
943     * {@link android.accessibilityservice.AccessibilityService}. This class is
944     * made immutable before being delivered to an AccessibilityService.
945     * </p>
946     *
947     * @param clickable True if the node is clickable.
948     * @throws IllegalStateException If called from an AccessibilityService.
949     */
950    public void setClickable(boolean clickable) {
951        IMPL.setClickable(mInfo, clickable);
952    }
953
954    /**
955     * Gets whether this node is long clickable.
956     *
957     * @return True if the node is long clickable.
958     */
959    public boolean isLongClickable() {
960        return IMPL.isLongClickable(mInfo);
961    }
962
963    /**
964     * Sets whether this node is long clickable.
965     * <p>
966     * <strong>Note:</strong> Cannot be called from an
967     * {@link android.accessibilityservice.AccessibilityService}. This class is
968     * made immutable before being delivered to an AccessibilityService.
969     * </p>
970     *
971     * @param longClickable True if the node is long clickable.
972     * @throws IllegalStateException If called from an AccessibilityService.
973     */
974    public void setLongClickable(boolean longClickable) {
975        IMPL.setLongClickable(mInfo, longClickable);
976    }
977
978    /**
979     * Gets whether this node is enabled.
980     *
981     * @return True if the node is enabled.
982     */
983    public boolean isEnabled() {
984        return IMPL.isEnabled(mInfo);
985    }
986
987    /**
988     * Sets whether this node is enabled.
989     * <p>
990     * <strong>Note:</strong> Cannot be called from an
991     * {@link android.accessibilityservice.AccessibilityService}. This class is
992     * made immutable before being delivered to an AccessibilityService.
993     * </p>
994     *
995     * @param enabled True if the node is enabled.
996     * @throws IllegalStateException If called from an AccessibilityService.
997     */
998    public void setEnabled(boolean enabled) {
999        IMPL.setEnabled(mInfo, enabled);
1000    }
1001
1002    /**
1003     * Gets whether this node is a password.
1004     *
1005     * @return True if the node is a password.
1006     */
1007    public boolean isPassword() {
1008        return IMPL.isPassword(mInfo);
1009    }
1010
1011    /**
1012     * Sets whether this node is a password.
1013     * <p>
1014     * <strong>Note:</strong> Cannot be called from an
1015     * {@link android.accessibilityservice.AccessibilityService}. This class is
1016     * made immutable before being delivered to an AccessibilityService.
1017     * </p>
1018     *
1019     * @param password True if the node is a password.
1020     * @throws IllegalStateException If called from an AccessibilityService.
1021     */
1022    public void setPassword(boolean password) {
1023        IMPL.setPassword(mInfo, password);
1024    }
1025
1026    /**
1027     * Gets if the node is scrollable.
1028     *
1029     * @return True if the node is scrollable, false otherwise.
1030     */
1031    public boolean isScrollable() {
1032        return IMPL.isScrollable(mInfo);
1033    }
1034
1035    /**
1036     * Sets if the node is scrollable.
1037     * <p>
1038     * <strong>Note:</strong> Cannot be called from an
1039     * {@link android.accessibilityservice.AccessibilityService}. This class is
1040     * made immutable before being delivered to an AccessibilityService.
1041     * </p>
1042     *
1043     * @param scrollable True if the node is scrollable, false otherwise.
1044     * @throws IllegalStateException If called from an AccessibilityService.
1045     */
1046    public void setScrollable(boolean scrollable) {
1047        IMPL.setScrollable(mInfo, scrollable);
1048    }
1049
1050    /**
1051     * Gets the package this node comes from.
1052     *
1053     * @return The package name.
1054     */
1055    public CharSequence getPackageName() {
1056        return IMPL.getPackageName(mInfo);
1057    }
1058
1059    /**
1060     * Sets the package this node comes from.
1061     * <p>
1062     * <strong>Note:</strong> Cannot be called from an
1063     * {@link android.accessibilityservice.AccessibilityService}. This class is
1064     * made immutable before being delivered to an AccessibilityService.
1065     * </p>
1066     *
1067     * @param packageName The package name.
1068     * @throws IllegalStateException If called from an AccessibilityService.
1069     */
1070    public void setPackageName(CharSequence packageName) {
1071        IMPL.setPackageName(mInfo, packageName);
1072    }
1073
1074    /**
1075     * Gets the class this node comes from.
1076     *
1077     * @return The class name.
1078     */
1079    public CharSequence getClassName() {
1080        return IMPL.getClassName(mInfo);
1081    }
1082
1083    /**
1084     * Sets the class this node comes from.
1085     * <p>
1086     * <strong>Note:</strong> Cannot be called from an
1087     * {@link android.accessibilityservice.AccessibilityService}. This class is
1088     * made immutable before being delivered to an AccessibilityService.
1089     * </p>
1090     *
1091     * @param className The class name.
1092     * @throws IllegalStateException If called from an AccessibilityService.
1093     */
1094    public void setClassName(CharSequence className) {
1095        IMPL.setClassName(mInfo, className);
1096    }
1097
1098    /**
1099     * Gets the text of this node.
1100     *
1101     * @return The text.
1102     */
1103    public CharSequence getText() {
1104        return IMPL.getText(mInfo);
1105    }
1106
1107    /**
1108     * Sets the text of this node.
1109     * <p>
1110     * <strong>Note:</strong> Cannot be called from an
1111     * {@link android.accessibilityservice.AccessibilityService}. This class is
1112     * made immutable before being delivered to an AccessibilityService.
1113     * </p>
1114     *
1115     * @param text The text.
1116     * @throws IllegalStateException If called from an AccessibilityService.
1117     */
1118    public void setText(CharSequence text) {
1119        IMPL.setText(mInfo, text);
1120    }
1121
1122    /**
1123     * Gets the content description of this node.
1124     *
1125     * @return The content description.
1126     */
1127    public CharSequence getContentDescription() {
1128        return IMPL.getContentDescription(mInfo);
1129    }
1130
1131    /**
1132     * Sets the content description of this node.
1133     * <p>
1134     * <strong>Note:</strong> Cannot be called from an
1135     * {@link android.accessibilityservice.AccessibilityService}. This class is
1136     * made immutable before being delivered to an AccessibilityService.
1137     * </p>
1138     *
1139     * @param contentDescription The content description.
1140     * @throws IllegalStateException If called from an AccessibilityService.
1141     */
1142    public void setContentDescription(CharSequence contentDescription) {
1143        IMPL.setContentDescription(mInfo, contentDescription);
1144    }
1145
1146    /**
1147     * Return an instance back to be reused.
1148     * <p>
1149     * <strong>Note:</strong> You must not touch the object after calling this function.
1150     *
1151     * @throws IllegalStateException If the info is already recycled.
1152     */
1153    public void recycle() {
1154        IMPL.recycle(mInfo);
1155    }
1156
1157    @Override
1158    public int hashCode() {
1159        return (mInfo == null) ? 0 : mInfo.hashCode();
1160    }
1161
1162    @Override
1163    public boolean equals(Object obj) {
1164        if (this == obj) {
1165            return true;
1166        }
1167        if (obj == null) {
1168            return false;
1169        }
1170        if (getClass() != obj.getClass()) {
1171            return false;
1172        }
1173        AccessibilityNodeInfoCompat other = (AccessibilityNodeInfoCompat) obj;
1174        if (mInfo == null) {
1175            if (other.mInfo != null) {
1176                return false;
1177            }
1178        } else if (!mInfo.equals(other.mInfo)) {
1179            return false;
1180        }
1181        return true;
1182    }
1183}
1184