From 1ec53ec50776cd1c6539bd5e339a951b990a1c76 Mon Sep 17 00:00:00 2001 From: Andrei Onea Date: Wed, 24 Feb 2021 15:24:39 +0000 Subject: Fix deadlock on CompatConfig.mChanges Only lock mChanges long enough to get a local copy of the list of changes. Bug: 181021273 Change-Id: I22e97e58b4fe9dbc70d11660f93c4afb5d514d24 --- .../com/android/server/compat/CompatConfig.java | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 422991e082a9..66a652053857 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() { -- cgit v1.2.3-59-g8ed1b