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