• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.taskbar;
17 
18 import android.util.SparseArray;
19 import android.view.View;
20 
21 import com.android.launcher3.LauncherSettings.Favorites;
22 import com.android.launcher3.model.BgDataModel;
23 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
24 import com.android.launcher3.model.data.AppInfo;
25 import com.android.launcher3.model.data.ItemInfo;
26 import com.android.launcher3.model.data.WorkspaceItemInfo;
27 import com.android.launcher3.util.ComponentKey;
28 import com.android.launcher3.util.IntArray;
29 import com.android.launcher3.util.IntSet;
30 import com.android.launcher3.util.ItemInfoMatcher;
31 import com.android.launcher3.util.LauncherBindableItemsContainer;
32 import com.android.quickstep.RecentsModel;
33 
34 import java.io.PrintWriter;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.function.Predicate;
41 
42 /**
43  * Launcher model Callbacks for rendering taskbar.
44  */
45 public class TaskbarModelCallbacks implements
46         BgDataModel.Callbacks, LauncherBindableItemsContainer, RecentsModel.RunningTasksListener {
47 
48     private final SparseArray<ItemInfo> mHotseatItems = new SparseArray<>();
49     private List<ItemInfo> mPredictedItems = Collections.emptyList();
50 
51     private final TaskbarActivityContext mContext;
52     private final TaskbarView mContainer;
53 
54     // Initialized in init.
55     private TaskbarControllers mControllers;
56 
TaskbarModelCallbacks( TaskbarActivityContext context, TaskbarView container)57     public TaskbarModelCallbacks(
58             TaskbarActivityContext context, TaskbarView container) {
59         mContext = context;
60         mContainer = container;
61     }
62 
init(TaskbarControllers controllers)63     public void init(TaskbarControllers controllers) {
64         mControllers = controllers;
65         if (mControllers.taskbarRecentAppsController.isEnabled()) {
66             RecentsModel.INSTANCE.get(mContext).registerRunningTasksListener(this);
67         }
68     }
69 
70     /**
71      * Unregisters listeners in this class.
72      */
unregisterListeners()73     public void unregisterListeners() {
74         RecentsModel.INSTANCE.get(mContext).unregisterRunningTasksListener();
75     }
76 
77     @Override
startBinding()78     public void startBinding() {
79         mContext.setBindingItems(true);
80         mHotseatItems.clear();
81         mPredictedItems = Collections.emptyList();
82     }
83 
84     @Override
finishBindingItems(IntSet pagesBoundFirst)85     public void finishBindingItems(IntSet pagesBoundFirst) {
86         mContext.setBindingItems(false);
87         commitItemsToUI();
88     }
89 
90     @Override
bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated)91     public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
92             ArrayList<ItemInfo> addAnimated) {
93         boolean add1 = handleItemsAdded(addNotAnimated);
94         boolean add2 = handleItemsAdded(addAnimated);
95         if (add1 || add2) {
96             commitItemsToUI();
97         }
98     }
99 
100     @Override
bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons)101     public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) {
102         if (handleItemsAdded(shortcuts)) {
103             commitItemsToUI();
104         }
105     }
106 
handleItemsAdded(List<ItemInfo> items)107     private boolean handleItemsAdded(List<ItemInfo> items) {
108         boolean modified = false;
109         for (ItemInfo item : items) {
110             if (item.container == Favorites.CONTAINER_HOTSEAT) {
111                 mHotseatItems.put(item.screenId, item);
112                 modified = true;
113             }
114         }
115         return modified;
116     }
117 
118 
119     @Override
bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated)120     public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
121         updateWorkspaceItems(updated, mContext);
122     }
123 
124     @Override
bindRestoreItemsChange(HashSet<ItemInfo> updates)125     public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
126         updateRestoreItems(updates, mContext);
127     }
128 
129     @Override
mapOverItems(ItemOperator op)130     public void mapOverItems(ItemOperator op) {
131         final int itemCount = mContainer.getChildCount();
132         for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
133             View item = mContainer.getChildAt(itemIdx);
134             if (op.evaluate((ItemInfo) item.getTag(), item)) {
135                 return;
136             }
137         }
138     }
139 
140     @Override
bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher)141     public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) {
142         if (handleItemsRemoved(matcher)) {
143             commitItemsToUI();
144         }
145     }
146 
handleItemsRemoved(Predicate<ItemInfo> matcher)147     private boolean handleItemsRemoved(Predicate<ItemInfo> matcher) {
148         boolean modified = false;
149         for (int i = mHotseatItems.size() - 1; i >= 0; i--) {
150             if (matcher.test(mHotseatItems.valueAt(i))) {
151                 modified = true;
152                 mHotseatItems.removeAt(i);
153             }
154         }
155         return modified;
156     }
157 
158     @Override
bindItemsModified(List<ItemInfo> items)159     public void bindItemsModified(List<ItemInfo> items) {
160         boolean removed = handleItemsRemoved(ItemInfoMatcher.ofItems(items));
161         boolean added = handleItemsAdded(items);
162         if (removed || added) {
163             commitItemsToUI();
164         }
165     }
166 
167     @Override
bindExtraContainerItems(FixedContainerItems item)168     public void bindExtraContainerItems(FixedContainerItems item) {
169         if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) {
170             mPredictedItems = item.items;
171             commitItemsToUI();
172         } else if (item.containerId == Favorites.CONTAINER_PREDICTION) {
173             mControllers.taskbarAllAppsController.setPredictedApps(item.items);
174         }
175     }
176 
commitItemsToUI()177     private void commitItemsToUI() {
178         if (mContext.isBindingItems()) {
179             return;
180         }
181 
182         ItemInfo[] hotseatItemInfos =
183                 new ItemInfo[mContext.getDeviceProfile().numShownHotseatIcons];
184         int predictionSize = mPredictedItems.size();
185         int predictionNextIndex = 0;
186 
187         for (int i = 0; i < hotseatItemInfos.length; i++) {
188             hotseatItemInfos[i] = mHotseatItems.get(i);
189             if (hotseatItemInfos[i] == null && predictionNextIndex < predictionSize) {
190                 hotseatItemInfos[i] = mPredictedItems.get(predictionNextIndex);
191                 hotseatItemInfos[i].screenId = i;
192                 predictionNextIndex++;
193             }
194         }
195         hotseatItemInfos = mControllers.taskbarRecentAppsController
196                 .updateHotseatItemInfos(hotseatItemInfos);
197         mContainer.updateHotseatItems(hotseatItemInfos);
198         mControllers.taskbarViewController.updateIconsBackground();
199     }
200 
201     @Override
onRunningTasksChanged()202     public void onRunningTasksChanged() {
203         updateRunningApps();
204     }
205 
206     /** Called when there's a change in running apps to update the UI. */
commitRunningAppsToUI()207     public void commitRunningAppsToUI() {
208         commitItemsToUI();
209     }
210 
211     /** Call TaskbarRecentAppsController to update running apps with mHotseatItems. */
updateRunningApps()212     public void updateRunningApps() {
213         mControllers.taskbarRecentAppsController.updateRunningApps(mHotseatItems);
214     }
215 
216     @Override
bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy)217     public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy) {
218         mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy);
219     }
220 
221     @Override
bindAllApplications(AppInfo[] apps, int flags)222     public void bindAllApplications(AppInfo[] apps, int flags) {
223         mControllers.taskbarAllAppsController.setApps(apps, flags);
224         mControllers.taskbarRecentAppsController.setApps(apps);
225     }
226 
dumpLogs(String prefix, PrintWriter pw)227     protected void dumpLogs(String prefix, PrintWriter pw) {
228         pw.println(prefix + "TaskbarModelCallbacks:");
229 
230         pw.println(String.format("%s\thotseat items count=%s", prefix, mHotseatItems.size()));
231         if (mPredictedItems != null) {
232             pw.println(
233                     String.format("%s\tpredicted items count=%s", prefix, mPredictedItems.size()));
234         }
235     }
236 }
237