Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 1 | package com.android.launcher3 |
| 2 | |
| 3 | import android.content.ComponentName |
| 4 | import android.view.View |
Sunny Goyal | e82a20a | 2023-10-19 13:52:49 -0700 | [diff] [blame] | 5 | import com.android.launcher3.BaseDraggingActivity.EVENT_RESUMED |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 6 | import com.android.launcher3.DropTarget.DragObject |
Sebastian Franco | 974cc94 | 2023-10-19 14:22:06 -0700 | [diff] [blame] | 7 | import com.android.launcher3.LauncherConstants.ActivityCodes |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 8 | import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete |
| 9 | import com.android.launcher3.dragndrop.DragLayer |
| 10 | import com.android.launcher3.logging.StatsLogManager.LauncherEvent |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 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 | |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 26 | 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 Goyal | e82a20a | 2023-10-19 13:52:49 -0700 | [diff] [blame] | 37 | mLauncher.addEventCallback(EVENT_RESUMED) { deferred.onLauncherResume() } |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 38 | } |
| 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 Franco | 974cc94 | 2023-10-19 14:22:06 -0700 | [diff] [blame] | 50 | ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 51 | ) |
| 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 Franco | a64f3a6 | 2023-05-05 16:00:32 -0600 | [diff] [blame] | 89 | mLauncher.modelWriter.abortDelete() |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 90 | mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO) |
| 91 | } |
| 92 | |
| 93 | Snackbar.show( |
| 94 | mLauncher, |
| 95 | R.string.item_removed, |
| 96 | R.string.undo, |
Sebastian Franco | a64f3a6 | 2023-05-05 16:00:32 -0600 | [diff] [blame] | 97 | mLauncher.modelWriter::commitDelete, |
Andrew Cole | 44898c3 | 2023-04-05 13:49:32 -0700 | [diff] [blame] | 98 | 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 | } |