Loading src/com/android/documentsui/HorizontalBreadcrumb.java +4 −3 Original line number Diff line number Diff line Loading @@ -17,8 +17,6 @@ package com.android.documentsui; import android.content.Context; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.KeyEvent; Loading @@ -28,6 +26,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.NavigationViewManager.Breadcrumb; import com.android.documentsui.NavigationViewManager.Environment; import com.android.documentsui.base.DocumentInfo; Loading Loading @@ -77,7 +78,7 @@ public final class HorizontalBreadcrumb extends RecyclerView // for more details on how we are routing these a11y events. setAccessibilityDelegateCompat( new AccessibilityEventRouter(this, (View child) -> onAccessibilityClick(child))); (View child) -> onAccessibilityClick(child), null)); setLayoutManager(mLayoutManager); addOnItemTouchListener(new ClickListener(getContext(), this::onSingleTapUp)); Loading src/com/android/documentsui/dirlist/AccessibilityEventRouter.java +18 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.documentsui.dirlist; import android.os.Bundle; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; Loading @@ -45,11 +47,14 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate private final ItemDelegate mItemDelegate; private final Function<View, Boolean> mClickCallback; private final Function<View, Boolean> mLongClickCallback; public AccessibilityEventRouter( RecyclerView recyclerView, Function<View, Boolean> clickCallback) { RecyclerView recyclerView, @NonNull Function<View, Boolean> clickCallback, @Nullable Function<View, Boolean> longClickCallback) { super(recyclerView); mClickCallback = clickCallback; mLongClickCallback = longClickCallback; mItemDelegate = new ItemDelegate(this) { @Override public void onInitializeAccessibilityNodeInfo(View host, Loading @@ -60,11 +65,10 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate // is null, it can't be clicked if (holder instanceof DocumentHolder) { if (((DocumentHolder)holder).getItemDetails() != null) { info.addAction(AccessibilityActionCompat.ACTION_CLICK); info.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); addAction(info); } } else { info.addAction(AccessibilityActionCompat.ACTION_CLICK); addAction(info); } info.setSelected(host.isActivated()); } Loading @@ -74,6 +78,9 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate // We are only handling click events; route all other to default implementation if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) { return mClickCallback.apply(host); } else if (action == AccessibilityNodeInfoCompat.ACTION_LONG_CLICK && mLongClickCallback != null) { return mLongClickCallback.apply(host); } return super.performAccessibilityAction(host, action, args); } Loading @@ -84,4 +91,11 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate public AccessibilityDelegateCompat getItemDelegate() { return mItemDelegate; } private void addAction(AccessibilityNodeInfoCompat info) { info.addAction(AccessibilityActionCompat.ACTION_CLICK); if (mLongClickCallback != null) { info.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); } } } No newline at end of file src/com/android/documentsui/dirlist/DirectoryFragment.java +17 −7 Original line number Diff line number Diff line Loading @@ -325,7 +325,8 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On mRecView.setAccessibilityDelegateCompat( new AccessibilityEventRouter(mRecView, (View child) -> onAccessibilityClick(child))); (View child) -> onAccessibilityClick(child), (View child) -> onAccessibilityLongClick(child))); mSelectionMetadata = new SelectionMetadata(mModel::getItem); mDetailsLookup = new DocsItemDetailsLookup(mRecView); Loading Loading @@ -765,12 +766,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On private boolean onAccessibilityClick(View child) { if (mSelectionMgr.hasSelection()) { final String id = getModelId(child); if (mSelectionMgr.isSelected(id)) { mSelectionMgr.deselect(id); } else { mSelectionMgr.select(id); } selectItem(child); } else { DocumentHolder holder = getDocumentHolder(child); mActions.openItem(holder.getItemDetails(), ActionHandler.VIEW_TYPE_PREVIEW, Loading @@ -779,6 +775,20 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On return true; } private boolean onAccessibilityLongClick(View child) { selectItem(child); return true; } private void selectItem(View child) { final String id = getModelId(child); if (mSelectionMgr.isSelected(id)) { mSelectionMgr.deselect(id); } else { mSelectionMgr.select(id); } } private void cancelThumbnailTask(View view) { final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb); if (iconThumb != null) { Loading tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java +21 −7 Original line number Diff line number Diff line Loading @@ -16,15 +16,15 @@ package com.android.documentsui.dirlist; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import android.database.Cursor; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.view.View; import android.widget.Space; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.testing.TestRecyclerView; import com.android.documentsui.testing.Views; Loading @@ -38,13 +38,17 @@ public class AccessibilityTest extends AndroidTestCase { private TestRecyclerView mView; private AccessibilityEventRouter mAccessibilityDelegate; private boolean mCallbackCalled = false; private boolean mClickCallbackCalled = false; private boolean mLongClickCallbackCalled = false; @Override public void setUp() throws Exception { mView = TestRecyclerView.create(ITEMS); mAccessibilityDelegate = new AccessibilityEventRouter(mView, (View v) -> { mCallbackCalled = true; mClickCallbackCalled = true; return true; }, (View v) -> { mLongClickCallbackCalled = true; return true; }); mView.setAccessibilityDelegateCompat(mAccessibilityDelegate); Loading Loading @@ -79,7 +83,17 @@ public class AccessibilityTest extends AndroidTestCase { View item = Views.createTestView(true); AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info); mAccessibilityDelegate.getItemDelegate().performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null); assertTrue(mCallbackCalled); mAccessibilityDelegate.getItemDelegate() .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null); assertTrue(mClickCallbackCalled); } public void test_routesAccessibilityLongClicks() throws Exception { View item = Views.createTestView(true); AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info); mAccessibilityDelegate.getItemDelegate() .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null); assertTrue(mLongClickCallbackCalled); } } Loading
src/com/android/documentsui/HorizontalBreadcrumb.java +4 −3 Original line number Diff line number Diff line Loading @@ -17,8 +17,6 @@ package com.android.documentsui; import android.content.Context; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.KeyEvent; Loading @@ -28,6 +26,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.NavigationViewManager.Breadcrumb; import com.android.documentsui.NavigationViewManager.Environment; import com.android.documentsui.base.DocumentInfo; Loading Loading @@ -77,7 +78,7 @@ public final class HorizontalBreadcrumb extends RecyclerView // for more details on how we are routing these a11y events. setAccessibilityDelegateCompat( new AccessibilityEventRouter(this, (View child) -> onAccessibilityClick(child))); (View child) -> onAccessibilityClick(child), null)); setLayoutManager(mLayoutManager); addOnItemTouchListener(new ClickListener(getContext(), this::onSingleTapUp)); Loading
src/com/android/documentsui/dirlist/AccessibilityEventRouter.java +18 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.documentsui.dirlist; import android.os.Bundle; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; Loading @@ -45,11 +47,14 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate private final ItemDelegate mItemDelegate; private final Function<View, Boolean> mClickCallback; private final Function<View, Boolean> mLongClickCallback; public AccessibilityEventRouter( RecyclerView recyclerView, Function<View, Boolean> clickCallback) { RecyclerView recyclerView, @NonNull Function<View, Boolean> clickCallback, @Nullable Function<View, Boolean> longClickCallback) { super(recyclerView); mClickCallback = clickCallback; mLongClickCallback = longClickCallback; mItemDelegate = new ItemDelegate(this) { @Override public void onInitializeAccessibilityNodeInfo(View host, Loading @@ -60,11 +65,10 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate // is null, it can't be clicked if (holder instanceof DocumentHolder) { if (((DocumentHolder)holder).getItemDetails() != null) { info.addAction(AccessibilityActionCompat.ACTION_CLICK); info.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); addAction(info); } } else { info.addAction(AccessibilityActionCompat.ACTION_CLICK); addAction(info); } info.setSelected(host.isActivated()); } Loading @@ -74,6 +78,9 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate // We are only handling click events; route all other to default implementation if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) { return mClickCallback.apply(host); } else if (action == AccessibilityNodeInfoCompat.ACTION_LONG_CLICK && mLongClickCallback != null) { return mLongClickCallback.apply(host); } return super.performAccessibilityAction(host, action, args); } Loading @@ -84,4 +91,11 @@ public class AccessibilityEventRouter extends RecyclerViewAccessibilityDelegate public AccessibilityDelegateCompat getItemDelegate() { return mItemDelegate; } private void addAction(AccessibilityNodeInfoCompat info) { info.addAction(AccessibilityActionCompat.ACTION_CLICK); if (mLongClickCallback != null) { info.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); } } } No newline at end of file
src/com/android/documentsui/dirlist/DirectoryFragment.java +17 −7 Original line number Diff line number Diff line Loading @@ -325,7 +325,8 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On mRecView.setAccessibilityDelegateCompat( new AccessibilityEventRouter(mRecView, (View child) -> onAccessibilityClick(child))); (View child) -> onAccessibilityClick(child), (View child) -> onAccessibilityLongClick(child))); mSelectionMetadata = new SelectionMetadata(mModel::getItem); mDetailsLookup = new DocsItemDetailsLookup(mRecView); Loading Loading @@ -765,12 +766,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On private boolean onAccessibilityClick(View child) { if (mSelectionMgr.hasSelection()) { final String id = getModelId(child); if (mSelectionMgr.isSelected(id)) { mSelectionMgr.deselect(id); } else { mSelectionMgr.select(id); } selectItem(child); } else { DocumentHolder holder = getDocumentHolder(child); mActions.openItem(holder.getItemDetails(), ActionHandler.VIEW_TYPE_PREVIEW, Loading @@ -779,6 +775,20 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On return true; } private boolean onAccessibilityLongClick(View child) { selectItem(child); return true; } private void selectItem(View child) { final String id = getModelId(child); if (mSelectionMgr.isSelected(id)) { mSelectionMgr.deselect(id); } else { mSelectionMgr.select(id); } } private void cancelThumbnailTask(View view) { final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb); if (iconThumb != null) { Loading
tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java +21 −7 Original line number Diff line number Diff line Loading @@ -16,15 +16,15 @@ package com.android.documentsui.dirlist; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import android.database.Cursor; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.view.View; import android.widget.Space; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.testing.TestRecyclerView; import com.android.documentsui.testing.Views; Loading @@ -38,13 +38,17 @@ public class AccessibilityTest extends AndroidTestCase { private TestRecyclerView mView; private AccessibilityEventRouter mAccessibilityDelegate; private boolean mCallbackCalled = false; private boolean mClickCallbackCalled = false; private boolean mLongClickCallbackCalled = false; @Override public void setUp() throws Exception { mView = TestRecyclerView.create(ITEMS); mAccessibilityDelegate = new AccessibilityEventRouter(mView, (View v) -> { mCallbackCalled = true; mClickCallbackCalled = true; return true; }, (View v) -> { mLongClickCallbackCalled = true; return true; }); mView.setAccessibilityDelegateCompat(mAccessibilityDelegate); Loading Loading @@ -79,7 +83,17 @@ public class AccessibilityTest extends AndroidTestCase { View item = Views.createTestView(true); AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info); mAccessibilityDelegate.getItemDelegate().performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null); assertTrue(mCallbackCalled); mAccessibilityDelegate.getItemDelegate() .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null); assertTrue(mClickCallbackCalled); } public void test_routesAccessibilityLongClicks() throws Exception { View item = Views.createTestView(true); AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info); mAccessibilityDelegate.getItemDelegate() .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null); assertTrue(mLongClickCallbackCalled); } }