Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4579c0ae authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Refactor ResourcesLoader APIs

This changes refactors the ResourcesLoader APIs.
The main changes are:

Rather than pairing a ResourcesLoader with a ResourcesProvider, a
ResourcesProvider is paired with an AssetsProvider which is only
responsible for overriding the values of file-base resources and
assets. An AssetsProvider can be shared between multiple
ResourcesProviders.

ResourcesLoader now holds a list of ResourcesProviders.

ResourcesLoaders are part of ResourcesKeys and requests for resources
with the same loaders will use the same underlying ResourcesImpl. This
allows the loader specific code in RM to be cleaned up.

ResourcesLoaders and Resources objects use callbacks to notify RM
of changes to the Resources instance that may require a new
ResourcesImpl.

When a context is created from another context, the new context will
include the loaders of the original context. Change to list of either
context's loaders will not change the loaders of the other context,
but changes to the providers a loaders uses will update all Resources
objects that use that loader.

Activity resources will include the loaders of the application context
at the time of the Activity's creation.

Bug: 147359613
Test: atest ResourceLoaderTests
Change-Id: I2957c803d3f0c1280abfd3c723d76b18df2c3789
parent 12ce8338
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -12635,8 +12635,8 @@ package android.content.res {
  public class Resources {
    ctor @Deprecated public Resources(android.content.res.AssetManager, android.util.DisplayMetrics, android.content.res.Configuration);
    method public void addLoader(@NonNull android.content.res.loader.ResourceLoader, @NonNull android.content.res.loader.ResourcesProvider, @IntRange(from=0) int);
    method public int addLoader(@NonNull android.content.res.loader.ResourceLoader, @NonNull android.content.res.loader.ResourcesProvider);
    method public void addLoader(@NonNull android.content.res.loader.ResourcesLoader);
    method public void clearLoaders();
    method public final void finishPreloading();
    method public final void flushLayoutCache();
    method @NonNull public android.content.res.XmlResourceParser getAnimation(@AnimRes @AnimatorRes int) throws android.content.res.Resources.NotFoundException;
@@ -12663,7 +12663,7 @@ package android.content.res {
    method @NonNull public int[] getIntArray(@ArrayRes int) throws android.content.res.Resources.NotFoundException;
    method public int getInteger(@IntegerRes int) throws android.content.res.Resources.NotFoundException;
    method @NonNull public android.content.res.XmlResourceParser getLayout(@LayoutRes int) throws android.content.res.Resources.NotFoundException;
    method @NonNull public java.util.List<android.util.Pair<android.content.res.loader.ResourceLoader,android.content.res.loader.ResourcesProvider>> getLoaders();
    method @NonNull public java.util.List<android.content.res.loader.ResourcesLoader> getLoaders();
    method @Deprecated public android.graphics.Movie getMovie(@RawRes int) throws android.content.res.Resources.NotFoundException;
    method @NonNull public String getQuantityString(@PluralsRes int, int, java.lang.Object...) throws android.content.res.Resources.NotFoundException;
    method @NonNull public String getQuantityString(@PluralsRes int, int) throws android.content.res.Resources.NotFoundException;
@@ -12691,8 +12691,8 @@ package android.content.res {
    method public android.content.res.AssetFileDescriptor openRawResourceFd(@RawRes int) throws android.content.res.Resources.NotFoundException;
    method public void parseBundleExtra(String, android.util.AttributeSet, android.os.Bundle) throws org.xmlpull.v1.XmlPullParserException;
    method public void parseBundleExtras(android.content.res.XmlResourceParser, android.os.Bundle) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int removeLoader(@NonNull android.content.res.loader.ResourceLoader);
    method public void setLoaders(@Nullable java.util.List<android.util.Pair<android.content.res.loader.ResourceLoader,android.content.res.loader.ResourcesProvider>>);
    method public void removeLoader(@NonNull android.content.res.loader.ResourcesLoader);
    method public void setLoaders(@NonNull java.util.List<android.content.res.loader.ResourcesLoader>);
    method @Deprecated public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
    field @AnyRes public static final int ID_NULL = 0; // 0x0
  }
@@ -12762,27 +12762,37 @@ package android.content.res {
package android.content.res.loader {
  public class DirectoryResourceLoader implements android.content.res.loader.ResourceLoader {
    ctor public DirectoryResourceLoader(@NonNull java.io.File);
  public interface AssetsProvider {
    method @Nullable public default java.io.InputStream loadAsset(@NonNull String, int) throws java.io.IOException;
    method @Nullable public default android.os.ParcelFileDescriptor loadAssetParcelFd(@NonNull String) throws java.io.IOException;
  }
  public class DirectoryAssetsProvider implements android.content.res.loader.AssetsProvider {
    ctor public DirectoryAssetsProvider(@NonNull java.io.File);
    method @Nullable public java.io.File findFile(@NonNull String);
    method @NonNull public java.io.File getDirectory();
  }
  public interface ResourceLoader {
    method @Nullable public default java.io.InputStream loadAsset(@NonNull String, int) throws java.io.IOException;
    method @Nullable public default android.os.ParcelFileDescriptor loadAssetFd(@NonNull String) throws java.io.IOException;
    method @Nullable public default android.graphics.drawable.Drawable loadDrawable(@NonNull android.util.TypedValue, int, int, @Nullable android.content.res.Resources.Theme);
    method @Nullable public default android.content.res.XmlResourceParser loadXmlResourceParser(@NonNull String, @AnyRes int);
  public class ResourcesLoader {
    ctor public ResourcesLoader();
    method public void addProvider(@NonNull android.content.res.loader.ResourcesProvider);
    method public void clearProviders();
    method @NonNull public java.util.List<android.content.res.loader.ResourcesProvider> getProviders();
    method public void removeProvider(@NonNull android.content.res.loader.ResourcesProvider);
    method public void setProviders(@NonNull java.util.List<android.content.res.loader.ResourcesProvider>);
  }
  public final class ResourcesProvider implements java.lang.AutoCloseable java.io.Closeable {
  public class ResourcesProvider implements java.lang.AutoCloseable java.io.Closeable {
    method public void close();
    method @NonNull public static android.content.res.loader.ResourcesProvider empty();
    method @NonNull public static android.content.res.loader.ResourcesProvider empty(@NonNull android.content.res.loader.AssetsProvider);
    method @Nullable public android.content.res.loader.AssetsProvider getAssetsProvider();
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromArsc(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromArsc(@NonNull android.os.SharedMemory) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromSplit(@NonNull android.content.Context, @NonNull String) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException;
    method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException;
  }
}
+1 −1
Original line number Diff line number Diff line
@@ -2206,7 +2206,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
            String[] libDirs, int displayId, LoadedApk pkgInfo) {
        return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
                displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader());
                displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(), null);
    }

    @UnsupportedAppUsage
+19 −9
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.content.res.CompatResources;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.loader.ResourcesLoader;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -100,6 +101,7 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;

@@ -2217,7 +2219,8 @@ class ContextImpl extends Context {
    }

    private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName,
            int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo) {
            int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo,
            List<ResourcesLoader> resourcesLoader) {
        final String[] splitResDirs;
        final ClassLoader classLoader;
        try {
@@ -2234,7 +2237,8 @@ class ContextImpl extends Context {
                displayId,
                overrideConfig,
                compatInfo,
                classLoader);
                classLoader,
                resourcesLoader);
    }

    @Override
@@ -2249,7 +2253,7 @@ class ContextImpl extends Context {
            final int displayId = getDisplayId();

            c.setResources(createResources(mToken, pi, null, displayId, null,
                    getDisplayAdjustments(displayId).getCompatibilityInfo()));
                    getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
            if (c.mResources != null) {
                return c;
            }
@@ -2284,7 +2288,7 @@ class ContextImpl extends Context {
            final int displayId = getDisplayId();

            c.setResources(createResources(mToken, pi, null, displayId, null,
                    getDisplayAdjustments(displayId).getCompatibilityInfo()));
                    getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
            if (c.mResources != null) {
                return c;
            }
@@ -2328,7 +2332,8 @@ class ContextImpl extends Context {
                displayId,
                null,
                mPackageInfo.getCompatibilityInfo(),
                classLoader));
                classLoader,
                mResources.getLoaders()));
        return context;
    }

@@ -2342,8 +2347,10 @@ class ContextImpl extends Context {
                mSplitName, mToken, mUser, mFlags, mClassLoader, null);

        final int displayId = getDisplayId();

        context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo()));
                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
                mResources.getLoaders()));
        return context;
    }

@@ -2357,8 +2364,10 @@ class ContextImpl extends Context {
                mSplitName, mToken, mUser, mFlags, mClassLoader, null);

        final int displayId = display.getDisplayId();

        context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
                null, getDisplayAdjustments(displayId).getCompatibilityInfo()));
                null, getDisplayAdjustments(displayId).getCompatibilityInfo(),
                mResources.getLoaders()));
        context.mDisplay = display;
        return context;
    }
@@ -2564,7 +2573,7 @@ class ContextImpl extends Context {
        ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
                null, null, null, 0, null, null);
        context.setResources(createResources(null, packageInfo, null, displayId, null,
                packageInfo.getCompatibilityInfo()));
                packageInfo.getCompatibilityInfo(), null));
        context.updateDisplay(displayId);
        context.mIsSystemOrSystemUiContext = true;
        return context;
@@ -2637,7 +2646,8 @@ class ContextImpl extends Context {
                displayId,
                overrideConfiguration,
                compatInfo,
                classLoader));
                classLoader,
                packageInfo.getApplication().getResources().getLoaders()));
        context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
                context.getResources());
        return context;
+3 −2
Original line number Diff line number Diff line
@@ -365,7 +365,8 @@ public final class LoadedApk {
                mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                        splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
                        Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
                        getClassLoader());
                        getClassLoader(), mApplication == null ? null
                                : mApplication.getResources().getLoaders());
            }
        }
        mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
@@ -1158,7 +1159,7 @@ public final class LoadedApk {
            mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                    splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
                    Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
                    getClassLoader());
                    getClassLoader(), null);
        }
        return mResources;
    }
+86 −302

File changed.

Preview size limit exceeded, changes collapsed.

Loading