diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 422991e082a9a..66a652053857e 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -50,6 +50,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -595,18 +596,24 @@ final class CompatConfig { * Rechecks all the existing overrides for a package. */ void recheckOverrides(String packageName) { + // Local cache of compat changes. Holding a lock on mChanges for the whole duration of the + // method will cause a deadlock. + List changes; synchronized (mChanges) { - boolean shouldInvalidateCache = false; + changes = new ArrayList<>(mChanges.size()); for (int idx = 0; idx < mChanges.size(); ++idx) { - CompatChange c = mChanges.valueAt(idx); - OverrideAllowedState allowedState = - mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); - shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext); - } - if (shouldInvalidateCache) { - invalidateCache(); + changes.add(mChanges.valueAt(idx)); } } + boolean shouldInvalidateCache = false; + for (CompatChange c: changes) { + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); + shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext); + } + if (shouldInvalidateCache) { + invalidateCache(); + } } void registerContentObserver() {