Home | History | Annotate | Download | only in model
      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 
     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
     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