diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2018-05-15 13:55:57 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2018-05-16 13:11:00 -0700 |
commit | de7532154259ed79d7ed6d2fcc9e82ff2860a5a3 (patch) | |
tree | a8865d45fd1ce0b2dc6d01beee460e34b35d27a3 /src/com | |
parent | 6ae02c6a61e2d2c7014bd5f8b2a0266c5b802245 (diff) | |
download | android_packages_apps_Trebuchet-de7532154259ed79d7ed6d2fcc9e82ff2860a5a3.tar.gz android_packages_apps_Trebuchet-de7532154259ed79d7ed6d2fcc9e82ff2860a5a3.tar.bz2 android_packages_apps_Trebuchet-de7532154259ed79d7ed6d2fcc9e82ff2860a5a3.zip |
Fixing wrong accessibility focus when opening a floating view
> Using common logic for announcing a floating view for widgets and folders
Bug: 79091095
Bug: 79748886
Change-Id: Ibb3fe48e68e724f50d69f51a03d3b35ad0baf625
Diffstat (limited to 'src/com')
10 files changed, 103 insertions, 73 deletions
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index 097c3415c..5a1c1580a 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -16,10 +16,18 @@ package com.android.launcher3; +import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; +import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED; +import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; + +import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled; +import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; + import android.annotation.SuppressLint; import android.content.Context; import android.support.annotation.IntDef; import android.util.AttributeSet; +import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; @@ -123,6 +131,25 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch return false; } + protected void announceAccessibilityChanges() { + Pair<View, String> targetInfo = getAccessibilityTarget(); + if (targetInfo == null || !isAccessibilityEnabled(getContext())) { + return; + } + sendCustomAccessibilityEvent( + targetInfo.first, TYPE_WINDOW_STATE_CHANGED, targetInfo.second); + + if (mIsOpen) { + sendAccessibilityEvent(TYPE_VIEW_FOCUSED); + } + BaseDraggingActivity.fromContext(getContext()).getDragLayer() + .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED); + } + + protected Pair<View, String> getAccessibilityTarget() { + return null; + } + protected static <T extends AbstractFloatingView> T getOpenView( BaseDraggingActivity activity, @FloatingViewType int type) { BaseDragLayer dragLayer = activity.getDragLayer(); diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 7fef904c2..53e9e2dac 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -28,8 +28,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; @@ -126,18 +124,6 @@ public class DragLayer extends BaseDragLayer<Launcher> { return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); } - public boolean isEventOverHotseat(MotionEvent ev) { - return isEventOverView(mActivity.getHotseat(), ev); - } - - private boolean isEventOverFolder(Folder folder, MotionEvent ev) { - return isEventOverView(folder, ev); - } - - private boolean isEventOverDropTargetBar(MotionEvent ev) { - return isEventOverView(mActivity.getDropTargetBar(), ev); - } - @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { ViewScrim scrim = ViewScrim.get(child); @@ -157,24 +143,29 @@ public class DragLayer extends BaseDragLayer<Launcher> { return super.findActiveController(ev); } + private boolean isEventOverAccessibleDropTargetBar(MotionEvent ev) { + return isInAccessibleDrag() && isEventOverView(mActivity.getDropTargetBar(), ev); + } + @Override public boolean onInterceptHoverEvent(MotionEvent ev) { if (mActivity == null || mActivity.getWorkspace() == null) { return false; } - Folder currentFolder = Folder.getOpen(mActivity); - if (currentFolder == null) { + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + if (!(topView instanceof Folder)) { return false; } else { AccessibilityManager accessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); if (accessibilityManager.isTouchExplorationEnabled()) { + Folder currentFolder = (Folder) topView; final int action = ev.getAction(); boolean isOverFolderOrSearchBar; switch (action) { case MotionEvent.ACTION_HOVER_ENTER: - isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || - (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); + isOverFolderOrSearchBar = isEventOverView(topView, ev) || + isEventOverAccessibleDropTargetBar(ev); if (!isOverFolderOrSearchBar) { sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); mHoverPointClosesFolder = true; @@ -183,8 +174,8 @@ public class DragLayer extends BaseDragLayer<Launcher> { mHoverPointClosesFolder = false; break; case MotionEvent.ACTION_HOVER_MOVE: - isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || - (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); + isOverFolderOrSearchBar = isEventOverView(topView, ev) || + isEventOverAccessibleDropTargetBar(ev); if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) { sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); mHoverPointClosesFolder = true; @@ -219,18 +210,8 @@ public class DragLayer extends BaseDragLayer<Launcher> { @Override public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { - // Shortcuts can appear above folder - View topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null) { - if (child == topView) { - return super.onRequestSendAccessibilityEvent(child, event); - } - if (isInAccessibleDrag() && child instanceof DropTargetBar) { - return super.onRequestSendAccessibilityEvent(child, event); - } - // Skip propagating onRequestSendAccessibilityEvent for all other children - // which are not topView - return false; + if (isInAccessibleDrag() && child instanceof DropTargetBar) { + return true; } return super.onRequestSendAccessibilityEvent(child, event); } @@ -239,11 +220,9 @@ public class DragLayer extends BaseDragLayer<Launcher> { public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) { View topView = AbstractFloatingView.getTopOpenView(mActivity); if (topView != null) { - // Only add the top view as a child for accessibility when it is open - childrenForAccessibility.add(topView); - + addAccessibleChildToList(topView, childrenForAccessibility); if (isInAccessibleDrag()) { - childrenForAccessibility.add(mActivity.getDropTargetBar()); + addAccessibleChildToList(mActivity.getDropTargetBar(), childrenForAccessibility); } } else { super.addChildrenForAccessibility(childrenForAccessibility); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 99c800d14..b49952f15 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -31,6 +31,7 @@ import android.text.InputType; import android.text.Selection; import android.util.AttributeSet; import android.util.Log; +import android.util.Pair; import android.view.ActionMode; import android.view.FocusFinder; import android.view.KeyEvent; @@ -516,15 +517,11 @@ public class Folder extends AbstractFloatingView implements DragSource, public void onAnimationStart(Animator animation) { mFolderIcon.setBackgroundVisible(false); mFolderIcon.drawLeaveBehindIfExists(); - - sendCustomAccessibilityEvent( - Folder.this, - AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, - mContent.getAccessibilityDescription()); } @Override public void onAnimationEnd(Animator animation) { mState = STATE_OPEN; + announceAccessibilityChanges(); mLauncher.getUserEventDispatcher().resetElapsedContainerMillis("folder opened"); mContent.setFocusOnFirstChild(); @@ -574,11 +571,6 @@ public class Folder extends AbstractFloatingView implements DragSource, } mContent.verifyVisibleHighResIcons(mContent.getNextPage()); - - // Notify the accessibility manager that this folder "window" has appeared and occluded - // the workspace items - sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - dragLayer.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } public void beginExternalDrag() { @@ -612,6 +604,7 @@ public class Folder extends AbstractFloatingView implements DragSource, animateClosed(); } else { closeComplete(false); + post(this::announceAccessibilityChanges); } // Notify the accessibility manager that this folder "window" has disappeared and no @@ -626,18 +619,18 @@ public class Folder extends AbstractFloatingView implements DragSource, @Override public void onAnimationEnd(Animator animation) { closeComplete(true); - } - @Override - public void onAnimationStart(Animator animation) { - sendCustomAccessibilityEvent( - Folder.this, - AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, - getContext().getString(R.string.folder_closed)); + announceAccessibilityChanges(); } }); startAnimation(a); } + @Override + protected Pair<View, String> getAccessibilityTarget() { + return Pair.create(mContent, mIsOpen ? mContent.getAccessibilityDescription() + : getContext().getString(R.string.folder_closed)); + } + private void closeComplete(boolean wasAnimated) { // TODO: Clear all active animations. DragLayer parent = (DragLayer) getParent(); diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 5589f1714..90987775b 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -367,6 +367,7 @@ public abstract class ArrowPopup extends AbstractFloatingView { openAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + announceAccessibilityChanges(); mOpenCloseAnimator = null; } }); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 763eb6fb6..f276fbfea 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -34,6 +34,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; +import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; @@ -263,9 +264,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag(); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - setAccessibilityPaneTitle(getContext().getString(mNumNotifications == 0 ? - R.string.action_deep_shortcut : - R.string.shortcuts_menu_with_notifications_description)); + setAccessibilityPaneTitle(getTitleForAccessibility()); } mLauncher.getDragController().addDragListener(this); @@ -281,6 +280,17 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, this, shortcutIds, mShortcuts, notificationKeys)); } + private String getTitleForAccessibility() { + return getContext().getString(mNumNotifications == 0 ? + R.string.action_deep_shortcut : + R.string.shortcuts_menu_with_notifications_description); + } + + @Override + protected Pair<View, String> getAccessibilityTarget() { + return Pair.create(this, ""); + } + @Override protected void getTargetObjectLocation(Rect outPos) { mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos); diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java index 7c4529dd7..c8d14572e 100644 --- a/src/com/android/launcher3/views/AbstractSlideInView.java +++ b/src/com/android/launcher3/views/AbstractSlideInView.java @@ -81,6 +81,7 @@ public abstract class AbstractSlideInView extends AbstractFloatingView @Override public void onAnimationEnd(Animator animation) { mSwipeDetector.finishedScrolling(); + announceAccessibilityChanges(); } }); } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 66d9498a9..2f142acc9 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -117,12 +117,20 @@ public abstract class BaseDragLayer<T extends BaseDraggingActivity> extends Inse View topView = AbstractFloatingView.getTopOpenView(mActivity); if (topView != null) { // Only add the top view as a child for accessibility when it is open - childrenForAccessibility.add(topView); + addAccessibleChildToList(topView, childrenForAccessibility); } else { super.addChildrenForAccessibility(childrenForAccessibility); } } + protected void addAccessibleChildToList(View child, ArrayList<View> outList) { + if (child.isImportantForAccessibility()) { + outList.add(child); + } else { + child.addChildrenForAccessibility(outList); + } + } + @Override public void onViewRemoved(View child) { super.onViewRemoved(child); diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index a2584852b..5ce7e0453 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -20,6 +20,7 @@ import android.animation.PropertyValuesHolder; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.Pair; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -72,7 +73,7 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { mLauncher.getDragLayer().addView(this); mIsOpen = false; - open(true); + animateOpen(); } @Override @@ -129,20 +130,16 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { return widget; } - private void open(boolean animate) { + private void animateOpen() { if (mIsOpen || mOpenCloseAnimator.isRunning()) { return; } mIsOpen = true; setupNavBarColor(); - if (animate) { - mOpenCloseAnimator.setValues( - PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED)); - mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mOpenCloseAnimator.start(); - } else { - setTranslationShift(TRANSLATION_SHIFT_OPENED); - } + mOpenCloseAnimator.setValues( + PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED)); + mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mOpenCloseAnimator.start(); } @Override @@ -170,4 +167,10 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { protected int getElementsRowCount() { return 1; } + + @Override + protected Pair<View, String> getAccessibilityTarget() { + return Pair.create(findViewById(R.id.title), getContext().getString( + mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed)); + } } diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java index a622624dc..e94d81d75 100644 --- a/src/com/android/launcher3/widget/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java @@ -21,8 +21,10 @@ import android.animation.PropertyValuesHolder; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.Pair; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.View; import android.view.animation.AnimationUtils; import com.android.launcher3.Insettable; @@ -55,6 +57,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet mAdapter = new WidgetsListAdapter(context, LayoutInflater.from(context), apps.getWidgetCache(), apps.getIconCache(), this, this); + } public WidgetsFullSheet(Context context, AttributeSet attrs) { @@ -77,6 +80,12 @@ public class WidgetsFullSheet extends BaseWidgetSheet } @Override + protected Pair<View, String> getAccessibilityTarget() { + return Pair.create(mRecyclerView, getContext().getString( + mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed)); + } + + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mLauncher.getAppWidgetHost().addProviderChangeListener(this); @@ -149,10 +158,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet } private void open(boolean animate) { - if (mIsOpen) { - return; - } - mIsOpen = true; if (animate) { if (mLauncher.getDragLayer().getInsets().bottom > 0) { mContent.setAlpha(0); @@ -180,6 +185,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet } else { setTranslationShift(TRANSLATION_SHIFT_OPENED); mAdapter.setApplyBitmapDeferred(false, mRecyclerView); + post(this::announceAccessibilityChanges); } } @@ -212,6 +218,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet public static WidgetsFullSheet show(Launcher launcher, boolean animate) { WidgetsFullSheet sheet = (WidgetsFullSheet) launcher.getLayoutInflater() .inflate(R.layout.widgets_full_sheet, launcher.getDragLayer(), false); + sheet.mIsOpen = true; launcher.getDragLayer().addView(sheet); sheet.open(animate); return sheet; diff --git a/src/com/android/launcher3/widget/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java index bc85db610..8f269a643 100644 --- a/src/com/android/launcher3/widget/WidgetsRowViewHolder.java +++ b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java @@ -29,7 +29,8 @@ public class WidgetsRowViewHolder extends ViewHolder { public WidgetsRowViewHolder(ViewGroup v) { super(v); - cellContainer = (ViewGroup) v.findViewById(R.id.widgets_cell_list); - title = (BubbleTextView) v.findViewById(R.id.section); + cellContainer = v.findViewById(R.id.widgets_cell_list); + title = v.findViewById(R.id.section); + title.setAccessibilityDelegate(null); } } |