From 1a70cef9884270f2f0a760f079a10fdfb1544c98 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 22 Apr 2015 11:29:51 -0700 Subject: Accessibility fixes > Enabling top bar buttons in accessibility drag-drop > Unifying logic to show delete/uninstall/app-info targets > Announcing cell loction as 1-index instead of 0-index Change-Id: Ibc7801f77e938b2646f0655462cbe9b7f781818b --- res/values/strings.xml | 4 +- src/com/android/launcher3/ButtonDropTarget.java | 19 +++++++- src/com/android/launcher3/CellLayout.java | 2 +- src/com/android/launcher3/DeleteDropTarget.java | 14 ++++-- src/com/android/launcher3/DragController.java | 5 +- src/com/android/launcher3/InfoDropTarget.java | 11 +++-- .../launcher3/LauncherAccessibilityDelegate.java | 53 +++++++++++++--------- src/com/android/launcher3/SearchDropTargetBar.java | 15 ++++++ src/com/android/launcher3/UninstallDropTarget.java | 17 +++++-- src/com/android/launcher3/Workspace.java | 1 + 10 files changed, 99 insertions(+), 42 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 52306e30e..bfe7e36f2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -309,13 +309,13 @@ s --> - Add To Workspace + Add to workspace Item added to workspace - Item removed from workspace + Item removed Move Item diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 5b399087a..fb49df5df 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -26,18 +26,19 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; import android.util.AttributeSet; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import android.view.animation.LinearInterpolator; import android.widget.TextView; -import com.android.launcher3.R; import com.android.launcher3.util.Thunk; /** * Implements a DropTarget. */ -public abstract class ButtonDropTarget extends TextView implements DropTarget, DragController.DragListener { +public abstract class ButtonDropTarget extends TextView + implements DropTarget, DragController.DragListener, OnClickListener { private static int DRAG_VIEW_DROP_DURATION = 285; @@ -256,4 +257,18 @@ public abstract class ButtonDropTarget extends TextView implements DropTarget, D public void getLocationInDragLayer(int[] loc) { mLauncher.getDragLayer().getLocationInDragLayer(this, loc); } + + public void enableAccessibleDrag(boolean enable) { + setOnClickListener(enable ? this : null); + } + + protected String getAccessibilityDropConfirmation() { + return null; + } + + @Override + public void onClick(View v) { + LauncherAppState.getInstance().getAccessibilityDelegate() + .handleAccessibleDrop(this, null, getAccessibilityDropConfirmation()); + } } diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index f4afb954d..f08f25fb2 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -557,7 +557,7 @@ public class CellLayout extends ViewGroup { Resources res = getContext().getResources(); View child = getChildAt(x, y); if (child == null || child == dragInfo.item) { - return res.getString(R.string.move_to_empty_cell, x, y); + return res.getString(R.string.move_to_empty_cell, x + 1, y + 1); } else { ItemInfo info = (ItemInfo) child.getTag(); if (info instanceof AppInfo || info instanceof ShortcutInfo) { diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index aa3e66c09..e741b9787 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -29,7 +29,6 @@ import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; -import com.android.launcher3.R; import com.android.launcher3.util.Thunk; import com.android.launcher3.widget.WidgetsContainerView; @@ -59,13 +58,15 @@ public class DeleteDropTarget extends ButtonDropTarget { setDrawable(R.drawable.remove_target_selector); } - public static boolean willAcceptDrop(DragSource source, Object info) { - return (info instanceof ItemInfo) && source.supportsDeleteDropTarget(); + public static boolean supportsDrop(Object info) { + return (info instanceof ShortcutInfo) + || (info instanceof LauncherAppWidgetInfo) + || (info instanceof FolderInfo); } @Override protected boolean supportsDrop(DragSource source, Object info) { - return willAcceptDrop(source, info); + return source.supportsDeleteDropTarget() && supportsDrop(info); } @Override @@ -304,4 +305,9 @@ public class DeleteDropTarget extends ButtonDropTarget { dragLayer.animateView(d.dragView, updateCb, duration, tInterpolator, onAnimationEndRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); } + + @Override + protected String getAccessibilityDropConfirmation() { + return getResources().getString(R.string.item_removed); + } } diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java index b24608cb1..196886895 100644 --- a/src/com/android/launcher3/DragController.java +++ b/src/com/android/launcher3/DragController.java @@ -462,8 +462,7 @@ public class DragController { mLastTouchUpTime = System.currentTimeMillis(); if (mDragging) { PointF vec = isFlingingToDelete(mDragObject.dragSource); - if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragSource, - mDragObject.dragInfo)) { + if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) { vec = null; } if (vec != null) { @@ -617,7 +616,7 @@ public class DragController { if (mDragging) { PointF vec = isFlingingToDelete(mDragObject.dragSource); - if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragSource, mDragObject.dragInfo)) { + if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) { vec = null; } if (vec != null) { diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java index e48640c93..f1ff48da3 100644 --- a/src/com/android/launcher3/InfoDropTarget.java +++ b/src/com/android/launcher3/InfoDropTarget.java @@ -21,7 +21,6 @@ import android.content.Context; import android.provider.Settings; import android.util.AttributeSet; -import com.android.launcher3.R; import com.android.launcher3.compat.UserHandleCompat; public class InfoDropTarget extends ButtonDropTarget { @@ -66,9 +65,13 @@ public class InfoDropTarget extends ButtonDropTarget { @Override protected boolean supportsDrop(DragSource source, Object info) { - return source.supportsAppInfoDropTarget() && - Settings.Global.getInt(getContext().getContentResolver(), - Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1; + return source.supportsAppInfoDropTarget() && supportsDrop(getContext(), info); + } + + public static boolean supportsDrop(Context context, Object info) { + return (Settings.Global.getInt(context.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) && + (info instanceof AppInfo || info instanceof PendingAddItemInfo); } @Override diff --git a/src/com/android/launcher3/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/LauncherAccessibilityDelegate.java index 8ba02ea5f..a60e16024 100644 --- a/src/com/android/launcher3/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/LauncherAccessibilityDelegate.java @@ -1,16 +1,13 @@ package com.android.launcher3; import android.annotation.TargetApi; -import android.content.res.Resources; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; -import android.support.v4.view.accessibility.AccessibilityEventCompat; -import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.text.TextUtils; import android.util.SparseArray; import android.view.View; import android.view.View.AccessibilityDelegate; -import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -68,18 +65,21 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { if (!(host.getTag() instanceof ItemInfo)) return; ItemInfo item = (ItemInfo) host.getTag(); + if (DeleteDropTarget.supportsDrop(item)) { + info.addAction(mActions.get(REMOVE)); + } + if (UninstallDropTarget.supportsDrop(host.getContext(), item)) { + info.addAction(mActions.get(UNINSTALL)); + } + if (InfoDropTarget.supportsDrop(host.getContext(), item)) { + info.addAction(mActions.get(INFO)); + } + if ((item instanceof ShortcutInfo) || (item instanceof LauncherAppWidgetInfo) || (item instanceof FolderInfo)) { - // Workspace shortcut / widget - info.addAction(mActions.get(REMOVE)); info.addAction(mActions.get(MOVE)); - } else if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) { - // App or Widget from customization tray - if (item instanceof AppInfo) { - info.addAction(mActions.get(UNINSTALL)); - } - info.addAction(mActions.get(INFO)); + } if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) { info.addAction(mActions.get(ADD_TO_WORKSPACE)); } } @@ -94,10 +94,9 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { } public boolean performAction(View host, ItemInfo item, int action) { - Resources res = mLauncher.getResources(); if (action == REMOVE) { if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) { - announceConfirmation(R.string.item_removed_from_workspace); + announceConfirmation(R.string.item_removed); return true; } return false; @@ -105,9 +104,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { InfoDropTarget.startDetailsActivityForInfo(item, mLauncher); return true; } else if (action == UNINSTALL) { - AppInfo info = (AppInfo) item; - mLauncher.startApplicationUninstallActivity(info.componentName, info.flags, info.user); - return true; + return UninstallDropTarget.startUninstallActivity(mLauncher, item); } else if (action == MOVE) { beginAccessibleDrag(host, item); } else if (action == ADD_TO_WORKSPACE) { @@ -158,19 +155,31 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate { return mDragInfo; } - public void handleAccessibleDrop(CellLayout targetContainer, Rect dropLocation, + /** + * @param clickedTarget the actual view that was clicked + * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used + * as the actual drop location otherwise the views center is used. + */ + public void handleAccessibleDrop(View clickedTarget, Rect dropLocation, String confirmation) { if (!isInAccessibleDrag()) return; int[] loc = new int[2]; - loc[0] = dropLocation.centerX(); - loc[1] = dropLocation.centerY(); + if (dropLocation == null) { + loc[0] = clickedTarget.getWidth() / 2; + loc[1] = clickedTarget.getHeight() / 2; + } else { + loc[0] = dropLocation.centerX(); + loc[1] = dropLocation.centerY(); + } - mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(targetContainer, loc); + mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc); mLauncher.getDragController().completeAccessibleDrag(loc); endAccessibleDrag(); - announceConfirmation(confirmation); + if (!TextUtils.isEmpty(confirmation)) { + announceConfirmation(confirmation); + } } public void beginAccessibleDrag(View item, ItemInfo info) { diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java index af8bc7580..44a76b73b 100644 --- a/src/com/android/launcher3/SearchDropTargetBar.java +++ b/src/com/android/launcher3/SearchDropTargetBar.java @@ -180,6 +180,9 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D prepareStartAnimation(mDropTargetBar); mShowDropTargetBarAnim.start(); hideSearchBar(true); + if (mQSBSearchBar != null) { + mQSBSearchBar.setVisibility(View.GONE); + } } /** @@ -190,6 +193,9 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D prepareStartAnimation(mDropTargetBar); mShowDropTargetBarAnim.reverse(); showSearchBar(true); + if (mQSBSearchBar != null) { + mQSBSearchBar.setVisibility(View.VISIBLE); + } } /* @@ -228,4 +234,13 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D return null; } } + + public void enableAccessibleDrag(boolean enable) { + if (mQSBSearchBar != null) { + mQSBSearchBar.setVisibility(enable ? View.GONE : View.VISIBLE); + } + mInfoDropTarget.enableAccessibleDrag(enable); + mDeleteDropTarget.enableAccessibleDrag(enable); + mUninstallDropTarget.enableAccessibleDrag(enable); + } } diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java index 4a7fffeb2..4c52d7e0f 100644 --- a/src/com/android/launcher3/UninstallDropTarget.java +++ b/src/com/android/launcher3/UninstallDropTarget.java @@ -33,9 +33,12 @@ public class UninstallDropTarget extends ButtonDropTarget { @Override protected boolean supportsDrop(DragSource source, Object info) { + return supportsDrop(getContext(), info); + } + + public static boolean supportsDrop(Context context, Object info) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - UserManager userManager = (UserManager) - getContext().getSystemService(Context.USER_SERVICE); + UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); Bundle restrictions = userManager.getUserRestrictions(); if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false) || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) { @@ -78,8 +81,7 @@ public class UninstallDropTarget extends ButtonDropTarget { void completeDrop(final DragObject d) { final Pair componentInfo = getAppInfoFlags(d.dragInfo); final UserHandleCompat user = ((ItemInfo) d.dragInfo).user; - if (mLauncher.startApplicationUninstallActivity( - componentInfo.first, componentInfo.second, user)) { + if (startUninstallActivity(mLauncher, d.dragInfo)) { final Runnable checkIfUninstallWasSuccess = new Runnable() { @Override @@ -96,6 +98,13 @@ public class UninstallDropTarget extends ButtonDropTarget { } } + public static boolean startUninstallActivity(Launcher launcher, Object info) { + final Pair componentInfo = getAppInfoFlags(info); + final UserHandleCompat user = ((ItemInfo) info).user; + return launcher.startApplicationUninstallActivity( + componentInfo.first, componentInfo.second, user); + } + @Thunk void sendUninstallResult(DragSource target, boolean result) { if (target instanceof UninstallSource) { ((UninstallSource) target).onUninstallActivityReturned(result); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index abb8489fd..0ae4ffa22 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1615,6 +1615,7 @@ public class Workspace extends SmoothPagedView // Reset our click listener setOnClickListener(mLauncher); } + mLauncher.getSearchBar().enableAccessibleDrag(enable); mLauncher.getHotseat().getLayout().enableAccessibleDrag(enable); } -- cgit v1.2.3