/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.support.v4.view.accessibility; import android.os.Build; import android.os.Parcelable; import android.view.View; import java.util.Collections; import java.util.List; /** * Helper for accessing {@link android.view.accessibility.AccessibilityRecord} * introduced after API level 4 in a backwards compatible fashion. */ public class AccessibilityRecordCompat { static interface AccessibilityRecordImpl { public Object obtain(); public Object obtain(Object record); public void setSource(Object record, View source); public Object getSource(Object record); public int getWindowId(Object record); public boolean isChecked(Object record); public void setChecked(Object record, boolean isChecked); public boolean isEnabled(Object record); public void setEnabled(Object record, boolean isEnabled); public boolean isPassword(Object record); public void setPassword(Object record, boolean isPassword); public boolean isFullScreen(Object record); public void setFullScreen(Object record, boolean isFullScreen); public boolean isScrollable(Object record); public void setScrollable(Object record, boolean scrollable); public int getItemCount(Object record); public void setItemCount(Object record, int itemCount); public int getCurrentItemIndex(Object record); public void setCurrentItemIndex(Object record, int currentItemIndex); public int getFromIndex(Object record); public void setFromIndex(Object record, int fromIndex); public int getToIndex(Object record); public void setToIndex(Object record, int toIndex); public int getScrollX(Object record); public void setScrollX(Object record, int scrollX); public int getScrollY(Object record); public void setScrollY(Object record, int scrollY); public int getMaxScrollX(Object record); public void setMaxScrollX(Object record, int maxScrollX); public int getMaxScrollY(Object record); public void setMaxScrollY(Object record, int maxScrollY); public int getAddedCount(Object record); public void setAddedCount(Object record, int addedCount); public int getRemovedCount(Object record); public void setRemovedCount(Object record, int removedCount); public CharSequence getClassName(Object record); public void setClassName(Object record, CharSequence className); public List getText(Object record); public CharSequence getBeforeText(Object record); public void setBeforeText(Object record, CharSequence beforeText); public CharSequence getContentDescription(Object record); public void setContentDescription(Object record, CharSequence contentDescription); public Parcelable getParcelableData(Object record); public void setParcelableData(Object record, Parcelable parcelableData); public void recycle(Object record); } static class AccessibilityRecordStubImpl implements AccessibilityRecordImpl { public Object obtain() { return null; } public Object obtain(Object record) { return null; } public int getAddedCount(Object record) { return 0; } public CharSequence getBeforeText(Object record) { return null; } public CharSequence getClassName(Object record) { return null; } public CharSequence getContentDescription(Object record) { return null; } public int getCurrentItemIndex(Object record) { return 0; } public int getFromIndex(Object record) { return 0; } public int getItemCount(Object record) { return 0; } public int getMaxScrollX(Object record) { return 0; } public int getMaxScrollY(Object record) { return 0; } public Parcelable getParcelableData(Object record) { return null; } public int getRemovedCount(Object record) { return 0; } public int getScrollX(Object record) { return 0; } public int getScrollY(Object record) { return 0; } public Object getSource(Object record) { return null; } public List getText(Object record) { return Collections.emptyList(); } public int getToIndex(Object record) { return 0; } public int getWindowId(Object record) { return 0; } public boolean isChecked(Object record) { return false; } public boolean isEnabled(Object record) { return false; } public boolean isFullScreen(Object record) { return false; } public boolean isPassword(Object record) { return false; } public boolean isScrollable(Object record) { return false; } public void recycle(Object record) { } public void setAddedCount(Object record, int addedCount) { } public void setBeforeText(Object record, CharSequence beforeText) { } public void setChecked(Object record, boolean isChecked) { } public void setClassName(Object record, CharSequence className) { } public void setContentDescription(Object record, CharSequence contentDescription) { } public void setCurrentItemIndex(Object record, int currentItemIndex) { } public void setEnabled(Object record, boolean isEnabled) { } public void setFromIndex(Object record, int fromIndex) { } public void setFullScreen(Object record, boolean isFullScreen) { } public void setItemCount(Object record, int itemCount) { } public void setMaxScrollX(Object record, int maxScrollX) { } public void setMaxScrollY(Object record, int maxScrollY) { } public void setParcelableData(Object record, Parcelable parcelableData) { } public void setPassword(Object record, boolean isPassword) { } public void setRemovedCount(Object record, int removedCount) { } public void setScrollX(Object record, int scrollX) { } public void setScrollY(Object record, int scrollY) { } public void setScrollable(Object record, boolean scrollable) { } public void setSource(Object record, View source) { } public void setToIndex(Object record, int toIndex) { } } static class AccessibilityRecordIcsImpl implements AccessibilityRecordImpl { public Object obtain() { return AccessibilityRecordCompatIcs.obtain(); } public Object obtain(Object record) { return AccessibilityRecordCompatIcs.obtain(record); } public int getAddedCount(Object record) { return AccessibilityRecordCompatIcs.getAddedCount(record); } public CharSequence getBeforeText(Object record) { return AccessibilityRecordCompatIcs.getBeforeText(record); } public CharSequence getClassName(Object record) { return AccessibilityRecordCompatIcs.getClassName(record); } public CharSequence getContentDescription(Object record) { return AccessibilityRecordCompatIcs.getContentDescription(record); } public int getCurrentItemIndex(Object record) { return AccessibilityRecordCompatIcs.getCurrentItemIndex(record); } public int getFromIndex(Object record) { return AccessibilityRecordCompatIcs.getFromIndex(record); } public int getItemCount(Object record) { return AccessibilityRecordCompatIcs.getItemCount(record); } public int getMaxScrollX(Object record) { // TODO: Uncomment when these APIs become public return 0;//AccessibilityRecordCompatIcs.getMaxScrollX(record); } public int getMaxScrollY(Object record) { // TODO: Uncomment when these APIs become public return 0;//AccessibilityRecordCompatIcs.getMaxScrollY(record); } public Parcelable getParcelableData(Object record) { return AccessibilityRecordCompatIcs.getParcelableData(record); } public int getRemovedCount(Object record) { return AccessibilityRecordCompatIcs.getRemovedCount(record); } public int getScrollX(Object record) { return AccessibilityRecordCompatIcs.getScrollX(record); } public int getScrollY(Object record) { return AccessibilityRecordCompatIcs.getScrollY(record); } public Object getSource(Object record) { return AccessibilityRecordCompatIcs.getSource(record); } public List getText(Object record) { return AccessibilityRecordCompatIcs.getText(record); } public int getToIndex(Object record) { return AccessibilityRecordCompatIcs.getToIndex(record); } public int getWindowId(Object record) { return AccessibilityRecordCompatIcs.getWindowId(record); } public boolean isChecked(Object record) { return AccessibilityRecordCompatIcs.isChecked(record); } public boolean isEnabled(Object record) { return AccessibilityRecordCompatIcs.isEnabled(record); } public boolean isFullScreen(Object record) { return AccessibilityRecordCompatIcs.isFullScreen(record); } public boolean isPassword(Object record) { return AccessibilityRecordCompatIcs.isPassword(record); } public boolean isScrollable(Object record) { return AccessibilityRecordCompatIcs.isScrollable(record); } public void recycle(Object record) { AccessibilityRecordCompatIcs.recycle(record); } public void setAddedCount(Object record, int addedCount) { AccessibilityRecordCompatIcs.setAddedCount(record, addedCount); } public void setBeforeText(Object record, CharSequence beforeText) { AccessibilityRecordCompatIcs.setBeforeText(record, beforeText); } public void setChecked(Object record, boolean isChecked) { AccessibilityRecordCompatIcs.setChecked(record, isChecked); } public void setClassName(Object record, CharSequence className) { AccessibilityRecordCompatIcs.setClassName(record, className); } public void setContentDescription(Object record, CharSequence contentDescription) { AccessibilityRecordCompatIcs.setContentDescription(record, contentDescription); } public void setCurrentItemIndex(Object record, int currentItemIndex) { AccessibilityRecordCompatIcs.setCurrentItemIndex(record, currentItemIndex); } public void setEnabled(Object record, boolean isEnabled) { AccessibilityRecordCompatIcs.setEnabled(record, isEnabled); } public void setFromIndex(Object record, int fromIndex) { AccessibilityRecordCompatIcs.setFromIndex(record, fromIndex); } public void setFullScreen(Object record, boolean isFullScreen) { AccessibilityRecordCompatIcs.setFullScreen(record, isFullScreen); } public void setItemCount(Object record, int itemCount) { AccessibilityRecordCompatIcs.setItemCount(record, itemCount); } public void setMaxScrollX(Object record, int maxScrollX) { // TODO: Uncomment when these APIs become public // AccessibilityRecordCompatIcs.setMaxScrollX(record, maxScrollX); } public void setMaxScrollY(Object record, int maxScrollY) { // TODO: Uncomment when these APIs become public // AccessibilityRecordCompatIcs.setMaxScrollY(record, maxScrollY); } public void setParcelableData(Object record, Parcelable parcelableData) { AccessibilityRecordCompatIcs.setParcelableData(record, parcelableData); } public void setPassword(Object record, boolean isPassword) { AccessibilityRecordCompatIcs.setPassword(record, isPassword); } public void setRemovedCount(Object record, int removedCount) { AccessibilityRecordCompatIcs.setRemovedCount(record, removedCount); } public void setScrollX(Object record, int scrollX) { AccessibilityRecordCompatIcs.setScrollX(record, scrollX); } public void setScrollY(Object record, int scrollY) { AccessibilityRecordCompatIcs.setScrollY(record, scrollY); } public void setScrollable(Object record, boolean scrollable) { AccessibilityRecordCompatIcs.setScrollable(record, scrollable); } public void setSource(Object record, View source) { AccessibilityRecordCompatIcs.setSource(record, source); } public void setToIndex(Object record, int toIndex) { AccessibilityRecordCompatIcs.setToIndex(record, toIndex); } } static { if (Build.VERSION.SDK_INT >= 14) { // ICS IMPL = new AccessibilityRecordIcsImpl(); } else { IMPL = new AccessibilityRecordStubImpl(); } } private static final AccessibilityRecordImpl IMPL; private final Object mRecord; /* * Hide constructor from clients. */ public AccessibilityRecordCompat(Object record) { mRecord = record; } /** * @return The wrapped implementation. */ public Object getImpl() { return mRecord; } /** * Returns a cached instance if such is available or a new one is * instantiated. The instance is initialized with data from the * given record. * * @return An instance. */ public static AccessibilityRecordCompat obtain(AccessibilityRecordCompat record) { return new AccessibilityRecordCompat(IMPL.obtain(record.mRecord)); } /** * Returns a cached instance if such is available or a new one is * instantiated. * * @return An instance. */ public static AccessibilityRecordCompat obtain() { return new AccessibilityRecordCompat(IMPL.obtain()); } /** * Sets the event source. * * @param source The source. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setSource(View source) { IMPL.setSource(mRecord, source); } /** * Gets the {@link android.view.accessibility.AccessibilityNodeInfo} of * the event source. *

* Note: It is a client responsibility to recycle the * received info by calling * {@link android.view.accessibility.AccessibilityNodeInfo#recycle() * AccessibilityNodeInfo#recycle()} to avoid creating of multiple instances. *

* * @return The info of the source. */ public AccessibilityNodeInfoCompat getSource() { return new AccessibilityNodeInfoCompat(IMPL.getSource(mRecord)); } /** * Gets the id of the window from which the event comes from. * * @return The window id. */ public int getWindowId() { return IMPL.getWindowId(mRecord); } /** * Gets if the source is checked. * * @return True if the view is checked, false otherwise. */ public boolean isChecked() { return IMPL.isChecked(mRecord); } /** * Sets if the source is checked. * * @param isChecked True if the view is checked, false otherwise. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setChecked(boolean isChecked) { IMPL.setChecked(mRecord, isChecked); } /** * Gets if the source is enabled. * * @return True if the view is enabled, false otherwise. */ public boolean isEnabled() { return IMPL.isEnabled(mRecord); } /** * Sets if the source is enabled. * * @param isEnabled True if the view is enabled, false otherwise. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setEnabled(boolean isEnabled) { IMPL.setEnabled(mRecord, isEnabled); } /** * Gets if the source is a password field. * * @return True if the view is a password field, false otherwise. */ public boolean isPassword() { return IMPL.isPassword(mRecord); } /** * Sets if the source is a password field. * * @param isPassword True if the view is a password field, false otherwise. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setPassword(boolean isPassword) { IMPL.setPassword(mRecord, isPassword); } /** * Gets if the source is taking the entire screen. * * @return True if the source is full screen, false otherwise. */ public boolean isFullScreen() { return IMPL.isFullScreen(mRecord); } /** * Sets if the source is taking the entire screen. * * @param isFullScreen True if the source is full screen, false otherwise. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setFullScreen(boolean isFullScreen) { IMPL.setFullScreen(mRecord, isFullScreen); } /** * Gets if the source is scrollable. * * @return True if the source is scrollable, false otherwise. */ public boolean isScrollable() { return IMPL.isScrollable(mRecord); } /** * Sets if the source is scrollable. * * @param scrollable True if the source is scrollable, false otherwise. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setScrollable(boolean scrollable) { IMPL.setScrollable(mRecord, scrollable); } /** * Gets the number of items that can be visited. * * @return The number of items. */ public int getItemCount() { return IMPL.getItemCount(mRecord); } /** * Sets the number of items that can be visited. * * @param itemCount The number of items. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setItemCount(int itemCount) { IMPL.setItemCount(mRecord, itemCount); } /** * Gets the index of the source in the list of items the can be visited. * * @return The current item index. */ public int getCurrentItemIndex() { return IMPL.getCurrentItemIndex(mRecord); } /** * Sets the index of the source in the list of items that can be visited. * * @param currentItemIndex The current item index. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setCurrentItemIndex(int currentItemIndex) { IMPL.setCurrentItemIndex(mRecord, currentItemIndex); } /** * Gets the index of the first character of the changed sequence, * or the beginning of a text selection or the index of the first * visible item when scrolling. * * @return The index of the first character or selection * start or the first visible item. */ public int getFromIndex() { return IMPL.getFromIndex(mRecord); } /** * Sets the index of the first character of the changed sequence * or the beginning of a text selection or the index of the first * visible item when scrolling. * * @param fromIndex The index of the first character or selection * start or the first visible item. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setFromIndex(int fromIndex) { IMPL.setFromIndex(mRecord, fromIndex); } /** * Gets the index of text selection end or the index of the last * visible item when scrolling. * * @return The index of selection end or last item index. */ public int getToIndex() { return IMPL.getToIndex(mRecord); } /** * Sets the index of text selection end or the index of the last * visible item when scrolling. * * @param toIndex The index of selection end or last item index. */ public void setToIndex(int toIndex) { IMPL.setToIndex(mRecord, toIndex); } /** * Gets the scroll offset of the source left edge in pixels. * * @return The scroll. */ public int getScrollX() { return IMPL.getScrollX(mRecord); } /** * Sets the scroll offset of the source left edge in pixels. * * @param scrollX The scroll. */ public void setScrollX(int scrollX) { IMPL.setScrollX(mRecord, scrollX); } /** * Gets the scroll offset of the source top edge in pixels. * * @return The scroll. */ public int getScrollY() { return IMPL.getScrollY(mRecord); } /** * Sets the scroll offset of the source top edge in pixels. * * @param scrollY The scroll. */ public void setScrollY(int scrollY) { IMPL.setScrollY(mRecord, scrollY); } // TODO: Uncomment when these APIs become public // /** // * Gets the max scroll offset of the source left edge in pixels. // * // * @return The max scroll. // */ // public int getMaxScrollX() { // return IMPL.getMaxScrollX(mRecord); // } // /** // * Sets the max scroll offset of the source left edge in pixels. // * // * @param maxScrollX The max scroll. // */ // public void setMaxScrollX(int maxScrollX) { // IMPL.setMaxScrollX(mRecord, maxScrollX); // } // // /** // * Gets the max scroll offset of the source top edge in pixels. // * // * @return The max scroll. // */ // public int getMaxScrollY() { // return IMPL.getMaxScrollY(mRecord); // } // // /** // * Sets the max scroll offset of the source top edge in pixels. // * // * @param maxScrollY The max scroll. // */ // public void setMaxScrollY(int maxScrollY) { // IMPL.setMaxScrollY(mRecord, maxScrollY); // } /** * Gets the number of added characters. * * @return The number of added characters. */ public int getAddedCount() { return IMPL.getAddedCount(mRecord); } /** * Sets the number of added characters. * * @param addedCount The number of added characters. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setAddedCount(int addedCount) { IMPL.setAddedCount(mRecord, addedCount); } /** * Gets the number of removed characters. * * @return The number of removed characters. */ public int getRemovedCount() { return IMPL.getRemovedCount(mRecord); } /** * Sets the number of removed characters. * * @param removedCount The number of removed characters. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setRemovedCount(int removedCount) { IMPL.setRemovedCount(mRecord, removedCount); } /** * Gets the class name of the source. * * @return The class name. */ public CharSequence getClassName() { return IMPL.getClassName(mRecord); } /** * Sets the class name of the source. * * @param className The lass name. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setClassName(CharSequence className) { IMPL.setClassName(mRecord, className); } /** * Gets the text of the event. The index in the list represents the priority * of the text. Specifically, the lower the index the higher the priority. * * @return The text. */ public List getText() { return IMPL.getText(mRecord); } /** * Sets the text before a change. * * @return The text before the change. */ public CharSequence getBeforeText() { return IMPL.getBeforeText(mRecord); } /** * Sets the text before a change. * * @param beforeText The text before the change. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setBeforeText(CharSequence beforeText) { IMPL.setBeforeText(mRecord, beforeText); } /** * Gets the description of the source. * * @return The description. */ public CharSequence getContentDescription() { return IMPL.getContentDescription(mRecord); } /** * Sets the description of the source. * * @param contentDescription The description. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setContentDescription(CharSequence contentDescription) { IMPL.setContentDescription(mRecord, contentDescription); } /** * Gets the {@link Parcelable} data. * * @return The parcelable data. */ public Parcelable getParcelableData() { return IMPL.getParcelableData(mRecord); } /** * Sets the {@link Parcelable} data of the event. * * @param parcelableData The parcelable data. * * @throws IllegalStateException If called from an AccessibilityService. */ public void setParcelableData(Parcelable parcelableData) { IMPL.setParcelableData(mRecord, parcelableData); } /** * Return an instance back to be reused. *

* Note: You must not touch the object after calling this * function. *

* * @throws IllegalStateException If the record is already recycled. */ public void recycle() { IMPL.recycle(mRecord); } @Override public int hashCode() { return (mRecord == null) ? 0 : mRecord.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } AccessibilityRecordCompat other = (AccessibilityRecordCompat) obj; if (mRecord == null) { if (other.mRecord != null) { return false; } } else if (!mRecord.equals(other.mRecord)) { return false; } return true; } }