• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.EncryptionType.ENCRYPTED;
19 import static com.android.launcher3.LauncherPrefs.nonRestorableItem;
20 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
21 import static com.android.launcher3.icons.cache.CacheLookupFlag.DEFAULT_LOOKUP_FLAG;
22 import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
23 
24 import android.app.prediction.AppTarget;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.pm.LauncherActivityInfo;
28 import android.content.pm.LauncherApps;
29 import android.content.pm.ShortcutInfo;
30 import android.os.UserHandle;
31 
32 import androidx.annotation.NonNull;
33 
34 import com.android.launcher3.ConstantItem;
35 import com.android.launcher3.LauncherModel.ModelUpdateTask;
36 import com.android.launcher3.LauncherPrefs;
37 import com.android.launcher3.icons.IconCache;
38 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
39 import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
40 import com.android.launcher3.model.data.AppInfo;
41 import com.android.launcher3.model.data.ItemInfo;
42 import com.android.launcher3.model.data.WorkspaceItemInfo;
43 
44 import java.util.ArrayList;
45 import java.util.List;
46 import java.util.Set;
47 import java.util.stream.Collectors;
48 
49 /**
50  * Task to update model as a result of predicted apps update
51  */
52 public class PredictionUpdateTask implements ModelUpdateTask {
53 
54     public static final ConstantItem<Boolean> LAST_PREDICTION_ENABLED =
55             nonRestorableItem("last_prediction_enabled_state", true, ENCRYPTED);
56 
57     private final List<AppTarget> mTargets;
58     private final PredictorState mPredictorState;
59 
PredictionUpdateTask(PredictorState predictorState, List<AppTarget> targets)60     PredictionUpdateTask(PredictorState predictorState, List<AppTarget> targets) {
61         mPredictorState = predictorState;
62         mTargets = targets;
63     }
64 
65     @Override
execute(@onNull ModelTaskController taskController, @NonNull BgDataModel dataModel, @NonNull AllAppsList apps)66     public void execute(@NonNull ModelTaskController taskController, @NonNull BgDataModel dataModel,
67             @NonNull AllAppsList apps) {
68         IconCache iconCache = taskController.getIconCache();
69         Context context = taskController.getContext();
70 
71         // TODO: remove this
72         LauncherPrefs.get(context).put(LAST_PREDICTION_ENABLED, !mTargets.isEmpty());
73 
74         Set<UserHandle> usersForChangedShortcuts =
75                 dataModel.extraItems.get(mPredictorState.containerId).items.stream()
76                         .filter(info -> info.itemType == ITEM_TYPE_DEEP_SHORTCUT)
77                         .map(info -> info.user)
78                         .collect(Collectors.toSet());
79 
80         List<ItemInfo> items = new ArrayList<>(mTargets.size());
81         for (AppTarget target : mTargets) {
82             WorkspaceItemInfo itemInfo;
83             ShortcutInfo si = target.getShortcutInfo();
84             if (si != null) {
85                 usersForChangedShortcuts.add(si.getUserHandle());
86                 itemInfo = new WorkspaceItemInfo(si, context);
87                 iconCache.getShortcutIcon(itemInfo, si);
88             } else {
89                 String className = target.getClassName();
90                 if (COMPONENT_CLASS_MARKER.equals(className)) {
91                     // TODO: Implement this
92                     continue;
93                 }
94                 ComponentName cn = new ComponentName(target.getPackageName(), className);
95                 UserHandle user = target.getUser();
96                 itemInfo = apps.data.stream()
97                         .filter(info -> user.equals(info.user) && cn.equals(info.componentName))
98                         .map(ai -> {
99                             iconCache.getTitleAndIcon(ai, mPredictorState.lookupFlag);
100                             return ai.makeWorkspaceItem(context);
101                         })
102                         .findAny()
103                         .orElseGet(() -> {
104                             LauncherActivityInfo lai = context.getSystemService(LauncherApps.class)
105                                     .resolveActivity(AppInfo.makeLaunchIntent(cn), user);
106                             if (lai == null) {
107                                 return null;
108                             }
109                             AppInfo ai = new AppInfo(context, lai, user);
110                             iconCache.getTitleAndIcon(ai, lai, DEFAULT_LOOKUP_FLAG);
111                             return ai.makeWorkspaceItem(context);
112                         });
113 
114                 if (itemInfo == null) {
115                     continue;
116                 }
117             }
118 
119             itemInfo.container = mPredictorState.containerId;
120             items.add(itemInfo);
121         }
122 
123         FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId, items);
124         dataModel.extraItems.put(fci.containerId, fci);
125         taskController.bindExtraContainerItems(fci);
126         usersForChangedShortcuts.forEach(u -> dataModel.updateShortcutPinnedState(context, u));
127 
128         // Save to disk
129         mPredictorState.storage.write(context, fci.items);
130     }
131 }
132