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