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