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 androidx.core.view.accessibility;
18 
19 import android.os.Build;
20 import android.os.Parcelable;
21 import android.view.View;
22 import android.view.accessibility.AccessibilityEvent;
23 import android.view.accessibility.AccessibilityRecord;
24 
25 import androidx.annotation.NonNull;
26 
27 import java.util.List;
28 
29 /**
30  * Helper for accessing {@link AccessibilityRecord}.
31  */
32 public class AccessibilityRecordCompat {
33     private final AccessibilityRecord mRecord;
34 
35     /**
36      * @deprecated This is not type safe. If you want to modify an
37      * {@link AccessibilityEvent}'s properties defined in
38      * {@link android.view.accessibility.AccessibilityRecord} use
39      * {@link AccessibilityEventCompat#asRecord(AccessibilityEvent)}. This method will be removed
40      * in a subsequent release of the support library.
41      */
42     @Deprecated
AccessibilityRecordCompat(Object record)43     public AccessibilityRecordCompat(Object record) {
44         mRecord = (AccessibilityRecord) record;
45     }
46 
47     /**
48      * @return The wrapped implementation.
49      *
50      * @deprecated This method will be removed in a subsequent release of
51      * the support library.
52      */
53     @Deprecated
getImpl()54     public Object getImpl() {
55         return mRecord;
56     }
57 
58     /**
59      * Returns a cached instance if such is available or a new one is
60      * instantiated. The instance is initialized with data from the
61      * given record.
62      *
63      * @return An instance.
64      *
65      * @deprecated Use {@link AccessibilityRecord#obtain(AccessibilityRecord)} directly.
66      */
67     @Deprecated
obtain(AccessibilityRecordCompat record)68     public static AccessibilityRecordCompat obtain(AccessibilityRecordCompat record) {
69         return new AccessibilityRecordCompat(AccessibilityRecord.obtain(record.mRecord));
70     }
71 
72     /**
73      * Returns a cached instance if such is available or a new one is
74      * instantiated.
75      *
76      * @return An instance.
77      *
78      * @deprecated Use {@link AccessibilityRecord#obtain()} directly.
79      */
80     @Deprecated
obtain()81     public static AccessibilityRecordCompat obtain() {
82         return new AccessibilityRecordCompat(AccessibilityRecord.obtain());
83     }
84 
85     /**
86      * Sets the event source.
87      *
88      * @param source The source.
89      *
90      * @throws IllegalStateException If called from an AccessibilityService.
91      *
92      * @deprecated Use {@link AccessibilityRecord#setSource(View)} directly.
93      */
94     @Deprecated
setSource(View source)95     public void setSource(View source) {
96         mRecord.setSource(source);
97     }
98 
99     /**
100      * Sets the source to be a virtual descendant of the given <code>root</code>.
101      * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
102      * is set as the source.
103      * <p>
104      * A virtual descendant is an imaginary View that is reported as a part of the view
105      * hierarchy for accessibility purposes. This enables custom views that draw complex
106      * content to report them selves as a tree of virtual views, thus conveying their
107      * logical structure.
108      * </p>
109      *
110      * @param root The root of the virtual subtree.
111      * @param virtualDescendantId The id of the virtual descendant.
112      *
113      * @deprecated Use {@link #setSource(AccessibilityRecord, View, int)} instead.
114      */
115     @Deprecated
setSource(View root, int virtualDescendantId)116     public void setSource(View root, int virtualDescendantId) {
117         AccessibilityRecordCompat.setSource(mRecord, root, virtualDescendantId);
118     }
119 
120     /**
121      * Sets the source to be a virtual descendant of the given <code>root</code>.
122      * If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
123      * is set as the source.
124      * <p>
125      * A virtual descendant is an imaginary View that is reported as a part of the view
126      * hierarchy for accessibility purposes. This enables custom views that draw complex
127      * content to report them selves as a tree of virtual views, thus conveying their
128      * logical structure.
129      * </p>
130      *
131      * @param record The {@link AccessibilityRecord} instance to use.
132      * @param root The root of the virtual subtree.
133      * @param virtualDescendantId The id of the virtual descendant.
134      */
setSource(@onNull AccessibilityRecord record, View root, int virtualDescendantId)135     public static void setSource(@NonNull AccessibilityRecord record, View root,
136             int virtualDescendantId) {
137         if (Build.VERSION.SDK_INT >= 16) {
138             record.setSource(root, virtualDescendantId);
139         }
140     }
141 
142     /**
143      * Gets the {@link android.view.accessibility.AccessibilityNodeInfo} of
144      * the event source.
145      * <p>
146      * <strong>Note:</strong> It is a client responsibility to recycle the
147      * received info by calling
148      * {@link android.view.accessibility.AccessibilityNodeInfo#recycle()
149      * AccessibilityNodeInfo#recycle()} to avoid creating of multiple instances.
150      *</p>
151      *
152      * @return The info of the source.
153      *
154      * @deprecated Use {@link AccessibilityRecord#getSource()} directly.
155      */
156     @Deprecated
getSource()157     public AccessibilityNodeInfoCompat getSource() {
158         return AccessibilityNodeInfoCompat.wrapNonNullInstance(mRecord.getSource());
159     }
160 
161     /**
162      * Gets the id of the window from which the event comes from.
163      *
164      * @return The window id.
165      *
166      * @deprecated Use {@link AccessibilityRecord#getWindowId()} directly.
167      */
168     @Deprecated
getWindowId()169     public int getWindowId() {
170         return mRecord.getWindowId();
171     }
172 
173     /**
174      * Gets if the source is checked.
175      *
176      * @return True if the view is checked, false otherwise.
177      *
178      * @deprecated Use {@link AccessibilityRecord#isChecked()} directly.
179      */
180     @Deprecated
isChecked()181     public boolean isChecked() {
182         return mRecord.isChecked();
183     }
184 
185     /**
186      * Sets if the source is checked.
187      *
188      * @param isChecked True if the view is checked, false otherwise.
189      *
190      * @throws IllegalStateException If called from an AccessibilityService.
191      *
192      * @deprecated Use {@link AccessibilityRecord#setChecked(boolean)} directly.
193      */
194     @Deprecated
setChecked(boolean isChecked)195     public void setChecked(boolean isChecked) {
196         mRecord.setChecked(isChecked);
197     }
198 
199     /**
200      * Gets if the source is enabled.
201      *
202      * @return True if the view is enabled, false otherwise.
203      *
204      * @deprecated Use {@link AccessibilityRecord#isEnabled()} directly.
205      */
206     @Deprecated
isEnabled()207     public boolean isEnabled() {
208         return mRecord.isEnabled();
209     }
210 
211     /**
212      * Sets if the source is enabled.
213      *
214      * @param isEnabled True if the view is enabled, false otherwise.
215      *
216      * @throws IllegalStateException If called from an AccessibilityService.
217      *
218      * @deprecated Use {@link AccessibilityRecord#isEnabled()} directly.
219      */
220     @Deprecated
setEnabled(boolean isEnabled)221     public void setEnabled(boolean isEnabled) {
222         mRecord.setEnabled(isEnabled);
223     }
224 
225     /**
226      * Gets if the source is a password field.
227      *
228      * @return True if the view is a password field, false otherwise.
229      *
230      * @deprecated Use {@link AccessibilityRecord#isPassword()} directly.
231      */
232     @Deprecated
isPassword()233     public boolean isPassword() {
234         return mRecord.isPassword();
235     }
236 
237     /**
238      * Sets if the source is a password field.
239      *
240      * @param isPassword True if the view is a password field, false otherwise.
241      *
242      * @throws IllegalStateException If called from an AccessibilityService.
243      *
244      * @deprecated Use {@link AccessibilityRecord#setPassword(boolean)} directly.
245      */
246     @Deprecated
setPassword(boolean isPassword)247     public void setPassword(boolean isPassword) {
248         mRecord.setPassword(isPassword);
249     }
250 
251     /**
252      * Gets if the source is taking the entire screen.
253      *
254      * @return True if the source is full screen, false otherwise.
255      *
256      * @deprecated Use {@link AccessibilityRecord#isFullScreen()} directly.
257      */
258     @Deprecated
isFullScreen()259     public boolean isFullScreen() {
260         return mRecord.isFullScreen();
261     }
262 
263     /**
264      * Sets if the source is taking the entire screen.
265      *
266      * @param isFullScreen True if the source is full screen, false otherwise.
267      *
268      * @throws IllegalStateException If called from an AccessibilityService.
269      *
270      * @deprecated Use {@link AccessibilityRecord#setFullScreen(boolean)} directly.
271      */
272     @Deprecated
setFullScreen(boolean isFullScreen)273     public void setFullScreen(boolean isFullScreen) {
274         mRecord.setFullScreen(isFullScreen);
275     }
276 
277     /**
278      * Gets if the source is scrollable.
279      *
280      * @return True if the source is scrollable, false otherwise.
281      *
282      * @deprecated Use {@link AccessibilityRecord#isScrollable()} directly.
283      */
284     @Deprecated
isScrollable()285     public boolean isScrollable() {
286         return mRecord.isScrollable();
287     }
288 
289     /**
290      * Sets if the source is scrollable.
291      *
292      * @param scrollable True if the source is scrollable, false otherwise.
293      *
294      * @throws IllegalStateException If called from an AccessibilityService.
295      *
296      * @deprecated Use {@link AccessibilityRecord#setScrollable(boolean)} directly.
297      */
298     @Deprecated
setScrollable(boolean scrollable)299     public void setScrollable(boolean scrollable) {
300         mRecord.setScrollable(scrollable);
301     }
302 
303     /**
304      * Gets the number of items that can be visited.
305      *
306      * @return The number of items.
307      *
308      * @deprecated Use {@link AccessibilityRecord#getItemCount()} directly.
309      */
310     @Deprecated
getItemCount()311     public int getItemCount() {
312         return mRecord.getItemCount();
313     }
314 
315     /**
316      * Sets the number of items that can be visited.
317      *
318      * @param itemCount The number of items.
319      *
320      * @throws IllegalStateException If called from an AccessibilityService.
321      *
322      * @deprecated Use {@link AccessibilityRecord#setItemCount(int)} directly.
323      */
324     @Deprecated
setItemCount(int itemCount)325     public void setItemCount(int itemCount) {
326         mRecord.setItemCount(itemCount);
327     }
328 
329     /**
330      * Gets the index of the source in the list of items the can be visited.
331      *
332      * @return The current item index.
333      *
334      * @deprecated Use {@link AccessibilityRecord#getCurrentItemIndex()} directly.
335      */
336     @Deprecated
getCurrentItemIndex()337     public int getCurrentItemIndex() {
338         return mRecord.getCurrentItemIndex();
339     }
340 
341     /**
342      * Sets the index of the source in the list of items that can be visited.
343      *
344      * @param currentItemIndex The current item index.
345      *
346      * @throws IllegalStateException If called from an AccessibilityService.
347      *
348      * @deprecated Use {@link AccessibilityRecord#setCurrentItemIndex(int)} directly.
349      */
350     @Deprecated
setCurrentItemIndex(int currentItemIndex)351     public void setCurrentItemIndex(int currentItemIndex) {
352         mRecord.setCurrentItemIndex(currentItemIndex);
353     }
354 
355     /**
356      * Gets the index of the first character of the changed sequence,
357      * or the beginning of a text selection or the index of the first
358      * visible item when scrolling.
359      *
360      * @return The index of the first character or selection
361      *        start or the first visible item.
362      *
363      * @deprecated Use {@link AccessibilityRecord#getFromIndex()} directly.
364      */
365     @Deprecated
getFromIndex()366     public int getFromIndex() {
367         return mRecord.getFromIndex();
368     }
369 
370     /**
371      * Sets the index of the first character of the changed sequence
372      * or the beginning of a text selection or the index of the first
373      * visible item when scrolling.
374      *
375      * @param fromIndex The index of the first character or selection
376      *        start or the first visible item.
377      *
378      * @throws IllegalStateException If called from an AccessibilityService.
379      *
380      * @deprecated Use {@link AccessibilityRecord#setFromIndex(int)} directly.
381      */
382     @Deprecated
setFromIndex(int fromIndex)383     public void setFromIndex(int fromIndex) {
384         mRecord.setFromIndex(fromIndex);
385     }
386 
387     /**
388      * Gets the index of text selection end or the index of the last
389      * visible item when scrolling.
390      *
391      * @return The index of selection end or last item index.
392      *
393      * @deprecated Use {@link AccessibilityRecord#getToIndex()} directly.
394      */
395     @Deprecated
getToIndex()396     public int getToIndex() {
397         return mRecord.getToIndex();
398     }
399 
400     /**
401      * Sets the index of text selection end or the index of the last
402      * visible item when scrolling.
403      *
404      * @param toIndex The index of selection end or last item index.
405      *
406      * @deprecated Use {@link AccessibilityRecord#setToIndex(int)} directly.
407      */
408     @Deprecated
setToIndex(int toIndex)409     public void setToIndex(int toIndex) {
410         mRecord.setToIndex(toIndex);
411     }
412 
413     /**
414      * Gets the scroll offset of the source left edge in pixels.
415      *
416      * @return The scroll.
417      *
418      * @deprecated Use {@link AccessibilityRecord#getScrollX()} directly.
419      */
420     @Deprecated
getScrollX()421     public int getScrollX() {
422         return mRecord.getScrollX();
423     }
424 
425     /**
426      * Sets the scroll offset of the source left edge in pixels.
427      *
428      * @param scrollX The scroll.
429      *
430      * @deprecated Use {@link AccessibilityRecord#setScrollX(int)} directly.
431      */
432     @Deprecated
setScrollX(int scrollX)433     public void setScrollX(int scrollX) {
434         mRecord.setScrollX(scrollX);
435     }
436 
437     /**
438      * Gets the scroll offset of the source top edge in pixels.
439      *
440      * @return The scroll.
441      *
442      * @deprecated Use {@link AccessibilityRecord#getScrollY()} directly.
443      */
444     @Deprecated
getScrollY()445     public int getScrollY() {
446         return mRecord.getScrollY();
447     }
448 
449     /**
450      * Sets the scroll offset of the source top edge in pixels.
451      *
452      * @param scrollY The scroll.
453      *
454      * @deprecated Use {@link AccessibilityRecord#setScrollY(int)} directly.
455      */
456     @Deprecated
setScrollY(int scrollY)457     public void setScrollY(int scrollY) {
458         mRecord.setScrollY(scrollY);
459     }
460 
461     /**
462      * Gets the max scroll offset of the source left edge in pixels.
463      *
464      * @return The max scroll.
465      *
466      * @deprecated Use {@link #getMaxScrollX(AccessibilityRecord)} instead.
467      */
468     @Deprecated
getMaxScrollX()469     public int getMaxScrollX() {
470         return AccessibilityRecordCompat.getMaxScrollX(mRecord);
471     }
472 
473     /**
474      * Gets the max scroll offset of the source left edge in pixels.
475      *
476      * @param record The {@link AccessibilityRecord} instance to use.
477      * @return The max scroll.
478      */
getMaxScrollX(AccessibilityRecord record)479     public static int getMaxScrollX(AccessibilityRecord record) {
480         if (Build.VERSION.SDK_INT >= 15) {
481             return record.getMaxScrollX();
482         } else {
483             return 0;
484         }
485     }
486 
487     /**
488      * Sets the max scroll offset of the source left edge in pixels.
489      *
490      * @param maxScrollX The max scroll.
491      *
492      * @deprecated Use {@link #setMaxScrollX(AccessibilityRecord, int)} instead.
493      */
494     @Deprecated
setMaxScrollX(int maxScrollX)495     public void setMaxScrollX(int maxScrollX) {
496         AccessibilityRecordCompat.setMaxScrollX(mRecord, maxScrollX);
497     }
498 
499     /**
500      * Sets the max scroll offset of the source left edge in pixels.
501      *
502      * @param record The {@link AccessibilityRecord} instance to use.
503      * @param maxScrollX The max scroll.
504      */
setMaxScrollX(AccessibilityRecord record, int maxScrollX)505     public static void setMaxScrollX(AccessibilityRecord record, int maxScrollX) {
506         if (Build.VERSION.SDK_INT >= 15) {
507             record.setMaxScrollX(maxScrollX);
508         }
509     }
510 
511     /**
512      * Gets the max scroll offset of the source top edge in pixels.
513      *
514      * @return The max scroll.
515      *
516      * @deprecated Use {@link #getMaxScrollY(AccessibilityRecord)} instead.
517      */
518     @Deprecated
getMaxScrollY()519     public int getMaxScrollY() {
520         return AccessibilityRecordCompat.getMaxScrollY(mRecord);
521     }
522 
523     /**
524      * Gets the max scroll offset of the source top edge in pixels.
525      *
526      * @param record The {@link AccessibilityRecord} instance to use.
527      * @return The max scroll.
528      */
getMaxScrollY(AccessibilityRecord record)529     public static int getMaxScrollY(AccessibilityRecord record) {
530         if (Build.VERSION.SDK_INT >= 15) {
531             return record.getMaxScrollY();
532         } else {
533             return 0;
534         }
535     }
536 
537     /**
538      * Sets the max scroll offset of the source top edge in pixels.
539      *
540      * @param maxScrollY The max scroll.
541      *
542      * @deprecated Use {@link #setMaxScrollY(AccessibilityRecord, int)} instead.
543      */
544     @Deprecated
setMaxScrollY(int maxScrollY)545     public void setMaxScrollY(int maxScrollY) {
546         AccessibilityRecordCompat.setMaxScrollY(mRecord, maxScrollY);
547     }
548 
549     /**
550      * Sets the max scroll offset of the source top edge in pixels.
551      *
552      * @param record The {@link AccessibilityRecord} instance to use.
553      * @param maxScrollY The max scroll.
554      */
setMaxScrollY(AccessibilityRecord record, int maxScrollY)555     public static void setMaxScrollY(AccessibilityRecord record, int maxScrollY) {
556         if (Build.VERSION.SDK_INT >= 15) {
557             record.setMaxScrollY(maxScrollY);
558         }
559     }
560 
561     /**
562      * Gets the number of added characters.
563      *
564      * @return The number of added characters.
565      *
566      * @deprecated Use {@link AccessibilityRecord#getAddedCount()} directly.
567      */
568     @Deprecated
getAddedCount()569     public int getAddedCount() {
570         return mRecord.getAddedCount();
571     }
572 
573     /**
574      * Sets the number of added characters.
575      *
576      * @param addedCount The number of added characters.
577      *
578      * @throws IllegalStateException If called from an AccessibilityService.
579      *
580      * @deprecated Use {@link AccessibilityRecord#setAddedCount(int)} directly.
581      */
582     @Deprecated
setAddedCount(int addedCount)583     public void setAddedCount(int addedCount) {
584         mRecord.setAddedCount(addedCount);
585     }
586 
587     /**
588      * Gets the number of removed characters.
589      *
590      * @return The number of removed characters.
591      *
592      * @deprecated Use {@link AccessibilityRecord#getRemovedCount()} directly.
593      */
594     @Deprecated
getRemovedCount()595     public int getRemovedCount() {
596         return mRecord.getRemovedCount();
597     }
598 
599     /**
600      * Sets the number of removed characters.
601      *
602      * @param removedCount The number of removed characters.
603      *
604      * @throws IllegalStateException If called from an AccessibilityService.
605      *
606      * @deprecated Use {@link AccessibilityRecord#setRemovedCount(int)} directly.
607      */
608     @Deprecated
setRemovedCount(int removedCount)609     public void setRemovedCount(int removedCount) {
610         mRecord.setRemovedCount(removedCount);
611     }
612 
613     /**
614      * Gets the class name of the source.
615      *
616      * @return The class name.
617      *
618      * @deprecated Use {@link AccessibilityRecord#getClassName()} directly.
619      */
620     @Deprecated
getClassName()621     public CharSequence getClassName() {
622         return mRecord.getClassName();
623     }
624 
625     /**
626      * Sets the class name of the source.
627      *
628      * @param className The lass name.
629      *
630      * @throws IllegalStateException If called from an AccessibilityService.
631      *
632      * @deprecated Use {@link AccessibilityRecord#setClassName(CharSequence)} directly.
633      */
634     @Deprecated
setClassName(CharSequence className)635     public void setClassName(CharSequence className) {
636         mRecord.setClassName(className);
637     }
638 
639     /**
640      * Gets the text of the event. The index in the list represents the priority
641      * of the text. Specifically, the lower the index the higher the priority.
642      *
643      * @return The text.
644      *
645      * @deprecated Use {@link AccessibilityRecord#getText()} directly.
646      */
647     @Deprecated
getText()648     public List<CharSequence> getText() {
649         return mRecord.getText();
650     }
651 
652     /**
653      * Sets the text before a change.
654      *
655      * @return The text before the change.
656      *
657      * @deprecated Use {@link AccessibilityRecord#getBeforeText()} directly.
658      */
659     @Deprecated
getBeforeText()660     public CharSequence getBeforeText() {
661         return mRecord.getBeforeText();
662     }
663 
664     /**
665      * Sets the text before a change.
666      *
667      * @param beforeText The text before the change.
668      *
669      * @throws IllegalStateException If called from an AccessibilityService.
670      *
671      * @deprecated Use {@link AccessibilityRecord#setBeforeText(CharSequence)} directly.
672      */
673     @Deprecated
setBeforeText(CharSequence beforeText)674     public void setBeforeText(CharSequence beforeText) {
675         mRecord.setBeforeText(beforeText);
676     }
677 
678     /**
679      * Gets the description of the source.
680      *
681      * @return The description.
682      *
683      * @deprecated Use {@link AccessibilityRecord#getContentDescription()} directly.
684      */
685     @Deprecated
getContentDescription()686     public CharSequence getContentDescription() {
687         return mRecord.getContentDescription();
688     }
689 
690     /**
691      * Sets the description of the source.
692      *
693      * @param contentDescription The description.
694      *
695      * @throws IllegalStateException If called from an AccessibilityService.
696      *
697      * @deprecated Use {@link AccessibilityRecord#setContentDescription(CharSequence)} directly.
698      */
699     @Deprecated
setContentDescription(CharSequence contentDescription)700     public void setContentDescription(CharSequence contentDescription) {
701         mRecord.setContentDescription(contentDescription);
702     }
703 
704     /**
705      * Gets the {@link Parcelable} data.
706      *
707      * @return The parcelable data.
708      *
709      * @deprecated Use {@link AccessibilityRecord#getParcelableData()} directly.
710      */
711     @Deprecated
getParcelableData()712     public Parcelable getParcelableData() {
713         return mRecord.getParcelableData();
714     }
715 
716     /**
717      * Sets the {@link Parcelable} data of the event.
718      *
719      * @param parcelableData The parcelable data.
720      *
721      * @throws IllegalStateException If called from an AccessibilityService.
722      *
723      * @deprecated Use {@link AccessibilityRecord#setParcelableData(Parcelable)} directly.
724      */
725     @Deprecated
setParcelableData(Parcelable parcelableData)726     public void setParcelableData(Parcelable parcelableData) {
727         mRecord.setParcelableData(parcelableData);
728     }
729 
730     /**
731      * Return an instance back to be reused.
732      * <p>
733      * <strong>Note:</strong> You must not touch the object after calling this
734      * function.
735      * </p>
736      *
737      * @throws IllegalStateException If the record is already recycled.
738      *
739      * @deprecated Use {@link AccessibilityRecord#recycle()} directly.
740      */
741     @Deprecated
recycle()742     public void recycle() {
743         mRecord.recycle();
744     }
745 
746     /**
747      * @deprecated Use {@link AccessibilityRecord#hashCode()} directly.
748      */
749     @Deprecated
750     @Override
hashCode()751     public int hashCode() {
752         return (mRecord == null) ? 0 : mRecord.hashCode();
753     }
754 
755     /**
756      * @deprecated Use {@link AccessibilityRecord} directly.
757      */
758     @Deprecated
759     @Override
equals(Object obj)760     public boolean equals(Object obj) {
761         if (this == obj) {
762             return true;
763         }
764         if (obj == null) {
765             return false;
766         }
767         if (getClass() != obj.getClass()) {
768             return false;
769         }
770         AccessibilityRecordCompat other = (AccessibilityRecordCompat) obj;
771         if (mRecord == null) {
772             if (other.mRecord != null) {
773                 return false;
774             }
775         } else if (!mRecord.equals(other.mRecord)) {
776             return false;
777         }
778         return true;
779     }
780 }
781