1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.launcher3.model 18 19 import com.android.launcher3.LauncherAppState 20 import com.android.launcher3.LauncherModel 21 import com.android.launcher3.LauncherModel.CallbackTask 22 import com.android.launcher3.celllayout.CellPosMapper 23 import com.android.launcher3.model.BgDataModel.FixedContainerItems 24 import com.android.launcher3.model.data.ItemInfo 25 import com.android.launcher3.model.data.WorkspaceItemInfo 26 import com.android.launcher3.util.PackageUserKey 27 import com.android.launcher3.widget.model.WidgetsListBaseEntriesBuilder 28 import java.util.Objects 29 import java.util.concurrent.Executor 30 import java.util.function.Predicate 31 32 /** Class with utility methods and properties for running a LauncherModel Task */ 33 class ModelTaskController( 34 val app: LauncherAppState, 35 val dataModel: BgDataModel, 36 val allAppsList: AllAppsList, 37 private val model: LauncherModel, 38 private val uiExecutor: Executor, 39 ) { 40 41 /** Schedules a {@param task} to be executed on the current callbacks. */ 42 fun scheduleCallbackTask(task: CallbackTask) { 43 for (cb in model.callbacks) { 44 uiExecutor.execute { task.execute(cb) } 45 } 46 } 47 48 /** 49 * Updates from model task, do not deal with icon position in hotseat. Also no need to verify 50 * changes as the ModelTasks always push the changes to callbacks 51 */ 52 fun getModelWriter() = model.getWriter(false /* verifyChanges */, CellPosMapper.DEFAULT, null) 53 54 fun bindUpdatedWorkspaceItems(allUpdates: List<WorkspaceItemInfo>) { 55 // Bind workspace items 56 val workspaceUpdates = 57 allUpdates.stream().filter { info -> info.id != ItemInfo.NO_ID }.toList() 58 if (workspaceUpdates.isNotEmpty()) { 59 scheduleCallbackTask { it.bindWorkspaceItemsChanged(workspaceUpdates) } 60 } 61 62 // Bind extra items if any 63 allUpdates 64 .stream() 65 .mapToInt { info: WorkspaceItemInfo -> info.container } 66 .distinct() 67 .mapToObj { dataModel.extraItems.get(it) } 68 .filter { Objects.nonNull(it) } 69 .forEach { bindExtraContainerItems(it) } 70 } 71 72 fun bindExtraContainerItems(item: FixedContainerItems) { 73 scheduleCallbackTask { it.bindExtraContainerItems(item) } 74 } 75 76 fun bindDeepShortcuts(dataModel: BgDataModel) { 77 val shortcutMapCopy = HashMap(dataModel.deepShortcutMap) 78 scheduleCallbackTask { it.bindDeepShortcutMap(shortcutMapCopy) } 79 } 80 81 fun bindUpdatedWidgets(dataModel: BgDataModel) { 82 val widgetsByPackageItem = dataModel.widgetsModel.widgetsByPackageItem 83 val allWidgets = WidgetsListBaseEntriesBuilder(app.context).build(widgetsByPackageItem) 84 85 val defaultWidgetsFilter = dataModel.widgetsModel.defaultWidgetsFilter 86 val defaultWidgets = 87 if (defaultWidgetsFilter != null) { 88 WidgetsListBaseEntriesBuilder(app.context) 89 .build(widgetsByPackageItem, defaultWidgetsFilter) 90 } else { 91 emptyList() 92 } 93 94 scheduleCallbackTask { it.bindAllWidgets(allWidgets, defaultWidgets) } 95 } 96 97 fun deleteAndBindComponentsRemoved(matcher: Predicate<ItemInfo?>, reason: String?) { 98 getModelWriter().deleteItemsFromDatabase(matcher, reason) 99 100 // Call the components-removed callback 101 scheduleCallbackTask { it.bindWorkspaceComponentsRemoved(matcher) } 102 } 103 104 fun bindApplicationsIfNeeded() { 105 if (allAppsList.getAndResetChangeFlag()) { 106 val apps = allAppsList.copyData() 107 val flags = allAppsList.flags 108 val packageUserKeyToUidMap = 109 apps.associateBy( 110 keySelector = { PackageUserKey(it.componentName!!.packageName, it.user) }, 111 valueTransform = { it.uid }, 112 ) 113 scheduleCallbackTask { it.bindAllApplications(apps, flags, packageUserKeyToUidMap) } 114 } 115 } 116 } 117