mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 08:16:49 +00:00
Originally there was a bug in a method (isTextClippedVertically) in ButtonDropTarget. While attempting to write a unit test it became necessary to refactor ButtonDropTarget and DeleteDropTarget to decouple them from their dependency on launcher in order to allow for a unit test to be written The pattern we are introducing here is to decouple Launcher from a controller, in order to facilitate easier testing. Instead of calling Launcher.getLauncher() we call the method through ActivityContext, which has a testing wrapper already defined. Here is a diagram that explains the old and new pattern Design Pattern: https://screenshot.googleplex.com/7apiE2DaGDrFzy9.png Test: isTextClippedVerticallyTest Bug: b/274402490 Change-Id: I1f3003d0b62dddbceb6e492b15aa5d7352d3a293
120 lines
4.4 KiB
Kotlin
120 lines
4.4 KiB
Kotlin
package com.android.launcher3
|
|
|
|
import android.content.ComponentName
|
|
import android.view.View
|
|
import com.android.launcher3.DropTarget.DragObject
|
|
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
|
|
import com.android.launcher3.dragndrop.DragLayer
|
|
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
|
|
import com.android.launcher3.model.ModelWriter
|
|
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
|
|
|
|
val modelWriter: ModelWriter = mLauncher.modelWriter
|
|
|
|
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.addOnResumeCallback { deferred.onLauncherResume() }
|
|
}
|
|
?: deferred.sendFailure()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
|
|
mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
|
|
mLauncher.appWidgetHolder.startConfigActivity(
|
|
mLauncher,
|
|
widgetId,
|
|
Launcher.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)
|
|
modelWriter.abortDelete()
|
|
mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
|
|
}
|
|
|
|
Snackbar.show(
|
|
mLauncher,
|
|
R.string.item_removed,
|
|
R.string.undo,
|
|
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)
|
|
}
|
|
}
|