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

Commit f883f174 authored by Pinyao Ting's avatar Pinyao Ting Committed by Android (Google) Code Review
Browse files

Merge "Shortcut integration with AppSearch (Part 3)" into sc-dev

parents 2f3b22c9 32e30398
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -280,7 +280,8 @@ public class ShortcutBitmapSaver {
                    IoUtils.closeQuietly(out);
                }

                shortcut.setBitmapPath(file.getAbsolutePath());
                final String path = file.getAbsolutePath();
                mService.postValue(shortcut, si -> si.setBitmapPath(path));

            } catch (IOException | RuntimeException e) {
                Slog.e(ShortcutService.TAG, "Unable to write bitmap to file", e);
@@ -295,12 +296,14 @@ public class ShortcutBitmapSaver {
                Slog.d(TAG, "Saved bitmap.");
            }
            if (shortcut != null) {
                if (shortcut.getBitmapPath() == null) {
                    removeIcon(shortcut);
                mService.postValue(shortcut, si -> {
                    if (si.getBitmapPath() == null) {
                        removeIcon(si);
                    }

                    // Whatever happened, remove this flag.
                shortcut.clearFlags(ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE);
                    si.clearFlags(ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE);
                });
            }
        }
        return true;
+120 −61
Original line number Diff line number Diff line
@@ -223,12 +223,14 @@ class ShortcutPackage extends ShortcutPackageItem {
        // - Disable if needed.
        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
            ShortcutInfo si = mShortcuts.valueAt(i);
            si.clearFlags(ShortcutInfo.FLAG_SHADOW);
            mutateShortcut(si.getId(), si, shortcut -> {
                shortcut.clearFlags(ShortcutInfo.FLAG_SHADOW);

            si.setDisabledReason(restoreBlockReason);
                shortcut.setDisabledReason(restoreBlockReason);
                if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
                si.addFlags(ShortcutInfo.FLAG_DISABLED);
                    shortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
                }
            });
        }
        // Because some launchers may not have been restored (e.g. allowBackup=false),
        // we need to re-calculate the pinned shortcuts.
@@ -460,9 +462,11 @@ class ShortcutPackage extends ShortcutPackageItem {
            if (si.isDynamic() && (!ignoreInvisible || si.isVisibleToPublisher())) {
                changed = true;

                si.setTimestamp(now);
                si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
                si.setRank(0); // It may still be pinned, so clear the rank.
                mutateShortcut(si.getId(), si, shortcut -> {
                    shortcut.setTimestamp(now);
                    shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
                    shortcut.setRank(0); // It may still be pinned, so clear the rank.
                });
            }
        }
        if (changed) {
@@ -506,7 +510,7 @@ class ShortcutPackage extends ShortcutPackageItem {
    public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
        final ShortcutInfo shortcut = mShortcuts.get(shortcutId);
        if (shortcut != null) {
            shortcut.clearFlags(ShortcutInfo.FLAG_CACHED_ALL);
            mutateShortcut(shortcutId, null, si -> si.clearFlags(ShortcutInfo.FLAG_CACHED_ALL));
        }
        return deleteOrDisableWithId(
                shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
@@ -527,7 +531,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                overrideImmutable, ignoreInvisible, disabledReason);

        // If disabled id still exists, it is pinned and we need to update the disabled message.
        final ShortcutInfo disabled = mShortcuts.get(shortcutId);
        mutateShortcut(shortcutId, null, disabled -> {
            if (disabled != null) {
                if (disabledMessage != null) {
                    disabled.setDisabledMessage(disabledMessage);
@@ -536,6 +540,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                    mShortcutUser.mService.fixUpShortcutResourceNamesAndValues(disabled);
                }
            }
        });

        return deleted;
    }
@@ -557,21 +562,23 @@ class ShortcutPackage extends ShortcutPackageItem {
        }
        if (oldShortcut.isPinned() || oldShortcut.isCached()) {

            oldShortcut.setRank(0);
            oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
            mutateShortcut(oldShortcut.getId(), oldShortcut, si -> {
                si.setRank(0);
                si.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
                if (disable) {
                oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
                    si.addFlags(ShortcutInfo.FLAG_DISABLED);
                    // Do not overwrite the disabled reason if one is alreay set.
                if (oldShortcut.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
                    oldShortcut.setDisabledReason(disabledReason);
                    if (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
                        si.setDisabledReason(disabledReason);
                    }
                }
            oldShortcut.setTimestamp(mShortcutUser.mService.injectCurrentTimeMillis());
                si.setTimestamp(mShortcutUser.mService.injectCurrentTimeMillis());

                // See ShortcutRequestPinProcessor.directPinShortcut().
            if (mShortcutUser.mService.isDummyMainActivity(oldShortcut.getActivity())) {
                oldShortcut.setActivity(null);
                if (mShortcutUser.mService.isDummyMainActivity(si.getActivity())) {
                    si.setActivity(null);
                }
            });

            return null;
        } else {
@@ -581,12 +588,11 @@ class ShortcutPackage extends ShortcutPackageItem {
    }

    public void enableWithId(@NonNull String shortcutId) {
        final ShortcutInfo shortcut = mShortcuts.get(shortcutId);
        if (shortcut != null) {
            ensureNotImmutable(shortcut, /*ignoreInvisible=*/ true);
            shortcut.clearFlags(ShortcutInfo.FLAG_DISABLED);
            shortcut.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
        }
        mutateShortcut(shortcutId, null, si -> {
            ensureNotImmutable(si, /*ignoreInvisible=*/ true);
            si.clearFlags(ShortcutInfo.FLAG_DISABLED);
            si.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
        });
    }

    public void updateInvisibleShortcutForPinRequestWith(@NonNull ShortcutInfo shortcut) {
@@ -609,22 +615,25 @@ class ShortcutPackage extends ShortcutPackageItem {
     * <p>Then remove all shortcuts that are not dynamic and no longer pinned either.
     */
    public void refreshPinnedFlags() {
        // First, un-pin all shortcuts
        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
            mShortcuts.valueAt(i).clearFlags(ShortcutInfo.FLAG_PINNED);
        // TODO: rewrite this function with proper query (i.e. fetch only pinned shortcuts and
        //  unpin if it's no longer pinned by any launcher and vice versa)
        final List<ShortcutInfo> shortcuts = new ArrayList<>(mShortcuts.values());
        final Map<String, ShortcutInfo> shortcutMap = new ArrayMap<>(shortcuts.size());
        for (ShortcutInfo si : shortcuts) {
            shortcutMap.put(si.getId(), si);
        }
        final Set<String> pinnedShortcuts = new ArraySet<>();

        // Then, for the pinned set for each launcher, set the pin flag one by one.
        // First, for the pinned set for each launcher, keep track of their id one by one.
        mShortcutUser.forAllLaunchers(launcherShortcuts -> {
            final ArraySet<String> pinned = launcherShortcuts.getPinnedShortcutIds(
                    getPackageName(), getPackageUserId());

            if (pinned == null || pinned.size() == 0) {
                return;
            }
            for (int i = pinned.size() - 1; i >= 0; i--) {
                final String id = pinned.valueAt(i);
                final ShortcutInfo si = mShortcuts.get(id);
                final ShortcutInfo si = shortcutMap.get(id);
                if (si == null) {
                    // This happens if a launcher pinned shortcuts from this package, then backup&
                    // restored, but this package doesn't allow backing up.
@@ -632,9 +641,21 @@ class ShortcutPackage extends ShortcutPackageItem {
                    // That's fine, when the launcher is restored, we'll fix it.
                    continue;
                }
                si.addFlags(ShortcutInfo.FLAG_PINNED);
                pinnedShortcuts.add(si.getId());
            }
        });
        // Then, update the pinned state if necessary
        for (int i = shortcuts.size() - 1; i >= 0; i--) {
            final ShortcutInfo si = shortcuts.get(i);
            if (pinnedShortcuts.contains(si.getId()) && !si.isPinned()) {
                mutateShortcut(si.getId(), si,
                        shortcut -> shortcut.addFlags(ShortcutInfo.FLAG_PINNED));
            }
            if (!pinnedShortcuts.contains(si.getId()) && si.isPinned()) {
                mutateShortcut(si.getId(), si, shortcut ->
                        shortcut.clearFlags(ShortcutInfo.FLAG_PINNED));
            }
        }

        // Lastly, remove the ones that are no longer pinned, cached nor dynamic.
        removeOrphans();
@@ -1034,8 +1055,10 @@ class ShortcutPackage extends ShortcutPackageItem {
                continue;
            }
            Slog.i(TAG, String.format("Restoring shortcut: %s", si.getId()));
            si.clearFlags(ShortcutInfo.FLAG_DISABLED);
            si.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
            mutateShortcut(si.getId(), si, shortcut -> {
                shortcut.clearFlags(ShortcutInfo.FLAG_DISABLED);
                shortcut.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
            });
        }

        // For existing shortcuts, update timestamps if they have any resources.
@@ -1065,7 +1088,6 @@ class ShortcutPackage extends ShortcutPackageItem {
                }

                if (si.hasAnyResources()) {
                    if (!si.isOriginallyFromManifest()) {
                    if (publisherRes == null) {
                        publisherRes = getPackageResources();
                        if (publisherRes == null) {
@@ -1073,13 +1095,17 @@ class ShortcutPackage extends ShortcutPackageItem {
                        }
                    }

                        // TODO: update resource strings in AppSearch
                    final Resources res = publisherRes;
                    mutateShortcut(si.getId(), si, shortcut -> {
                        if (!shortcut.isOriginallyFromManifest()) {
                            shortcut.lookupAndFillInResourceIds(res);
                        }

                        // If this shortcut is not from a manifest, then update all resource IDs
                        // from resource names.  (We don't allow resource strings for
                        // non-manifest at the moment, but icons can still be resources.)
                        si.lookupAndFillInResourceIds(publisherRes);
                    }
                    si.setTimestamp(s.injectCurrentTimeMillis());
                        shortcut.setTimestamp(s.injectCurrentTimeMillis());
                    });
                }
            }
        }
@@ -1382,8 +1408,11 @@ class ShortcutPackage extends ShortcutPackageItem {
                    }
                }

                si.resolveResourceStrings(publisherRes);
                si.setTimestamp(s.injectCurrentTimeMillis());
                final Resources res = publisherRes;
                mutateShortcut(si.getId(), si, shortcut -> {
                    shortcut.resolveResourceStrings(res);
                    shortcut.setTimestamp(s.injectCurrentTimeMillis());
                });

                if (changedShortcuts == null) {
                    changedShortcuts = new ArrayList<>(1);
@@ -1400,7 +1429,7 @@ class ShortcutPackage extends ShortcutPackageItem {
    public void clearAllImplicitRanks() {
        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
            final ShortcutInfo si = mShortcuts.valueAt(i);
            si.clearImplicitRankAndRankChangedFlag();
            mutateShortcut(si.getId(), si, ShortcutInfo::clearImplicitRankAndRankChangedFlag);
        }
    }

@@ -1445,8 +1474,10 @@ class ShortcutPackage extends ShortcutPackageItem {
            final ShortcutInfo si = mShortcuts.valueAt(i);
            if (si.isFloating()) {
                if (si.getRank() != 0) {
                    si.setTimestamp(now);
                    si.setRank(0);
                    mutateShortcut(si.getId(), si, shortcut -> {
                        shortcut.setTimestamp(now);
                        shortcut.setRank(0);
                    });
                }
            }
        }
@@ -1479,8 +1510,10 @@ class ShortcutPackage extends ShortcutPackageItem {
                }
                final int thisRank = rank++;
                if (si.getRank() != thisRank) {
                    si.setTimestamp(now);
                    si.setRank(thisRank);
                    mutateShortcut(si.getId(), si, shortcut -> {
                        shortcut.setTimestamp(now);
                        shortcut.setRank(thisRank);
                    });
                }
            }
        }
@@ -2172,6 +2205,32 @@ class ShortcutPackage extends ShortcutPackageItem {
        resetAppSearch(null);
    }

    void mutateShortcut(@NonNull final String id, @Nullable final ShortcutInfo shortcut,
            @NonNull final Consumer<ShortcutInfo> transform) {
        Objects.requireNonNull(id);
        Objects.requireNonNull(transform);
        synchronized (mLock) {
            if (shortcut != null) {
                transform.accept(shortcut);
            } else {
                transform.accept(findShortcutById(id));
            }
            // TODO: Load ShortcutInfo from AppSearch, apply transformation logic and save
        }
    }

    /**
     * Removes shortcuts from AppSearch.
     */
    void removeShortcuts() {
    }

    /**
     * Merge/replace shortcuts parsed from xml file.
     */
    void restoreParsedShortcuts(final boolean replace) {
    }

    private boolean verifyRanksSequential(List<ShortcutInfo> list) {
        boolean failed = false;

+52 −45
Original line number Diff line number Diff line
@@ -1179,6 +1179,14 @@ public class ShortcutService extends IShortcutService.Stub {
        }
    }

    void postValue(@NonNull final ShortcutInfo shortcutInfo,
            @NonNull final Consumer<ShortcutInfo> cb) {
        final String pkg = shortcutInfo.getPackage();
        final int userId = shortcutInfo.getUserId();
        final String id = shortcutInfo.getId();
        getPackageShortcutsLocked(pkg, userId).mutateShortcut(id, shortcutInfo, cb);
    }

    /** Return the last reset time. */
    @GuardedBy("mLock")
    long getLastResetTimeLocked() {
@@ -1566,7 +1574,6 @@ public class ShortcutService extends IShortcutService.Stub {
     * resource-based strings.
     */
    void fixUpShortcutResourceNamesAndValues(ShortcutInfo si) {
        // TODO: update resource names in AppSearch
        final Resources publisherRes = injectGetResourcesForApplicationAsUser(
                si.getPackage(), si.getUserId());
        if (publisherRes != null) {
@@ -1947,7 +1954,7 @@ public class ShortcutService extends IShortcutService.Stub {
        final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
                injectBinderCallingPid(), injectBinderCallingUid());

        List<ShortcutInfo> changedShortcuts = null;
        final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);

        synchronized (mLock) {
            throwIfUserLockedL(userId);
@@ -1975,11 +1982,10 @@ public class ShortcutService extends IShortcutService.Stub {
                final ShortcutInfo source = newShortcuts.get(i);
                fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);

                final ShortcutInfo target = ps.findShortcutById(source.getId());

                ps.mutateShortcut(source.getId(), null, target -> {
                    // Invisible shortcuts can't be updated.
                    if (target == null || !target.isVisibleToPublisher()) {
                    continue;
                        return;
                    }

                    if (target.isEnabled() != source.isEnabled()) {
@@ -2018,16 +2024,15 @@ public class ShortcutService extends IShortcutService.Stub {
                        fixUpShortcutResourceNamesAndValues(target);
                    }

                if (changedShortcuts == null) {
                    changedShortcuts = new ArrayList<>(1);
                }
                    changedShortcuts.add(target);
                });
            }

            // Lastly, adjust the ranks.
            ps.adjustRanks();
        }
        packageShortcutsChanged(packageName, userId, changedShortcuts, null);
        packageShortcutsChanged(packageName, userId,
                changedShortcuts.isEmpty() ? null : changedShortcuts, null);

        verifyStates();

@@ -3114,7 +3119,8 @@ public class ShortcutService extends IShortcutService.Stub {

                    if (doCache) {
                        if (si.isLongLived()) {
                            si.addFlags(cacheFlags);
                            sp.mutateShortcut(si.getId(), si,
                                    shortcut -> shortcut.addFlags(cacheFlags));
                            if (changedShortcuts == null) {
                                changedShortcuts = new ArrayList<>(1);
                            }
@@ -3125,7 +3131,8 @@ public class ShortcutService extends IShortcutService.Stub {
                        }
                    } else {
                        ShortcutInfo removed = null;
                        si.clearFlags(cacheFlags);
                        sp.mutateShortcut(si.getId(), si, shortcut ->
                                shortcut.clearFlags(cacheFlags));
                        if (!si.isDynamic() && !si.isCached()) {
                            removed = sp.deleteLongLivedWithId(id, /*ignoreInvisible=*/ true);
                        }
+10 −1
Original line number Diff line number Diff line
@@ -185,6 +185,9 @@ class ShortcutUser {
    public ShortcutPackage removePackage(@NonNull String packageName) {
        final ShortcutPackage removed = mPackages.remove(packageName);

        if (removed != null) {
            removed.removeShortcuts();
        }
        mService.cleanupBitmapsForPackage(mUserId, packageName);

        return removed;
@@ -330,7 +333,10 @@ class ShortcutUser {

        if (!shortcutPackage.rescanPackageIfNeeded(isNewApp, forceRescan)) {
            if (isNewApp) {
                mPackages.remove(packageName);
                final ShortcutPackage sp = mPackages.remove(packageName);
                if (sp != null) {
                    sp.removeShortcuts();
                }
            }
        }
    }
@@ -454,6 +460,7 @@ class ShortcutUser {
                        case ShortcutPackage.TAG_ROOT: {
                            final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml(
                                    s, ret, parser, fromBackup);
                            shortcuts.restoreParsedShortcuts(false);

                            // Don't use addShortcut(), we don't need to save the icon.
                            ret.mPackages.put(shortcuts.getPackageName(), shortcuts);
@@ -488,6 +495,7 @@ class ShortcutUser {
                final ShortcutPackage sp = ShortcutPackage.loadFromFile(s, ret, f, fromBackup);
                if (sp != null) {
                    ret.mPackages.put(sp.getPackageName(), sp);
                    sp.restoreParsedShortcuts(false);
                }
            });

@@ -570,6 +578,7 @@ class ShortcutUser {
                Log.w(TAG, "Shortcuts for package " + sp.getPackageName() + " are being restored."
                        + " Existing non-manifeset shortcuts will be overwritten.");
            }
            sp.restoreParsedShortcuts(true);
            addPackage(sp);
            restoredPackages[0]++;
            restoredShortcuts[0] += sp.getShortcutCount();