Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4d2a73b authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Removing MultiHashMap and using java-streams instead

This makes it easier to choose different collection
implementations

Change-Id: Ic44e128b7478fcbbb1b546027685e058945af3f9
parent 8e1b32d8
Loading
Loading
Loading
Loading
+19 −24
Original line number Diff line number Diff line
@@ -17,25 +17,30 @@ package com.android.launcher3.model;

import static android.os.Process.myUserHandle;

import static com.android.launcher3.pm.InstallSessionHelper.getUserHandle;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller.SessionInfo;
import android.os.UserHandle;
import android.util.Log;

import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageUserKey;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Helper class to send broadcasts to package installers that have:
@@ -61,26 +66,10 @@ public class FirstScreenBroadcast {

    private static final String VERIFICATION_TOKEN_EXTRA = "verificationToken";

    private final MultiHashMap<String, String> mPackagesForInstaller;
    private final HashMap<PackageUserKey, SessionInfo> mSessionInfoForPackage;

    public FirstScreenBroadcast(HashMap<PackageUserKey, SessionInfo> sessionInfoForPackage) {
        mPackagesForInstaller = getPackagesForInstaller(sessionInfoForPackage);
    }

    /**
     * @return Map where the key is the package name of the installer, and the value is a list
     *         of packages with active sessions for that installer.
     */
    private MultiHashMap<String, String> getPackagesForInstaller(
            HashMap<PackageUserKey, SessionInfo> sessionInfoForPackage) {
        MultiHashMap<String, String> packagesForInstaller = new MultiHashMap<>();
        for (Map.Entry<PackageUserKey, SessionInfo> entry : sessionInfoForPackage.entrySet()) {
            if (myUserHandle().equals(entry.getKey().mUser)) {
                packagesForInstaller.addToList(entry.getValue().getInstallerPackageName(),
                        entry.getKey().mPackageName);
            }
        }
        return packagesForInstaller;
        mSessionInfoForPackage = sessionInfoForPackage;
    }

    /**
@@ -88,9 +77,15 @@ public class FirstScreenBroadcast {
     * first screen.
     */
    public void sendBroadcasts(Context context, List<ItemInfo> firstScreenItems) {
        for (Map.Entry<String, ArrayList<String>> entry : mPackagesForInstaller.entrySet()) {
            sendBroadcastToInstaller(context, entry.getKey(), entry.getValue(), firstScreenItems);
        }
        UserHandle myUser = myUserHandle();
        mSessionInfoForPackage
                .values()
                .stream()
                .filter(info -> myUser.equals(getUserHandle(info)))
                .collect(groupingBy(SessionInfo::getInstallerPackageName,
                        mapping(SessionInfo::getAppPackageName, Collectors.toSet())))
                .forEach((installer, packages) ->
                    sendBroadcastToInstaller(context, installer, packages, firstScreenItems));
    }

    /**
@@ -99,7 +94,7 @@ public class FirstScreenBroadcast {
     * @param firstScreenItems List of items on the first screen.
     */
    private void sendBroadcastToInstaller(Context context, String installerPackageName,
            List<String> packages, List<ItemInfo> firstScreenItems) {
            Set<String> packages, List<ItemInfo> firstScreenItems) {
        Set<String> folderItems = new HashSet<>();
        Set<String> workspaceItems = new HashSet<>();
        Set<String> hotseatItems = new HashSet<>();
+4 −3
Original line number Diff line number Diff line
@@ -81,7 +81,6 @@ import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.TraceHelper;
@@ -90,8 +89,10 @@ import com.android.launcher3.widget.WidgetManagerHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CancellationException;

/**
@@ -302,7 +303,7 @@ public class LoaderTask implements Runnable {
        final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
        final boolean isSafeMode = pmHelper.isSafeMode();
        final boolean isSdCardReady = Utilities.isBootCompleted();
        final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
        final Set<PackageUserKey> pendingPackages = new HashSet<>();

        boolean clearDb = false;
        try {
@@ -483,7 +484,7 @@ public class LoaderTask implements Runnable {
                                    // SdCard is not ready yet. Package might get available,
                                    // once it is ready.
                                    Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
                                    pendingPackages.addToList(c.user, targetPkg);
                                    pendingPackages.add(new PackageUserKey(targetPkg, c.user));
                                    // Add the icon on the workspace anyway.
                                    allowMissingTarget = true;
                                } else {
+2 −8
Original line number Diff line number Diff line
@@ -36,8 +36,8 @@ import com.android.launcher3.util.IntSet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;

/**
@@ -56,13 +56,7 @@ public class ModelUtils {
            ArrayList<T> currentScreenItems,
            ArrayList<T> otherScreenItems) {
        // Purge any null ItemInfos
        Iterator<T> iter = allWorkspaceItems.iterator();
        while (iter.hasNext()) {
            ItemInfo i = iter.next();
            if (i == null) {
                iter.remove();
            }
        }
        allWorkspaceItems.removeIf(Objects::isNull);
        // Order the set of items by their containers first, this allows use to walk through the
        // list sequentially, build up a list of containers that are in the specified screen,
        // as well as all items in those containers.
+11 −15
Original line number Diff line number Diff line
@@ -24,12 +24,11 @@ import android.os.UserHandle;

import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Helper class to re-query app status when SD-card becomes available.
@@ -42,10 +41,9 @@ public class SdCardAvailableReceiver extends BroadcastReceiver {

    private final LauncherModel mModel;
    private final Context mContext;
    private final MultiHashMap<UserHandle, String> mPackages;
    private final Set<PackageUserKey> mPackages;

    public SdCardAvailableReceiver(LauncherAppState app,
            MultiHashMap<UserHandle, String> packages) {
    public SdCardAvailableReceiver(LauncherAppState app, Set<PackageUserKey> packages) {
        mModel = app.getModel();
        mContext = app.getContext();
        mPackages = packages;
@@ -55,19 +53,17 @@ public class SdCardAvailableReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        final LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
        final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
        for (Entry<UserHandle, ArrayList<String>> entry : mPackages.entrySet()) {
            UserHandle user = entry.getKey();
        for (PackageUserKey puk : mPackages) {
            UserHandle user = puk.mUser;

            final ArrayList<String> packagesRemoved = new ArrayList<>();
            final ArrayList<String> packagesUnavailable = new ArrayList<>();

            for (String pkg : new HashSet<>(entry.getValue())) {
                if (!launcherApps.isPackageEnabled(pkg, user)) {
                    if (pmHelper.isAppOnSdcard(pkg, user)) {
                        packagesUnavailable.add(pkg);
            if (!launcherApps.isPackageEnabled(puk.mPackageName, user)) {
                if (pmHelper.isAppOnSdcard(puk.mPackageName, user)) {
                    packagesUnavailable.add(puk.mPackageName);
                } else {
                        packagesRemoved.add(pkg);
                    }
                    packagesRemoved.add(puk.mPackageName);
                }
            }
            if (!packagesRemoved.isEmpty()) {
+31 −31
Original line number Diff line number Diff line
@@ -25,11 +25,12 @@ import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.MultiHashMap;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Handles changes due to shortcut manager updates (deep shortcut changes)
@@ -53,54 +54,53 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
    public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
        final Context context = app.getContext();
        // Find WorkspaceItemInfo's that have changed on the workspace.
        HashSet<ShortcutKey> removedKeys = new HashSet<>();
        MultiHashMap<ShortcutKey, WorkspaceItemInfo> keyToShortcutInfo = new MultiHashMap<>();
        HashSet<String> allIds = new HashSet<>();
        ArrayList<WorkspaceItemInfo> matchingWorkspaceItems = new ArrayList<>();

        synchronized (dataModel) {
            dataModel.forAllWorkspaceItemInfos(mUser, si -> {
                if ((si.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                        && mPackageName.equals(si.getIntent().getPackage())) {
                    keyToShortcutInfo.addToList(ShortcutKey.fromItemInfo(si), si);
                    allIds.add(si.getDeepShortcutId());
                    matchingWorkspaceItems.add(si);
                }
            });
        }

        final ArrayList<WorkspaceItemInfo> updatedWorkspaceItemInfos = new ArrayList<>();
        if (!keyToShortcutInfo.isEmpty()) {
        if (!matchingWorkspaceItems.isEmpty()) {
            // Update the workspace to reflect the changes to updated shortcuts residing on it.
            List<String> allLauncherKnownIds = matchingWorkspaceItems.stream()
                    .map(WorkspaceItemInfo::getDeepShortcutId)
                    .distinct()
                    .collect(Collectors.toList());
            List<ShortcutInfo> shortcuts = new ShortcutRequest(context, mUser)
                    .forPackage(mPackageName, new ArrayList<>(allIds))
                    .forPackage(mPackageName, allLauncherKnownIds)
                    .query(ShortcutRequest.ALL);

            Set<String> nonPinnedIds = new HashSet<>(allLauncherKnownIds);
            ArrayList<WorkspaceItemInfo> updatedWorkspaceItemInfos = new ArrayList<>();
            for (ShortcutInfo fullDetails : shortcuts) {
                ShortcutKey key = ShortcutKey.fromInfo(fullDetails);
                List<WorkspaceItemInfo> workspaceItemInfos = keyToShortcutInfo.remove(key);
                if (!fullDetails.isPinned()) {
                    // The shortcut was previously pinned but is no longer, so remove it from
                    // the workspace and our pinned shortcut counts.
                    // Note that we put this check here, after querying for full details,
                    // because there's a possible race condition between pinning and
                    // receiving this callback.
                    removedKeys.add(key);
                    continue;
                }
                for (final WorkspaceItemInfo workspaceItemInfo : workspaceItemInfos) {

                String sid = fullDetails.getId();
                nonPinnedIds.remove(sid);
                matchingWorkspaceItems
                        .stream()
                        .filter(itemInfo -> sid.equals(itemInfo.getDeepShortcutId()))
                        .forEach(workspaceItemInfo -> {
                            workspaceItemInfo.updateFromDeepShortcutInfo(fullDetails, context);
                            app.getIconCache().getShortcutIcon(workspaceItemInfo, fullDetails);
                            updatedWorkspaceItemInfos.add(workspaceItemInfo);
                        });
            }
            }
        }

        // If there are still entries in keyToShortcutInfo, that means that
        // the corresponding shortcuts weren't passed in onShortcutsChanged(). This
        // means they were cleared, so we remove and unpin them now.
        removedKeys.addAll(keyToShortcutInfo.keySet());

            bindUpdatedWorkspaceItems(updatedWorkspaceItemInfos);
        if (!keyToShortcutInfo.isEmpty()) {
            deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys));
            if (!nonPinnedIds.isEmpty()) {
                deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(
                        nonPinnedIds.stream()
                                .map(id -> new ShortcutKey(mPackageName, mUser, id))
                                .collect(Collectors.toSet())));
            }
        }

        if (mUpdateIdMap) {
Loading