• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.model;
17 
18 import android.content.Context;
19 import android.os.UserHandle;
20 
21 import com.android.launcher3.AllAppsList;
22 import com.android.launcher3.ItemInfo;
23 import com.android.launcher3.LauncherAppState;
24 import com.android.launcher3.LauncherSettings;
25 import com.android.launcher3.ShortcutInfo;
26 import com.android.launcher3.graphics.LauncherIcons;
27 import com.android.launcher3.shortcuts.DeepShortcutManager;
28 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
29 import com.android.launcher3.shortcuts.ShortcutKey;
30 import com.android.launcher3.util.ItemInfoMatcher;
31 import com.android.launcher3.util.MultiHashMap;
32 import com.android.launcher3.util.Provider;
33 
34 import java.util.ArrayList;
35 import java.util.HashSet;
36 import java.util.List;
37 
38 /**
39  * Handles changes due to shortcut manager updates (deep shortcut changes)
40  */
41 public class ShortcutsChangedTask extends BaseModelUpdateTask {
42 
43     private final String mPackageName;
44     private final List<ShortcutInfoCompat> mShortcuts;
45     private final UserHandle mUser;
46     private final boolean mUpdateIdMap;
47 
ShortcutsChangedTask(String packageName, List<ShortcutInfoCompat> shortcuts, UserHandle user, boolean updateIdMap)48     public ShortcutsChangedTask(String packageName, List<ShortcutInfoCompat> shortcuts,
49             UserHandle user, boolean updateIdMap) {
50         mPackageName = packageName;
51         mShortcuts = shortcuts;
52         mUser = user;
53         mUpdateIdMap = updateIdMap;
54     }
55 
56     @Override
execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps)57     public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
58         final Context context = app.getContext();
59         DeepShortcutManager deepShortcutManager = DeepShortcutManager.getInstance(context);
60         deepShortcutManager.onShortcutsChanged(mShortcuts);
61 
62         // Find ShortcutInfo's that have changed on the workspace.
63         HashSet<ShortcutKey> removedKeys = new HashSet<>();
64         MultiHashMap<ShortcutKey, ShortcutInfo> keyToShortcutInfo = new MultiHashMap<>();
65         HashSet<String> allIds = new HashSet<>();
66 
67         for (ItemInfo itemInfo : dataModel.itemsIdMap) {
68             if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
69                 ShortcutInfo si = (ShortcutInfo) itemInfo;
70                 if (si.getIntent().getPackage().equals(mPackageName) && si.user.equals(mUser)) {
71                     keyToShortcutInfo.addToList(ShortcutKey.fromItemInfo(si), si);
72                     allIds.add(si.getDeepShortcutId());
73                 }
74             }
75         }
76 
77         final ArrayList<ShortcutInfo> updatedShortcutInfos = new ArrayList<>();
78         if (!keyToShortcutInfo.isEmpty()) {
79             // Update the workspace to reflect the changes to updated shortcuts residing on it.
80             List<ShortcutInfoCompat> shortcuts = deepShortcutManager.queryForFullDetails(
81                     mPackageName, new ArrayList<>(allIds), mUser);
82             for (ShortcutInfoCompat fullDetails : shortcuts) {
83                 ShortcutKey key = ShortcutKey.fromInfo(fullDetails);
84                 List<ShortcutInfo> shortcutInfos = keyToShortcutInfo.remove(key);
85                 if (!fullDetails.isPinned()) {
86                     // The shortcut was previously pinned but is no longer, so remove it from
87                     // the workspace and our pinned shortcut counts.
88                     // Note that we put this check here, after querying for full details,
89                     // because there's a possible race condition between pinning and
90                     // receiving this callback.
91                     removedKeys.add(key);
92                     continue;
93                 }
94                 for (final ShortcutInfo shortcutInfo : shortcutInfos) {
95                     shortcutInfo.updateFromDeepShortcutInfo(fullDetails, context);
96                     // If the shortcut is pinned but no longer has an icon in the system,
97                     // keep the current icon instead of reverting to the default icon.
98                     LauncherIcons li = LauncherIcons.obtain(context);
99                     li.createShortcutIcon(fullDetails, true, Provider.of(shortcutInfo.iconBitmap))
100                             .applyTo(shortcutInfo);
101                     li.recycle();
102                     updatedShortcutInfos.add(shortcutInfo);
103                 }
104             }
105         }
106 
107         // If there are still entries in keyToShortcutInfo, that means that
108         // the corresponding shortcuts weren't passed in onShortcutsChanged(). This
109         // means they were cleared, so we remove and unpin them now.
110         removedKeys.addAll(keyToShortcutInfo.keySet());
111 
112         bindUpdatedShortcuts(updatedShortcutInfos, mUser);
113         if (!keyToShortcutInfo.isEmpty()) {
114             deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys));
115         }
116 
117         if (mUpdateIdMap) {
118             // Update the deep shortcut map if the list of ids has changed for an activity.
119             dataModel.updateDeepShortcutMap(mPackageName, mUser, mShortcuts);
120             bindDeepShortcuts(dataModel);
121         }
122     }
123 }
124