blob: 277f8b37db93a6ecbfd675ae2c6e3d3355789677 [file] [log] [blame]
Andrew Cole44898c32023-04-05 13:49:32 -07001package com.android.launcher3
2
3import android.content.ComponentName
4import android.view.View
5import com.android.launcher3.DropTarget.DragObject
6import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
7import com.android.launcher3.dragndrop.DragLayer
8import com.android.launcher3.logging.StatsLogManager.LauncherEvent
9import com.android.launcher3.model.ModelWriter
10import com.android.launcher3.model.data.ItemInfo
11import com.android.launcher3.model.data.LauncherAppWidgetInfo
12import com.android.launcher3.util.IntSet
13import com.android.launcher3.util.PendingRequestArgs
14import com.android.launcher3.views.Snackbar
15
16/**
17 * Handler class for drop target actions that require modifying or interacting with launcher.
18 *
19 * This class is created by Launcher and provided the instance of launcher when created, which
20 * allows us to decouple drop target controllers from Launcher to enable easier testing.
21 */
22class DropTargetHandler(launcher: Launcher) {
23 val mLauncher: Launcher = launcher
24
25 val modelWriter: ModelWriter = mLauncher.modelWriter
26
27 fun onDropAnimationComplete() {
28 mLauncher.stateManager.goToState(LauncherState.NORMAL)
29 }
30
31 fun onSecondaryTargetCompleteDrop(target: ComponentName?, d: DragObject) {
32 when (val dragSource = d.dragSource) {
33 is DeferredOnComplete -> {
34 val deferred: DeferredOnComplete = dragSource
35 if (d.dragSource is SecondaryDropTarget.DeferredOnComplete) {
36 target?.let {
37 deferred.mPackageName = it.packageName
38 mLauncher.addOnResumeCallback { deferred.onLauncherResume() }
39 }
40 ?: deferred.sendFailure()
41 }
42 }
43 }
44 }
45
46 fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
47 mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
48 mLauncher.appWidgetHolder.startConfigActivity(
49 mLauncher,
50 widgetId,
51 Launcher.REQUEST_RECONFIGURE_APPWIDGET
52 )
53 }
54
55 fun dismissPrediction(
56 announcement: CharSequence,
57 onActionClicked: Runnable,
58 onDismiss: Runnable?
59 ) {
60 mLauncher.dragLayer.announceForAccessibility(announcement)
61 Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, onDismiss, onActionClicked)
62 }
63
64 fun getViewUnderDrag(info: ItemInfo): View? {
65 return if (
66 info is LauncherAppWidgetInfo &&
67 info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
68 mLauncher.workspace.dragInfo != null
69 ) {
70 mLauncher.workspace.dragInfo.cell
71 } else null
72 }
73
74 fun prepareToUndoDelete() {
75 mLauncher.modelWriter.prepareToUndoDelete()
76 }
77
78 fun onDeleteComplete(item: ItemInfo) {
79 var pageItem: ItemInfo = item
80 if (item.container <= 0) {
81 val v = mLauncher.workspace.getHomescreenIconByItemId(item.container)
82 v?.let { pageItem = v.tag as ItemInfo }
83 }
84 val pageIds =
85 if (pageItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP)
86 IntSet.wrap(pageItem.screenId)
87 else mLauncher.workspace.currentPageScreenIds
88 val onUndoClicked = Runnable {
89 mLauncher.setPagesToBindSynchronously(pageIds)
90 modelWriter.abortDelete()
91 mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
92 }
93
94 Snackbar.show(
95 mLauncher,
96 R.string.item_removed,
97 R.string.undo,
98 modelWriter::commitDelete,
99 onUndoClicked
100 )
101 }
102
103 fun onAccessibilityDelete(view: View?, item: ItemInfo, announcement: CharSequence) {
104 // Remove the item from launcher and the db, we can ignore the containerInfo in this call
105 // because we already remove the drag view from the folder (if the drag originated from
106 // a folder) in Folder.beginDrag()
107 mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop")
108 mLauncher.workspace.stripEmptyScreens()
109 mLauncher.dragLayer.announceForAccessibility(announcement)
110 }
111
112 fun getDragLayer(): DragLayer {
113 return mLauncher.dragLayer
114 }
115
116 fun onClick(buttonDropTarget: ButtonDropTarget) {
117 mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
118 }
119}