196 lines
8.9 KiB
Java
196 lines
8.9 KiB
Java
package androidx.core.view;
|
|
|
|
import android.os.Bundle;
|
|
import android.text.style.ClickableSpan;
|
|
import android.util.SparseArray;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.accessibility.AccessibilityEvent;
|
|
import android.view.accessibility.AccessibilityNodeInfo;
|
|
import android.view.accessibility.AccessibilityNodeProvider;
|
|
import androidx.annotation.RequiresApi;
|
|
import androidx.annotation.RestrictTo;
|
|
import androidx.core.R;
|
|
import androidx.core.view.accessibility.AccessibilityClickableSpanCompat;
|
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
|
import androidx.core.view.accessibility.AccessibilityNodeProviderCompat;
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
public class AccessibilityDelegateCompat {
|
|
private static final View.AccessibilityDelegate DEFAULT_DELEGATE = new View.AccessibilityDelegate();
|
|
private final View.AccessibilityDelegate mBridge;
|
|
private final View.AccessibilityDelegate mOriginalDelegate;
|
|
|
|
public static final class AccessibilityDelegateAdapter extends View.AccessibilityDelegate {
|
|
public final AccessibilityDelegateCompat mCompat;
|
|
|
|
public AccessibilityDelegateAdapter(AccessibilityDelegateCompat accessibilityDelegateCompat) {
|
|
this.mCompat = accessibilityDelegateCompat;
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public boolean dispatchPopulateAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
return this.mCompat.dispatchPopulateAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
@RequiresApi(16)
|
|
public AccessibilityNodeProvider getAccessibilityNodeProvider(View view) {
|
|
AccessibilityNodeProviderCompat accessibilityNodeProvider = this.mCompat.getAccessibilityNodeProvider(view);
|
|
if (accessibilityNodeProvider != null) {
|
|
return (AccessibilityNodeProvider) accessibilityNodeProvider.getProvider();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public void onInitializeAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mCompat.onInitializeAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public void onInitializeAccessibilityNodeInfo(View view, AccessibilityNodeInfo accessibilityNodeInfo) {
|
|
AccessibilityNodeInfoCompat wrap = AccessibilityNodeInfoCompat.wrap(accessibilityNodeInfo);
|
|
wrap.setScreenReaderFocusable(ViewCompat.isScreenReaderFocusable(view));
|
|
wrap.setHeading(ViewCompat.isAccessibilityHeading(view));
|
|
wrap.setPaneTitle(ViewCompat.getAccessibilityPaneTitle(view));
|
|
this.mCompat.onInitializeAccessibilityNodeInfo(view, wrap);
|
|
wrap.addSpansToExtras(accessibilityNodeInfo.getText(), view);
|
|
List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> actionList = AccessibilityDelegateCompat.getActionList(view);
|
|
for (int i = 0; i < actionList.size(); i++) {
|
|
wrap.addAction(actionList.get(i));
|
|
}
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public void onPopulateAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mCompat.onPopulateAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public boolean onRequestSendAccessibilityEvent(ViewGroup viewGroup, View view, AccessibilityEvent accessibilityEvent) {
|
|
return this.mCompat.onRequestSendAccessibilityEvent(viewGroup, view, accessibilityEvent);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public boolean performAccessibilityAction(View view, int i, Bundle bundle) {
|
|
return this.mCompat.performAccessibilityAction(view, i, bundle);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public void sendAccessibilityEvent(View view, int i) {
|
|
this.mCompat.sendAccessibilityEvent(view, i);
|
|
}
|
|
|
|
@Override // android.view.View.AccessibilityDelegate
|
|
public void sendAccessibilityEventUnchecked(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mCompat.sendAccessibilityEventUnchecked(view, accessibilityEvent);
|
|
}
|
|
}
|
|
|
|
public AccessibilityDelegateCompat() {
|
|
this(DEFAULT_DELEGATE);
|
|
}
|
|
|
|
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP_PREFIX})
|
|
public AccessibilityDelegateCompat(View.AccessibilityDelegate accessibilityDelegate) {
|
|
this.mOriginalDelegate = accessibilityDelegate;
|
|
this.mBridge = new AccessibilityDelegateAdapter(this);
|
|
}
|
|
|
|
public static List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> getActionList(View view) {
|
|
List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> list = (List) view.getTag(R.id.tag_accessibility_actions);
|
|
return list == null ? Collections.emptyList() : list;
|
|
}
|
|
|
|
private boolean isSpanStillValid(ClickableSpan clickableSpan, View view) {
|
|
if (clickableSpan != null) {
|
|
ClickableSpan[] clickableSpans = AccessibilityNodeInfoCompat.getClickableSpans(view.createAccessibilityNodeInfo().getText());
|
|
int i = 0;
|
|
while (clickableSpans != null && i < clickableSpans.length) {
|
|
if (clickableSpan.equals(clickableSpans[i])) {
|
|
return true;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean performClickableSpanAction(int i, View view) {
|
|
WeakReference weakReference;
|
|
SparseArray sparseArray = (SparseArray) view.getTag(R.id.tag_accessibility_clickable_spans);
|
|
if (sparseArray == null || (weakReference = (WeakReference) sparseArray.get(i)) == null) {
|
|
return false;
|
|
}
|
|
ClickableSpan clickableSpan = (ClickableSpan) weakReference.get();
|
|
if (!isSpanStillValid(clickableSpan, view)) {
|
|
return false;
|
|
}
|
|
clickableSpan.onClick(view);
|
|
return true;
|
|
}
|
|
|
|
public boolean dispatchPopulateAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
return this.mOriginalDelegate.dispatchPopulateAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
|
|
AccessibilityNodeProvider accessibilityNodeProvider = this.mOriginalDelegate.getAccessibilityNodeProvider(view);
|
|
if (accessibilityNodeProvider != null) {
|
|
return new AccessibilityNodeProviderCompat(accessibilityNodeProvider);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public View.AccessibilityDelegate getBridge() {
|
|
return this.mBridge;
|
|
}
|
|
|
|
public void onInitializeAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mOriginalDelegate.onInitializeAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
public void onInitializeAccessibilityNodeInfo(View view, AccessibilityNodeInfoCompat accessibilityNodeInfoCompat) {
|
|
this.mOriginalDelegate.onInitializeAccessibilityNodeInfo(view, accessibilityNodeInfoCompat.unwrap());
|
|
}
|
|
|
|
public void onPopulateAccessibilityEvent(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mOriginalDelegate.onPopulateAccessibilityEvent(view, accessibilityEvent);
|
|
}
|
|
|
|
public boolean onRequestSendAccessibilityEvent(ViewGroup viewGroup, View view, AccessibilityEvent accessibilityEvent) {
|
|
return this.mOriginalDelegate.onRequestSendAccessibilityEvent(viewGroup, view, accessibilityEvent);
|
|
}
|
|
|
|
public boolean performAccessibilityAction(View view, int i, Bundle bundle) {
|
|
List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> actionList = getActionList(view);
|
|
boolean z2 = false;
|
|
int i2 = 0;
|
|
while (true) {
|
|
if (i2 >= actionList.size()) {
|
|
break;
|
|
}
|
|
AccessibilityNodeInfoCompat.AccessibilityActionCompat accessibilityActionCompat = actionList.get(i2);
|
|
if (accessibilityActionCompat.getId() == i) {
|
|
z2 = accessibilityActionCompat.perform(view, bundle);
|
|
break;
|
|
}
|
|
i2++;
|
|
}
|
|
if (!z2) {
|
|
z2 = this.mOriginalDelegate.performAccessibilityAction(view, i, bundle);
|
|
}
|
|
return (z2 || i != R.id.accessibility_action_clickable_span) ? z2 : performClickableSpanAction(bundle.getInt(AccessibilityClickableSpanCompat.SPAN_ID, -1), view);
|
|
}
|
|
|
|
public void sendAccessibilityEvent(View view, int i) {
|
|
this.mOriginalDelegate.sendAccessibilityEvent(view, i);
|
|
}
|
|
|
|
public void sendAccessibilityEventUnchecked(View view, AccessibilityEvent accessibilityEvent) {
|
|
this.mOriginalDelegate.sendAccessibilityEventUnchecked(view, accessibilityEvent);
|
|
}
|
|
}
|