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.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; 19 import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE; 20 import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER; 21 22 import android.app.prediction.AppTarget; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.pm.LauncherActivityInfo; 26 import android.content.pm.LauncherApps; 27 import android.content.pm.ShortcutInfo; 28 import android.os.UserHandle; 29 30 import com.android.launcher3.LauncherAppState; 31 import com.android.launcher3.Utilities; 32 import com.android.launcher3.model.BgDataModel.FixedContainerItems; 33 import com.android.launcher3.model.QuickstepModelDelegate.PredictorState; 34 import com.android.launcher3.model.data.AppInfo; 35 import com.android.launcher3.model.data.WorkspaceItemInfo; 36 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.Set; 40 import java.util.stream.Collectors; 41 42 /** 43 * Task to update model as a result of predicted apps update 44 */ 45 public class PredictionUpdateTask extends BaseModelUpdateTask { 46 47 private final List<AppTarget> mTargets; 48 private final PredictorState mPredictorState; 49 PredictionUpdateTask(PredictorState predictorState, List<AppTarget> targets)50 PredictionUpdateTask(PredictorState predictorState, List<AppTarget> targets) { 51 mPredictorState = predictorState; 52 mTargets = targets; 53 } 54 55 @Override execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps)56 public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { 57 Context context = app.getContext(); 58 59 // TODO: remove this 60 Utilities.getDevicePrefs(context).edit() 61 .putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply(); 62 63 FixedContainerItems fci = mPredictorState.items; 64 Set<UserHandle> usersForChangedShortcuts = new HashSet<>(fci.items.stream() 65 .filter(info -> info.itemType == ITEM_TYPE_DEEP_SHORTCUT) 66 .map(info -> info.user) 67 .collect(Collectors.toSet())); 68 fci.items.clear(); 69 70 for (AppTarget target : mTargets) { 71 WorkspaceItemInfo itemInfo; 72 ShortcutInfo si = target.getShortcutInfo(); 73 if (si != null) { 74 usersForChangedShortcuts.add(si.getUserHandle()); 75 itemInfo = new WorkspaceItemInfo(si, context); 76 app.getIconCache().getShortcutIcon(itemInfo, si); 77 } else { 78 String className = target.getClassName(); 79 if (COMPONENT_CLASS_MARKER.equals(className)) { 80 // TODO: Implement this 81 continue; 82 } 83 ComponentName cn = new ComponentName(target.getPackageName(), className); 84 UserHandle user = target.getUser(); 85 itemInfo = apps.data.stream() 86 .filter(info -> user.equals(info.user) && cn.equals(info.componentName)) 87 .map(ai -> { 88 app.getIconCache().getTitleAndIcon(ai, false); 89 return ai.makeWorkspaceItem(); 90 }) 91 .findAny() 92 .orElseGet(() -> { 93 LauncherActivityInfo lai = context.getSystemService(LauncherApps.class) 94 .resolveActivity(AppInfo.makeLaunchIntent(cn), user); 95 if (lai == null) { 96 return null; 97 } 98 AppInfo ai = new AppInfo(context, lai, user); 99 app.getIconCache().getTitleAndIcon(ai, lai, false); 100 return ai.makeWorkspaceItem(); 101 }); 102 103 if (itemInfo == null) { 104 continue; 105 } 106 } 107 108 itemInfo.container = fci.containerId; 109 fci.items.add(itemInfo); 110 } 111 112 bindExtraContainerItems(fci); 113 usersForChangedShortcuts.forEach( 114 u -> dataModel.updateShortcutPinnedState(app.getContext(), u)); 115 116 // Save to disk 117 mPredictorState.storage.write(context, fci.items); 118 } 119 } 120