Update IntentResolver snapshots

Bug: 179652745

Update IntentResolver snapshots to deep-copy the arrays that are part
of the maps.  This change makes copies of the IntentFilter arrays but
the IntentFilter elements are still copied by reference.  Therefore,
this change addresses the race condition of the bug but does not
address dynamic mime types as per the comment.

With this change, the steady-state overhead of a snapshot is
approximately 1.4Mb relative to not using snapshots at all.  This was
measured by comparing the rss (mean of five runs) and pss of three
images:
 * disabled - snapshots disabled
 * baseline - snapshots enabled, without this CL
 * proposed - snapshots enabled, with this CL

Test: atest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:ScanTests
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * PackageManagerServiceBootTest
 * UserLifecycleTests#startUser
 * UserLifecycleTests#stopUser
 * UserLifecycleTests#switchUser
 * android.appsecurity.cts.EphemeralTest
 * android.appsecurity.cts.InstantAppUserTest

Change-Id: I704bf8e6c0888c2ffb9563e188ebd8ac91c2f597
This commit is contained in:
Lee Shombert
2021-03-04 10:34:50 -08:00
parent c241755d1f
commit 36d42a5545

View File

@@ -839,23 +839,34 @@ public abstract class IntentResolver<F, R extends Object> {
}
};
// Helper method to copy some of the maps.
private static <E> void copyInto(ArrayMap<String, E[]> l, ArrayMap<String, E[]> r) {
final int end = r.size();
l.ensureCapacity(end);
for (int i = 0; i < end; i++) {
final E[] val = r.valueAt(i);
final String key = r.keyAt(i);
l.put(key, Arrays.copyOf(val, val.length));
}
}
// Make <this> a copy of <orig>. The presumption is that <this> is empty but all
// arrays are cleared out explicitly, just to be sure.
protected void copyFrom(IntentResolver orig) {
mFilters.clear();
mFilters.addAll(orig.mFilters);
mTypeToFilter.clear();
mTypeToFilter.putAll(orig.mTypeToFilter);
copyInto(mTypeToFilter, orig.mTypeToFilter);
mBaseTypeToFilter.clear();
mBaseTypeToFilter.putAll(orig.mBaseTypeToFilter);
copyInto(mBaseTypeToFilter, orig.mBaseTypeToFilter);
mWildTypeToFilter.clear();
mWildTypeToFilter.putAll(orig.mWildTypeToFilter);
copyInto(mWildTypeToFilter, orig.mWildTypeToFilter);
mSchemeToFilter.clear();
mSchemeToFilter.putAll(orig.mSchemeToFilter);
copyInto(mSchemeToFilter, orig.mSchemeToFilter);
mActionToFilter.clear();
mActionToFilter.putAll(orig.mActionToFilter);
copyInto(mActionToFilter, orig.mActionToFilter);
mTypedActionToFilter.clear();
mTypedActionToFilter.putAll(orig.mTypedActionToFilter);
copyInto(mTypedActionToFilter, orig.mTypedActionToFilter);
}
/**