Synchronize before calling unstableRemoveIf

The call to unstableRemoveIf should be synchronized on the
ResourcesManager instance since the collection belongs to the instance.

Also remove dead code from the loader refactor to prevent apps from
creating AssetManagers that return InputStreams instead of
AssetInputStreams.

Bug: 145510133
Test: boots
Change-Id: I50bcfc8e882f3d8a7827688e32f68790dd226801
This commit is contained in:
Ryan Mitchell
2020-03-26 19:23:51 -07:00
parent 393c9121ce
commit c23b0165f8
2 changed files with 16 additions and 42 deletions

View File

@@ -214,11 +214,10 @@ public class ResourcesManager {
for (int i = mCachedApkAssets.size() - 1; i >= 0; i--) {
final ApkKey key = mCachedApkAssets.keyAt(i);
if (key.path.equals(path)) {
WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.remove(key);
WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.removeAt(i);
if (apkAssetsRef != null && apkAssetsRef.get() != null) {
apkAssetsRef.get().close();
}
mCachedApkAssets.remove(key);
}
}
}
@@ -774,19 +773,21 @@ public class ResourcesManager {
* Rebases a key's override config on top of the Activity's base override.
*/
private void rebaseKeyForActivity(IBinder activityToken, ResourcesKey key) {
final ActivityResources activityResources =
getOrCreateActivityResourcesStructLocked(activityToken);
synchronized (this) {
final ActivityResources activityResources =
getOrCreateActivityResourcesStructLocked(activityToken);
// Clean up any dead references so they don't pile up.
ArrayUtils.unstableRemoveIf(activityResources.activityResources,
sEmptyReferencePredicate);
// Clean up any dead references so they don't pile up.
ArrayUtils.unstableRemoveIf(activityResources.activityResources,
sEmptyReferencePredicate);
// Rebase the key's override config on top of the Activity's base override.
if (key.hasOverrideConfiguration()
&& !activityResources.overrideConfig.equals(Configuration.EMPTY)) {
final Configuration temp = new Configuration(activityResources.overrideConfig);
temp.updateFrom(key.mOverrideConfiguration);
key.mOverrideConfiguration.setTo(temp);
// Rebase the key's override config on top of the Activity's base override.
if (key.hasOverrideConfiguration()
&& !activityResources.overrideConfig.equals(Configuration.EMPTY)) {
final Configuration temp = new Configuration(activityResources.overrideConfig);
temp.updateFrom(key.mOverrideConfiguration);
key.mOverrideConfiguration.setTo(temp);
}
}
}

View File

@@ -57,8 +57,6 @@ import android.view.DisplayAdjustments;
import com.android.internal.util.GrowingArrayUtils;
import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -817,27 +815,6 @@ public class ResourcesImpl {
}
}
/**
* Loads a Drawable from an encoded image stream, or null.
*
* This call will handle closing the {@link InputStream}.
*/
@Nullable
private Drawable decodeImageDrawable(@NonNull InputStream inputStream,
@NonNull Resources wrapper, @NonNull TypedValue value) {
ImageDecoder.Source src = ImageDecoder.createSource(wrapper, inputStream, value.density);
try {
return ImageDecoder.decodeDrawable(src, (decoder, info, s) ->
decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE));
} catch (IOException ignored) {
// This is okay. This may be something that ImageDecoder does not
// support, like SVG.
return null;
} finally {
IoUtils.closeQuietly(inputStream);
}
}
/**
* Loads a drawable from XML or resources stream.
*
@@ -902,12 +879,8 @@ public class ResourcesImpl {
} else {
final InputStream is = mAssets.openNonAsset(
value.assetCookie, file, AssetManager.ACCESS_STREAMING);
if (is instanceof AssetInputStream) {
AssetInputStream ais = (AssetInputStream) is;
dr = decodeImageDrawable(ais, wrapper, value);
} else {
dr = decodeImageDrawable(is, wrapper, value);
}
final AssetInputStream ais = (AssetInputStream) is;
dr = decodeImageDrawable(ais, wrapper, value);
}
} finally {
stack.pop();