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 java.util.Objects 28 import java.util.concurrent.Executor 29 import java.util.function.Predicate 30 31 /** Class with utility methods and properties for running a LauncherModel Task */ 32 class ModelTaskController( 33 val app: LauncherAppState, 34 val dataModel: BgDataModel, 35 val allAppsList: AllAppsList, 36 private val model: LauncherModel, 37 private val uiExecutor: Executor 38 ) { 39 40 /** Schedules a {@param task} to be executed on the current callbacks. */ 41 fun scheduleCallbackTask(task: CallbackTask) { 42 for (cb in model.callbacks) { 43 uiExecutor.execute { task.execute(cb) } 44 } 45 } 46 47 /** 48 * Updates from model task, do not deal with icon position in hotseat. Also no need to verify 49 * changes as the ModelTasks always push the changes to callbacks 50 */ 51 fun getModelWriter() = model.getWriter(false /* verifyChanges */, CellPosMapper.DEFAULT, null) 52 53 fun bindUpdatedWorkspaceItems(allUpdates: List<WorkspaceItemInfo>) { 54 // Bind workspace items 55 val workspaceUpdates = 56 allUpdates.stream().filter { info -> info.id != ItemInfo.NO_ID }.toList() 57 if (workspaceUpdates.isNotEmpty()) { 58 scheduleCallbackTask { it.bindWorkspaceItemsChanged(workspaceUpdates) } 59 } 60 61 // Bind extra items if any 62 allUpdates 63 .stream() 64 .mapToInt { info: WorkspaceItemInfo -> info.container } 65 .distinct() 66 .mapToObj { dataModel.extraItems.get(it) } 67 .filter { Objects.nonNull(it) } 68 .forEach { bindExtraContainerItems(it) } 69 } 70 71 fun bindExtraContainerItems(item: FixedContainerItems) { 72 scheduleCallbackTask { it.bindExtraContainerItems(item) } 73 } 74 75 fun bindDeepShortcuts(dataModel: BgDataModel) { 76 val shortcutMapCopy = HashMap(dataModel.deepShortcutMap) 77 scheduleCallbackTask { it.bindDeepShortcutMap(shortcutMapCopy) } 78 } 79 80 fun bindUpdatedWidgets(dataModel: BgDataModel) { 81 val widgets = dataModel.widgetsModel.getWidgetsListForPicker(app.context) 82 scheduleCallbackTask { it.bindAllWidgets(widgets) } 83 } 84 85 fun deleteAndBindComponentsRemoved(matcher: Predicate<ItemInfo?>, reason: String?) { 86 getModelWriter().deleteItemsFromDatabase(matcher, reason) 87 88 // Call the components-removed callback 89 scheduleCallbackTask { it.bindWorkspaceComponentsRemoved(matcher) } 90 } 91 92 fun bindApplicationsIfNeeded() { 93 if (allAppsList.getAndResetChangeFlag()) { 94 val apps = allAppsList.copyData() 95 val flags = allAppsList.flags 96 val packageUserKeyToUidMap = 97 apps.associateBy( 98 keySelector = { PackageUserKey(it.componentName!!.packageName, it.user) }, 99 valueTransform = { it.uid } 100 ) 101 scheduleCallbackTask { it.bindAllApplications(apps, flags, packageUserKeyToUidMap) } 102 } 103 } 104 } 105