Search in sources :

Example 1 with ItemInfoMatcher

use of com.android.launcher3.util.ItemInfoMatcher in project android_packages_apps_Launcher3 by crdroidandroid.

the class AllAppsList method updateDisabledFlags.

/**
 * Updates the disabled flags of apps matching {@param matcher} based on {@param op}.
 */
public void updateDisabledFlags(ItemInfoMatcher matcher, FlagOp op) {
    final List<AppInfo> data = this.data;
    for (int i = data.size() - 1; i >= 0; i--) {
        AppInfo info = data.get(i);
        if (matcher.matches(info, info.componentName)) {
            info.runtimeStatusFlags = op.apply(info.runtimeStatusFlags);
            mDataChanged = true;
        }
    }
}
Also used : AppInfo(com.android.launcher3.model.data.AppInfo)

Example 2 with ItemInfoMatcher

use of com.android.launcher3.util.ItemInfoMatcher in project android_packages_apps_Launcher3 by crdroidandroid.

the class Workspace method removeAbandonedPromise.

public void removeAbandonedPromise(String packageName, UserHandle user) {
    ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(Collections.singleton(packageName), user);
    mLauncher.getModelWriter().deleteItemsFromDatabase(matcher);
    removeItemsByMatcher(matcher);
}
Also used : ItemInfoMatcher(com.android.launcher3.util.ItemInfoMatcher)

Example 3 with ItemInfoMatcher

use of com.android.launcher3.util.ItemInfoMatcher in project android_packages_apps_Launcher3 by crdroidandroid.

the class PackageUpdatedTask method execute.

@Override
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList appsList) {
    final Context context = app.getContext();
    final IconCache iconCache = app.getIconCache();
    final String[] packages = mPackages;
    final int N = packages.length;
    final FlagOp flagOp;
    final HashSet<String> packageSet = new HashSet<>(Arrays.asList(packages));
    final ItemInfoMatcher matcher = mOp == OP_USER_AVAILABILITY_CHANGE ? // We want to update all packages for this user
    ItemInfoMatcher.ofUser(mUser) : ItemInfoMatcher.ofPackages(packageSet, mUser);
    final HashSet<ComponentName> removedComponents = new HashSet<>();
    final HashMap<String, List<LauncherActivityInfo>> activitiesLists = new HashMap<>();
    boolean needsRestart = false;
    switch(mOp) {
        case OP_ADD:
            {
                for (int i = 0; i < N; i++) {
                    if (DEBUG)
                        Log.d(TAG, "mAllAppsList.addPackage " + packages[i]);
                    if (isTargetPackage(packages[i])) {
                        needsRestart = true;
                    }
                    iconCache.updateIconsForPkg(packages[i], mUser);
                    if (FeatureFlags.PROMISE_APPS_IN_ALL_APPS.get()) {
                        appsList.removePackage(packages[i], mUser);
                    }
                    activitiesLists.put(packages[i], appsList.addPackage(context, packages[i], mUser));
                }
                flagOp = FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
                break;
            }
        case OP_UPDATE:
            try (SafeCloseable t = appsList.trackRemoves(a -> removedComponents.add(a.componentName))) {
                for (int i = 0; i < N; i++) {
                    if (DEBUG)
                        Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]);
                    iconCache.updateIconsForPkg(packages[i], mUser);
                    activitiesLists.put(packages[i], appsList.updatePackage(context, packages[i], mUser));
                    app.getWidgetCache().removePackage(packages[i], mUser);
                    // The update may have changed which shortcuts/widgets are available.
                    // Refresh the widgets for the package if we have an activity running.
                    Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
                    if (launcher != null) {
                        launcher.refreshAndBindWidgetsForPackageUser(new PackageUserKey(packages[i], mUser));
                    }
                }
            }
            // Since package was just updated, the target must be available now.
            flagOp = FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
            break;
        case OP_REMOVE:
            {
                for (int i = 0; i < N; i++) {
                    FileLog.d(TAG, "Removing app icon" + packages[i]);
                    iconCache.removeIconsForPkg(packages[i], mUser);
                    if (isTargetPackage(packages[i])) {
                        needsRestart = true;
                    }
                }
            // Fall through
            }
        case OP_UNAVAILABLE:
            for (int i = 0; i < N; i++) {
                if (DEBUG)
                    Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
                appsList.removePackage(packages[i], mUser);
                app.getWidgetCache().removePackage(packages[i], mUser);
            }
            flagOp = FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
            break;
        case OP_SUSPEND:
        case OP_UNSUSPEND:
            flagOp = mOp == OP_SUSPEND ? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED) : FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED);
            if (DEBUG)
                Log.d(TAG, "mAllAppsList.(un)suspend " + N);
            appsList.updateDisabledFlags(matcher, flagOp);
            for (int i = 0; i < N; i++) {
                if (isTargetPackage(packages[i])) {
                    needsRestart = true;
                }
            }
            break;
        case OP_USER_AVAILABILITY_CHANGE:
            {
                UserManagerState ums = new UserManagerState();
                ums.init(UserCache.INSTANCE.get(context), context.getSystemService(UserManager.class));
                flagOp = ums.isUserQuiet(mUser) ? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER) : FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER);
                appsList.updateDisabledFlags(matcher, flagOp);
                // We are not synchronizing here, as int operations are atomic
                appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled());
                break;
            }
        default:
            flagOp = FlagOp.NO_OP;
            break;
    }
    bindApplicationsIfNeeded();
    final IntSet removedShortcuts = new IntSet();
    // Shortcuts to keep even if the corresponding app was removed
    final IntSet forceKeepShortcuts = new IntSet();
    // Update shortcut infos
    if (mOp == OP_ADD || flagOp != FlagOp.NO_OP) {
        final ArrayList<WorkspaceItemInfo> updatedWorkspaceItems = new ArrayList<>();
        final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<>();
        // For system apps, package manager send OP_UPDATE when an app is enabled.
        final boolean isNewApkAvailable = mOp == OP_ADD || mOp == OP_UPDATE;
        synchronized (dataModel) {
            dataModel.forAllWorkspaceItemInfos(mUser, si -> {
                boolean infoUpdated = false;
                boolean shortcutUpdated = false;
                // Update shortcuts which use iconResource.
                if ((si.iconResource != null) && packageSet.contains(si.iconResource.packageName)) {
                    LauncherIcons li = LauncherIcons.obtain(context);
                    BitmapInfo iconInfo = li.createIconBitmap(si.iconResource);
                    li.recycle();
                    if (iconInfo != null) {
                        si.bitmap = iconInfo;
                        infoUpdated = true;
                    }
                }
                ComponentName cn = si.getTargetComponent();
                if (cn != null && matcher.matches(si, cn)) {
                    String packageName = cn.getPackageName();
                    if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)) {
                        forceKeepShortcuts.add(si.id);
                        if (mOp == OP_REMOVE) {
                            return;
                        }
                    }
                    if (si.isPromise() && isNewApkAvailable) {
                        boolean isTargetValid = !cn.getClassName().equals(IconCache.EMPTY_CLASS_NAME);
                        if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
                            List<ShortcutInfo> shortcut = new ShortcutRequest(context, mUser).forPackage(cn.getPackageName(), si.getDeepShortcutId()).query(ShortcutRequest.PINNED);
                            if (shortcut.isEmpty()) {
                                isTargetValid = false;
                            } else {
                                si.updateFromDeepShortcutInfo(shortcut.get(0), context);
                                infoUpdated = true;
                            }
                        } else if (isTargetValid) {
                            isTargetValid = context.getSystemService(LauncherApps.class).isActivityEnabled(cn, mUser);
                        }
                        if (!isTargetValid && si.hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)) {
                            if (updateWorkspaceItemIntent(context, si, packageName)) {
                                infoUpdated = true;
                            } else if (si.hasPromiseIconUi()) {
                                removedShortcuts.add(si.id);
                                return;
                            }
                        } else if (!isTargetValid) {
                            removedShortcuts.add(si.id);
                            FileLog.e(TAG, "Restored shortcut no longer valid " + si.getIntent());
                            return;
                        } else {
                            si.status = WorkspaceItemInfo.DEFAULT;
                            infoUpdated = true;
                        }
                    } else if (isNewApkAvailable && removedComponents.contains(cn)) {
                        if (updateWorkspaceItemIntent(context, si, packageName)) {
                            infoUpdated = true;
                        }
                    }
                    if (isNewApkAvailable) {
                        List<LauncherActivityInfo> activities = activitiesLists.get(packageName);
                        si.setProgressLevel(activities == null || activities.isEmpty() ? 100 : PackageManagerHelper.getLoadingProgress(activities.get(0)), PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
                        if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
                            iconCache.getTitleAndIcon(si, si.usingLowResIcon());
                            infoUpdated = true;
                        }
                    }
                    int oldRuntimeFlags = si.runtimeStatusFlags;
                    si.runtimeStatusFlags = flagOp.apply(si.runtimeStatusFlags);
                    if (si.runtimeStatusFlags != oldRuntimeFlags) {
                        shortcutUpdated = true;
                    }
                }
                if (infoUpdated || shortcutUpdated) {
                    updatedWorkspaceItems.add(si);
                }
                if (infoUpdated && si.id != ItemInfo.NO_ID) {
                    getModelWriter().updateItemInDatabase(si);
                }
            });
            for (LauncherAppWidgetInfo widgetInfo : dataModel.appWidgets) {
                if (mUser.equals(widgetInfo.user) && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) && packageSet.contains(widgetInfo.providerName.getPackageName())) {
                    widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY & ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
                    // adding this flag ensures that launcher shows 'click to setup'
                    // if the widget has a config activity. In case there is no config
                    // activity, it will be marked as 'restored' during bind.
                    widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
                    widgets.add(widgetInfo);
                    getModelWriter().updateItemInDatabase(widgetInfo);
                }
            }
        }
        bindUpdatedWorkspaceItems(updatedWorkspaceItems);
        if (!removedShortcuts.isEmpty()) {
            deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedShortcuts));
        }
        if (!widgets.isEmpty()) {
            scheduleCallbackTask(c -> c.bindWidgetsRestored(widgets));
        }
    }
    final HashSet<String> removedPackages = new HashSet<>();
    if (mOp == OP_REMOVE) {
        // Mark all packages in the broadcast to be removed
        Collections.addAll(removedPackages, packages);
    // No need to update the removedComponents as
    // removedPackages is a super-set of removedComponents
    } else if (mOp == OP_UPDATE) {
        // Mark disabled packages in the broadcast to be removed
        final LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
        for (int i = 0; i < N; i++) {
            if (!launcherApps.isPackageEnabled(packages[i], mUser)) {
                removedPackages.add(packages[i]);
            }
        }
    }
    if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
        ItemInfoMatcher removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser).or(ItemInfoMatcher.ofComponents(removedComponents, mUser)).and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate());
        deleteAndBindComponentsRemoved(removeMatch);
        // Remove any queued items from the install queue
        ItemInstallQueue.INSTANCE.get(context).removeFromInstallQueue(removedPackages, mUser);
    }
    if (mOp == OP_ADD) {
        // AppWidgetHost events, this is just to initialize the long-press options.
        for (int i = 0; i < N; i++) {
            dataModel.widgetsModel.update(app, new PackageUserKey(packages[i], mUser));
        }
        bindUpdatedWidgets(dataModel);
    }
    if (needsRestart) {
        Utilities.restart(context);
    }
}
Also used : HashMap(java.util.HashMap) IntSet(com.android.launcher3.util.IntSet) ArrayList(java.util.ArrayList) ShortcutRequest(com.android.launcher3.shortcuts.ShortcutRequest) IconCache(com.android.launcher3.icons.IconCache) ItemInfoMatcher(com.android.launcher3.util.ItemInfoMatcher) ComponentName(android.content.ComponentName) ArrayList(java.util.ArrayList) List(java.util.List) FlagOp(com.android.launcher3.util.FlagOp) HashSet(java.util.HashSet) Context(android.content.Context) ShortcutInfo(android.content.pm.ShortcutInfo) PackageUserKey(com.android.launcher3.util.PackageUserKey) LauncherAppWidgetInfo(com.android.launcher3.model.data.LauncherAppWidgetInfo) LauncherApps(android.content.pm.LauncherApps) LauncherIcons(com.android.launcher3.icons.LauncherIcons) LauncherActivityInfo(android.content.pm.LauncherActivityInfo) Launcher(com.android.launcher3.Launcher) SafeCloseable(com.android.launcher3.util.SafeCloseable) BitmapInfo(com.android.launcher3.icons.BitmapInfo) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo)

Example 4 with ItemInfoMatcher

use of com.android.launcher3.util.ItemInfoMatcher in project android_packages_apps_Launcher3 by crdroidandroid.

the class Workspace method removeItemsByMatcher.

/**
 * Removes items that match the {@param matcher}. When applications are removed
 * as a part of an update, this is called to ensure that other widgets and application
 * shortcuts are not removed.
 */
public void removeItemsByMatcher(final ItemInfoMatcher matcher) {
    for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
        ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets();
        // Iterate in reverse order as we are removing items
        for (int i = container.getChildCount() - 1; i >= 0; i--) {
            View child = container.getChildAt(i);
            ItemInfo info = (ItemInfo) child.getTag();
            if (matcher.matchesInfo(info)) {
                layout.removeViewInLayout(child);
                if (child instanceof DropTarget) {
                    mDragController.removeDropTarget((DropTarget) child);
                }
            } else if (child instanceof FolderIcon) {
                FolderInfo folderInfo = (FolderInfo) info;
                List<WorkspaceItemInfo> matches = folderInfo.contents.stream().filter(matcher::matchesInfo).collect(Collectors.toList());
                if (!matches.isEmpty()) {
                    folderInfo.removeAll(matches, false);
                    if (((FolderIcon) child).getFolder().isOpen()) {
                        ((FolderIcon) child).getFolder().close(false);
                    }
                }
            }
        }
    }
    // Strip all the empty screens
    stripEmptyScreens();
}
Also used : WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo) ItemInfo(com.android.launcher3.model.data.ItemInfo) FolderIcon(com.android.launcher3.folder.FolderIcon) ArrayList(java.util.ArrayList) RunnableList(com.android.launcher3.util.RunnableList) List(java.util.List) DraggableView(com.android.launcher3.dragndrop.DraggableView) LauncherAppWidgetHostView(com.android.launcher3.widget.LauncherAppWidgetHostView) AppWidgetHostView(android.appwidget.AppWidgetHostView) View(android.view.View) PendingAppWidgetHostView(com.android.launcher3.widget.PendingAppWidgetHostView) DragView(com.android.launcher3.dragndrop.DragView) FolderInfo(com.android.launcher3.model.data.FolderInfo) SuppressLint(android.annotation.SuppressLint) Point(android.graphics.Point)

Aggregations

WorkspaceItemInfo (com.android.launcher3.model.data.WorkspaceItemInfo)2 ItemInfoMatcher (com.android.launcher3.util.ItemInfoMatcher)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 SuppressLint (android.annotation.SuppressLint)1 AppWidgetHostView (android.appwidget.AppWidgetHostView)1 ComponentName (android.content.ComponentName)1 Context (android.content.Context)1 LauncherActivityInfo (android.content.pm.LauncherActivityInfo)1 LauncherApps (android.content.pm.LauncherApps)1 ShortcutInfo (android.content.pm.ShortcutInfo)1 Point (android.graphics.Point)1 View (android.view.View)1 Launcher (com.android.launcher3.Launcher)1 DragView (com.android.launcher3.dragndrop.DragView)1 DraggableView (com.android.launcher3.dragndrop.DraggableView)1 FolderIcon (com.android.launcher3.folder.FolderIcon)1 BitmapInfo (com.android.launcher3.icons.BitmapInfo)1 IconCache (com.android.launcher3.icons.IconCache)1 LauncherIcons (com.android.launcher3.icons.LauncherIcons)1