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

Commit 782fb579 authored by Jeongsik Mun's avatar Jeongsik Mun Committed by Song Chun Fan
Browse files

Fix watchdog timeout during recomputeComponentVisibility

Due to a held lock, watchdog timeout or lock contentions could occur.

This fix is to remove the lock guard from Computer and make it work
with snapshots.

Bug: 312057281
Test: Manually tested with below steps
      1. Install 2000 packages
      2. Reboot
      3. Make sure watchdog timeout or lock contention doesn't occur
(cherry picked from https://partner-android-review.googlesource.com/q/commit:c788c4cad5740ec21084db2095979d31871daed4)
Change-Id: I40f735924025575477ba24bf35ed3211494159bd
parent 5e8e346c
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.SparseSetArray;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -1030,14 +1031,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
    private void recomputeComponentVisibility(
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        final WatchedArraySet<String> protectedBroadcasts;
        final WatchedArraySet<Integer> forceQueryable;
        synchronized (mProtectedBroadcastsLock) {
            protectedBroadcasts = mProtectedBroadcasts.snapshot();
        }
        synchronized (mForceQueryableLock) {
            forceQueryable = mForceQueryable.snapshot();
        }
        final ParallelComputeComponentVisibility computer = new ParallelComputeComponentVisibility(
                existingSettings, mForceQueryable, protectedBroadcasts);
                existingSettings, forceQueryable, protectedBroadcasts);
        SparseSetArray<Integer> queriesViaComponent = computer.execute();
        synchronized (mQueriesViaComponentLock) {
            mQueriesViaComponent.clear();
            computer.execute(mQueriesViaComponent);
            mQueriesViaComponent.copyFrom(queriesViaComponent);
        }

        mQueriesViaComponentRequireRecompute.set(false);
+6 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.IntentFilter;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.util.SparseSetArray;

import com.android.internal.pm.pkg.component.ParsedComponent;
import com.android.internal.pm.pkg.component.ParsedIntentInfo;
@@ -37,7 +38,6 @@ import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.utils.WatchedArraySet;
import com.android.server.utils.WatchedSparseSetArray;

import java.util.ArrayList;
import java.util.List;
@@ -213,7 +213,9 @@ final class AppsFilterUtils {
        /**
         * Computes component visibility of all packages in parallel from a thread pool.
         */
        void execute(@NonNull WatchedSparseSetArray<Integer> outQueriesViaComponent) {
        @NonNull
        SparseSetArray<Integer> execute() {
            final SparseSetArray<Integer> queriesViaComponent = new SparseSetArray<>();
            final ExecutorService pool = ConcurrentUtils.newFixedThreadPool(
                    MAX_THREADS, ParallelComputeComponentVisibility.class.getSimpleName(),
                    THREAD_PRIORITY_DEFAULT);
@@ -239,7 +241,7 @@ final class AppsFilterUtils {
                    try {
                        final ArraySet<Integer> visibleList = future.get();
                        if (visibleList.size() != 0) {
                            outQueriesViaComponent.addAll(appId, visibleList);
                            queriesViaComponent.addAll(appId, visibleList);
                        }
                    } catch (InterruptedException | ExecutionException e) {
                        throw new IllegalStateException(e);
@@ -248,6 +250,7 @@ final class AppsFilterUtils {
            } finally {
                pool.shutdownNow();
            }
            return queriesViaComponent;
        }

        /**
+14 −0
Original line number Diff line number Diff line
@@ -142,6 +142,20 @@ public class WatchedSparseSetArray<T> extends WatchableImpl implements Snappable
        return (T) mStorage.valueAt(intIndex, valueIndex);
    }

    /**
     * Copy from another SparseSetArray.
     */
    public void copyFrom(@NonNull SparseSetArray<T> c) {
        clear();
        final int end = c.size();
        for (int i = 0; i < end; i++) {
            final int key = c.keyAt(i);
            final ArraySet<T> set = c.get(key);
            mStorage.addAll(key, set);
        }
        onChanged();
    }

    @NonNull
    @Override
    public Object snapshot() {