summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/com/android/launcher3/AppWidgetResizeFrame.java12
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java2
-rw-r--r--src/com/android/launcher3/CellLayout.java17
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java5
-rw-r--r--src/com/android/launcher3/DropTarget.java4
-rw-r--r--src/com/android/launcher3/Folder.java5
-rw-r--r--src/com/android/launcher3/Utilities.java22
-rw-r--r--src/com/android/launcher3/Workspace.java78
-rw-r--r--src/com/android/launcher3/accessibility/DragViewStateAnnouncer.java57
-rw-r--r--src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java7
-rw-r--r--src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java37
-rw-r--r--src/com/android/launcher3/dragndrop/DragController.java17
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java8
14 files changed, 206 insertions, 69 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7947fbd4a..f09f72a81 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -48,6 +48,8 @@
<!-- Widgets -->
<!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
<string name="long_press_widget_to_add">Touch &amp; hold to pick up a widget.</string>
+ <!-- Accessibility spoken hint message in widget picker, which allows user to add a widget. Custom action is the label for additional accessibility actions available in this mode [CHAR_LIMIT=100] -->
+ <string name="long_accessible_way_to_add">Double-tap &amp; hold to pick up a widget or use custom actions.</string>
<!-- The format string for the dimensions of a widget in the drawer -->
<!-- There is a special version of this format string for Farsi -->
<string name="widget_dims_format">%1$d \u00d7 %2$d</string>
@@ -123,6 +125,8 @@
<string name="default_scroll_format">Page %1$d of %2$d</string>
<!-- The format string for Workspace page scroll text [CHAR_LIMIT=none] -->
<string name="workspace_scroll_format">Home screen %1$d of %2$d</string>
+ <!-- Description for a new page on homescreen[CHAR_LIMIT=none] -->
+ <string name="workspace_new_page">New home screen page</string>
<!-- Clings -->
<!-- The title text for the workspace cling [CHAR_LIMIT=30] -->
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 6818929f7..7bd5284fc 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -17,6 +17,8 @@ import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.launcher3.accessibility.DragViewStateAnnouncer;
+
public class AppWidgetResizeFrame extends FrameLayout {
private static final int SNAP_DURATION = 150;
private static final float DIMMED_HANDLE_ALPHA = 0f;
@@ -46,6 +48,8 @@ public class AppWidgetResizeFrame extends FrameLayout {
private final int[] mLastDirectionVector = new int[2];
private final int[] mTmpPt = new int[2];
+ private final DragViewStateAnnouncer mStateAnnouncer;
+
private boolean mLeftBorderActive;
private boolean mRightBorderActive;
private boolean mTopBorderActive;
@@ -84,6 +88,8 @@ public class AppWidgetResizeFrame extends FrameLayout {
mMinHSpan = info.minSpanX;
mMinVSpan = info.minSpanY;
+ mStateAnnouncer = DragViewStateAnnouncer.createFor(this);
+
setBackgroundResource(R.drawable.widget_resize_shadow);
setForeground(getResources().getDrawable(R.drawable.widget_resize_frame));
setPadding(0, 0, 0, 0);
@@ -326,12 +332,18 @@ public class AppWidgetResizeFrame extends FrameLayout {
if (mCellLayout.createAreaForResize(cellX, cellY, spanX, spanY, mWidgetView,
mDirectionVector, onDismiss)) {
+ if (mStateAnnouncer != null && (lp.cellHSpan != spanX || lp.cellVSpan != spanY) ) {
+ mStateAnnouncer.announce(
+ mLauncher.getString(R.string.widget_resized, spanX, spanY));
+ }
+
lp.tmpCellX = cellX;
lp.tmpCellY = cellY;
lp.cellHSpan = spanX;
lp.cellVSpan = spanY;
mRunningVInc += vSpanDelta;
mRunningHInc += hSpanDelta;
+
if (!onDismiss) {
updateWidgetSizeRanges(mWidgetView, mLauncher, spanX, spanY);
}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 703de5326..56f209e8c 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -34,6 +34,7 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;
@@ -126,6 +127,7 @@ public abstract class ButtonDropTarget extends TextView
mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
setTextColor(mHoverColor);
}
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
}
@Override
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index b8b41443e..92e4043df 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -1042,7 +1042,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
}
void visualizeDropLocation(View v, Bitmap dragOutline, int originX, int originY, int cellX,
- int cellY, int spanX, int spanY, boolean resize, Point dragOffset, Rect dragRegion) {
+ int cellY, int spanX, int spanY, boolean resize, DropTarget.DragObject dragObject) {
final int oldDragCellX = mDragCell[0];
final int oldDragCellY = mDragCell[1];
@@ -1051,6 +1051,9 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
}
if (cellX != oldDragCellX || cellY != oldDragCellY) {
+ Point dragOffset = dragObject.dragView.getDragVisualizeOffset();
+ Rect dragRegion = dragObject.dragView.getDragRegion();
+
mDragCell[0] = cellX;
mDragCell[1] = cellY;
@@ -1106,6 +1109,18 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
Utilities.scaleRectAboutCenter(r, getChildrenScale());
mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
mDragOutlineAnims[mDragOutlineCurrent].animateIn();
+
+ if (dragObject.stateAnnouncer != null) {
+ String msg;
+ if (isHotseat()) {
+ msg = getContext().getString(R.string.move_to_hotseat_position,
+ Math.max(cellX, cellY) + 1);
+ } else {
+ msg = getContext().getString(R.string.move_to_empty_cell,
+ cellY + 1, cellX + 1);
+ }
+ dragObject.stateAnnouncer.announce(msg);
+ }
}
}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9b65a7127..3a79d94fa 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -67,15 +67,14 @@ public class DeleteDropTarget extends ButtonDropTarget {
/**
* Removes the item from the workspace. If the view is not null, it also removes the view.
- * @return true if the item was removed.
*/
- public static boolean removeWorkspaceOrFolderItem(Launcher launcher, ItemInfo item, View view) {
+ public static void removeWorkspaceOrFolderItem(Launcher launcher, ItemInfo item, View view) {
// Remove the item from launcher and the db, we can ignore the containerInfo in this call
// because we already remove the drag view from the folder (if the drag originated from
// a folder) in Folder.beginDrag()
launcher.removeItem(view, item, true /* deleteFromDb */);
launcher.getWorkspace().stripEmptyScreens();
- return true;
+ launcher.getDragLayer().announceForAccessibility(launcher.getString(R.string.item_removed));
}
@Override
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index 592cd3277..bab46d9f4 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -21,6 +21,8 @@ import com.android.launcher3.dragndrop.DragView;
import android.graphics.PointF;
import android.graphics.Rect;
+import com.android.launcher3.accessibility.DragViewStateAnnouncer;
+
/**
* Interface defining an object that can receive a drag.
*
@@ -66,6 +68,8 @@ public interface DropTarget {
/** Defers removing the DragView from the DragLayer until after the drop animation. */
public boolean deferDragViewCleanupPostAnimation = true;
+ public DragViewStateAnnouncer stateAnnouncer;
+
public DragObject() {
}
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 5c4df7426..7f8917ccd 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -716,6 +716,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
mReorderAlarm.setAlarm(REORDER_DELAY);
mPrevTargetRank = mTargetRank;
+
+ if (d.stateAnnouncer != null) {
+ d.stateAnnouncer.announce(getContext().getString(R.string.move_to_position,
+ mTargetRank + 1));
+ }
}
float x = r[0];
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 2587e5c44..31c141460 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -47,7 +47,10 @@ import android.graphics.drawable.PaintDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
+import android.text.Spannable;
+import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.style.TtsSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
@@ -729,7 +732,6 @@ public final class Utilities {
return String.format(Locale.ENGLISH, "%s IN (%s)", columnName, TextUtils.join(", ", values));
}
- @SuppressWarnings({"unchecked", "rawtypes"})
public static boolean isBootCompleted() {
try {
Class clazz = Class.forName("android.os.SystemProperties");
@@ -751,4 +753,22 @@ public final class Utilities {
public static int boundInRange(int value, int lowerBound, int upperBound) {
return Math.max(lowerBound, Math.min(value, upperBound));
}
+
+ /**
+ * Wraps a message with a TTS span, so that a different message is spoken than
+ * what is getting displayed.
+ * @param msg original message
+ * @param ttsMsg message to be spoken
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public static CharSequence wrapForTts(CharSequence msg, String ttsMsg) {
+ if (Utilities.ATLEAST_LOLLIPOP) {
+ SpannableString spanned = new SpannableString(msg);
+ spanned.setSpan(new TtsSpan.TextBuilder(ttsMsg).build(),
+ 0, spanned.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ return spanned;
+ } else {
+ return msg;
+ }
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index d923c2016..5e052243c 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -64,6 +64,7 @@ import com.android.launcher3.UninstallDropTarget.UninstallSource;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.AccessibilityDragSource;
import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate;
+import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dragndrop.DragController;
@@ -2037,7 +2038,7 @@ public class Workspace extends PagedView
}
setImportantForAccessibility((mState == State.NORMAL || mState == State.OVERVIEW)
? IMPORTANT_FOR_ACCESSIBILITY_AUTO
- : IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+ : IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
} else {
int accessible = mState == State.NORMAL ?
IMPORTANT_FOR_ACCESSIBILITY_AUTO :
@@ -2492,11 +2493,14 @@ public class Workspace extends PagedView
return true;
}
- boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell, float
- distance, boolean considerTimeout) {
+ boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
+ float distance, boolean considerTimeout) {
if (distance > mMaxDistanceForFolderCreation) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+ return willCreateUserFolder(info, dropOverView, considerTimeout);
+ }
+ boolean willCreateUserFolder(ItemInfo info, View dropOverView, boolean considerTimeout) {
if (dropOverView != null) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) dropOverView.getLayoutParams();
if (lp.useTmpCoords && (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.tmpCellY)) {
@@ -2516,7 +2520,7 @@ public class Workspace extends PagedView
boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo);
boolean willBecomeShortcut =
(info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
- info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT);
+ info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT);
return (aboveShortcut && willBecomeShortcut);
}
@@ -2525,7 +2529,10 @@ public class Workspace extends PagedView
float distance) {
if (distance > mMaxDistanceForFolderCreation) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
+ return willAddToExistingUserFolder(dragInfo, dropOverView);
+ }
+ boolean willAddToExistingUserFolder(ItemInfo dragInfo, View dropOverView) {
if (dropOverView != null) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) dropOverView.getLayoutParams();
if (lp.useTmpCoords && (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.tmpCellY)) {
@@ -3163,8 +3170,6 @@ public class Workspace extends PagedView
mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter);
}
- ItemInfo info = d.dragInfo;
-
int minSpanX = item.spanX;
int minSpanY = item.spanY;
if (item.minSpanX > 0 && item.minSpanY > 0) {
@@ -3183,11 +3188,7 @@ public class Workspace extends PagedView
float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
- final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0],
- mTargetCell[1]);
-
- manageFolderFeedback(info, mDragTargetLayout, mTargetCell,
- targetCellDistance, dragOverView, d.accessibleDrag);
+ manageFolderFeedback(mDragTargetLayout, mTargetCell, targetCellDistance, d);
boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int)
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
@@ -3196,8 +3197,7 @@ public class Workspace extends PagedView
if (!nearestDropOccupied) {
mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
(int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
- mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false,
- d.dragView.getDragVisualizeOffset(), d.dragView.getDragRegion());
+ mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false, d);
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
&& !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
mLastReorderY != reorderY)) {
@@ -3210,7 +3210,7 @@ public class Workspace extends PagedView
// Otherwise, if we aren't adding to or creating a folder and there's no pending
// reorder, then we schedule a reorder
ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter,
- minSpanX, minSpanY, item.spanX, item.spanY, d.dragView, child);
+ minSpanX, minSpanY, item.spanX, item.spanY, d, child);
mReorderAlarm.setOnAlarmListener(listener);
mReorderAlarm.setAlarm(REORDER_TIMEOUT);
}
@@ -3224,28 +3224,34 @@ public class Workspace extends PagedView
}
}
- private void manageFolderFeedback(ItemInfo info, CellLayout targetLayout,
- int[] targetCell, float distance, View dragOverView, boolean accessibleDrag) {
- boolean userFolderPending = willCreateUserFolder(info, targetLayout, targetCell, distance,
- false);
+ private void manageFolderFeedback(CellLayout targetLayout,
+ int[] targetCell, float distance, DragObject dragObject) {
+ if (distance > mMaxDistanceForFolderCreation) return;
+
+ final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
+ ItemInfo info = dragObject.dragInfo;
+ boolean userFolderPending = willCreateUserFolder(info, dragOverView, false);
if (mDragMode == DRAG_MODE_NONE && userFolderPending &&
!mFolderCreationAlarm.alarmPending()) {
FolderCreationAlarmListener listener = new
FolderCreationAlarmListener(targetLayout, targetCell[0], targetCell[1]);
- if (!accessibleDrag) {
+ if (!dragObject.accessibleDrag) {
mFolderCreationAlarm.setOnAlarmListener(listener);
mFolderCreationAlarm.setAlarm(FOLDER_CREATION_TIMEOUT);
} else {
listener.onAlarm(mFolderCreationAlarm);
}
+
+ if (dragObject.stateAnnouncer != null) {
+ dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
+ .getDescriptionForDropOver(dragOverView, getContext()));
+ }
return;
}
- boolean willAddToFolder =
- willAddToExistingUserFolder(info, targetLayout, targetCell, distance);
-
+ boolean willAddToFolder = willAddToExistingUserFolder(info, dragOverView);
if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
mDragOverFolderIcon = ((FolderIcon) dragOverView);
mDragOverFolderIcon.onDragEnter(info);
@@ -3253,6 +3259,11 @@ public class Workspace extends PagedView
targetLayout.clearDragOutlines();
}
setDragMode(DRAG_MODE_ADD_TO_FOLDER);
+
+ if (dragObject.stateAnnouncer != null) {
+ dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
+ .getDescriptionForDropOver(dragOverView, getContext()));
+ }
return;
}
@@ -3262,8 +3273,6 @@ public class Workspace extends PagedView
if (mDragMode == DRAG_MODE_CREATE_FOLDER && !userFolderPending) {
setDragMode(DRAG_MODE_NONE);
}
-
- return;
}
class FolderCreationAlarmListener implements OnAlarmListener {
@@ -3295,18 +3304,18 @@ public class Workspace extends PagedView
class ReorderAlarmListener implements OnAlarmListener {
float[] dragViewCenter;
int minSpanX, minSpanY, spanX, spanY;
- DragView dragView;
+ DragObject dragObject;
View child;
public ReorderAlarmListener(float[] dragViewCenter, int minSpanX, int minSpanY, int spanX,
- int spanY, DragView dragView, View child) {
+ int spanY, DragObject dragObject, View child) {
this.dragViewCenter = dragViewCenter;
this.minSpanX = minSpanX;
this.minSpanY = minSpanY;
this.spanX = spanX;
this.spanY = spanY;
this.child = child;
- this.dragView = dragView;
+ this.dragObject = dragObject;
}
public void onAlarm(Alarm alarm) {
@@ -3330,8 +3339,7 @@ public class Workspace extends PagedView
boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY;
mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
(int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
- mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], resize,
- dragView.getDragVisualizeOffset(), dragView.getDragRegion());
+ mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], resize, dragObject);
}
}
@@ -4388,8 +4396,16 @@ public class Workspace extends PagedView
private String getPageDescription(int page) {
int delta = numCustomPages();
- return getContext().getString(R.string.workspace_scroll_format,
- page + 1 - delta, getChildCount() - delta);
+ int nScreens = getChildCount() - delta;
+ int extraScreenId = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
+ if (extraScreenId >= 0 && nScreens > 1) {
+ if (page == extraScreenId) {
+ return getContext().getString(R.string.workspace_new_page);
+ }
+ nScreens--;
+ }
+ return String.format(getContext().getString(R.string.workspace_scroll_format),
+ page + 1 - delta, nScreens);
}
public void getLocationInDragLayer(int[] loc) {
diff --git a/src/com/android/launcher3/accessibility/DragViewStateAnnouncer.java b/src/com/android/launcher3/accessibility/DragViewStateAnnouncer.java
new file mode 100644
index 000000000..b5e6194a0
--- /dev/null
+++ b/src/com/android/launcher3/accessibility/DragViewStateAnnouncer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.accessibility;
+
+import android.content.Context;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+/**
+ * Periodically sends accessibility events to announce ongoing state changed. Based on the
+ * implementation in ProgressBar.
+ */
+public class DragViewStateAnnouncer implements Runnable {
+
+ private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
+
+ private final View mTargetView;
+
+ private DragViewStateAnnouncer(View view) {
+ mTargetView = view;
+ }
+
+ public void announce(CharSequence msg) {
+ mTargetView.setContentDescription(msg);
+ mTargetView.removeCallbacks(this);
+ mTargetView.postDelayed(this, TIMEOUT_SEND_ACCESSIBILITY_EVENT);
+ }
+
+ @Override
+ public void run() {
+ mTargetView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
+
+ public static DragViewStateAnnouncer createFor(View v) {
+ if (((AccessibilityManager) v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE))
+ .isEnabled()) {
+ return new DragViewStateAnnouncer(v);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 947968587..f8bf5a85b 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -134,11 +134,8 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
public boolean performAction(final View host, final ItemInfo item, int action) {
if (action == REMOVE) {
- if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) {
- announceConfirmation(R.string.item_removed);
- return true;
- }
- return false;
+ DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host);
+ return true;
} else if (action == INFO) {
InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
return true;
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index 80ddc13b7..73b824bb5 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -16,6 +16,7 @@
package com.android.launcher3.accessibility;
+import android.content.Context;
import android.text.TextUtils;
import android.view.View;
@@ -140,26 +141,30 @@ public class WorkspaceAccessibilityHelper extends DragAndDropAccessibilityDelega
return mContext.getString(R.string.move_to_empty_cell, y + 1, x + 1);
}
} else {
- ItemInfo info = (ItemInfo) child.getTag();
- if (info instanceof ShortcutInfo) {
- return mContext.getString(R.string.create_folder_with, info.title);
- } else if (info instanceof FolderInfo) {
- if (TextUtils.isEmpty(info.title)) {
- // Find the first item in the folder.
- FolderInfo folder = (FolderInfo) info;
- ShortcutInfo firstItem = null;
- for (ShortcutInfo shortcut : folder.contents) {
- if (firstItem == null || firstItem.rank > shortcut.rank) {
- firstItem = shortcut;
- }
- }
+ return getDescriptionForDropOver(child, mContext);
+ }
+ }
- if (firstItem != null) {
- return mContext.getString(R.string.add_to_folder_with_app, firstItem.title);
+ public static String getDescriptionForDropOver(View overChild, Context context) {
+ ItemInfo info = (ItemInfo) overChild.getTag();
+ if (info instanceof ShortcutInfo) {
+ return context.getString(R.string.create_folder_with, info.title);
+ } else if (info instanceof FolderInfo) {
+ if (TextUtils.isEmpty(info.title)) {
+ // Find the first item in the folder.
+ FolderInfo folder = (FolderInfo) info;
+ ShortcutInfo firstItem = null;
+ for (ShortcutInfo shortcut : folder.contents) {
+ if (firstItem == null || firstItem.rank > shortcut.rank) {
+ firstItem = shortcut;
}
}
- return mContext.getString(R.string.add_to_folder, info.title);
+
+ if (firstItem != null) {
+ return context.getString(R.string.add_to_folder_with_app, firstItem.title);
+ }
}
+ return context.getString(R.string.add_to_folder, info.title);
}
return "";
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 4a39e6be1..5097ea179 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -41,11 +41,11 @@ import com.android.launcher3.DropTarget;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.PagedView;
+import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.util.Thunk;
-import com.android.launcher3.R;
-
import java.util.ArrayList;
import java.util.HashSet;
@@ -233,6 +233,9 @@ public class DragController implements DragDriver.EventListener {
mDragObject = new DropTarget.DragObject();
+ final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX,
+ registrationY, 0, 0, b.getWidth(), b.getHeight(), initialDragViewScale);
+
mDragObject.dragComplete = false;
if (mIsAccessibleDrag) {
// For an accessible drag, we assume the view is being dragged from the center.
@@ -242,18 +245,14 @@ public class DragController implements DragDriver.EventListener {
} else {
mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft);
mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop);
+ mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
+
+ mDragDriver = DragDriver.create(this, dragInfo, dragView);
}
mDragObject.dragSource = source;
mDragObject.dragInfo = dragInfo;
- final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX,
- registrationY, 0, 0, b.getWidth(), b.getHeight(), initialDragViewScale);
-
- if (!accessible) {
- mDragDriver = DragDriver.create(this, dragInfo, dragView);
- }
-
if (dragOffset != null) {
dragView.setDragVisualizeOffset(new Point(dragOffset));
}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 81a8465d8..0f5ca15b6 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -148,8 +148,11 @@ public class WidgetsContainerView extends BaseContainerView
if (mWidgetInstructionToast != null) {
mWidgetInstructionToast.cancel();
}
- mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add,
- Toast.LENGTH_SHORT);
+
+ CharSequence msg = Utilities.wrapForTts(
+ getContext().getText(R.string.long_press_widget_to_add),
+ getContext().getString(R.string.long_accessible_way_to_add));
+ mWidgetInstructionToast = Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT);
mWidgetInstructionToast.show();
}
@@ -164,7 +167,6 @@ public class WidgetsContainerView extends BaseContainerView
if (!mLauncher.isWidgetsViewVisible() ||
mLauncher.getWorkspace().isSwitchingState()) return false;
// Return if global dragging is not enabled
- Log.d(TAG, String.format("onLonglick dragging enabled?.", v));
if (!mLauncher.isDraggingEnabled()) return false;
boolean status = beginDragging(v);