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

Commit 609bf656 authored by Bryce Lee's avatar Bryce Lee
Browse files

Update DisplayAdjustments in Display from Resources.

Previously, a copy of DisplayAdjustments was provided during Display
construction. If the Display instance is held, the adjustments would
not update. However, the DisplayInfo would, leading to a mismatch.

This changelist adds a reference to the Resources, which can be
queried to provide the latest adjustments.

Fixes: 33430498
Test: manual from bug repro steps.
Test: make -j32 cts; cts-tradefed; run cts --module CtsAppTestCases --test android.app.cts.DisplayTest#testRotation

Change-Id: Ida2ed3990add885d06b011494af24b055343f3fa
parent a1d54802
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2916,7 +2916,7 @@ public final class ActivityThread {
            for (int id : dm.getDisplayIds()) {
                if (id != Display.DEFAULT_DISPLAY) {
                    Display display =
                            dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
                            dm.getCompatibleDisplay(id, appContext.getResources());
                    appContext = (ContextImpl) appContext.createDisplayContext(display);
                    break;
                }
+3 −10
Original line number Diff line number Diff line
@@ -2067,24 +2067,17 @@ class ContextImpl extends Context {

    @Override
    public Display getDisplay() {
        final DisplayAdjustments displayAdjustments = mResources.getDisplayAdjustments();
        if (mDisplay == null) {
            return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
                    displayAdjustments);
                    mResources);
        }

        if (!mDisplay.getDisplayAdjustments().equals(displayAdjustments)) {
            mDisplay = mResourcesManager.getAdjustedDisplay(mDisplay.getDisplayId(),
                    displayAdjustments);
        }
        return mDisplay;
    }

    @Override
    public void updateDisplay(int displayId) {
        final DisplayAdjustments displayAdjustments = mResources.getDisplayAdjustments();
        mDisplay = mResourcesManager.getAdjustedDisplay(displayId,
                displayAdjustments);
        mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources);
    }

    @Override
@@ -2202,7 +2195,7 @@ class ContextImpl extends Context {
                compatInfo,
                classLoader);
        context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
                context.mResources.getDisplayAdjustments());
                context.getResources());
        return context;
    }

+50 −8
Original line number Diff line number Diff line
@@ -104,9 +104,16 @@ public class ResourcesManager {
            new WeakHashMap<>();

    /**
     * A cache of DisplayId to DisplayAdjustments.
     * A cache of DisplayId, DisplayAdjustments to Display.
     */
    private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>> mDisplays =
    private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>>
            mAdjustedDisplays = new ArrayMap<>();

    /**
     * A cache of DisplayId, Resources to Display. These display adjustments associated with these
     * {@link Display}s will change as the resources change.
     */
    private final ArrayMap<Pair<Integer, Resources>, WeakReference<Display>> mResourceDisplays =
        new ArrayMap<>();

    public static ResourcesManager getInstance() {
@@ -201,19 +208,21 @@ public class ResourcesManager {

    /**
     * Returns an adjusted {@link Display} object based on the inputs or null if display isn't
     * available.
     * available. This method is only used within {@link ResourcesManager} to calculate display
     * metrics based on a set {@link DisplayAdjustments}. All other usages should instead call
     * {@link ResourcesManager#getAdjustedDisplay(int, Resources)}.
     *
     * @param displayId display Id.
     * @param displayAdjustments display adjustments.
     */
    public Display getAdjustedDisplay(final int displayId,
    private Display getAdjustedDisplay(final int displayId,
            @Nullable DisplayAdjustments displayAdjustments) {
        final DisplayAdjustments displayAdjustmentsCopy = (displayAdjustments != null)
                ? new DisplayAdjustments(displayAdjustments) : new DisplayAdjustments();
        final Pair<Integer, DisplayAdjustments> key =
                Pair.create(displayId, displayAdjustmentsCopy);
        synchronized (this) {
            WeakReference<Display> wd = mDisplays.get(key);
            WeakReference<Display> wd = mAdjustedDisplays.get(key);
            if (wd != null) {
                final Display display = wd.get();
                if (display != null) {
@@ -227,7 +236,37 @@ public class ResourcesManager {
            }
            final Display display = dm.getCompatibleDisplay(displayId, key.second);
            if (display != null) {
                mDisplays.put(key, new WeakReference<>(display));
                mAdjustedDisplays.put(key, new WeakReference<>(display));
            }
            return display;
        }
    }

    /**
     * Returns an adjusted {@link Display} object based on the inputs or null if display isn't
     * available.
     *
     * @param displayId display Id.
     * @param resources The {@link Resources} backing the display adjustments.
     */
    public Display getAdjustedDisplay(final int displayId, Resources resources) {
        final Pair<Integer, Resources> key = Pair.create(displayId, resources);
        synchronized (this) {
            WeakReference<Display> wd = mResourceDisplays.get(key);
            if (wd != null) {
                final Display display = wd.get();
                if (display != null) {
                    return display;
                }
            }
            final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
            if (dm == null) {
                // may be null early in system startup
                return null;
            }
            final Display display = dm.getCompatibleDisplay(displayId, resources);
            if (display != null) {
                mResourceDisplays.put(key, new WeakReference<>(display));
            }
            return display;
        }
@@ -316,6 +355,7 @@ public class ResourcesManager {
        final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj);
        final Configuration config = generateConfig(key, dm);
        final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj);

        if (DEBUG) {
            Slog.d(TAG, "- creating impl=" + impl + " with key: " + key);
        }
@@ -811,7 +851,9 @@ public class ResourcesManager {
            }
            int changes = mResConfiguration.updateFrom(config);
            // Things might have changed in display manager, so clear the cached displays.
            mDisplays.clear();
            mAdjustedDisplays.clear();
            mResourceDisplays.clear();

            DisplayMetrics defaultDisplayMetrics = getDisplayMetrics();

            if (compat != null && (mResCompatibilityInfo == null ||
+1 −2
Original line number Diff line number Diff line
@@ -339,8 +339,7 @@ public final class DisplayManager {
    private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
        Display display = mDisplays.get(displayId);
        if (display == null) {
            display = mGlobal.getCompatibleDisplay(displayId,
                    mContext.getDisplayAdjustments(displayId));
            display = mGlobal.getCompatibleDisplay(displayId, mContext.getResources());
            if (display != null) {
                mDisplays.put(displayId, display);
            }
+19 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.hardware.display;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.projection.MediaProjection;
import android.media.projection.IMediaProjection;
@@ -180,6 +181,24 @@ public final class DisplayManagerGlobal {
        return new Display(this, displayId, displayInfo, daj);
    }

    /**
     * Gets information about a logical display.
     *
     * The display metrics may be adjusted to provide compatibility
     * for legacy applications or limited screen areas.
     *
     * @param displayId The logical display id.
     * @param resources Resources providing compatibility info.
     * @return The display object, or null if there is no display with the given id.
     */
    public Display getCompatibleDisplay(int displayId, Resources resources) {
        DisplayInfo displayInfo = getDisplayInfo(displayId);
        if (displayInfo == null) {
            return null;
        }
        return new Display(this, displayId, displayInfo, resources);
    }

    /**
     * Gets information about a logical display without applying any compatibility metrics.
     *
Loading