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

Commit 645f51d3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Properly protect ShortcutPackage#mShortcuts with synchronization lock." into tm-dev

parents 8721d110 9e9c9a8c
Loading
Loading
Loading
Loading
+180 −148
Original line number Diff line number Diff line
@@ -166,18 +166,19 @@ class ShortcutPackage extends ShortcutPackageItem {
     * An in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs.
     */
    @GuardedBy("mLock")
    final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
    private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();

    /**
     * A temporary copy of shortcuts that are to be cleared once persisted into AppSearch, keyed on
     * IDs.
     */
    @GuardedBy("mLock")
    private ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0);
    private final ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0);

    /**
     * All the share targets from the package
     */
    @GuardedBy("mLock")
    private final ArrayList<ShareTargetInfo> mShareTargets = new ArrayList<>(0);

    /**
@@ -231,8 +232,10 @@ class ShortcutPackage extends ShortcutPackageItem {
    }

    public int getShortcutCount() {
        synchronized (mLock) {
            return mShortcuts.size();
        }
    }

    @Override
    protected boolean canRestoreAnyVersion() {
@@ -272,8 +275,10 @@ class ShortcutPackage extends ShortcutPackageItem {
    @Nullable
    public ShortcutInfo findShortcutById(@Nullable final String id) {
        if (id == null) return null;
        synchronized (mLock) {
            return mShortcuts.get(id);
        }
    }

    public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
        ShortcutInfo si = findShortcutById(id);
@@ -347,12 +352,15 @@ class ShortcutPackage extends ShortcutPackageItem {
     * Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible.
     */
    private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) {
        final ShortcutInfo shortcut = mShortcuts.remove(id);
        final ShortcutInfo shortcut;
        synchronized (mLock) {
            shortcut = mShortcuts.remove(id);
            if (shortcut != null) {
                removeIcon(shortcut);
                shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
                        | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL);
            }
        }
        return shortcut;
    }

@@ -524,6 +532,7 @@ class ShortcutPackage extends ShortcutPackageItem {
    public List<ShortcutInfo> deleteAllDynamicShortcuts() {
        final long now = mShortcutUser.mService.injectCurrentTimeMillis();
        boolean changed = false;
        synchronized (mLock) {
            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                ShortcutInfo si = mShortcuts.valueAt(i);
                if (si.isDynamic() && si.isVisibleToPublisher()) {
@@ -534,6 +543,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                    si.setRank(0); // It may still be pinned, so clear the rank.
                }
            }
        }
        removeAllShortcutsAsync();
        if (changed) {
            return removeOrphans();
@@ -874,6 +884,7 @@ class ShortcutPackage extends ShortcutPackageItem {
     */
    public List<ShortcutManager.ShareShortcutInfo> getMatchingShareTargets(
            @NonNull IntentFilter filter) {
        synchronized (mLock) {
            final List<ShareTargetInfo> matchedTargets = new ArrayList<>();
            for (int i = 0; i < mShareTargets.size(); i++) {
                final ShareTargetInfo target = mShareTargets.get(i);
@@ -924,10 +935,13 @@ class ShortcutPackage extends ShortcutPackageItem {
            }
            return result;
        }
    }

    public boolean hasShareTargets() {
        synchronized (mLock) {
            return !mShareTargets.isEmpty();
        }
    }

    /**
     * Returns the number of shortcuts that can be used as a share target in the ShareSheet. Such
@@ -935,6 +949,7 @@ class ShortcutPackage extends ShortcutPackageItem {
     * the app's Xml resource.
     */
    int getSharingShortcutCount() {
        synchronized (mLock) {
            if (mShareTargets.isEmpty()) {
                return 0;
            }
@@ -968,6 +983,7 @@ class ShortcutPackage extends ShortcutPackageItem {
            }
            return sharingShortcutCount;
        }
    }

    /**
     * Return the filenames (excluding path names) of icon bitmap files from this package.
@@ -1090,19 +1106,25 @@ class ShortcutPackage extends ShortcutPackageItem {

        // Now prepare to publish manifest shortcuts.
        List<ShortcutInfo> newManifestShortcutList = null;
        final int shareTargetSize;
        synchronized (mLock) {
            try {
                shareTargetSize = mShareTargets.size();
                newManifestShortcutList = ShortcutParser.parseShortcuts(mShortcutUser.mService,
                        getPackageName(), getPackageUserId(), mShareTargets);
            } catch (IOException | XmlPullParserException e) {
                Slog.e(TAG, "Failed to load shortcuts from AndroidManifest.xml.", e);
            }
        }
        final int manifestShortcutSize = newManifestShortcutList == null ? 0
                : newManifestShortcutList.size();
        if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) {
            Slog.d(TAG,
                    String.format("Package %s has %d manifest shortcut(s), and %d share target(s)",
                            getPackageName(), manifestShortcutSize, mShareTargets.size()));
                    String.format(
                            "Package %s has %d manifest shortcut(s), and %d share target(s)",
                            getPackageName(), manifestShortcutSize, shareTargetSize));
        }

        if (isNewApp && (manifestShortcutSize == 0)) {
            // If it's a new app, and it doesn't have manifest shortcuts, then nothing to do.

@@ -1701,6 +1723,7 @@ class ShortcutPackage extends ShortcutPackageItem {
    @Override
    public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup)
            throws IOException, XmlPullParserException {
        synchronized (mLock) {
            final int size = mShortcuts.size();
            final int shareTargetSize = mShareTargets.size();

@@ -1714,15 +1737,14 @@ class ShortcutPackage extends ShortcutPackageItem {
            ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
            ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
            if (!forBackup) {
            synchronized (mLock) {
                ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, (mIsAppSearchSchemaUpToDate)
                ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, mIsAppSearchSchemaUpToDate
                        ? AppSearchShortcutInfo.SCHEMA_VERSION : 0);
            }
        }
            getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);

            for (int j = 0; j < size; j++) {
            saveShortcut(out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed());
                saveShortcut(
                        out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed());
            }

            if (!forBackup) {
@@ -1733,6 +1755,7 @@ class ShortcutPackage extends ShortcutPackageItem {

            out.endTag(null, TAG_ROOT);
        }
    }

    private void saveShortcut(TypedXmlSerializer out, ShortcutInfo si, boolean forBackup,
            boolean appSupportsBackup)
@@ -1917,11 +1940,10 @@ class ShortcutPackage extends ShortcutPackageItem {
        synchronized (ret.mLock) {
            ret.mIsAppSearchSchemaUpToDate = ShortcutService.parseIntAttribute(
                    parser, ATTR_SCHEMA_VERSON, 0) == AppSearchShortcutInfo.SCHEMA_VERSION;
        }

            ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
            ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);


            final int outerDepth = parser.getDepth();
            int type;
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1950,6 +1972,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                }
                ShortcutService.warnForInvalidTag(depth, tag);
            }
        }
        return ret;
    }

@@ -2152,8 +2175,10 @@ class ShortcutPackage extends ShortcutPackageItem {

    @VisibleForTesting
    List<ShareTargetInfo> getAllShareTargetsForTest() {
        synchronized (mLock) {
            return new ArrayList<>(mShareTargets);
        }
    }

    @Override
    public void verifyStates() {
@@ -2291,16 +2316,20 @@ class ShortcutPackage extends ShortcutPackageItem {

    private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) {
        Objects.requireNonNull(shortcuts);
        synchronized (mLock) {
            for (ShortcutInfo si : shortcuts) {
                mShortcuts.put(si.getId(), si);
            }
        }
    }

    @Nullable
    List<ShortcutInfo> findAll(@NonNull final Collection<String> ids) {
        synchronized (mLock) {
            return ids.stream().map(mShortcuts::get)
                    .filter(Objects::nonNull).collect(Collectors.toList());
        }
    }

    private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) {
        forEachShortcutStopWhen(si -> {
@@ -2318,6 +2347,7 @@ class ShortcutPackage extends ShortcutPackageItem {

    private void forEachShortcutStopWhen(
            @NonNull final Function<ShortcutInfo, Boolean> cb) {
        synchronized (mLock) {
            for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                final ShortcutInfo si = mShortcuts.valueAt(i);
                if (cb.apply(si)) {
@@ -2325,6 +2355,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                }
            }
        }
    }

    @NonNull
    private AndroidFuture<AppSearchSession> setupSchema(
@@ -2461,6 +2492,7 @@ class ShortcutPackage extends ShortcutPackageItem {
                        })));
    }

    @GuardedBy("mLock")
    @Override
    void scheduleSaveToAppSearchLocked() {
        final Map<String, ShortcutInfo> copy = new ArrayMap<>(mShortcuts);