Sebastian Franco | bd7919c | 2023-09-19 10:55:37 -0700 | [diff] [blame] | 1 | package com.android.launcher3 |
| 2 | |
| 3 | import androidx.annotation.UiThread |
| 4 | import com.android.launcher3.model.BgDataModel |
| 5 | import com.android.launcher3.model.data.AppInfo |
| 6 | import com.android.launcher3.model.data.ItemInfo |
| 7 | import com.android.launcher3.model.data.LauncherAppWidgetInfo |
| 8 | import com.android.launcher3.model.data.WorkspaceItemInfo |
| 9 | import com.android.launcher3.popup.PopupContainerWithArrow |
| 10 | import com.android.launcher3.util.ComponentKey |
Sebastian Franco | 69fd742 | 2023-10-06 16:48:58 -0700 | [diff] [blame] | 11 | import com.android.launcher3.util.IntArray as LIntArray |
| 12 | import com.android.launcher3.util.IntSet as LIntSet |
Sebastian Franco | bd7919c | 2023-09-19 10:55:37 -0700 | [diff] [blame] | 13 | import com.android.launcher3.util.PackageUserKey |
| 14 | import com.android.launcher3.util.Preconditions |
| 15 | import com.android.launcher3.widget.model.WidgetsListBaseEntry |
| 16 | import java.util.function.Predicate |
| 17 | |
| 18 | class ModelCallbacks(private var launcher: Launcher) : BgDataModel.Callbacks { |
Sebastian Franco | 69fd742 | 2023-10-06 16:48:58 -0700 | [diff] [blame] | 19 | |
| 20 | var synchronouslyBoundPages = LIntSet() |
| 21 | var pagesToBindSynchronously = LIntSet() |
| 22 | |
Sebastian Franco | bd7919c | 2023-09-19 10:55:37 -0700 | [diff] [blame] | 23 | override fun preAddApps() { |
| 24 | // If there's an undo snackbar, force it to complete to ensure empty screens are removed |
| 25 | // before trying to add new items. |
| 26 | launcher.modelWriter.commitDelete() |
| 27 | val snackbar = |
| 28 | AbstractFloatingView.getOpenView<AbstractFloatingView>( |
| 29 | launcher, |
| 30 | AbstractFloatingView.TYPE_SNACKBAR |
| 31 | ) |
| 32 | snackbar?.post { snackbar.close(true) } |
| 33 | } |
| 34 | |
| 35 | @UiThread |
| 36 | override fun bindAllApplications( |
| 37 | apps: Array<AppInfo?>?, |
| 38 | flags: Int, |
| 39 | packageUserKeytoUidMap: Map<PackageUserKey?, Int?>? |
| 40 | ) { |
| 41 | Preconditions.assertUIThread() |
| 42 | val hadWorkApps = launcher.appsView.shouldShowTabs() |
| 43 | launcher.appsView.appsStore.setApps(apps, flags, packageUserKeytoUidMap) |
| 44 | PopupContainerWithArrow.dismissInvalidPopup(launcher) |
| 45 | if (hadWorkApps != launcher.appsView.shouldShowTabs()) { |
| 46 | launcher.stateManager.goToState(LauncherState.NORMAL) |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Copies LauncherModel's map of activities to shortcut counts to Launcher's. This is necessary |
| 52 | * because LauncherModel's map is updated in the background, while Launcher runs on the UI. |
| 53 | */ |
| 54 | override fun bindDeepShortcutMap(deepShortcutMapCopy: HashMap<ComponentKey?, Int?>?) { |
| 55 | launcher.popupDataProvider.setDeepShortcutMap(deepShortcutMapCopy) |
| 56 | } |
| 57 | |
| 58 | override fun bindIncrementalDownloadProgressUpdated(app: AppInfo?) { |
| 59 | launcher.appsView.appsStore.updateProgressBar(app) |
| 60 | } |
| 61 | |
| 62 | override fun bindWidgetsRestored(widgets: ArrayList<LauncherAppWidgetInfo?>?) { |
| 63 | launcher.workspace.widgetsRestored(widgets) |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * Some shortcuts were updated in the background. Implementation of the method from |
| 68 | * LauncherModel.Callbacks. |
| 69 | * |
| 70 | * @param updated list of shortcuts which have changed. |
| 71 | */ |
| 72 | override fun bindWorkspaceItemsChanged(updated: List<WorkspaceItemInfo?>) { |
| 73 | if (updated.isNotEmpty()) { |
| 74 | launcher.workspace.updateWorkspaceItems(updated, launcher) |
| 75 | PopupContainerWithArrow.dismissInvalidPopup(launcher) |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Update the state of a package, typically related to install state. Implementation of the |
| 81 | * method from LauncherModel.Callbacks. |
| 82 | */ |
| 83 | override fun bindRestoreItemsChange(updates: HashSet<ItemInfo?>?) { |
| 84 | launcher.workspace.updateRestoreItems(updates, launcher) |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * A package was uninstalled/updated. We take both the super set of packageNames in addition to |
| 89 | * specific applications to remove, the reason being that this can be called when a package is |
| 90 | * updated as well. In that scenario, we only remove specific components from the workspace and |
| 91 | * hotseat, where as package-removal should clear all items by package name. |
| 92 | */ |
| 93 | override fun bindWorkspaceComponentsRemoved(matcher: Predicate<ItemInfo?>?) { |
| 94 | launcher.workspace.removeItemsByMatcher(matcher) |
| 95 | launcher.dragController.onAppsRemoved(matcher) |
| 96 | PopupContainerWithArrow.dismissInvalidPopup(launcher) |
| 97 | } |
| 98 | |
| 99 | override fun bindAllWidgets(allWidgets: List<WidgetsListBaseEntry?>?) { |
| 100 | launcher.popupDataProvider.allWidgets = allWidgets |
| 101 | } |
Sebastian Franco | 69fd742 | 2023-10-06 16:48:58 -0700 | [diff] [blame] | 102 | |
| 103 | /** Returns the ids of the workspaces to bind. */ |
| 104 | override fun getPagesToBindSynchronously(orderedScreenIds: LIntArray): LIntSet { |
| 105 | // If workspace binding is still in progress, getCurrentPageScreenIds won't be |
| 106 | // accurate, and we should use mSynchronouslyBoundPages that's set during initial binding. |
| 107 | val visibleIds = |
| 108 | when { |
| 109 | !pagesToBindSynchronously.isEmpty -> pagesToBindSynchronously |
| 110 | !launcher.isWorkspaceLoading -> launcher.workspace.currentPageScreenIds |
| 111 | else -> synchronouslyBoundPages |
| 112 | } |
| 113 | // Launcher IntArray has the same name as Kotlin IntArray |
| 114 | val result = LIntSet() |
| 115 | if (visibleIds.isEmpty) { |
| 116 | return result |
| 117 | } |
| 118 | val actualIds = orderedScreenIds.clone() |
| 119 | val firstId = visibleIds.first() |
| 120 | val pairId = launcher.workspace.getScreenPair(firstId) |
| 121 | // Double check that actual screenIds contains the visibleId, as empty screens are hidden |
| 122 | // in single panel. |
| 123 | if (actualIds.contains(firstId)) { |
| 124 | result.add(firstId) |
| 125 | if (launcher.deviceProfile.isTwoPanels && actualIds.contains(pairId)) { |
| 126 | result.add(pairId) |
| 127 | } |
| 128 | } else if ( |
| 129 | LauncherAppState.getIDP(launcher).supportedProfiles.any(DeviceProfile::isTwoPanels) && |
| 130 | actualIds.contains(pairId) |
| 131 | ) { |
| 132 | // Add the right panel if left panel is hidden when switching display, due to empty |
| 133 | // pages being hidden in single panel. |
| 134 | result.add(pairId) |
| 135 | } |
| 136 | return result |
| 137 | } |
Sebastian Franco | bd7919c | 2023-09-19 10:55:37 -0700 | [diff] [blame] | 138 | } |