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