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