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.util;
17 
18 import android.graphics.drawable.Drawable;
19 import android.view.View;
20 
21 import com.android.launcher3.BubbleTextView;
22 import com.android.launcher3.apppairs.AppPairIcon;
23 import com.android.launcher3.folder.Folder;
24 import com.android.launcher3.folder.FolderIcon;
25 import com.android.launcher3.graphics.PreloadIconDrawable;
26 import com.android.launcher3.model.data.AppPairInfo;
27 import com.android.launcher3.model.data.FolderInfo;
28 import com.android.launcher3.model.data.ItemInfo;
29 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
30 import com.android.launcher3.model.data.WorkspaceItemInfo;
31 import com.android.launcher3.views.ActivityContext;
32 import com.android.launcher3.widget.PendingAppWidgetHostView;
33 
34 import java.util.HashSet;
35 import java.util.List;
36 
37 /**
38  * Interface representing a container which can bind Launcher items with some utility methods
39  */
40 public interface LauncherBindableItemsContainer {
41 
42     /**
43      * Called to update workspace items as a result of
44      * {@link com.android.launcher3.model.BgDataModel.Callbacks#bindWorkspaceItemsChanged(List)}
45      */
updateWorkspaceItems(List<WorkspaceItemInfo> shortcuts, ActivityContext context)46     default void updateWorkspaceItems(List<WorkspaceItemInfo> shortcuts, ActivityContext context) {
47         final HashSet<WorkspaceItemInfo> updates = new HashSet<>(shortcuts);
48         ItemOperator op = (info, v) -> {
49             if (v instanceof BubbleTextView && updates.contains(info)) {
50                 WorkspaceItemInfo si = (WorkspaceItemInfo) info;
51                 BubbleTextView shortcut = (BubbleTextView) v;
52                 Drawable oldIcon = shortcut.getIcon();
53                 boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
54                         && ((PreloadIconDrawable) oldIcon).hasNotCompleted();
55                 shortcut.applyFromWorkspaceItem(
56                         si,
57                         si.isPromise() != oldPromiseState
58                                 && oldIcon instanceof PreloadIconDrawable
59                                 ? (PreloadIconDrawable) oldIcon
60                                 : null);
61             } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
62                 ((FolderIcon) v).updatePreviewItems(updates::contains);
63             } else if (info instanceof AppPairInfo && v instanceof AppPairIcon appPairIcon) {
64                 appPairIcon.maybeRedrawForWorkspaceUpdate(updates::contains);
65             }
66 
67             // Iterate all items
68             return false;
69         };
70 
71         mapOverItems(op);
72         Folder openFolder = Folder.getOpen(context);
73         if (openFolder != null) {
74             openFolder.iterateOverItems(op);
75         }
76     }
77 
78     /**
79      * Called to update restored items as a result of
80      * {@link com.android.launcher3.model.BgDataModel.Callbacks#bindRestoreItemsChange(HashSet)}}
81      */
updateRestoreItems(final HashSet<ItemInfo> updates, ActivityContext context)82     default void updateRestoreItems(final HashSet<ItemInfo> updates, ActivityContext context) {
83         ItemOperator op = (info, v) -> {
84             if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView
85                     && updates.contains(info)) {
86                 ((BubbleTextView) v).applyLoadingState(null);
87             } else if (v instanceof PendingAppWidgetHostView
88                     && info instanceof LauncherAppWidgetInfo
89                     && updates.contains(info)) {
90                 ((PendingAppWidgetHostView) v).applyState();
91             } else if (v instanceof FolderIcon && info instanceof FolderInfo) {
92                 ((FolderIcon) v).updatePreviewItems(updates::contains);
93             } else if (info instanceof AppPairInfo && v instanceof AppPairIcon appPairIcon) {
94                 appPairIcon.maybeRedrawForWorkspaceUpdate(updates::contains);
95             }
96             // process all the shortcuts
97             return false;
98         };
99 
100         mapOverItems(op);
101         Folder folder = Folder.getOpen(context);
102         if (folder != null) {
103             folder.iterateOverItems(op);
104         }
105     }
106 
107     /**
108      * Map the operator over the shortcuts and widgets.
109      *
110      * @param op the operator to map over the shortcuts
111      */
mapOverItems(ItemOperator op)112     void mapOverItems(ItemOperator op);
113 
114     interface ItemOperator {
115         /**
116          * Process the next itemInfo, possibly with side-effect on the next item.
117          *
118          * @param info info for the shortcut
119          * @param view view for the shortcut
120          * @return true if done, false to continue the map
121          */
evaluate(ItemInfo info, View view)122         boolean evaluate(ItemInfo info, View view);
123     }
124 }
125