blob: 8ba02ea5f6ac0cc4976bc5d302fe7e068109ad23 [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) {
Sunny Goyalfa401a12015-04-10 13:45:42 -0700108 AppInfo info = (AppInfo) item;
109 mLauncher.startApplicationUninstallActivity(info.componentName, info.flags, info.user);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800110 return true;
Adam Cohenc9735cf2015-01-23 16:11:55 -0800111 } else if (action == MOVE) {
112 beginAccessibleDrag(host, item);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800113 } else if (action == ADD_TO_WORKSPACE) {
114 final int preferredPage = mLauncher.getWorkspace().getCurrentPage();
115 final ScreenPosProvider screenProvider = new ScreenPosProvider() {
116
117 @Override
118 public int getScreenIndex(ArrayList<Long> screenIDs) {
119 return preferredPage;
120 }
121 };
122 if (item instanceof AppInfo) {
123 final ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>();
124 addShortcuts.add(((AppInfo) item).makeShortcut());
125 mLauncher.showWorkspace(true, new Runnable() {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800126 @Override
127 public void run() {
Sunny Goyal18bf8e22015-04-08 18:13:46 -0700128 mLauncher.getModel().addAndBindAddedWorkspaceItems(
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800129 mLauncher, addShortcuts, screenProvider, 0, true);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800130 announceConfirmation(R.string.item_added_to_workspace);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800131 }
132 });
133 return true;
134 } else if (item instanceof PendingAddItemInfo) {
135 mLauncher.getModel().addAndBindPendingItem(
136 mLauncher, (PendingAddItemInfo) item, screenProvider, 0);
Adam Cohenc9735cf2015-01-23 16:11:55 -0800137 announceConfirmation(R.string.item_added_to_workspace);
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800138 return true;
139 }
140 }
141 return false;
142 }
Adam Cohenc9735cf2015-01-23 16:11:55 -0800143
Adam Cohen091440a2015-03-18 14:16:05 -0700144 @Thunk void announceConfirmation(int resId) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800145 announceConfirmation(mLauncher.getResources().getString(resId));
146 }
147
Adam Cohen091440a2015-03-18 14:16:05 -0700148 @Thunk void announceConfirmation(String confirmation) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800149 mLauncher.getDragLayer().announceForAccessibility(confirmation);
150
151 }
152
153 public boolean isInAccessibleDrag() {
154 return mDragInfo != null;
155 }
156
157 public DragInfo getDragInfo() {
158 return mDragInfo;
159 }
160
161 public void handleAccessibleDrop(CellLayout targetContainer, Rect dropLocation,
162 String confirmation) {
163 if (!isInAccessibleDrag()) return;
164
165 int[] loc = new int[2];
166 loc[0] = dropLocation.centerX();
167 loc[1] = dropLocation.centerY();
168
169 mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(targetContainer, loc);
170 mLauncher.getDragController().completeAccessibleDrag(loc);
171
172 endAccessibleDrag();
173 announceConfirmation(confirmation);
174 }
175
176 public void beginAccessibleDrag(View item, ItemInfo info) {
177 mDragInfo = new DragInfo();
178 mDragInfo.info = info;
179 mDragInfo.item = item;
180 mDragInfo.dragType = DragType.ICON;
181 if (info instanceof FolderInfo) {
182 mDragInfo.dragType = DragType.FOLDER;
183 } else if (info instanceof LauncherAppWidgetInfo) {
184 mDragInfo.dragType = DragType.WIDGET;
185 }
186
187 CellLayout.CellInfo cellInfo = new CellLayout.CellInfo(item, info);
188
189 Rect pos = new Rect();
190 mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
191
192 mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
193 mLauncher.getWorkspace().enableAccessibleDrag(true);
194 mLauncher.getWorkspace().startDrag(cellInfo, true);
195 }
196
197 public boolean onBackPressed() {
198 if (isInAccessibleDrag()) {
199 cancelAccessibleDrag();
200 return true;
201 }
202 return false;
203 }
204
205 private void cancelAccessibleDrag() {
206 mLauncher.getDragController().cancelDrag();
207 endAccessibleDrag();
208 }
209
210 private void endAccessibleDrag() {
211 mDragInfo = null;
212 mLauncher.getWorkspace().enableAccessibleDrag(false);
213 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -0800214}