1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.view.accessibility;
18
19import android.os.Build;
20import android.os.Parcelable;
21import android.view.View;
22
23import java.util.Collections;
24import java.util.List;
25
26/**
27 * Helper for accessing {@link android.view.accessibility.AccessibilityRecord}
28 * introduced after API level 4 in a backwards compatible fashion.
29 */
30public class AccessibilityRecordCompat {
31
32    static interface AccessibilityRecordImpl {
33        public Object obtain();
34        public Object obtain(Object record);
35        public void setSource(Object record, View source);
36        public void setSource(Object record, View root, int virtualDescendantId);
37        public AccessibilityNodeInfoCompat getSource(Object record);
38        public int getWindowId(Object record);
39        public boolean isChecked(Object record);
40        public void setChecked(Object record, boolean isChecked);
41        public boolean isEnabled(Object record);
42        public void setEnabled(Object record, boolean isEnabled);
43        public boolean isPassword(Object record);
44        public void setPassword(Object record, boolean isPassword);
45        public boolean isFullScreen(Object record);
46        public void setFullScreen(Object record, boolean isFullScreen);
47        public boolean isScrollable(Object record);
48        public void setScrollable(Object record, boolean scrollable);
49        public int getItemCount(Object record);
50        public void setItemCount(Object record, int itemCount);
51        public int getCurrentItemIndex(Object record);
52        public void setCurrentItemIndex(Object record, int currentItemIndex);
53        public int getFromIndex(Object record);
54        public void setFromIndex(Object record, int fromIndex);
55        public int getToIndex(Object record);
56        public void setToIndex(Object record, int toIndex);
57        public int getScrollX(Object record);
58        public void setScrollX(Object record, int scrollX);
59        public int getScrollY(Object record);
60        public void setScrollY(Object record, int scrollY);
61        public int getMaxScrollX(Object record);
62        public void setMaxScrollX(Object record, int maxScrollX);
63        public int getMaxScrollY(Object record);
64        public void setMaxScrollY(Object record, int maxScrollY);
65        public int getAddedCount(Object record);
66        public void setAddedCount(Object record, int addedCount);
67        public int getRemovedCount(Object record);
68        public void setRemovedCount(Object record, int removedCount);
69        public CharSequence getClassName(Object record);
70        public void setClassName(Object record, CharSequence className);
71        public List<CharSequence> getText(Object record);
72        public CharSequence getBeforeText(Object record);
73        public void setBeforeText(Object record, CharSequence beforeText);
74        public CharSequence getContentDescription(Object record);
75        public void setContentDescription(Object record, CharSequence contentDescription);
76        public Parcelable getParcelableData(Object record);
77        public void setParcelableData(Object record, Parcelable parcelableData);
78        public void recycle(Object record);
79    }
80
81    static class AccessibilityRecordStubImpl implements AccessibilityRecordImpl {
82        public Object obtain() {
83            return null;
84        }
85
86        public Object obtain(Object record) {
87            return null;
88        }
89
90        public int getAddedCount(Object record) {
91            return 0;
92        }
93
94        public CharSequence getBeforeText(Object record) {
95            return null;
96        }
97
98        public CharSequence getClassName(Object record) {
99            return null;
100        }
101
102        public CharSequence getContentDescription(Object record) {
103            return null;
104        }
105
106        public int getCurrentItemIndex(Object record) {
107            return 0;
108        }
109
110        public int getFromIndex(Object record) {
111            return 0;
112        }
113
114        public int getItemCount(Object record) {
115            return 0;
116        }
117
118        public int getMaxScrollX(Object record) {
119            return 0;
120        }
121
122        public int getMaxScrollY(Object record) {
123            return 0;
124        }
125
126        public Parcelable getParcelableData(Object record) {
127            return null;
128        }
129
130        public int getRemovedCount(Object record) {
131            return 0;
132        }
133
134        public int getScrollX(Object record) {
135            return 0;
136        }
137
138        public int getScrollY(Object record) {
139            return 0;
140        }
141
142        public AccessibilityNodeInfoCompat getSource(Object record) {
143            return null;
144        }
145
146        public List<CharSequence> getText(Object record) {
147            return Collections.emptyList();
148        }
149
150        public int getToIndex(Object record) {
151            return 0;
152        }
153
154        public int getWindowId(Object record) {
155            return 0;
156        }
157
158        public boolean isChecked(Object record) {
159            return false;
160        }
161
162        public boolean isEnabled(Object record) {
163            return false;
164        }
165
166        public boolean isFullScreen(Object record) {
167            return false;
168        }
169
170        public boolean isPassword(Object record) {
171            return false;
172        }
173
174        public boolean isScrollable(Object record) {
175            return false;
176        }
177
178        public void recycle(Object record) {
179
180        }
181
182        public void setAddedCount(Object record, int addedCount) {
183
184        }
185
186        public void setBeforeText(Object record, CharSequence beforeText) {
187
188        }
189
190        public void setChecked(Object record, boolean isChecked) {
191
192        }
193
194        public void setClassName(Object record, CharSequence className) {
195
196        }
197
198        public void setContentDescription(Object record, CharSequence contentDescription) {
199
200        }
201
202        public void setCurrentItemIndex(Object record, int currentItemIndex) {
203
204        }
205
206        public void setEnabled(Object record, boolean isEnabled) {
207
208        }
209
210        public void setFromIndex(Object record, int fromIndex) {
211
212        }
213
214        public void setFullScreen(Object record, boolean isFullScreen) {
215
216        }
217
218        public void setItemCount(Object record, int itemCount) {
219
220        }
221
222        public void setMaxScrollX(Object record, int maxScrollX) {
223
224        }
225
226        public void setMaxScrollY(Object record, int maxScrollY) {
227
228        }
229
230        public void setParcelableData(Object record, Parcelable parcelableData) {
231
232        }
233
234        public void setPassword(Object record, boolean isPassword) {
235
236        }
237
238        public void setRemovedCount(Object record, int removedCount) {
239
240        }
241
242        public void setScrollX(Object record, int scrollX) {
243
244        }
245
246        public void setScrollY(Object record, int scrollY) {
247
248        }
249
250        public void setScrollable(Object record, boolean scrollable) {
251
252        }
253
254        public void setSource(Object record, View source) {
255
256        }
257
258        public void setSource(Object record, View root, int virtualDescendantId) {
259
260        }
261
262        public void setToIndex(Object record, int toIndex) {
263
264        }
265    }
266
267    static class AccessibilityRecordIcsImpl extends AccessibilityRecordStubImpl {
268        @Override
269        public Object obtain() {
270            return AccessibilityRecordCompatIcs.obtain();
271        }
272
273        @Override
274        public Object obtain(Object record) {
275            return AccessibilityRecordCompatIcs.obtain(record);
276        }
277
278        @Override
279        public int getAddedCount(Object record) {
280            return AccessibilityRecordCompatIcs.getAddedCount(record);
281        }
282
283        @Override
284        public CharSequence getBeforeText(Object record) {
285            return AccessibilityRecordCompatIcs.getBeforeText(record);
286        }
287
288        @Override
289        public CharSequence getClassName(Object record) {
290            return AccessibilityRecordCompatIcs.getClassName(record);
291        }
292
293        @Override
294        public CharSequence getContentDescription(Object record) {
295            return AccessibilityRecordCompatIcs.getContentDescription(record);
296        }
297
298        @Override
299        public int getCurrentItemIndex(Object record) {
300            return AccessibilityRecordCompatIcs.getCurrentItemIndex(record);
301        }
302
303        @Override
304        public int getFromIndex(Object record) {
305            return AccessibilityRecordCompatIcs.getFromIndex(record);
306        }
307
308        @Override
309        public int getItemCount(Object record) {
310            return AccessibilityRecordCompatIcs.getItemCount(record);
311        }
312
313        @Override
314        public Parcelable getParcelableData(Object record) {
315            return AccessibilityRecordCompatIcs.getParcelableData(record);
316        }
317
318        @Override
319        public int getRemovedCount(Object record) {
320            return AccessibilityRecordCompatIcs.getRemovedCount(record);
321        }
322
323        @Override
324        public int getScrollX(Object record) {
325            return AccessibilityRecordCompatIcs.getScrollX(record);
326        }
327
328        @Override
329        public int getScrollY(Object record) {
330            return AccessibilityRecordCompatIcs.getScrollY(record);
331        }
332
333        @Override
334        public AccessibilityNodeInfoCompat getSource(Object record) {
335            return AccessibilityNodeInfoCompat.wrapNonNullInstance(
336                    AccessibilityRecordCompatIcs.getSource(record));
337        }
338
339        @Override
340        public List<CharSequence> getText(Object record) {
341            return AccessibilityRecordCompatIcs.getText(record);
342        }
343
344        @Override
345        public int getToIndex(Object record) {
346            return AccessibilityRecordCompatIcs.getToIndex(record);
347        }
348
349        @Override
350        public int getWindowId(Object record) {
351            return AccessibilityRecordCompatIcs.getWindowId(record);
352        }
353
354        @Override
355        public boolean isChecked(Object record) {
356            return AccessibilityRecordCompatIcs.isChecked(record);
357        }
358
359        @Override
360        public boolean isEnabled(Object record) {
361            return AccessibilityRecordCompatIcs.isEnabled(record);
362        }
363
364        @Override
365        public boolean isFullScreen(Object record) {
366            return AccessibilityRecordCompatIcs.isFullScreen(record);
367        }
368
369        @Override
370        public boolean isPassword(Object record) {
371            return AccessibilityRecordCompatIcs.isPassword(record);
372        }
373
374        @Override
375        public boolean isScrollable(Object record) {
376            return AccessibilityRecordCompatIcs.isScrollable(record);
377        }
378
379        @Override
380        public void recycle(Object record) {
381            AccessibilityRecordCompatIcs.recycle(record);
382        }
383
384        @Override
385        public void setAddedCount(Object record, int addedCount) {
386            AccessibilityRecordCompatIcs.setAddedCount(record, addedCount);
387        }
388
389        @Override
390        public void setBeforeText(Object record, CharSequence beforeText) {
391            AccessibilityRecordCompatIcs.setBeforeText(record, beforeText);
392        }
393
394        @Override
395        public void setChecked(Object record, boolean isChecked) {
396            AccessibilityRecordCompatIcs.setChecked(record, isChecked);
397        }
398
399        @Override
400        public void setClassName(Object record, CharSequence className) {
401            AccessibilityRecordCompatIcs.setClassName(record, className);
402        }
403
404        @Override
405        public void setContentDescription(Object record, CharSequence contentDescription) {
406            AccessibilityRecordCompatIcs.setContentDescription(record, contentDescription);
407        }
408
409        @Override
410        public void setCurrentItemIndex(Object record, int currentItemIndex) {
411            AccessibilityRecordCompatIcs.setCurrentItemIndex(record, currentItemIndex);
412        }
413
414        @Override
415        public void setEnabled(Object record, boolean isEnabled) {
416            AccessibilityRecordCompatIcs.setEnabled(record, isEnabled);
417        }
418
419        @Override
420        public void setFromIndex(Object record, int fromIndex) {
421            AccessibilityRecordCompatIcs.setFromIndex(record, fromIndex);
422        }
423
424        @Override
425        public void setFullScreen(Object record, boolean isFullScreen) {
426            AccessibilityRecordCompatIcs.setFullScreen(record, isFullScreen);
427        }
428
429        @Override
430        public void setItemCount(Object record, int itemCount) {
431            AccessibilityRecordCompatIcs.setItemCount(record, itemCount);
432        }
433
434        @Override
435        public void setParcelableData(Object record, Parcelable parcelableData) {
436            AccessibilityRecordCompatIcs.setParcelableData(record, parcelableData);
437        }
438
439        @Override
440        public void setPassword(Object record, boolean isPassword) {
441            AccessibilityRecordCompatIcs.setPassword(record, isPassword);
442        }
443
444        @Override
445        public void setRemovedCount(Object record, int removedCount) {
446            AccessibilityRecordCompatIcs.setRemovedCount(record, removedCount);
447        }
448
449        @Override
450        public void setScrollX(Object record, int scrollX) {
451            AccessibilityRecordCompatIcs.setScrollX(record, scrollX);
452        }
453
454        @Override
455        public void setScrollY(Object record, int scrollY) {
456            AccessibilityRecordCompatIcs.setScrollY(record, scrollY);
457        }
458
459        @Override
460        public void setScrollable(Object record, boolean scrollable) {
461            AccessibilityRecordCompatIcs.setScrollable(record, scrollable);
462        }
463
464        @Override
465        public void setSource(Object record, View source) {
466            AccessibilityRecordCompatIcs.setSource(record, source);
467        }
468
469        @Override
470        public void setToIndex(Object record, int toIndex) {
471            AccessibilityRecordCompatIcs.setToIndex(record, toIndex);
472        }
473    }
474
475    static class AccessibilityRecordIcsMr1Impl extends AccessibilityRecordIcsImpl {
476        @Override
477        public int getMaxScrollX(Object record) {
478            return AccessibilityRecordCompatIcsMr1.getMaxScrollX(record);
479        }
480
481        @Override
482        public int getMaxScrollY(Object record) {
483            return AccessibilityRecordCompatIcsMr1.getMaxScrollY(record);
484        }
485
486        @Override
487        public void setMaxScrollX(Object record, int maxScrollX) {
488            AccessibilityRecordCompatIcsMr1.setMaxScrollX(record, maxScrollX);
489        }
490
491        @Override
492        public void setMaxScrollY(Object record, int maxScrollY) {
493            AccessibilityRecordCompatIcsMr1.setMaxScrollY(record, maxScrollY);
494        }
495    }
496
497    static class AccessibilityRecordJellyBeanImpl extends AccessibilityRecordIcsMr1Impl {
498        @Override
499        public void setSource(Object record, View root, int virtualDescendantId) {
500            AccessibilityRecordCompatJellyBean.setSource(record, root, virtualDescendantId);
501        }
502    }
503
504    static {
505        if (Build.VERSION.SDK_INT >= 16) { // JellyBean
506            IMPL = new AccessibilityRecordJellyBeanImpl();
507        } else if (Build.VERSION.SDK_INT >= 15) {  // ICS MR1
508            IMPL = new AccessibilityRecordIcsMr1Impl();
509        } else if (Build.VERSION.SDK_INT >= 14) { // ICS
510            IMPL = new AccessibilityRecordIcsImpl();
511        } else {
512            IMPL = new AccessibilityRecordStubImpl();
513        }
514    }
515
516    private static final AccessibilityRecordImpl IMPL;
517
518    private final Object mRecord;
519
520    /*
521     * Hide constructor from clients.
522     */
523    public AccessibilityRecordCompat(Object record) {
524        mRecord = record;
525    }
526
527    /**
528     * @return The wrapped implementation.
529     */
530    public Object getImpl() {
531        return mRecord;
532    }
533
534    /**
535     * Returns a cached instance if such is available or a new one is
536     * instantiated. The instance is initialized with data from the
537     * given record.
538     *
539     * @return An instance.
540     */
541    public static AccessibilityRecordCompat obtain(AccessibilityRecordCompat record) {
542       return new AccessibilityRecordCompat(IMPL.obtain(record.mRecord));
543    }
544
545    /**
546     * Returns a cached instance if such is available or a new one is
547     * instantiated.
548     *
549     * @return An instance.
550     */
551    public static AccessibilityRecordCompat obtain() {
552        return new AccessibilityRecordCompat(IMPL.obtain());
553    }
554
555    /**
556     * Sets the event source.
557     *
558     * @param source The source.
559     *
560     * @throws IllegalStateException If called from an AccessibilityService.
561     */
562    public void setSource(View source) {
563        IMPL.setSource(mRecord, source);
564    }
565
566    /**
567     * Sets the source to be a virtual descendant of the given <code>root</code>.
568     * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
569     * is set as the source.
570     * <p>
571     * A virtual descendant is an imaginary View that is reported as a part of the view
572     * hierarchy for accessibility purposes. This enables custom views that draw complex
573     * content to report them selves as a tree of virtual views, thus conveying their
574     * logical structure.
575     * </p>
576     *
577     * @param root The root of the virtual subtree.
578     * @param virtualDescendantId The id of the virtual descendant.
579     */
580    public void setSource(View root, int virtualDescendantId) {
581        IMPL.setSource(mRecord, root, virtualDescendantId);
582    }
583
584    /**
585     * Gets the {@link android.view.accessibility.AccessibilityNodeInfo} of
586     * the event source.
587     * <p>
588     * <strong>Note:</strong> It is a client responsibility to recycle the
589     * received info by calling
590     * {@link android.view.accessibility.AccessibilityNodeInfo#recycle()
591     * AccessibilityNodeInfo#recycle()} to avoid creating of multiple instances.
592     *</p>
593     *
594     * @return The info of the source.
595     */
596    public AccessibilityNodeInfoCompat getSource() {
597        return IMPL.getSource(mRecord);
598    }
599
600    /**
601     * Gets the id of the window from which the event comes from.
602     *
603     * @return The window id.
604     */
605    public int getWindowId() {
606        return IMPL.getWindowId(mRecord);
607    }
608
609    /**
610     * Gets if the source is checked.
611     *
612     * @return True if the view is checked, false otherwise.
613     */
614    public boolean isChecked() {
615        return IMPL.isChecked(mRecord);
616    }
617
618    /**
619     * Sets if the source is checked.
620     *
621     * @param isChecked True if the view is checked, false otherwise.
622     *
623     * @throws IllegalStateException If called from an AccessibilityService.
624     */
625    public void setChecked(boolean isChecked) {
626        IMPL.setChecked(mRecord, isChecked);
627    }
628
629    /**
630     * Gets if the source is enabled.
631     *
632     * @return True if the view is enabled, false otherwise.
633     */
634    public boolean isEnabled() {
635        return IMPL.isEnabled(mRecord);
636    }
637
638    /**
639     * Sets if the source is enabled.
640     *
641     * @param isEnabled True if the view is enabled, false otherwise.
642     *
643     * @throws IllegalStateException If called from an AccessibilityService.
644     */
645    public void setEnabled(boolean isEnabled) {
646        IMPL.setEnabled(mRecord, isEnabled);
647    }
648
649    /**
650     * Gets if the source is a password field.
651     *
652     * @return True if the view is a password field, false otherwise.
653     */
654    public boolean isPassword() {
655        return IMPL.isPassword(mRecord);
656    }
657
658    /**
659     * Sets if the source is a password field.
660     *
661     * @param isPassword True if the view is a password field, false otherwise.
662     *
663     * @throws IllegalStateException If called from an AccessibilityService.
664     */
665    public void setPassword(boolean isPassword) {
666        IMPL.setPassword(mRecord, isPassword);
667    }
668
669    /**
670     * Gets if the source is taking the entire screen.
671     *
672     * @return True if the source is full screen, false otherwise.
673     */
674    public boolean isFullScreen() {
675        return IMPL.isFullScreen(mRecord);
676    }
677
678    /**
679     * Sets if the source is taking the entire screen.
680     *
681     * @param isFullScreen True if the source is full screen, false otherwise.
682     *
683     * @throws IllegalStateException If called from an AccessibilityService.
684     */
685    public void setFullScreen(boolean isFullScreen) {
686        IMPL.setFullScreen(mRecord, isFullScreen);
687    }
688
689    /**
690     * Gets if the source is scrollable.
691     *
692     * @return True if the source is scrollable, false otherwise.
693     */
694    public boolean isScrollable() {
695        return IMPL.isScrollable(mRecord);
696    }
697
698    /**
699     * Sets if the source is scrollable.
700     *
701     * @param scrollable True if the source is scrollable, false otherwise.
702     *
703     * @throws IllegalStateException If called from an AccessibilityService.
704     */
705    public void setScrollable(boolean scrollable) {
706        IMPL.setScrollable(mRecord, scrollable);
707    }
708
709    /**
710     * Gets the number of items that can be visited.
711     *
712     * @return The number of items.
713     */
714    public int getItemCount() {
715        return IMPL.getItemCount(mRecord);
716    }
717
718    /**
719     * Sets the number of items that can be visited.
720     *
721     * @param itemCount The number of items.
722     *
723     * @throws IllegalStateException If called from an AccessibilityService.
724     */
725    public void setItemCount(int itemCount) {
726        IMPL.setItemCount(mRecord, itemCount);
727    }
728
729    /**
730     * Gets the index of the source in the list of items the can be visited.
731     *
732     * @return The current item index.
733     */
734    public int getCurrentItemIndex() {
735        return IMPL.getCurrentItemIndex(mRecord);
736    }
737
738    /**
739     * Sets the index of the source in the list of items that can be visited.
740     *
741     * @param currentItemIndex The current item index.
742     *
743     * @throws IllegalStateException If called from an AccessibilityService.
744     */
745    public void setCurrentItemIndex(int currentItemIndex) {
746        IMPL.setCurrentItemIndex(mRecord, currentItemIndex);
747    }
748
749    /**
750     * Gets the index of the first character of the changed sequence,
751     * or the beginning of a text selection or the index of the first
752     * visible item when scrolling.
753     *
754     * @return The index of the first character or selection
755     *        start or the first visible item.
756     */
757    public int getFromIndex() {
758        return IMPL.getFromIndex(mRecord);
759    }
760
761    /**
762     * Sets the index of the first character of the changed sequence
763     * or the beginning of a text selection or the index of the first
764     * visible item when scrolling.
765     *
766     * @param fromIndex The index of the first character or selection
767     *        start or the first visible item.
768     *
769     * @throws IllegalStateException If called from an AccessibilityService.
770     */
771    public void setFromIndex(int fromIndex) {
772        IMPL.setFromIndex(mRecord, fromIndex);
773    }
774
775    /**
776     * Gets the index of text selection end or the index of the last
777     * visible item when scrolling.
778     *
779     * @return The index of selection end or last item index.
780     */
781    public int getToIndex() {
782        return IMPL.getToIndex(mRecord);
783    }
784
785    /**
786     * Sets the index of text selection end or the index of the last
787     * visible item when scrolling.
788     *
789     * @param toIndex The index of selection end or last item index.
790     */
791    public void setToIndex(int toIndex) {
792        IMPL.setToIndex(mRecord, toIndex);
793    }
794
795    /**
796     * Gets the scroll offset of the source left edge in pixels.
797     *
798     * @return The scroll.
799     */
800    public int getScrollX() {
801        return IMPL.getScrollX(mRecord);
802    }
803
804    /**
805     * Sets the scroll offset of the source left edge in pixels.
806     *
807     * @param scrollX The scroll.
808     */
809    public void setScrollX(int scrollX) {
810        IMPL.setScrollX(mRecord, scrollX);
811    }
812
813    /**
814     * Gets the scroll offset of the source top edge in pixels.
815     *
816     * @return The scroll.
817     */
818    public int getScrollY() {
819        return IMPL.getScrollY(mRecord);
820    }
821
822    /**
823     * Sets the scroll offset of the source top edge in pixels.
824     *
825     * @param scrollY The scroll.
826     */
827    public void setScrollY(int scrollY) {
828        IMPL.setScrollY(mRecord, scrollY);
829    }
830
831    /**
832     * Gets the max scroll offset of the source left edge in pixels.
833     *
834     * @return The max scroll.
835     */
836    public int getMaxScrollX() {
837        return IMPL.getMaxScrollX(mRecord);
838    }
839    /**
840     * Sets the max scroll offset of the source left edge in pixels.
841     *
842     * @param maxScrollX The max scroll.
843     */
844    public void setMaxScrollX(int maxScrollX) {
845        IMPL.setMaxScrollX(mRecord, maxScrollX);
846    }
847
848    /**
849     * Gets the max scroll offset of the source top edge in pixels.
850     *
851     * @return The max scroll.
852     */
853    public int getMaxScrollY() {
854        return IMPL.getMaxScrollY(mRecord);
855    }
856
857    /**
858     * Sets the max scroll offset of the source top edge in pixels.
859     *
860     * @param maxScrollY The max scroll.
861     */
862    public void setMaxScrollY(int maxScrollY) {
863        IMPL.setMaxScrollY(mRecord, maxScrollY);
864    }
865
866    /**
867     * Gets the number of added characters.
868     *
869     * @return The number of added characters.
870     */
871    public int getAddedCount() {
872        return IMPL.getAddedCount(mRecord);
873    }
874
875    /**
876     * Sets the number of added characters.
877     *
878     * @param addedCount The number of added characters.
879     *
880     * @throws IllegalStateException If called from an AccessibilityService.
881     */
882    public void setAddedCount(int addedCount) {
883        IMPL.setAddedCount(mRecord, addedCount);
884    }
885
886    /**
887     * Gets the number of removed characters.
888     *
889     * @return The number of removed characters.
890     */
891    public int getRemovedCount() {
892        return IMPL.getRemovedCount(mRecord);
893    }
894
895    /**
896     * Sets the number of removed characters.
897     *
898     * @param removedCount The number of removed characters.
899     *
900     * @throws IllegalStateException If called from an AccessibilityService.
901     */
902    public void setRemovedCount(int removedCount) {
903        IMPL.setRemovedCount(mRecord, removedCount);
904    }
905
906    /**
907     * Gets the class name of the source.
908     *
909     * @return The class name.
910     */
911    public CharSequence getClassName() {
912        return IMPL.getClassName(mRecord);
913    }
914
915    /**
916     * Sets the class name of the source.
917     *
918     * @param className The lass name.
919     *
920     * @throws IllegalStateException If called from an AccessibilityService.
921     */
922    public void setClassName(CharSequence className) {
923        IMPL.setClassName(mRecord, className);
924    }
925
926    /**
927     * Gets the text of the event. The index in the list represents the priority
928     * of the text. Specifically, the lower the index the higher the priority.
929     *
930     * @return The text.
931     */
932    public List<CharSequence> getText() {
933        return IMPL.getText(mRecord);
934    }
935
936    /**
937     * Sets the text before a change.
938     *
939     * @return The text before the change.
940     */
941    public CharSequence getBeforeText() {
942        return IMPL.getBeforeText(mRecord);
943    }
944
945    /**
946     * Sets the text before a change.
947     *
948     * @param beforeText The text before the change.
949     *
950     * @throws IllegalStateException If called from an AccessibilityService.
951     */
952    public void setBeforeText(CharSequence beforeText) {
953        IMPL.setBeforeText(mRecord, beforeText);
954    }
955
956    /**
957     * Gets the description of the source.
958     *
959     * @return The description.
960     */
961    public CharSequence getContentDescription() {
962        return IMPL.getContentDescription(mRecord);
963    }
964
965    /**
966     * Sets the description of the source.
967     *
968     * @param contentDescription The description.
969     *
970     * @throws IllegalStateException If called from an AccessibilityService.
971     */
972    public void setContentDescription(CharSequence contentDescription) {
973        IMPL.setContentDescription(mRecord, contentDescription);
974    }
975
976    /**
977     * Gets the {@link Parcelable} data.
978     *
979     * @return The parcelable data.
980     */
981    public Parcelable getParcelableData() {
982        return IMPL.getParcelableData(mRecord);
983    }
984
985    /**
986     * Sets the {@link Parcelable} data of the event.
987     *
988     * @param parcelableData The parcelable data.
989     *
990     * @throws IllegalStateException If called from an AccessibilityService.
991     */
992    public void setParcelableData(Parcelable parcelableData) {
993        IMPL.setParcelableData(mRecord, parcelableData);
994    }
995
996    /**
997     * Return an instance back to be reused.
998     * <p>
999     * <strong>Note:</strong> You must not touch the object after calling this
1000     * function.
1001     * </p>
1002     *
1003     * @throws IllegalStateException If the record is already recycled.
1004     */
1005    public void recycle() {
1006        IMPL.recycle(mRecord);
1007    }
1008
1009    @Override
1010    public int hashCode() {
1011        return (mRecord == null) ? 0 : mRecord.hashCode();
1012    }
1013
1014
1015    @Override
1016    public boolean equals(Object obj) {
1017        if (this == obj) {
1018            return true;
1019        }
1020        if (obj == null) {
1021            return false;
1022        }
1023        if (getClass() != obj.getClass()) {
1024            return false;
1025        }
1026        AccessibilityRecordCompat other = (AccessibilityRecordCompat) obj;
1027        if (mRecord == null) {
1028            if (other.mRecord != null) {
1029                return false;
1030            }
1031        } else if (!mRecord.equals(other.mRecord)) {
1032            return false;
1033        }
1034        return true;
1035    }
1036}
1037