blob: 42f1914c606c30521c54452ee5bf5e5a777fefd0 [file] [log] [blame]
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08001package com.android.launcher3;
2
3import android.annotation.TargetApi;
Adam Cohenc9735cf2015-01-23 16:11:55 -08004import android.content.res.Resources;
5import android.graphics.Rect;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -08006import android.os.Build;
7import android.os.Bundle;
Adam Cohenc9735cf2015-01-23 16:11:55 -08008import android.support.v4.view.accessibility.AccessibilityEventCompat;
9import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080010import android.util.SparseArray;
11import android.view.View;
12import android.view.View.AccessibilityDelegate;
Adam Cohenc9735cf2015-01-23 16:11:55 -080013import android.view.accessibility.AccessibilityEvent;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080014import android.view.accessibility.AccessibilityNodeInfo;
15import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
16
17import com.android.launcher3.LauncherModel.ScreenPosProvider;
Adam Cohen091440a2015-03-18 14:16:05 -070018import com.android.launcher3.util.Thunk;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080019
20import java.util.ArrayList;
21
22@TargetApi(Build.VERSION_CODES.LOLLIPOP)
23public class LauncherAccessibilityDelegate extends AccessibilityDelegate {
24
25 public static final int REMOVE = R.id.action_remove;
26 public static final int INFO = R.id.action_info;
27 public static final int UNINSTALL = R.id.action_uninstall;
28 public static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
Adam Cohenc9735cf2015-01-23 16:11:55 -080029 public static final int MOVE = R.id.action_move;
30
31 enum DragType {
32 ICON,
33 FOLDER,
34 WIDGET
35 }
36
37 public static class DragInfo {
38 DragType dragType;
39 ItemInfo info;
40 View item;
41 }
42
43 private DragInfo mDragInfo = null;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080044
45 private final SparseArray<AccessibilityAction> mActions =
46 new SparseArray<AccessibilityAction>();
Adam Cohen091440a2015-03-18 14:16:05 -070047 @Thunk final Launcher mLauncher;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080048
49 public LauncherAccessibilityDelegate(Launcher launcher) {
50 mLauncher = launcher;
51
52 mActions.put(REMOVE, new AccessibilityAction(REMOVE,
53 launcher.getText(R.string.delete_target_label)));
54 mActions.put(INFO, new AccessibilityAction(INFO,
55 launcher.getText(R.string.info_target_label)));
56 mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
57 launcher.getText(R.string.delete_target_uninstall_label)));
58 mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
59 launcher.getText(R.string.action_add_to_workspace)));
Adam Cohenc9735cf2015-01-23 16:11:55 -080060 mActions.put(MOVE, new AccessibilityAction(MOVE,
61 launcher.getText(R.string.action_move)));
62
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080063 }
64
65 @Override
66 public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
67 super.onInitializeAccessibilityNodeInfo(host, info);
68 if (!(host.getTag() instanceof ItemInfo)) return;
69 ItemInfo item = (ItemInfo) host.getTag();
70
71 if ((item instanceof ShortcutInfo)
72 || (item instanceof LauncherAppWidgetInfo)
73 || (item instanceof FolderInfo)) {
74 // Workspace shortcut / widget
75 info.addAction(mActions.get(REMOVE));
Adam Cohenc9735cf2015-01-23 16:11:55 -080076 info.addAction(mActions.get(MOVE));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080077 } else if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
78 // App or Widget from customization tray
79 if (item instanceof AppInfo) {
80 info.addAction(mActions.get(UNINSTALL));
81 }
82 info.addAction(mActions.get(INFO));
83 info.addAction(mActions.get(ADD_TO_WORKSPACE));
84 }
85 }
86
87 @Override
88 public boolean performAccessibilityAction(View host, int action, Bundle args) {
89 if ((host.getTag() instanceof ItemInfo)
90 && performAction(host, (ItemInfo) host.getTag(), action)) {
91 return true;
92 }
93 return super.performAccessibilityAction(host, action, args);
94 }
95
96 public boolean performAction(View host, ItemInfo item, int action) {
Adam Cohenc9735cf2015-01-23 16:11:55 -080097 Resources res = mLauncher.getResources();
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080098 if (action == REMOVE) {
Adam Cohenc9735cf2015-01-23 16:11:55 -080099 if (DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host)) {
100 announceConfirmation(R.string.item_removed_from_workspace);
101 return true;
102 }
103 return false;
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800104 } else if (action == INFO) {
105 InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
106 return true;
107 } else if (action == UNINSTALL) {
108 DeleteDropTarget.uninstallApp(mLauncher, (AppInfo) item);
109 return true;
Adam Cohenc9735cf2015-01-23 16:11:55 -0800110 } else if (action == MOVE) {
111 beginAccessibleDrag(host, item);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800112 } else if (action == ADD_TO_WORKSPACE) {
113 final int preferredPage = mLauncher.getWorkspace().getCurrentPage();
114 final ScreenPosProvider screenProvider = new ScreenPosProvider() {
115
116 @Override
117 public int getScreenIndex(ArrayList<Long> screenIDs) {
118 return preferredPage;
119 }
120 };
121 if (item instanceof AppInfo) {
122 final ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>();
123 addShortcuts.add(((AppInfo) item).makeShortcut());
124 mLauncher.showWorkspace(true, new Runnable() {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800125 @Override
126 public void run() {
127 mLauncher.getModel().addAndBindAddedWorkspaceApps(
128 mLauncher, addShortcuts, screenProvider, 0, true);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800129 announceConfirmation(R.string.item_added_to_workspace);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800130 }
131 });
132 return true;
133 } else if (item instanceof PendingAddItemInfo) {
134 mLauncher.getModel().addAndBindPendingItem(
135 mLauncher, (PendingAddItemInfo) item, screenProvider, 0);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800136 announceConfirmation(R.string.item_added_to_workspace);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800137 return true;
138 }
139 }
140 return false;
141 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800142
Adam Cohen091440a2015-03-18 14:16:05 -0700143 @Thunk void announceConfirmation(int resId) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800144 announceConfirmation(mLauncher.getResources().getString(resId));
145 }
146
Adam Cohen091440a2015-03-18 14:16:05 -0700147 @Thunk void announceConfirmation(String confirmation) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800148 mLauncher.getDragLayer().announceForAccessibility(confirmation);
149
150 }
151
152 public boolean isInAccessibleDrag() {
153 return mDragInfo != null;
154 }
155
156 public DragInfo getDragInfo() {
157 return mDragInfo;
158 }
159
160 public void handleAccessibleDrop(CellLayout targetContainer, Rect dropLocation,
161 String confirmation) {
162 if (!isInAccessibleDrag()) return;
163
164 int[] loc = new int[2];
165 loc[0] = dropLocation.centerX();
166 loc[1] = dropLocation.centerY();
167
168 mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(targetContainer, loc);
169 mLauncher.getDragController().completeAccessibleDrag(loc);
170
171 endAccessibleDrag();
172 announceConfirmation(confirmation);
173 }
174
175 public void beginAccessibleDrag(View item, ItemInfo info) {
176 mDragInfo = new DragInfo();
177 mDragInfo.info = info;
178 mDragInfo.item = item;
179 mDragInfo.dragType = DragType.ICON;
180 if (info instanceof FolderInfo) {
181 mDragInfo.dragType = DragType.FOLDER;
182 } else if (info instanceof LauncherAppWidgetInfo) {
183 mDragInfo.dragType = DragType.WIDGET;
184 }
185
186 CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
187
188 Rect pos = new Rect();
189 mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
190
191 mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
192 mLauncher.getWorkspace().enableAccessibleDrag(true);
193 mLauncher.getWorkspace().startDrag(cellInfo, true);
194 }
195
196 public boolean onBackPressed() {
197 if (isInAccessibleDrag()) {
198 cancelAccessibleDrag();
199 return true;
200 }
201 return false;
202 }
203
204 private void cancelAccessibleDrag() {
205 mLauncher.getDragController().cancelDrag();
206 endAccessibleDrag();
207 }
208
209 private void endAccessibleDrag() {
210 mDragInfo = null;
211 mLauncher.getWorkspace().enableAccessibleDrag(false);
212 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800213}