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