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 static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
19 
20 import android.content.Context;
21 import android.content.pm.ShortcutInfo;
22 import android.os.UserHandle;
23 
24 import com.android.launcher3.LauncherAppState;
25 import com.android.launcher3.LauncherSettings;
26 import com.android.launcher3.model.data.ItemInfo;
27 import com.android.launcher3.model.data.WorkspaceItemInfo;
28 import com.android.launcher3.shortcuts.ShortcutKey;
29 import com.android.launcher3.shortcuts.ShortcutRequest;
30 import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
31 import com.android.launcher3.util.ComponentKey;
32 import com.android.launcher3.util.ItemInfoMatcher;
33 
34 import java.util.ArrayList;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 
39 /**
40  * Task to handle changing of lock state of the user
41  */
42 public class UserLockStateChangedTask extends BaseModelUpdateTask {
43 
44     private final UserHandle mUser;
45     private boolean mIsUserUnlocked;
46 
UserLockStateChangedTask(UserHandle user, boolean isUserUnlocked)47     public UserLockStateChangedTask(UserHandle user, boolean isUserUnlocked) {
48         mUser = user;
49         mIsUserUnlocked = isUserUnlocked;
50     }
51 
52     @Override
execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps)53     public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
54         Context context = app.getContext();
55 
56         HashMap<ShortcutKey, ShortcutInfo> pinnedShortcuts = new HashMap<>();
57         if (mIsUserUnlocked) {
58             QueryResult shortcuts = new ShortcutRequest(context, mUser)
59                     .query(ShortcutRequest.PINNED);
60             if (shortcuts.wasSuccess()) {
61                 for (ShortcutInfo shortcut : shortcuts) {
62                     pinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), shortcut);
63                 }
64             } else {
65                 // Shortcut manager can fail due to some race condition when the lock state
66                 // changes too frequently. For the purpose of the update,
67                 // consider it as still locked.
68                 mIsUserUnlocked = false;
69             }
70         }
71 
72         // Update the workspace to reflect the changes to updated shortcuts residing on it.
73         ArrayList<WorkspaceItemInfo> updatedWorkspaceItemInfos = new ArrayList<>();
74         HashSet<ShortcutKey> removedKeys = new HashSet<>();
75 
76         for (ItemInfo itemInfo : dataModel.itemsIdMap) {
77             if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
78                     && mUser.equals(itemInfo.user)) {
79                 WorkspaceItemInfo si = (WorkspaceItemInfo) itemInfo;
80                 if (mIsUserUnlocked) {
81                     ShortcutKey key = ShortcutKey.fromItemInfo(si);
82                     ShortcutInfo shortcut = pinnedShortcuts.get(key);
83                     // We couldn't verify the shortcut during loader. If its no longer available
84                     // (probably due to clear data), delete the workspace item as well
85                     if (shortcut == null) {
86                         removedKeys.add(key);
87                         continue;
88                     }
89                     si.runtimeStatusFlags &= ~FLAG_DISABLED_LOCKED_USER;
90                     si.updateFromDeepShortcutInfo(shortcut, context);
91                     app.getIconCache().getShortcutIcon(si, shortcut);
92                 } else {
93                     si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
94                 }
95                 updatedWorkspaceItemInfos.add(si);
96             }
97         }
98         bindUpdatedWorkspaceItems(updatedWorkspaceItemInfos);
99         if (!removedKeys.isEmpty()) {
100             deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys));
101         }
102 
103         // Remove shortcut id map for that user
104         Iterator<ComponentKey> keysIter = dataModel.deepShortcutMap.keySet().iterator();
105         while (keysIter.hasNext()) {
106             if (keysIter.next().user.equals(mUser)) {
107                 keysIter.remove();
108             }
109         }
110 
111         if (mIsUserUnlocked) {
112             dataModel.updateDeepShortcutCounts(
113                     null, mUser,
114                     new ShortcutRequest(context, mUser).query(ShortcutRequest.ALL));
115         }
116         bindDeepShortcuts(dataModel);
117     }
118 }
119