ResourcesManager: Return null on failure to create Resources

am: 53fafdfbe7

Change-Id: I47c891d2c21c2ba95cc05d4972332ea128b2d444
This commit is contained in:
Adam Lesinski
2016-08-04 00:19:23 +00:00
committed by android-build-merger
2 changed files with 42 additions and 23 deletions

View File

@@ -1245,18 +1245,16 @@ public class ApplicationPackageManager extends PackageManager {
return mContext.mMainThread.getSystemContext().getResources(); return mContext.mMainThread.getSystemContext().getResources();
} }
final boolean sameUid = (app.uid == Process.myUid()); final boolean sameUid = (app.uid == Process.myUid());
try { final Resources r = mContext.mMainThread.getTopLevelResources(
return mContext.mMainThread.getTopLevelResources(
sameUid ? app.sourceDir : app.publicSourceDir, sameUid ? app.sourceDir : app.publicSourceDir,
sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY, app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
mContext.mPackageInfo); mContext.mPackageInfo);
} catch (Resources.NotFoundException cause) { if (r != null) {
final NameNotFoundException ex = return r;
new NameNotFoundException("Unable to open " + app.publicSourceDir);
ex.initCause(cause);
throw ex;
} }
throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
} }
@Override @Override

View File

@@ -242,7 +242,7 @@ public class ResourcesManager {
* @return a new AssetManager. * @return a new AssetManager.
*/ */
@VisibleForTesting @VisibleForTesting
protected @NonNull AssetManager createAssetManager(@NonNull final ResourcesKey key) { protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key) {
AssetManager assets = new AssetManager(); AssetManager assets = new AssetManager();
// resDir can be null if the 'android' package is creating a new Resources object. // resDir can be null if the 'android' package is creating a new Resources object.
@@ -250,15 +250,16 @@ public class ResourcesManager {
// already. // already.
if (key.mResDir != null) { if (key.mResDir != null) {
if (assets.addAssetPath(key.mResDir) == 0) { if (assets.addAssetPath(key.mResDir) == 0) {
throw new Resources.NotFoundException("failed to add asset path " + key.mResDir); Log.e(TAG, "failed to add asset path " + key.mResDir);
return null;
} }
} }
if (key.mSplitResDirs != null) { if (key.mSplitResDirs != null) {
for (final String splitResDir : key.mSplitResDirs) { for (final String splitResDir : key.mSplitResDirs) {
if (assets.addAssetPath(splitResDir) == 0) { if (assets.addAssetPath(splitResDir) == 0) {
throw new Resources.NotFoundException( Log.e(TAG, "failed to add split asset path " + splitResDir);
"failed to add split asset path " + splitResDir); return null;
} }
} }
} }
@@ -303,11 +304,15 @@ public class ResourcesManager {
return config; return config;
} }
private @NonNull ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) { private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) {
final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration); final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
daj.setCompatibilityInfo(key.mCompatInfo); daj.setCompatibilityInfo(key.mCompatInfo);
final AssetManager assets = createAssetManager(key); final AssetManager assets = createAssetManager(key);
if (assets == null) {
return null;
}
final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj); final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj);
final Configuration config = generateConfig(key, dm); final Configuration config = generateConfig(key, dm);
final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj); final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj);
@@ -323,7 +328,7 @@ public class ResourcesManager {
* @param key The key to match. * @param key The key to match.
* @return a ResourcesImpl if the key matches a cache entry, null otherwise. * @return a ResourcesImpl if the key matches a cache entry, null otherwise.
*/ */
private ResourcesImpl findResourcesImplForKeyLocked(@NonNull ResourcesKey key) { private @Nullable ResourcesImpl findResourcesImplForKeyLocked(@NonNull ResourcesKey key) {
WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.get(key); WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.get(key);
ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
if (impl != null && impl.getAssets().isUpToDate()) { if (impl != null && impl.getAssets().isUpToDate()) {
@@ -338,13 +343,15 @@ public class ResourcesManager {
* @param key The key to match. * @param key The key to match.
* @return a ResourcesImpl object matching the key. * @return a ResourcesImpl object matching the key.
*/ */
private @NonNull ResourcesImpl findOrCreateResourcesImplForKeyLocked( private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
@NonNull ResourcesKey key) { @NonNull ResourcesKey key) {
ResourcesImpl impl = findResourcesImplForKeyLocked(key); ResourcesImpl impl = findResourcesImplForKeyLocked(key);
if (impl == null) { if (impl == null) {
impl = createResourcesImpl(key); impl = createResourcesImpl(key);
if (impl != null) {
mResourceImpls.put(key, new WeakReference<>(impl)); mResourceImpls.put(key, new WeakReference<>(impl));
} }
}
return impl; return impl;
} }
@@ -352,7 +359,8 @@ public class ResourcesManager {
* Find the ResourcesKey that this ResourcesImpl object is associated with. * Find the ResourcesKey that this ResourcesImpl object is associated with.
* @return the ResourcesKey or null if none was found. * @return the ResourcesKey or null if none was found.
*/ */
private ResourcesKey findKeyForResourceImplLocked(@NonNull ResourcesImpl resourceImpl) { private @Nullable ResourcesKey findKeyForResourceImplLocked(
@NonNull ResourcesImpl resourceImpl) {
final int refCount = mResourceImpls.size(); final int refCount = mResourceImpls.size();
for (int i = 0; i < refCount; i++) { for (int i = 0; i < refCount; i++) {
WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i); WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
@@ -480,7 +488,7 @@ public class ResourcesManager {
* {@link ClassLoader#getSystemClassLoader()} is used. * {@link ClassLoader#getSystemClassLoader()} is used.
* @return a Resources object from which to access resources. * @return a Resources object from which to access resources.
*/ */
public @NonNull Resources createBaseActivityResources(@NonNull IBinder activityToken, public @Nullable Resources createBaseActivityResources(@NonNull IBinder activityToken,
@Nullable String resDir, @Nullable String resDir,
@Nullable String[] splitResDirs, @Nullable String[] splitResDirs,
@Nullable String[] overlayDirs, @Nullable String[] overlayDirs,
@@ -534,7 +542,7 @@ public class ResourcesManager {
* {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)} * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
* is called. * is called.
*/ */
private @NonNull Resources getOrCreateResources(@Nullable IBinder activityToken, private @Nullable Resources getOrCreateResources(@Nullable IBinder activityToken,
@NonNull ResourcesKey key, @NonNull ClassLoader classLoader) { @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) {
synchronized (this) { synchronized (this) {
if (DEBUG) { if (DEBUG) {
@@ -589,6 +597,9 @@ public class ResourcesManager {
// If we're here, we didn't find a suitable ResourcesImpl to use, so create one now. // If we're here, we didn't find a suitable ResourcesImpl to use, so create one now.
ResourcesImpl resourcesImpl = createResourcesImpl(key); ResourcesImpl resourcesImpl = createResourcesImpl(key);
if (resourcesImpl == null) {
return null;
}
synchronized (this) { synchronized (this) {
ResourcesImpl existingResourcesImpl = findResourcesImplForKeyLocked(key); ResourcesImpl existingResourcesImpl = findResourcesImplForKeyLocked(key);
@@ -642,7 +653,7 @@ public class ResourcesManager {
* {@link ClassLoader#getSystemClassLoader()} is used. * {@link ClassLoader#getSystemClassLoader()} is used.
* @return a Resources object from which to access resources. * @return a Resources object from which to access resources.
*/ */
public @NonNull Resources getResources(@Nullable IBinder activityToken, public @Nullable Resources getResources(@Nullable IBinder activityToken,
@Nullable String resDir, @Nullable String resDir,
@Nullable String[] splitResDirs, @Nullable String[] splitResDirs,
@Nullable String[] overlayDirs, @Nullable String[] overlayDirs,
@@ -765,10 +776,12 @@ public class ResourcesManager {
ResourcesImpl resourcesImpl = findResourcesImplForKeyLocked(newKey); ResourcesImpl resourcesImpl = findResourcesImplForKeyLocked(newKey);
if (resourcesImpl == null) { if (resourcesImpl == null) {
resourcesImpl = createResourcesImpl(newKey); resourcesImpl = createResourcesImpl(newKey);
if (resourcesImpl != null) {
mResourceImpls.put(newKey, new WeakReference<>(resourcesImpl)); mResourceImpls.put(newKey, new WeakReference<>(resourcesImpl));
} }
}
if (resourcesImpl != resources.getImpl()) { if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
// Set the ResourcesImpl, updating it for all users of this Resources // Set the ResourcesImpl, updating it for all users of this Resources
// object. // object.
resources.setImpl(resourcesImpl); resources.setImpl(resourcesImpl);
@@ -910,7 +923,11 @@ public class ResourcesManager {
if (r != null) { if (r != null) {
final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
if (key != null) { if (key != null) {
r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
if (impl == null) {
throw new Resources.NotFoundException("failed to load " + libAsset);
}
r.setImpl(impl);
} }
} }
} }
@@ -923,7 +940,11 @@ public class ResourcesManager {
if (r != null) { if (r != null) {
final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
if (key != null) { if (key != null) {
r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
if (impl == null) {
throw new Resources.NotFoundException("failed to load " + libAsset);
}
r.setImpl(impl);
} }
} }
} }