1 /* 2 * Copyright (C) 2016 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 package com.android.launcher3.model; 17 18 import android.util.Log; 19 20 import com.android.launcher3.LauncherAppState; 21 import com.android.launcher3.LauncherModel; 22 import com.android.launcher3.LauncherModel.CallbackTask; 23 import com.android.launcher3.LauncherModel.ModelUpdateTask; 24 import com.android.launcher3.model.BgDataModel.Callbacks; 25 import com.android.launcher3.model.data.AppInfo; 26 import com.android.launcher3.model.data.WorkspaceItemInfo; 27 import com.android.launcher3.util.ComponentKey; 28 import com.android.launcher3.util.ItemInfoMatcher; 29 import com.android.launcher3.widget.WidgetListRowEntry; 30 31 import java.util.ArrayList; 32 import java.util.HashMap; 33 import java.util.concurrent.Executor; 34 35 /** 36 * Extension of {@link ModelUpdateTask} with some utility methods 37 */ 38 public abstract class BaseModelUpdateTask implements ModelUpdateTask { 39 40 private static final boolean DEBUG_TASKS = false; 41 private static final String TAG = "BaseModelUpdateTask"; 42 43 private LauncherAppState mApp; 44 private LauncherModel mModel; 45 private BgDataModel mDataModel; 46 private AllAppsList mAllAppsList; 47 private Executor mUiExecutor; 48 init(LauncherAppState app, LauncherModel model, BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor)49 public void init(LauncherAppState app, LauncherModel model, 50 BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor) { 51 mApp = app; 52 mModel = model; 53 mDataModel = dataModel; 54 mAllAppsList = allAppsList; 55 mUiExecutor = uiExecutor; 56 } 57 58 @Override run()59 public final void run() { 60 if (!mModel.isModelLoaded()) { 61 if (DEBUG_TASKS) { 62 Log.d(TAG, "Ignoring model task since loader is pending=" + this); 63 } 64 // Loader has not yet run. 65 return; 66 } 67 execute(mApp, mDataModel, mAllAppsList); 68 } 69 70 /** 71 * Execute the actual task. Called on the worker thread. 72 */ execute( LauncherAppState app, BgDataModel dataModel, AllAppsList apps)73 public abstract void execute( 74 LauncherAppState app, BgDataModel dataModel, AllAppsList apps); 75 76 /** 77 * Schedules a {@param task} to be executed on the current callbacks. 78 */ scheduleCallbackTask(final CallbackTask task)79 public final void scheduleCallbackTask(final CallbackTask task) { 80 for (final Callbacks cb : mModel.getCallbacks()) { 81 mUiExecutor.execute(() -> task.execute(cb)); 82 } 83 } 84 getModelWriter()85 public ModelWriter getModelWriter() { 86 // Updates from model task, do not deal with icon position in hotseat. Also no need to 87 // verify changes as the ModelTasks always push the changes to callbacks 88 return mModel.getWriter(false /* hasVerticalHotseat */, false /* verifyChanges */); 89 } 90 91 bindUpdatedWorkspaceItems(final ArrayList<WorkspaceItemInfo> updatedShortcuts)92 public void bindUpdatedWorkspaceItems(final ArrayList<WorkspaceItemInfo> updatedShortcuts) { 93 if (!updatedShortcuts.isEmpty()) { 94 scheduleCallbackTask(c -> c.bindWorkspaceItemsChanged(updatedShortcuts)); 95 } 96 } 97 bindDeepShortcuts(BgDataModel dataModel)98 public void bindDeepShortcuts(BgDataModel dataModel) { 99 final HashMap<ComponentKey, Integer> shortcutMapCopy = 100 new HashMap<>(dataModel.deepShortcutMap); 101 scheduleCallbackTask(callbacks -> callbacks.bindDeepShortcutMap(shortcutMapCopy)); 102 } 103 bindUpdatedWidgets(BgDataModel dataModel)104 public void bindUpdatedWidgets(BgDataModel dataModel) { 105 final ArrayList<WidgetListRowEntry> widgets = 106 dataModel.widgetsModel.getWidgetsList(mApp.getContext()); 107 scheduleCallbackTask(c -> c.bindAllWidgets(widgets)); 108 } 109 deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher)110 public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) { 111 getModelWriter().deleteItemsFromDatabase(matcher); 112 113 // Call the components-removed callback 114 scheduleCallbackTask(c -> c.bindWorkspaceComponentsRemoved(matcher)); 115 } 116 bindApplicationsIfNeeded()117 public void bindApplicationsIfNeeded() { 118 if (mAllAppsList.getAndResetChangeFlag()) { 119 AppInfo[] apps = mAllAppsList.copyData(); 120 int flags = mAllAppsList.getFlags(); 121 scheduleCallbackTask(c -> c.bindAllApplications(apps, flags)); 122 } 123 } 124 } 125