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