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