From a27780e0aa7eab16ea42ad4f93957cf523c82002 Mon Sep 17 00:00:00 2001 From: Fyodor Kupolov Date: Thu, 2 Feb 2017 18:33:18 -0800 Subject: [PATCH] Use self-locking for mAvailableFeatures mAvailableFeatures is read-only and set in the constructor. Calls to hasSystemFeature are often blocked if PM is busy with other operations. Test: manual - device boots without errors Bug: 33199244 Change-Id: I5ce0fa7af37e95ac64afb11a1022a27e37c67703 --- .../server/pm/PackageManagerService.java | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6f20f10881838..0e5ea6e8e8af7 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -712,6 +712,7 @@ public class PackageManagerService extends IPackageManager.Stub { // System configuration read by SystemConfig. final int[] mGlobalGids; final SparseArray> mSystemPermissions; + @GuardedBy("mAvailableFeatures") final ArrayMap mAvailableFeatures; // If mac_permissions.xml was found for seinfo labeling. @@ -4215,21 +4216,22 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public @NonNull ParceledListSlice getSystemAvailableFeatures() { - synchronized (mPackages) { - final ArrayList res = new ArrayList<>(mAvailableFeatures.values()); - - final FeatureInfo fi = new FeatureInfo(); - fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", - FeatureInfo.GL_ES_VERSION_UNDEFINED); - res.add(fi); - - return new ParceledListSlice<>(res); + ArrayList res; + synchronized (mAvailableFeatures) { + res = new ArrayList<>(mAvailableFeatures.size() + 1); + res.addAll(mAvailableFeatures.values()); } + final FeatureInfo fi = new FeatureInfo(); + fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", + FeatureInfo.GL_ES_VERSION_UNDEFINED); + res.add(fi); + + return new ParceledListSlice<>(res); } @Override public boolean hasSystemFeature(String name, int version) { - synchronized (mPackages) { + synchronized (mAvailableFeatures) { final FeatureInfo feat = mAvailableFeatures.get(name); if (feat == null) { return false; @@ -20379,20 +20381,22 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); pw.println("Features:"); } - for (FeatureInfo feat : mAvailableFeatures.values()) { - if (checkin) { - pw.print("feat,"); - pw.print(feat.name); - pw.print(","); - pw.println(feat.version); - } else { - pw.print(" "); - pw.print(feat.name); - if (feat.version > 0) { - pw.print(" version="); - pw.print(feat.version); + synchronized (mAvailableFeatures) { + for (FeatureInfo feat : mAvailableFeatures.values()) { + if (checkin) { + pw.print("feat,"); + pw.print(feat.name); + pw.print(","); + pw.println(feat.version); + } else { + pw.print(" "); + pw.print(feat.name); + if (feat.version > 0) { + pw.print(" version="); + pw.print(feat.version); + } + pw.println(); } - pw.println(); } } }