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