• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.launcher3
2 
3 import android.content.ComponentName
4 import android.view.View
5 import com.android.launcher3.BaseActivity.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                     } ?: deferred.sendFailure()
39                 }
40             }
41         }
42     }
43 
reconfigureWidgetnull44     fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
45         mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
46         mLauncher.appWidgetHolder.startConfigActivity(
47             mLauncher,
48             widgetId,
49             ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET,
50         )
51     }
52 
getViewUnderDragnull53     fun getViewUnderDrag(info: ItemInfo): View? {
54         return if (
55             info is LauncherAppWidgetInfo &&
56                 info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
57                 mLauncher.workspace.dragInfo != null
58         ) {
59             mLauncher.workspace.dragInfo.cell
60         } else null
61     }
62 
prepareToUndoDeletenull63     fun prepareToUndoDelete() {
64         mLauncher.modelWriter.prepareToUndoDelete()
65     }
66 
onDeleteCompletenull67     fun onDeleteComplete(item: ItemInfo) {
68         removeItemAndStripEmptyScreens(null /* view */, item)
69         AbstractFloatingView.closeOpenViews(
70             mLauncher,
71             false,
72             AbstractFloatingView.TYPE_WIDGET_RESIZE_FRAME,
73         )
74         var pageItem: ItemInfo = item
75         if (item.container >= 0) {
76             mLauncher.workspace.getViewByItemId(item.container)?.let {
77                 pageItem = it.tag as ItemInfo
78             }
79         }
80         val pageIds =
81             if (pageItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP)
82                 IntSet.wrap(pageItem.screenId)
83             else mLauncher.workspace.currentPageScreenIds
84         val onUndoClicked = Runnable {
85             mLauncher.setPagesToBindSynchronously(pageIds)
86             mLauncher.modelWriter.abortDelete()
87             mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
88         }
89 
90         Snackbar.show(
91             mLauncher,
92             R.string.item_removed,
93             R.string.undo,
94             mLauncher.modelWriter::commitDelete,
95             onUndoClicked,
96         )
97     }
98 
onAccessibilityDeletenull99     fun onAccessibilityDelete(view: View?, item: ItemInfo, announcement: CharSequence) {
100         removeItemAndStripEmptyScreens(view, item)
101         mLauncher.dragLayer.announceForAccessibility(announcement)
102     }
103 
getDragLayernull104     fun getDragLayer(): DragLayer {
105         return mLauncher.dragLayer
106     }
107 
onClicknull108     fun onClick(buttonDropTarget: ButtonDropTarget) {
109         mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
110     }
111 
removeItemAndStripEmptyScreensnull112     private fun removeItemAndStripEmptyScreens(view: View?, item: ItemInfo) {
113         // Remove the item from launcher and the db, we can ignore the containerInfo in this call
114         // because we already remove the drag view from the folder (if the drag originated from
115         // a folder) in Folder.beginDrag()
116         mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop")
117         mLauncher.workspace.stripEmptyScreens()
118     }
119 }
120