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

Commit e03b9669 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Add support to override display adjustments by token

This is the bridge to link customized adjustments to an activity
or window token.

The DisplayAdjustments in ResourcesImpl is associated with
ResourcesKey. The new usage requires to associate with token.
That is why the new field is added in Resources.

Bug: 147213487
Test: atest ResourcesManagerTest#testOverrideDisplayAdjustments
Change-Id: Ie79c331654d564aee7af8c6ce98a4c72dd3132b1
parent ca70b013
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;

/** @hide */
@@ -1296,6 +1297,35 @@ public class ResourcesManager {
        }
    }

    /**
     * Overrides the display adjustments of all resources which are associated with the given token.
     *
     * @param token The token that owns the resources.
     * @param override The operation to override the existing display adjustments. If it is null,
     *                 the override adjustments will be cleared.
     * @return {@code true} if the override takes effect.
     */
    public boolean overrideTokenDisplayAdjustments(IBinder token,
            @Nullable Consumer<DisplayAdjustments> override) {
        boolean handled = false;
        synchronized (this) {
            final ActivityResources tokenResources = mActivityResourceReferences.get(token);
            if (tokenResources == null) {
                return false;
            }
            final ArrayList<WeakReference<Resources>> resourcesRefs =
                    tokenResources.activityResources;
            for (int i = resourcesRefs.size() - 1; i >= 0; i--) {
                final Resources res = resourcesRefs.get(i).get();
                if (res != null) {
                    res.overrideDisplayAdjustments(override);
                    handled = true;
                }
            }
        }
        return handled;
    }

    private class UpdateHandler implements Resources.UpdateCallbacks {

        /**
+35 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * Class for accessing an application's resources.  This sits on top of the
@@ -140,6 +141,9 @@ public class Resources {
    @UnsupportedAppUsage
    private DrawableInflater mDrawableInflater;

    /** Used to override the returned adjustments of {@link #getDisplayAdjustments}. */
    private DisplayAdjustments mOverrideDisplayAdjustments;

    /** Lock object used to protect access to {@link #mTmpValue}. */
    private final Object mTmpValueLock = new Object();

@@ -2055,9 +2059,40 @@ public class Resources {
    /** @hide */
    @UnsupportedAppUsage
    public DisplayAdjustments getDisplayAdjustments() {
        final DisplayAdjustments overrideDisplayAdjustments = mOverrideDisplayAdjustments;
        if (overrideDisplayAdjustments != null) {
            return overrideDisplayAdjustments;
        }
        return mResourcesImpl.getDisplayAdjustments();
    }

    /**
     * Customize the display adjustments based on the current one in {@link #mResourcesImpl}, in
     * order to isolate the effect with other instances of {@link Resource} that may share the same
     * instance of {@link ResourcesImpl}.
     *
     * @param override The operation to override the existing display adjustments. If it is null,
     *                 the override adjustments will be cleared.
     * @hide
     */
    public void overrideDisplayAdjustments(@Nullable Consumer<DisplayAdjustments> override) {
        if (override != null) {
            mOverrideDisplayAdjustments = new DisplayAdjustments(
                    mResourcesImpl.getDisplayAdjustments());
            override.accept(mOverrideDisplayAdjustments);
        } else {
            mOverrideDisplayAdjustments = null;
        }
    }

    /**
     * Return {@code true} if the override display adjustments have been set.
     * @hide
     */
    public boolean hasOverrideDisplayAdjustments() {
        return mOverrideDisplayAdjustments != null;
    }

    /**
     * Return the current configuration that is in effect for this resource 
     * object.  The returned object should be treated as read-only.
+31 −0
Original line number Diff line number Diff line
@@ -259,4 +259,35 @@ public class ResourcesManagerTest extends TestCase {
        expectedConfig2.orientation = Configuration.ORIENTATION_LANDSCAPE;
        assertEquals(expectedConfig2, resources2.getConfiguration());
    }

    @SmallTest
    public void testOverrideDisplayAdjustments() {
        final int originalOverrideDensity = 200;
        final int overrideDisplayDensity = 400;
        final Binder token = new Binder();
        final Configuration overrideConfig = new Configuration();
        overrideConfig.densityDpi = originalOverrideDensity;
        final Resources resources = mResourcesManager.createBaseTokenResources(
                token, APP_ONE_RES_DIR, null /* splitResDirs */, null /* overlayDirs */,
                null /* libDirs */, Display.DEFAULT_DISPLAY, overrideConfig,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* classLoader */,
                null /* loaders */);

        // Update the override.
        boolean handled = mResourcesManager.overrideTokenDisplayAdjustments(token,
                adjustments -> adjustments.getConfiguration().densityDpi = overrideDisplayDensity);

        assertTrue(handled);
        assertTrue(resources.hasOverrideDisplayAdjustments());
        assertEquals(overrideDisplayDensity,
                resources.getDisplayAdjustments().getConfiguration().densityDpi);

        // Clear the override.
        handled = mResourcesManager.overrideTokenDisplayAdjustments(token, null /* override */);

        assertTrue(handled);
        assertFalse(resources.hasOverrideDisplayAdjustments());
        assertEquals(originalOverrideDensity,
                resources.getDisplayAdjustments().getConfiguration().densityDpi);
    }
}