/* * Copyright (C) 2012 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.inputmethod.accessibility; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat; import android.support.v4.view.accessibility.AccessibilityRecordCompat; import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityEvent; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardView; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; /** * Exposes a virtual view sub-tree for {@link KeyboardView} and generates * {@link AccessibilityEvent}s for individual {@link Key}s. *
* A virtual sub-tree is composed of imaginary {@link View}s that are reported * as a part of the view hierarchy for accessibility purposes. This enables * custom views that draw complex content to report them selves as a tree of * virtual views, thus conveying their logical structure. *
*/ public class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat { private static final String TAG = AccessibilityEntityProvider.class.getSimpleName(); private final KeyboardView mKeyboardView; private final InputMethodService mInputMethodService; private final KeyCodeDescriptionMapper mKeyCodeDescriptionMapper; private final AccessibilityUtils mAccessibilityUtils; /** A map of integer IDs to {@link Key}s. */ private final SparseArrayvirtualViewId
or
* the host View itself if virtualViewId
equals to {@link View#NO_ID}.
* * A virtual descendant is an imaginary View that is reported as a part of * the view hierarchy for accessibility purposes. This enables custom views * that draw complex content to report them selves as a tree of virtual * views, thus conveying their logical structure. *
** The implementer is responsible for obtaining an accessibility node info * from the pool of reusable instances and setting the desired properties of * the node info before returning it. *
* * @param virtualViewId A client defined virtual view id. * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual * descendant or the host View. * @see AccessibilityNodeInfoCompat */ @Override public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { AccessibilityNodeInfoCompat info = null; if (virtualViewId == View.NO_ID) { // We are requested to create an AccessibilityNodeInfo describing // this View, i.e. the root of the virtual sub-tree. info = AccessibilityNodeInfoCompat.obtain(mKeyboardView); ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, info); // Add the virtual children of the root View. // TODO(alanv): Need to assign a unique ID to each key. final Keyboard keyboard = mKeyboardView.getKeyboard(); final SetvirtualViewId
or the host View itself if
* virtualViewId
equals to {@link View#NO_ID}.
*
* @param action The action to perform.
* @param virtualViewId A client defined virtual view id.
* @return True if the action was performed.
* @see #createAccessibilityNodeInfo(int)
* @see AccessibilityNodeInfoCompat
*/
@Override
public boolean performAccessibilityAction(int action, int virtualViewId) {
if (virtualViewId == View.NO_ID) {
// Perform the action on the host View.
switch (action) {
case AccessibilityNodeInfoCompat.ACTION_SELECT:
if (!mKeyboardView.isSelected()) {
mKeyboardView.setSelected(true);
return mKeyboardView.isSelected();
}
break;
case AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION:
if (mKeyboardView.isSelected()) {
mKeyboardView.setSelected(false);
return !mKeyboardView.isSelected();
}
break;
}
} else {
// Find the view that corresponds to the given id.
final Key child = mVirtualViewIdToKey.get(virtualViewId);
if (child == null)
return false;
// Perform the action on a virtual view.
switch (action) {
case AccessibilityNodeInfoCompat.ACTION_SELECT:
// TODO: Provide some focus indicator.
return true;
case AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION:
// TODO: Provide some clear focus indicator.
return true;
}
}
return false;
}
/**
* Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case
* insensitive containment. The search is relative to the virtual view, i.e.
* a descendant of the host View, with the given virtualViewId
or the host
* View itself virtualViewId
equals to {@link View#NO_ID}.
*
* @param virtualViewId A client defined virtual view id which defined the
* root of the tree in which to perform the search.
* @param text The searched text.
* @return A list of node info.
* @see #createAccessibilityNodeInfo(int)
* @see AccessibilityNodeInfoCompat
*/
@Override
public List