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