summaryrefslogtreecommitdiff
path: root/src/com/android/launcher3/DropTargetHandler.kt
blob: e022159d157c85cac8214e63fa507eb482eca38b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.android.launcher3

import android.content.ComponentName
import android.view.View
import com.android.launcher3.BaseDraggingActivity.EVENT_RESUMED
import com.android.launcher3.DropTarget.DragObject
import com.android.launcher3.LauncherConstants.ActivityCodes
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
import com.android.launcher3.dragndrop.DragLayer
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.util.IntSet
import com.android.launcher3.util.PendingRequestArgs
import com.android.launcher3.views.Snackbar

/**
 * Handler class for drop target actions that require modifying or interacting with launcher.
 *
 * This class is created by Launcher and provided the instance of launcher when created, which
 * allows us to decouple drop target controllers from Launcher to enable easier testing.
 */
class DropTargetHandler(launcher: Launcher) {
    val mLauncher: Launcher = launcher

    fun onDropAnimationComplete() {
        mLauncher.stateManager.goToState(LauncherState.NORMAL)
    }

    fun onSecondaryTargetCompleteDrop(target: ComponentName?, d: DragObject) {
        when (val dragSource = d.dragSource) {
            is DeferredOnComplete -> {
                val deferred: DeferredOnComplete = dragSource
                if (d.dragSource is SecondaryDropTarget.DeferredOnComplete) {
                    target?.let {
                        deferred.mPackageName = it.packageName
                        mLauncher.addEventCallback(EVENT_RESUMED) { deferred.onLauncherResume() }
                    }
                        ?: deferred.sendFailure()
                }
            }
        }
    }

    fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
        mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
        mLauncher.appWidgetHolder.startConfigActivity(
            mLauncher,
            widgetId,
            ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET
        )
    }

    fun dismissPrediction(
        announcement: CharSequence,
        onActionClicked: Runnable,
        onDismiss: Runnable?
    ) {
        mLauncher.dragLayer.announceForAccessibility(announcement)
        Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, onDismiss, onActionClicked)
    }

    fun getViewUnderDrag(info: ItemInfo): View? {
        return if (
            info is LauncherAppWidgetInfo &&
                info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
                mLauncher.workspace.dragInfo != null
        ) {
            mLauncher.workspace.dragInfo.cell
        } else null
    }

    fun prepareToUndoDelete() {
        mLauncher.modelWriter.prepareToUndoDelete()
    }

    fun onDeleteComplete(item: ItemInfo) {
        var pageItem: ItemInfo = item
        if (item.container <= 0) {
            val v = mLauncher.workspace.getHomescreenIconByItemId(item.container)
            v?.let { pageItem = v.tag as ItemInfo }
        }
        val pageIds =
            if (pageItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP)
                IntSet.wrap(pageItem.screenId)
            else mLauncher.workspace.currentPageScreenIds
        val onUndoClicked = Runnable {
            mLauncher.setPagesToBindSynchronously(pageIds)
            mLauncher.modelWriter.abortDelete()
            mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
        }

        Snackbar.show(
            mLauncher,
            R.string.item_removed,
            R.string.undo,
            mLauncher.modelWriter::commitDelete,
            onUndoClicked
        )
    }

    fun onAccessibilityDelete(view: View?, item: ItemInfo, announcement: CharSequence) {
        // Remove the item from launcher and the db, we can ignore the containerInfo in this call
        // because we already remove the drag view from the folder (if the drag originated from
        // a folder) in Folder.beginDrag()
        mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop")
        mLauncher.workspace.stripEmptyScreens()
        mLauncher.dragLayer.announceForAccessibility(announcement)
    }

    fun getDragLayer(): DragLayer {
        return mLauncher.dragLayer
    }

    fun onClick(buttonDropTarget: ButtonDropTarget) {
        mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
    }
}