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

Commit 6e106c54 authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Android (Google) Code Review
Browse files

Merge "API council changes for ResourcesLoaders"

parents 8c03bb83 e272307d
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -12703,8 +12703,7 @@ 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.ResourcesLoader);
    method public void clearLoaders();
    method public void addLoaders(@NonNull android.content.res.loader.ResourcesLoader...);
    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;
@@ -12731,7 +12730,6 @@ 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.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;
@@ -12759,8 +12757,7 @@ 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 void removeLoader(@NonNull android.content.res.loader.ResourcesLoader);
    method public void setLoaders(@NonNull java.util.List<android.content.res.loader.ResourcesLoader>);
    method public void removeLoaders(@NonNull 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
  }
+52 −55
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import android.view.DisplayAdjustments;
import android.view.ViewDebug;
import android.view.ViewHierarchyEncoder;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
@@ -112,7 +113,7 @@ public class Resources {
    static final String TAG = "Resources";

    private static final Object sSync = new Object();
    private final Object mLock = new Object();
    private final Object mUpdateLock = new Object();

    // Used by BridgeResources in layoutlib
    @UnsupportedAppUsage
@@ -139,6 +140,7 @@ public class Resources {
    @UnsupportedAppUsage
    final ClassLoader mClassLoader;

    @GuardedBy("mUpdateLock")
    private UpdateCallbacks mCallbacks = null;

    /**
@@ -2375,6 +2377,7 @@ public class Resources {
     *
     * <p>Loaders are listed in increasing precedence order. A loader will override the resources
     * and assets of loaders listed before itself.
     * @hide
     */
    @NonNull
    public List<ResourcesLoader> getLoaders() {
@@ -2382,87 +2385,81 @@ public class Resources {
    }

    /**
     * Appends a loader to the end of the loader list. If the loader is already present in the
     * loader list, the list will not be modified.
     * Adds a loader to the list of loaders. If the loader is already present in the list, the list
     * will not be modified.
     *
     * @param loader the loader to add
     * @param loaders the loaders to add
     */
    public void addLoader(@NonNull ResourcesLoader loader) {
        synchronized (mLock) {
    public void addLoaders(@NonNull ResourcesLoader... loaders) {
        synchronized (mUpdateLock) {
            checkCallbacksRegistered();
            final List<ResourcesLoader> newLoaders =
                    new ArrayList<>(mResourcesImpl.getAssets().getLoaders());
            final ArraySet<ResourcesLoader> loaderSet = new ArraySet<>(newLoaders);

            final List<ResourcesLoader> loaders = new ArrayList<>(
                    mResourcesImpl.getAssets().getLoaders());
            if (loaders.contains(loader)) {
                return;
            for (int i = 0; i < loaders.length; i++) {
                final ResourcesLoader loader = loaders[i];
                if (!loaderSet.contains(loader)) {
                    newLoaders.add(loader);
                }

            loaders.add(loader);
            mCallbacks.onLoadersChanged(this, loaders);
            loader.registerOnProvidersChangedCallback(this, mCallbacks);
            }
    }

    /**
     * Removes a loader from the loaders. If the loader is not present in the loader list, the list
     * will not be modified.
     *
     * @param loader the loader to remove
     */
    public void removeLoader(@NonNull ResourcesLoader loader) {
        synchronized (mLock) {
            checkCallbacksRegistered();

            final List<ResourcesLoader> loaders = new ArrayList<>(
                    mResourcesImpl.getAssets().getLoaders());
            if (!loaders.remove(loader)) {
            if (loaderSet.size() == newLoaders.size()) {
                return;
            }

            mCallbacks.onLoadersChanged(this, loaders);
            loader.unregisterOnProvidersChangedCallback(this);
            mCallbacks.onLoadersChanged(this, newLoaders);
            for (int i = loaderSet.size(), n = newLoaders.size(); i < n; i++) {
                newLoaders.get(i).registerOnProvidersChangedCallback(this, mCallbacks);
            }
        }
    }

    /**
     * Sets the list of loaders.
     * Removes loaders from the list of loaders. If the loader is not present in the list, the list
     * will not be modified.
     *
     * @param loaders the new loaders
     * @param loaders the loaders to remove
     */
    public void setLoaders(@NonNull List<ResourcesLoader> loaders) {
        synchronized (mLock) {
    public void removeLoaders(@NonNull ResourcesLoader... loaders) {
        synchronized (mUpdateLock) {
            checkCallbacksRegistered();

            final ArraySet<ResourcesLoader> removedLoaders = new ArraySet<>(loaders);
            final List<ResourcesLoader> newLoaders = new ArrayList<>();
            final List<ResourcesLoader> oldLoaders = mResourcesImpl.getAssets().getLoaders();
            int index = 0;
            boolean modified = loaders.size() != oldLoaders.size();
            final ArraySet<ResourcesLoader> seenLoaders = new ArraySet<>();
            for (final ResourcesLoader loader : loaders) {
                if (!seenLoaders.add(loader)) {
                    throw new IllegalArgumentException("Loader " + loader + " present twice");
                }

                if (!modified && oldLoaders.get(index++) != loader) {
                    modified = true;
            for (int i = 0, n = oldLoaders.size(); i < n; i++) {
                final ResourcesLoader loader = oldLoaders.get(i);
                if (!removedLoaders.contains(loader)) {
                    newLoaders.add(loader);
                }
            }

            if (!modified) {
            if (oldLoaders.size() == newLoaders.size()) {
                return;
            }

            mCallbacks.onLoadersChanged(this, loaders);
            for (int i = 0, n = oldLoaders.size(); i < n; i++) {
                oldLoaders.get(i).unregisterOnProvidersChangedCallback(this);
            }
            for (ResourcesLoader newLoader : loaders) {
                newLoader.registerOnProvidersChangedCallback(this, mCallbacks);
            mCallbacks.onLoadersChanged(this, newLoaders);
            for (int i = 0; i < loaders.length; i++) {
                loaders[i].unregisterOnProvidersChangedCallback(this);
            }
        }
    }

    /** Removes all {@link ResourcesLoader ResourcesLoader(s)}. */
    /**
     * Removes all {@link ResourcesLoader ResourcesLoader(s)}.
     * @hide
     */
    @VisibleForTesting
    public void clearLoaders() {
        setLoaders(Collections.emptyList());
        synchronized (mUpdateLock) {
            checkCallbacksRegistered();
            final List<ResourcesLoader> newLoaders = Collections.emptyList();
            final List<ResourcesLoader> oldLoaders = mResourcesImpl.getAssets().getLoaders();
            mCallbacks.onLoadersChanged(this, newLoaders);
            for (ResourcesLoader loader : oldLoaders) {
                loader.unregisterOnProvidersChangedCallback(this);
            }
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ import java.util.List;
 * of {@link ResourcesProvider ResourcesProvider(s)} a loader contains propagates to all Resources
 * objects that use the loader.
 *
 * <p>Loaders retrieved with {@link Resources#getLoaders()} are listed in increasing precedence
 * order. A loader will override the resources and assets of loaders listed before itself.
 * <p>Loaders must be added to Resources objects in increasing precedence order. A loader will
 * override the resources and assets of loaders added before itself.
 *
 * <p>Providers retrieved with {@link #getProviders()} are listed in increasing precedence order. A
 * provider will override the resources and assets of providers listed before itself.
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class DirectoryAssetsProviderTest : ResourceLoaderTestBase() {
        testDir = context.filesDir.resolve("DirectoryAssetsProvider_${testName.methodName}")
        assetsProvider = DirectoryAssetsProvider(testDir)
        loader = ResourcesLoader()
        resources.addLoader(loader)
        resources.addLoaders(loader)
    }

    @After
+5 −5
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {

        val loader = ResourcesLoader()
        loader.providers = listOf(one, two)
        resources.addLoader(loader)
        resources.addLoaders(loader)

        assertOpenedAsset()
        inOrder(two.assetsProvider, one.assetsProvider).apply {
@@ -149,7 +149,7 @@ class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {
        val loader2 = ResourcesLoader()
        loader2.addProvider(two)

        resources.loaders = listOf(loader1, loader2)
        resources.addLoaders(loader1, loader2)

        assertOpenedAsset()
        inOrder(two.assetsProvider, one.assetsProvider).apply {
@@ -170,7 +170,7 @@ class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {
        val loader = ResourcesLoader()
        val one = ResourcesProvider.empty(assetsProvider1)
        val two = ResourcesProvider.empty(assetsProvider2)
        resources.addLoader(loader)
        resources.addLoaders(loader)
        loader.providers = listOf(one, two)

        assertOpenedAsset()
@@ -186,7 +186,7 @@ class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {
        val loader = ResourcesLoader()
        val one = ResourcesProvider.empty(assetsProvider1)
        val two = ResourcesProvider.empty(assetsProvider2)
        resources.addLoader(loader)
        resources.addLoaders(loader)
        loader.providers = listOf(one, two)

        assertOpenedAsset()
@@ -202,7 +202,7 @@ class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {
        val loader = ResourcesLoader()
        val one = ResourcesProvider.empty(assetsProvider1)
        val two = ResourcesProvider.empty(assetsProvider2)
        resources.addLoader(loader)
        resources.addLoaders(loader)
        loader.providers = listOf(one, two)

        assertOpenedAsset()
Loading