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

Commit b8478363 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix Amazon Prime Video sign in failure caused by...

Merge "Fix Amazon Prime Video sign in failure caused by register_resource_paths feature flag." into main
parents a9b3adea 500a2bb4
Loading
Loading
Loading
Loading
+62 −1
Original line number Diff line number Diff line
@@ -119,6 +119,17 @@ public class ResourcesManager {
    private final ArrayList<WeakReference<Resources>> mResourceReferences = new ArrayList<>();
    private final ReferenceQueue<Resources> mResourcesReferencesQueue = new ReferenceQueue<>();

    /**
     * A list of Resources references for all Resources instances created through Resources public
     * constructor, only system Resources created by the private constructor are excluded.
     * This addition is necessary due to certain Application Resources created by constructor
     * directly which are not managed by ResourcesManager, hence we require a comprehensive
     * collection of all Resources references to help with asset paths appending tasks when shared
     * libraries are registered.
     */
    private final ArrayList<WeakReference<Resources>> mAllResourceReferences = new ArrayList<>();
    private final ReferenceQueue<Resources> mAllResourceReferencesQueue = new ReferenceQueue<>();

    /**
     * The localeConfig of the app.
     */
@@ -1568,7 +1579,7 @@ public class ResourcesManager {
                }
            }

            redirectResourcesToNewImplLocked(updatedResourceKeys);
            redirectAllResourcesToNewImplLocked(updatedResourceKeys);
        }
    }

@@ -1707,6 +1718,43 @@ public class ResourcesManager {
        }
    }

    // Another redirect function which will loop through all Resources and reload ResourcesImpl
    // if it needs a shared library asset paths update.
    private void redirectAllResourcesToNewImplLocked(
            @NonNull final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys) {
        cleanupReferences(mAllResourceReferences, mAllResourceReferencesQueue);

        // Update any references to ResourcesImpl that require reloading.
        final int resourcesCount = mAllResourceReferences.size();
        for (int i = 0; i < resourcesCount; i++) {
            final WeakReference<Resources> ref = mAllResourceReferences.get(i);
            final Resources r = ref != null ? ref.get() : null;
            if (r != null) {
                final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
                if (key != null) {
                    final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
                    if (impl == null) {
                        throw new Resources.NotFoundException("failed to redirect ResourcesImpl");
                    }
                    r.setImpl(impl);
                } else {
                    // ResourcesKey is null which means the ResourcesImpl could belong to a
                    // Resources created by application through Resources constructor and was not
                    // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to
                    // have shared library asset paths appended if there are any.
                    if (r.getImpl() != null) {
                        final ResourcesImpl oldImpl = r.getImpl();
                        // ResourcesImpl constructor will help to append shared library asset paths.
                        final ResourcesImpl newImpl = new ResourcesImpl(oldImpl.getAssets(),
                                oldImpl.getMetrics(), oldImpl.getConfiguration(),
                                oldImpl.getDisplayAdjustments());
                        r.setImpl(newImpl);
                    }
                }
            }
        }
    }

    /**
     * Returns the LocaleConfig current set
     */
@@ -1827,4 +1875,17 @@ public class ResourcesManager {
    public @NonNull ArrayMap<String, SharedLibraryAssets> getSharedLibAssetsMap() {
        return new ArrayMap<>(mSharedLibAssetsMap);
    }

    /**
     * Add all resources references to the list which is designed to help to append shared library
     * asset paths. This is invoked in Resources constructor to include all Resources instances.
     */
    public void registerAllResourcesReference(@NonNull Resources resources) {
        if (android.content.res.Flags.registerResourcePaths()) {
            synchronized (mLock) {
                mAllResourceReferences.add(
                        new WeakReference<>(resources, mAllResourceReferencesQueue));
            }
        }
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -339,14 +339,17 @@ public class Resources {
    public Resources(@Nullable ClassLoader classLoader) {
        mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
        sResourcesHistory.add(this);
        ResourcesManager.getInstance().registerAllResourcesReference(this);
    }

    /**
     * Only for creating the System resources.
     * Only for creating the System resources. This is the only constructor that doesn't add
     * Resources itself to the ResourcesManager list of all Resources references.
     */
    @UnsupportedAppUsage
    private Resources() {
        this(null);
        mClassLoader = ClassLoader.getSystemClassLoader();
        sResourcesHistory.add(this);

        final DisplayMetrics metrics = new DisplayMetrics();
        metrics.setToDefaults();
+7 −1
Original line number Diff line number Diff line
@@ -228,6 +228,11 @@ public class ResourcesImpl {
        return mAssets;
    }

    @UnsupportedAppUsage
    public DisplayMetrics getMetrics() {
        return mMetrics;
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    DisplayMetrics getDisplayMetrics() {
        if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels
@@ -235,7 +240,8 @@ public class ResourcesImpl {
        return mMetrics;
    }

    Configuration getConfiguration() {
    @UnsupportedAppUsage
    public Configuration getConfiguration() {
        return mConfiguration;
    }

+38 −0
Original line number Diff line number Diff line
@@ -421,6 +421,44 @@ public class ResourcesManagerTest extends TestCase {
        ResourcesManager.setInstance(oriResourcesManager);
    }

    @Test
    @SmallTest
    @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
    public void testExistingResourcesCreatedByConstructorAfterResourcePathsRegistration()
            throws PackageManager.NameNotFoundException {
        // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
        // the static method can interact with this test smoothly.
        ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
        ResourcesManager.setInstance(mResourcesManager);

        // Create a Resources through constructor directly before register resources' paths.
        final DisplayMetrics metrics = new DisplayMetrics();
        metrics.setToDefaults();
        final Configuration config = new Configuration();
        config.setToDefaults();
        Resources resources = new Resources(new AssetManager(), metrics, config);
        assertNotNull(resources);

        ResourcesImpl oriResImpl = resources.getImpl();

        ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
        Resources.registerResourcePaths(TEST_LIB, appInfo);

        assertNotSame(oriResImpl, resources.getImpl());

        String[] resourcePaths = appInfo.getAllApkPaths();
        resourcePaths = removeDuplicates(resourcePaths);
        ApkAssets[] loadedAssets = resources.getAssets().getApkAssets();
        assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));

        // Package resources' paths should be cached in ResourcesManager.
        assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
                .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));

        // Revert the ResourcesManager instance back.
        ResourcesManager.setInstance(oriResourcesManager);
    }

    @Test
    @SmallTest
    @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)