Skip to content

Commit

Permalink
[AutoComplete] Enabled switch access in MaterialAutoCompleteTextView.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 587556416
  • Loading branch information
Material Design Team authored and afohrman committed Dec 4, 2023
1 parent 8ccec33 commit 14a7b40
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ public void onPopulateAccessibilityEvent(View host, @NonNull AccessibilityEvent
// TODO(b/256138189): Find better workaround, back gesture should call
// AutoCompleteTextView.OnDismissListener.
boolean invalidState =
event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
(event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
|| event.getEventType() == AccessibilityEventCompat.CONTENT_CHANGE_TYPE_PANE_TITLE)
&& isEndIconChecked
&& !autoCompleteTextView.isPopupShowing();
// If dropdown is non editable, layout click is what triggers showing/hiding the popup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
Expand All @@ -35,6 +36,7 @@
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
Expand All @@ -58,6 +60,7 @@
import com.google.android.material.internal.ThemeEnforcement;
import com.google.android.material.resources.MaterialResources;
import com.google.android.material.shape.MaterialShapeDrawable;
import java.util.List;

/**
* A special sub-class of {@link android.widget.AutoCompleteTextView} that is auto-inflated so that
Expand All @@ -73,6 +76,7 @@
public class MaterialAutoCompleteTextView extends AppCompatAutoCompleteTextView {

private static final int MAX_ITEMS_MEASURED = 15;
private static final String SWITCH_ACCESS_ACTIVITY_NAME = "SwitchAccess";

@NonNull private final ListPopupWindow modalListPopup;
@Nullable private final AccessibilityManager accessibilityManager;
Expand Down Expand Up @@ -185,7 +189,7 @@ public void onItemClick(AdapterView<?> parent, View selectedView, int position,

@Override
public void showDropDown() {
if (isTouchExplorationEnabled()) {
if (isPopupRequired()) {
modalListPopup.show();
} else {
super.showDropDown();
Expand All @@ -194,7 +198,7 @@ public void showDropDown() {

@Override
public void dismissDropDown() {
if (isTouchExplorationEnabled()) {
if (isPopupRequired()) {
modalListPopup.dismiss();
} else {
super.dismissDropDown();
Expand All @@ -203,18 +207,40 @@ public void dismissDropDown() {

@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (isTouchExplorationEnabled()) {
// Do not dismissDropDown if touch exploration is enabled, in case the window lost focus
// in favor of the modalListPopup.
if (isPopupRequired()) {
// Do not dismissDropDown if touch exploration or switch access is enabled, in case the window
// lost focus in favor of the modalListPopup.
return;
}
super.onWindowFocusChanged(hasWindowFocus);
}

private boolean isPopupRequired() {
return isTouchExplorationEnabled() || isSwitchAccessEnabled();
}

private boolean isTouchExplorationEnabled() {
return accessibilityManager != null && accessibilityManager.isTouchExplorationEnabled();
}

private boolean isSwitchAccessEnabled() {
if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
return false;
}
List<AccessibilityServiceInfo> accessibilityServiceInfos =
accessibilityManager.getEnabledAccessibilityServiceList(
AccessibilityServiceInfo.FEEDBACK_GENERIC);
if (accessibilityServiceInfos != null) {
for (AccessibilityServiceInfo info : accessibilityServiceInfos) {
if (info.getSettingsActivityName() != null
&& info.getSettingsActivityName().contains(SWITCH_ACCESS_ACTIVITY_NAME)) {
return true;
}
}
}
return false;
}

@Override
public <T extends ListAdapter & Filterable> void setAdapter(@Nullable T adapter) {
super.setAdapter(adapter);
Expand Down

0 comments on commit 14a7b40

Please sign in to comment.