1e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal/* 2e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Copyright (C) 2016 The Android Open Source Project 3e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * 4e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); 5e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * you may not use this file except in compliance with the License. 6e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * You may obtain a copy of the License at 7e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * 8e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * http://www.apache.org/licenses/LICENSE-2.0 9e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * 10e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Unless required by applicable law or agreed to in writing, software 11e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, 12e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * See the License for the specific language governing permissions and 14e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * limitations under the License. 15e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal */ 16e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalpackage com.android.launcher3.model; 17e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 18e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport android.os.UserHandle; 19e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport android.util.Log; 20e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 21e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.AllAppsList; 22e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.LauncherAppState; 23e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.LauncherModel; 24e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.LauncherModel.ModelUpdateTask; 25e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.LauncherModel.CallbackTask; 26e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.LauncherModel.Callbacks; 27e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.ShortcutInfo; 28e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.util.ComponentKey; 296e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyalimport com.android.launcher3.util.ItemInfoMatcher; 30e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport com.android.launcher3.util.MultiHashMap; 31f1fbc3fbe78997f141e2770221fe5ab1b1e68014Sunny Goyalimport com.android.launcher3.widget.WidgetListRowEntry; 32e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 33e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport java.util.ArrayList; 34e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalimport java.util.concurrent.Executor; 35e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 36e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal/** 37e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Extension of {@link ModelUpdateTask} with some utility methods 38e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal */ 39e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyalpublic abstract class BaseModelUpdateTask implements ModelUpdateTask { 40e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 41e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private static final boolean DEBUG_TASKS = false; 42e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private static final String TAG = "BaseModelUpdateTask"; 43e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 44e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private LauncherAppState mApp; 45e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private LauncherModel mModel; 46e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private BgDataModel mDataModel; 47e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private AllAppsList mAllAppsList; 48e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal private Executor mUiExecutor; 49e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 50e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void init(LauncherAppState app, LauncherModel model, 51e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor) { 52e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal mApp = app; 53e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal mModel = model; 54e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal mDataModel = dataModel; 55e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal mAllAppsList = allAppsList; 56e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal mUiExecutor = uiExecutor; 57e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 58e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 59e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal @Override 60e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public final void run() { 61e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal if (!mModel.isModelLoaded()) { 62e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal if (DEBUG_TASKS) { 63e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal Log.d(TAG, "Ignoring model task since loader is pending=" + this); 64e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 65e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal // Loader has not yet run. 66e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal return; 67e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 68e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal execute(mApp, mDataModel, mAllAppsList); 69e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 70e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 71e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal /** 72e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Execute the actual task. Called on the worker thread. 73e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal */ 74e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public abstract void execute( 75e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal LauncherAppState app, BgDataModel dataModel, AllAppsList apps); 76e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 77e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal /** 78e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal * Schedules a {@param task} to be executed on the current callbacks. 79e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal */ 80e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public final void scheduleCallbackTask(final CallbackTask task) { 81e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal final Callbacks callbacks = mModel.getCallback(); 823f7df53dda43d05c7a40ed8c4114b63189936ffeJon mUiExecutor.execute(() -> { 833f7df53dda43d05c7a40ed8c4114b63189936ffeJon Callbacks cb = mModel.getCallback(); 843f7df53dda43d05c7a40ed8c4114b63189936ffeJon if (callbacks == cb && cb != null) { 853f7df53dda43d05c7a40ed8c4114b63189936ffeJon task.execute(callbacks); 86e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 87e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal }); 88e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 89e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 90e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public ModelWriter getModelWriter() { 913f7df53dda43d05c7a40ed8c4114b63189936ffeJon // Updates from model task, do not deal with icon position in hotseat. Also no need to 923f7df53dda43d05c7a40ed8c4114b63189936ffeJon // verify changes as the ModelTasks always push the changes to callbacks 933f7df53dda43d05c7a40ed8c4114b63189936ffeJon return mModel.getWriter(false /* hasVerticalHotseat */, false /* verifyChanges */); 94e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 95e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 96e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 97e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void bindUpdatedShortcuts( 986e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts, final UserHandle user) { 996e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal if (!updatedShortcuts.isEmpty()) { 100e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal scheduleCallbackTask(new CallbackTask() { 101e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal @Override 102e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void execute(Callbacks callbacks) { 1036e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal callbacks.bindShortcutsChanged(updatedShortcuts, user); 104e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 105e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal }); 106e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 107e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 108e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 109e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void bindDeepShortcuts(BgDataModel dataModel) { 110e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal final MultiHashMap<ComponentKey, String> shortcutMapCopy = dataModel.deepShortcutMap.clone(); 111e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal scheduleCallbackTask(new CallbackTask() { 112e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal @Override 113e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void execute(Callbacks callbacks) { 114e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal callbacks.bindDeepShortcutMap(shortcutMapCopy); 115e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 116e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal }); 117e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 118e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal 119e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void bindUpdatedWidgets(BgDataModel dataModel) { 120f1fbc3fbe78997f141e2770221fe5ab1b1e68014Sunny Goyal final ArrayList<WidgetListRowEntry> widgets = 121f1fbc3fbe78997f141e2770221fe5ab1b1e68014Sunny Goyal dataModel.widgetsModel.getWidgetsList(mApp.getContext()); 122e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal scheduleCallbackTask(new CallbackTask() { 123e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal @Override 124e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal public void execute(Callbacks callbacks) { 125e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal callbacks.bindAllWidgets(widgets); 126e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 127e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal }); 128e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal } 1296e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal 1306e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) { 1316e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal getModelWriter().deleteItemsFromDatabase(matcher); 1326e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal 1336e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal // Call the components-removed callback 1346e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal scheduleCallbackTask(new CallbackTask() { 1356e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal @Override 1366e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal public void execute(Callbacks callbacks) { 1376e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal callbacks.bindWorkspaceComponentsRemoved(matcher); 1386e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal } 1396e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal }); 1406e13dd3aa867d01f3f1d196ac82eca184328577cSunny Goyal } 141e86f11fa386e5cc3ee81bd72771fc22750a35f03Sunny Goyal} 142