1 /* 2 * 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 android.content.Context 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.dagger.ApplicationContext 24 import com.android.launcher3.icons.IconCache 25 import com.android.launcher3.model.BgDataModel.FixedContainerItems 26 import com.android.launcher3.model.data.ItemInfo 27 import com.android.launcher3.util.Executors.MAIN_EXECUTOR 28 import com.android.launcher3.util.PackageUserKey 29 import com.android.launcher3.widget.model.WidgetsListBaseEntriesBuilder 30 import java.util.Objects 31 import java.util.function.Predicate 32 import javax.inject.Inject 33 34 /** Class with utility methods and properties for running a LauncherModel Task */ 35 class ModelTaskController 36 @Inject 37 constructor( 38 @ApplicationContext val context: Context, 39 val iconCache: IconCache, 40 val dataModel: BgDataModel, 41 val allAppsList: AllAppsList, 42 val model: LauncherModel, 43 ) { 44 45 private val uiExecutor = MAIN_EXECUTOR 46 47 /** Schedules a {@param task} to be executed on the current callbacks. */ scheduleCallbackTasknull48 fun scheduleCallbackTask(task: CallbackTask) { 49 for (cb in model.callbacks) { 50 uiExecutor.execute { task.execute(cb) } 51 } 52 } 53 54 /** 55 * Updates from model task, do not deal with icon position in hotseat. Also no need to verify 56 * changes as the ModelTasks always push the changes to callbacks 57 */ getModelWriternull58 fun getModelWriter() = model.getWriter(false /* verifyChanges */, CellPosMapper.DEFAULT, null) 59 60 fun bindUpdatedWorkspaceItems(allUpdates: Collection<ItemInfo>) { 61 // Bind workspace items 62 val workspaceUpdates = allUpdates.filter { it.id != ItemInfo.NO_ID }.toSet() 63 if (workspaceUpdates.isNotEmpty()) { 64 scheduleCallbackTask { it.bindItemsUpdated(workspaceUpdates) } 65 } 66 67 // Bind extra items if any 68 allUpdates 69 .stream() 70 .mapToInt { it.container } 71 .distinct() 72 .mapToObj { dataModel.extraItems.get(it) } 73 .filter { Objects.nonNull(it) } 74 .forEach { bindExtraContainerItems(it) } 75 } 76 bindExtraContainerItemsnull77 fun bindExtraContainerItems(item: FixedContainerItems) { 78 scheduleCallbackTask { it.bindExtraContainerItems(item) } 79 } 80 bindDeepShortcutsnull81 fun bindDeepShortcuts(dataModel: BgDataModel) { 82 val shortcutMapCopy = HashMap(dataModel.deepShortcutMap) 83 scheduleCallbackTask { it.bindDeepShortcutMap(shortcutMapCopy) } 84 } 85 bindUpdatedWidgetsnull86 fun bindUpdatedWidgets(dataModel: BgDataModel) { 87 val allWidgets = 88 WidgetsListBaseEntriesBuilder(context) 89 .build(dataModel.widgetsModel.widgetsByPackageItemForPicker) 90 scheduleCallbackTask { it.bindAllWidgets(allWidgets) } 91 } 92 deleteAndBindComponentsRemovednull93 fun deleteAndBindComponentsRemoved(matcher: Predicate<ItemInfo?>, reason: String?) { 94 getModelWriter().deleteItemsFromDatabase(matcher, reason) 95 96 // Call the components-removed callback 97 scheduleCallbackTask { it.bindWorkspaceComponentsRemoved(matcher) } 98 } 99 bindApplicationsIfNeedednull100 fun bindApplicationsIfNeeded() { 101 if (allAppsList.getAndResetChangeFlag()) { 102 val apps = allAppsList.copyData() 103 val flags = allAppsList.flags 104 val packageUserKeyToUidMap = 105 apps.associateBy( 106 keySelector = { PackageUserKey(it.componentName!!.packageName, it.user) }, 107 valueTransform = { it.uid }, 108 ) 109 scheduleCallbackTask { it.bindAllApplications(apps, flags, packageUserKeyToUidMap) } 110 } 111 } 112 } 113