From e8c3a7c2d3c2647714e3a7a3d7dd45ea56dfac59 Mon Sep 17 00:00:00 2001 From: Maurice Lam Date: Wed, 15 Mar 2017 20:31:36 -0700 Subject: [PATCH] Remove unused ExploreByTouchHelper class Framework bug fixes removed the need for this copy, and it's not referenced anyway. Test: Existing tests pass Change-Id: I1dd5045246ed737b30da2d558d14bc2c86af4f31 --- .../settings/widget/ExploreByTouchHelper.java | 724 ------------------ 1 file changed, 724 deletions(-) delete mode 100644 src/com/android/settings/widget/ExploreByTouchHelper.java diff --git a/src/com/android/settings/widget/ExploreByTouchHelper.java b/src/com/android/settings/widget/ExploreByTouchHelper.java deleted file mode 100644 index b64a74c544a..00000000000 --- a/src/com/android/settings/widget/ExploreByTouchHelper.java +++ /dev/null @@ -1,724 +0,0 @@ -/* - * Copyright (C) 2013 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 com.android.settings.widget; - -import android.content.Context; -import android.graphics.Rect; -import android.os.Bundle; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewParent; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.AccessibilityNodeInfo; -import android.view.accessibility.AccessibilityNodeProvider; - -import java.util.LinkedList; -import java.util.List; - -/** - * Copied from setup wizard, which is in turn a modified copy of - * com.android.internal.ExploreByTouchHelper with the following modifications: - * - * - Make accessibility calls to the views, instead of to the accessibility delegate directly to - * make sure those methods for View subclasses are called. - * - * ExploreByTouchHelper is a utility class for implementing accessibility - * support in custom {@link android.view.View}s that represent a collection of View-like - * logical items. It extends {@link android.view.accessibility.AccessibilityNodeProvider} and - * simplifies many aspects of providing information to accessibility services - * and managing accessibility focus. This class does not currently support - * hierarchies of logical items. - *

- * This should be applied to the parent view using - * {@link android.view.View#setAccessibilityDelegate}: - * - *

- * mAccessHelper = ExploreByTouchHelper.create(someView, mAccessHelperCallback);
- * ViewCompat.setAccessibilityDelegate(someView, mAccessHelper);
- * 
- */ -public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { - /** Virtual node identifier value for invalid nodes. */ - public static final int INVALID_ID = Integer.MIN_VALUE; - - /** Default class name used for virtual views. */ - private static final String DEFAULT_CLASS_NAME = View.class.getName(); - - // Temporary, reusable data structures. - private final Rect mTempScreenRect = new Rect(); - private final Rect mTempParentRect = new Rect(); - private final Rect mTempVisibleRect = new Rect(); - private final int[] mTempGlobalRect = new int[2]; - - /** View's context **/ - private Context mContext; - - /** System accessibility manager, used to check state and send events. */ - private final AccessibilityManager mManager; - - /** View whose internal structure is exposed through this helper. */ - private final View mView; - - /** Node provider that handles creating nodes and performing actions. */ - private ExploreByTouchNodeProvider mNodeProvider; - - /** Virtual view id for the currently focused logical item. */ - private int mFocusedVirtualViewId = INVALID_ID; - - /** Virtual view id for the currently hovered logical item. */ - private int mHoveredVirtualViewId = INVALID_ID; - - /** - * Factory method to create a new {@link com.google.android.setupwizard.util.ExploreByTouchHelper}. - * - * @param forView View whose logical children are exposed by this helper. - */ - public ExploreByTouchHelper(View forView) { - if (forView == null) { - throw new IllegalArgumentException("View may not be null"); - } - - mView = forView; - mContext = forView.getContext(); - mManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); - } - - /** - * Returns the {@link android.view.accessibility.AccessibilityNodeProvider} for this helper. - * - * @param host View whose logical children are exposed by this helper. - * @return The accessibility node provider for this helper. - */ - @Override - public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) { - if (mNodeProvider == null) { - mNodeProvider = new ExploreByTouchNodeProvider(); - } - return mNodeProvider; - } - - /** - * Dispatches hover {@link android.view.MotionEvent}s to the virtual view hierarchy when - * the Explore by Touch feature is enabled. - *

- * This method should be called by overriding - * {@link android.view.View#dispatchHoverEvent}: - * - *

@Override
-     * public boolean dispatchHoverEvent(MotionEvent event) {
-     *   if (mHelper.dispatchHoverEvent(this, event) {
-     *     return true;
-     *   }
-     *   return super.dispatchHoverEvent(event);
-     * }
-     * 
- * - * @param event The hover event to dispatch to the virtual view hierarchy. - * @return Whether the hover event was handled. - */ - public boolean dispatchHoverEvent(MotionEvent event) { - if (!mManager.isEnabled() || !mManager.isTouchExplorationEnabled()) { - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_HOVER_MOVE: - case MotionEvent.ACTION_HOVER_ENTER: - final int virtualViewId = getVirtualViewAt(event.getX(), event.getY()); - updateHoveredVirtualView(virtualViewId); - return (virtualViewId != INVALID_ID); - case MotionEvent.ACTION_HOVER_EXIT: - if (mFocusedVirtualViewId != INVALID_ID) { - updateHoveredVirtualView(INVALID_ID); - return true; - } - return false; - default: - return false; - } - } - - /** - * Populates an event of the specified type with information about an item - * and attempts to send it up through the view hierarchy. - *

- * You should call this method after performing a user action that normally - * fires an accessibility event, such as clicking on an item. - * - *

public void performItemClick(T item) {
-     *   ...
-     *   sendEventForVirtualViewId(item.id, AccessibilityEvent.TYPE_VIEW_CLICKED);
-     * }
-     * 
- * - * @param virtualViewId The virtual view id for which to send an event. - * @param eventType The type of event to send. - * @return true if the event was sent successfully. - */ - public boolean sendEventForVirtualView(int virtualViewId, int eventType) { - if ((virtualViewId == INVALID_ID) || !mManager.isEnabled()) { - return false; - } - - final ViewParent parent = mView.getParent(); - if (parent == null) { - return false; - } - - final AccessibilityEvent event = createEvent(virtualViewId, eventType); - return parent.requestSendAccessibilityEvent(mView, event); - } - - /** - * Notifies the accessibility framework that the properties of the parent - * view have changed. - *

- * You must call this method after adding or removing items from the - * parent view. - */ - public void invalidateRoot() { - invalidateVirtualView(View.NO_ID); - } - - /** - * Notifies the accessibility framework that the properties of a particular - * item have changed. - *

- * You must call this method after changing any of the properties set - * in {@link #onPopulateNodeForVirtualView}. - * - * @param virtualViewId The virtual view id to invalidate. - */ - public void invalidateVirtualView(int virtualViewId) { - sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); - } - - /** - * Returns the virtual view id for the currently focused item, - * - * @return A virtual view id, or {@link #INVALID_ID} if no item is - * currently focused. - */ - public int getFocusedVirtualView() { - return mFocusedVirtualViewId; - } - - /** - * Sets the currently hovered item, sending hover accessibility events as - * necessary to maintain the correct state. - * - * @param virtualViewId The virtual view id for the item currently being - * hovered, or {@link #INVALID_ID} if no item is hovered within - * the parent view. - */ - private void updateHoveredVirtualView(int virtualViewId) { - if (mHoveredVirtualViewId == virtualViewId) { - return; - } - - final int previousVirtualViewId = mHoveredVirtualViewId; - mHoveredVirtualViewId = virtualViewId; - - // Stay consistent with framework behavior by sending ENTER/EXIT pairs - // in reverse order. This is accurate as of API 18. - sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); - sendEventForVirtualView(previousVirtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityEvent} for the specified - * virtual view id, which includes the host view ({@link android.view.View#NO_ID}). - * - * @param virtualViewId The virtual view id for the item for which to - * construct an event. - * @param eventType The type of event to construct. - * @return An {@link android.view.accessibility.AccessibilityEvent} populated with information about - * the specified item. - */ - private AccessibilityEvent createEvent(int virtualViewId, int eventType) { - switch (virtualViewId) { - case View.NO_ID: - return createEventForHost(eventType); - default: - return createEventForChild(virtualViewId, eventType); - } - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityEvent} for the host node. - * - * @param eventType The type of event to construct. - * @return An {@link android.view.accessibility.AccessibilityEvent} populated with information about - * the specified item. - */ - private AccessibilityEvent createEventForHost(int eventType) { - final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); - mView.onInitializeAccessibilityEvent(event); - return event; - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityEvent} populated with - * information about the specified item. - * - * @param virtualViewId The virtual view id for the item for which to - * construct an event. - * @param eventType The type of event to construct. - * @return An {@link android.view.accessibility.AccessibilityEvent} populated with information about - * the specified item. - */ - private AccessibilityEvent createEventForChild(int virtualViewId, int eventType) { - final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); - event.setEnabled(true); - event.setClassName(DEFAULT_CLASS_NAME); - - // Allow the client to populate the event. - onPopulateEventForVirtualView(virtualViewId, event); - - // Make sure the developer is following the rules. - if (event.getText().isEmpty() && (event.getContentDescription() == null)) { - throw new RuntimeException("Callbacks must add text or a content description in " - + "populateEventForVirtualViewId()"); - } - - // Don't allow the client to override these properties. - event.setPackageName(mView.getContext().getPackageName()); - event.setSource(mView, virtualViewId); - - return event; - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityNodeInfo} for the - * specified virtual view id, which includes the host view - * ({@link android.view.View#NO_ID}). - * - * @param virtualViewId The virtual view id for the item for which to - * construct a node. - * @return An {@link android.view.accessibility.AccessibilityNodeInfo} populated with information - * about the specified item. - */ - private AccessibilityNodeInfo createNode(int virtualViewId) { - switch (virtualViewId) { - case View.NO_ID: - return createNodeForHost(); - default: - return createNodeForChild(virtualViewId); - } - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityNodeInfo} for the - * host view populated with its virtual descendants. - * - * @return An {@link android.view.accessibility.AccessibilityNodeInfo} for the parent node. - */ - private AccessibilityNodeInfo createNodeForHost() { - final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(mView); - mView.onInitializeAccessibilityNodeInfo(node); - - // Add the virtual descendants. - final LinkedList virtualViewIds = new LinkedList(); - getVisibleVirtualViews(virtualViewIds); - - for (Integer childVirtualViewId : virtualViewIds) { - node.addChild(mView, childVirtualViewId); - } - - return node; - } - - /** - * Constructs and returns an {@link android.view.accessibility.AccessibilityNodeInfo} for the - * specified item. Automatically manages accessibility focus actions. - *

- * Allows the implementing class to specify most node properties, but - * overrides the following: - *

- *

- * Uses the bounds of the parent view and the parent-relative bounding - * rectangle specified by - * {@link android.view.accessibility.AccessibilityNodeInfo#getBoundsInParent} to automatically - * update the following properties: - *

- * - * @param virtualViewId The virtual view id for item for which to construct - * a node. - * @return An {@link android.view.accessibility.AccessibilityNodeInfo} for the specified item. - */ - private AccessibilityNodeInfo createNodeForChild(int virtualViewId) { - final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(); - - // Ensure the client has good defaults. - node.setEnabled(true); - node.setClassName(DEFAULT_CLASS_NAME); - - // Allow the client to populate the node. - onPopulateNodeForVirtualView(virtualViewId, node); - - // Make sure the developer is following the rules. - if ((node.getText() == null) && (node.getContentDescription() == null)) { - throw new RuntimeException("Callbacks must add text or a content description in " - + "populateNodeForVirtualViewId()"); - } - - node.getBoundsInParent(mTempParentRect); - if (mTempParentRect.isEmpty()) { - throw new RuntimeException("Callbacks must set parent bounds in " - + "populateNodeForVirtualViewId()"); - } - - final int actions = node.getActions(); - if ((actions & AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) != 0) { - throw new RuntimeException("Callbacks must not add ACTION_ACCESSIBILITY_FOCUS in " - + "populateNodeForVirtualViewId()"); - } - if ((actions & AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS) != 0) { - throw new RuntimeException("Callbacks must not add ACTION_CLEAR_ACCESSIBILITY_FOCUS in " - + "populateNodeForVirtualViewId()"); - } - - // Don't allow the client to override these properties. - node.setPackageName(mView.getContext().getPackageName()); - node.setSource(mView, virtualViewId); - node.setParent(mView); - - // Manage internal accessibility focus state. - if (mFocusedVirtualViewId == virtualViewId) { - node.setAccessibilityFocused(true); - node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); - } else { - node.setAccessibilityFocused(false); - node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); - } - - // Set the visibility based on the parent bound. - if (intersectVisibleToUser(mTempParentRect)) { - node.setVisibleToUser(true); - node.setBoundsInParent(mTempParentRect); - } - - // Calculate screen-relative bound. - mView.getLocationOnScreen(mTempGlobalRect); - final int offsetX = mTempGlobalRect[0]; - final int offsetY = mTempGlobalRect[1]; - mTempScreenRect.set(mTempParentRect); - mTempScreenRect.offset(offsetX, offsetY); - node.setBoundsInScreen(mTempScreenRect); - - return node; - } - - private boolean performAction(int virtualViewId, int action, Bundle arguments) { - switch (virtualViewId) { - case View.NO_ID: - return performActionForHost(action, arguments); - default: - return performActionForChild(virtualViewId, action, arguments); - } - } - - private boolean performActionForHost(int action, Bundle arguments) { - return mView.performAccessibilityAction(action, arguments); - } - - private boolean performActionForChild(int virtualViewId, int action, Bundle arguments) { - switch (action) { - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - return manageFocusForChild(virtualViewId, action, arguments); - default: - return onPerformActionForVirtualView(virtualViewId, action, arguments); - } - } - - private boolean manageFocusForChild(int virtualViewId, int action, Bundle arguments) { - switch (action) { - case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: - return requestAccessibilityFocus(virtualViewId); - case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - return clearAccessibilityFocus(virtualViewId); - default: - return false; - } - } - - /** - * Computes whether the specified {@link android.graphics.Rect} intersects with the visible - * portion of its parent {@link android.view.View}. Modifies {@code localRect} to contain - * only the visible portion. - * - * @param localRect A rectangle in local (parent) coordinates. - * @return Whether the specified {@link android.graphics.Rect} is visible on the screen. - */ - private boolean intersectVisibleToUser(Rect localRect) { - // Missing or empty bounds mean this view is not visible. - if ((localRect == null) || localRect.isEmpty()) { - return false; - } - - // Attached to invisible window means this view is not visible. - if (mView.getWindowVisibility() != View.VISIBLE) { - return false; - } - - // An invisible predecessor means that this view is not visible. - ViewParent viewParent = mView.getParent(); - while (viewParent instanceof View) { - final View view = (View) viewParent; - if ((view.getAlpha() <= 0) || (view.getVisibility() != View.VISIBLE)) { - return false; - } - viewParent = view.getParent(); - } - - // A null parent implies the view is not visible. - if (viewParent == null) { - return false; - } - - // If no portion of the parent is visible, this view is not visible. - if (!mView.getLocalVisibleRect(mTempVisibleRect)) { - return false; - } - - // Check if the view intersects the visible portion of the parent. - return localRect.intersect(mTempVisibleRect); - } - - /** - * Returns whether this virtual view is accessibility focused. - * - * @return True if the view is accessibility focused. - */ - private boolean isAccessibilityFocused(int virtualViewId) { - return (mFocusedVirtualViewId == virtualViewId); - } - - /** - * Attempts to give accessibility focus to a virtual view. - *

- * A virtual view will not actually take focus if - * {@link android.view.accessibility.AccessibilityManager#isEnabled()} returns false, - * {@link android.view.accessibility.AccessibilityManager#isTouchExplorationEnabled()} returns false, - * or the view already has accessibility focus. - * - * @param virtualViewId The id of the virtual view on which to place - * accessibility focus. - * @return Whether this virtual view actually took accessibility focus. - */ - private boolean requestAccessibilityFocus(int virtualViewId) { - final AccessibilityManager accessibilityManager = - (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); - - if (!mManager.isEnabled() - || !accessibilityManager.isTouchExplorationEnabled()) { - return false; - } - // TODO: Check virtual view visibility. - if (!isAccessibilityFocused(virtualViewId)) { - mFocusedVirtualViewId = virtualViewId; - // TODO: Only invalidate virtual view bounds. - mView.invalidate(); - sendEventForVirtualView(virtualViewId, - AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); - return true; - } - return false; - } - - /** - * Attempts to clear accessibility focus from a virtual view. - * - * @param virtualViewId The id of the virtual view from which to clear - * accessibility focus. - * @return Whether this virtual view actually cleared accessibility focus. - */ - private boolean clearAccessibilityFocus(int virtualViewId) { - if (isAccessibilityFocused(virtualViewId)) { - mFocusedVirtualViewId = INVALID_ID; - mView.invalidate(); - sendEventForVirtualView(virtualViewId, - AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); - return true; - } - return false; - } - - /** - * Provides a mapping between view-relative coordinates and logical - * items. - * - * @param x The view-relative x coordinate - * @param y The view-relative y coordinate - * @return virtual view identifier for the logical item under - * coordinates (x,y) - */ - protected abstract int getVirtualViewAt(float x, float y); - - /** - * Populates a list with the view's visible items. The ordering of items - * within {@code virtualViewIds} specifies order of accessibility focus - * traversal. - * - * @param virtualViewIds The list to populate with visible items - */ - protected abstract void getVisibleVirtualViews(List virtualViewIds); - - /** - * Populates an {@link android.view.accessibility.AccessibilityEvent} with information about the - * specified item. - *

- * Implementations must populate the following required fields: - *

- *

- * The helper class automatically populates the following fields with - * default values, but implementations may optionally override them: - *

- *

- * The following required fields are automatically populated by the - * helper class and may not be overridden: - *

- * - * @param virtualViewId The virtual view id for the item for which to - * populate the event - * @param event The event to populate - */ - protected abstract void onPopulateEventForVirtualView( - int virtualViewId, AccessibilityEvent event); - - /** - * Populates an {@link android.view.accessibility.AccessibilityNodeInfo} with information - * about the specified item. - *

- * Implementations must populate the following required fields: - *

- *

- * The helper class automatically populates the following fields with - * default values, but implementations may optionally override them: - *

- *

- * The following required fields are automatically populated by the - * helper class and may not be overridden: - *

- *

- * Additionally, the helper class automatically handles accessibility - * focus management by adding the appropriate - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS} or - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS} - * action. Implementations must never manually add these actions. - *

- * The helper class also automatically modifies parent- and - * screen-relative bounds to reflect the portion of the item visible - * within its parent. - * - * @param virtualViewId The virtual view identifier of the item for - * which to populate the node - * @param node The node to populate - */ - protected abstract void onPopulateNodeForVirtualView( - int virtualViewId, AccessibilityNodeInfo node); - - /** - * Performs the specified accessibility action on the item associated - * with the virtual view identifier. See - * {@link android.view.accessibility.AccessibilityNodeInfo#performAction(int, android.os.Bundle)} for - * more information. - *

- * Implementations must handle any actions added manually in - * {@link #onPopulateNodeForVirtualView}. - *

- * The helper class automatically handles focus management resulting - * from {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS} - * and - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS} - * actions. - * - * @param virtualViewId The virtual view identifier of the item on which - * to perform the action - * @param action The accessibility action to perform - * @param arguments (Optional) A bundle with additional arguments, or - * null - * @return true if the action was performed - */ - protected abstract boolean onPerformActionForVirtualView( - int virtualViewId, int action, Bundle arguments); - - /** - * Exposes a virtual view hierarchy to the accessibility framework. Only - * used in API 16+. - */ - private class ExploreByTouchNodeProvider extends AccessibilityNodeProvider { - @Override - public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { - return ExploreByTouchHelper.this.createNode(virtualViewId); - } - - @Override - public boolean performAction(int virtualViewId, int action, Bundle arguments) { - return ExploreByTouchHelper.this.performAction(virtualViewId, action, arguments); - } - } -}