1 package com.android.launcher3
2 
3 import android.content.ComponentName
4 import android.view.View
5 import com.android.launcher3.BaseDraggingActivity.EVENT_RESUMED
6 import com.android.launcher3.DropTarget.DragObject
7 import com.android.launcher3.LauncherConstants.ActivityCodes
8 import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
9 import com.android.launcher3.dragndrop.DragLayer
10 import com.android.launcher3.logging.StatsLogManager.LauncherEvent
11 import com.android.launcher3.model.data.ItemInfo
12 import com.android.launcher3.model.data.LauncherAppWidgetInfo
13 import com.android.launcher3.util.IntSet
14 import com.android.launcher3.util.PendingRequestArgs
15 import 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  */
23 class DropTargetHandler(launcher: Launcher) {
24     val mLauncher: Launcher = launcher
25 
onDropAnimationCompletenull26     fun onDropAnimationComplete() {
27         mLauncher.stateManager.goToState(LauncherState.NORMAL)
28     }
29 
onSecondaryTargetCompleteDropnull30     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
37                         mLauncher.addEventCallback(EVENT_RESUMED) { deferred.onLauncherResume() }
38                     }
39                         ?: deferred.sendFailure()
40                 }
41             }
42         }
43     }
44 
reconfigureWidgetnull45     fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
46         mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
47         mLauncher.appWidgetHolder.startConfigActivity(
48             mLauncher,
49             widgetId,
50             ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET
51         )
52     }
53 
dismissPredictionnull54     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 
getViewUnderDragnull63     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 
prepareToUndoDeletenull73     fun prepareToUndoDelete() {
74         mLauncher.modelWriter.prepareToUndoDelete()
75     }
76 
onDeleteCompletenull77     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)
89             mLauncher.modelWriter.abortDelete()
90             mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
91         }
92 
93         Snackbar.show(
94             mLauncher,
95             R.string.item_removed,
96             R.string.undo,
97             mLauncher.modelWriter::commitDelete,
98             onUndoClicked
99         )
100     }
101 
onAccessibilityDeletenull102     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 
getDragLayernull111     fun getDragLayer(): DragLayer {
112         return mLauncher.dragLayer
113     }
114 
onClicknull115     fun onClick(buttonDropTarget: ButtonDropTarget) {
116         mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
117     }
118 }
119