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

Commit 52ca3aed authored by Michael Wright's avatar Michael Wright
Browse files

Connect follower displays to lead display.

Now that the lead display is defined in the DDC, we can use this
information to connect followers to their appropriate leaders.

Bug: 265793751

Test: atest DisplayPowerControllerTest
Test: atest DisplayPowerController2Test
Change-Id: I2ef55c44ba95d3cc71c7e81d7f2c45085a369d75
parent cfe5b618
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ import com.android.server.SystemService;
import com.android.server.UiThread;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.display.DisplayDeviceConfig.SensorData;
import com.android.server.display.layout.Layout;
import com.android.server.display.utils.SensorUtils;
import com.android.server.input.InputManagerInternal;
import com.android.server.wm.SurfaceAnimationThread;
@@ -1665,12 +1666,37 @@ public final class DisplayManagerService extends SystemService {
                return;
            }

            // TODO (b/265793751): Set this DPC as a follower of the default DPC if needed,
            // clear this DPC's followers if it's not a lead display
            final int leadDisplayId = display.getLeadDisplayIdLocked();
            updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);

            final String uniqueId = device.getUniqueId();
            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
            dpc.onDisplayChanged(hbmMetadata);
            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
        }
    }

    private void updateDisplayPowerControllerLeaderLocked(DisplayPowerControllerInterface dpc,
            int leadDisplayId) {
        if (dpc.getLeadDisplayId() == leadDisplayId) {
            // Lead display hasn't changed, nothing to do.
            return;
        }

        // If it has changed, then we need to unregister from the previous leader if there was one.
        final int prevLeaderId = dpc.getLeadDisplayId();
        if (prevLeaderId != Layout.NO_LEAD_DISPLAY) {
            final DisplayPowerControllerInterface prevLeader =
                    mDisplayPowerControllers.get(prevLeaderId);
            if (prevLeader != null) {
                prevLeader.removeDisplayBrightnessFollower(dpc);
            }
        }

        // And then, if it's following, register it with the new one.
        if (leadDisplayId != Layout.NO_LEAD_DISPLAY) {
            final DisplayPowerControllerInterface newLead =
                    mDisplayPowerControllers.get(leadDisplayId);
            newLead.addDisplayBrightnessFollower(dpc);
        }
    }

@@ -1734,9 +1760,13 @@ public final class DisplayManagerService extends SystemService {
                        + display.getDisplayIdLocked());
                return;
            }

            final int leadDisplayId = display.getLeadDisplayIdLocked();
            updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);

            final String uniqueId = device.getUniqueId();
            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
            dpc.onDisplayChanged(hbmMetadata);
            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
        }
    }

+22 −14
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.display;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -74,6 +75,7 @@ import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.layout.Layout;
import com.android.server.display.utils.SensorUtils;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
@@ -195,6 +197,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    // The ID of the LogicalDisplay tied to this DisplayPowerController.
    private final int mDisplayId;

    // The ID of the display which this display follows for brightness purposes.
    private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;

    // The unique ID of the primary display device currently tied to this logical display
    private String mUniqueDisplayId;

@@ -509,8 +514,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
    // is one lead display, the additional displays follow the brightness value of the lead display.
    @GuardedBy("mLock")
    private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray();
    private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
            new SparseArray<>();

    /**
     * Creates the display power controller.
@@ -721,6 +726,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        return mDisplayId;
    }

    @Override
    public int getLeadDisplayId() {
        return mLeadDisplayId;
    }

    @Override
    public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
        mHbmController.onAmbientLuxChange(ambientLux);
@@ -739,24 +749,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    @Override
    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
    public void addDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
            sendUpdatePowerStateLocked();
        }
        sendUpdatePowerState();
    }

    @Override
    public void clearDisplayBrightnessFollowers() {
        SparseArray<DisplayPowerControllerInterface> followers;
    public void removeDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            followers = mDisplayBrightnessFollowers.clone();
            mDisplayBrightnessFollowers.clear();
        }
        for (int i = 0; i < followers.size(); i++) {
            DisplayPowerControllerInterface follower = followers.valueAt(i);
            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
                    /* ambientLux= */ 0);
            mDisplayBrightnessFollowers.remove(follower.getDisplayId());
            mHandler.postAtTime(() -> follower.setBrightnessToFollow(
                    PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
                    /* ambientLux= */ 0), mClock.uptimeMillis());
        }
    }

@@ -851,7 +857,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
     * Make sure DisplayManagerService.mSyncRoot is held when this is called
     */
    @Override
    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
        mLeadDisplayId = leadDisplayId;
        final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        if (device == null) {
            Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
@@ -2701,6 +2708,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            pw.println();
            pw.println("Display Power Controller:");
            pw.println("  mDisplayId=" + mDisplayId);
            pw.println("  mLeadDisplayId=" + mLeadDisplayId);
            pw.println("  mLightSensor=" + mLightSensor);

            pw.println();
+18 −11
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.server.display.brightness.BrightnessUtils;
import com.android.server.display.brightness.DisplayBrightnessController;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.layout.Layout;
import com.android.server.display.state.DisplayStateController;
import com.android.server.display.utils.SensorUtils;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -179,6 +180,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    // The ID of the LogicalDisplay tied to this DisplayPowerController2.
    private final int mDisplayId;

    // The ID of the display which this display follows for brightness purposes.
    private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;

    // The unique ID of the primary display device currently tied to this logical display
    private String mUniqueDisplayId;

@@ -694,7 +698,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
     * Make sure DisplayManagerService.mSyncRoot lock is held when this is called
     */
    @Override
    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
        mLeadDisplayId = leadDisplayId;
        final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        if (device == null) {
            Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: "
@@ -2148,6 +2153,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        return mDisplayId;
    }

    @Override
    public int getLeadDisplayId() {
        return mLeadDisplayId;
    }

    @Override
    public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
        mHbmController.onAmbientLuxChange(ambientLux);
@@ -2218,21 +2228,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
            sendUpdatePowerStateLocked();
        }
        sendUpdatePowerState();
    }

    @Override
    public void clearDisplayBrightnessFollowers() {
        SparseArray<DisplayPowerControllerInterface> followers;
    public void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
        synchronized (mLock) {
            followers = mDisplayBrightnessFollowers.clone();
            mDisplayBrightnessFollowers.clear();
        }
        for (int i = 0; i < followers.size(); i++) {
            DisplayPowerControllerInterface follower = followers.valueAt(i);
            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
                    /* ambientLux= */ 0);
            mDisplayBrightnessFollowers.remove(follower.getDisplayId());
            mHandler.postAtTime(() -> follower.setBrightnessToFollow(
                    PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
                    /* ambientLux= */ 0), mClock.uptimeMillis());
        }
    }

@@ -2242,6 +2248,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
            pw.println();
            pw.println("Display Power Controller:");
            pw.println("  mDisplayId=" + mDisplayId);
            pw.println("  mLeadDisplayId=" + mLeadDisplayId);
            pw.println("  mLightSensor=" + mLightSensor);

            pw.println();
+24 −8
Original line number Diff line number Diff line
@@ -32,13 +32,18 @@ public interface DisplayPowerControllerInterface {

    /**
     * Notified when the display is changed.
     * We use this to apply any changes that might be needed
     * when displays get swapped on foldable devices.
     * We also pass the High brightness mode metadata like
     * remaining time and hbm events for the corresponding
     * physical display, to update the values correctly.
     *
     * We use this to apply any changes that might be needed when displays get swapped on foldable
     * devices, when layouts change, etc.
     *
     * Must be called while holding the SyncRoot lock.
     *
     * @param hbmInfo The high brightness mode metadata, like
     *                remaining time and hbm events, for the corresponding
     *                physical display, to make sure we stay within the safety margins.
     * @param leadDisplayId The display who is considered our "leader" for things like brightness.
     */
    void onDisplayChanged(HighBrightnessModeMetadata hbmInfo);
    void onDisplayChanged(HighBrightnessModeMetadata hbmInfo, int leadDisplayId);

    /**
     * Unregisters all listeners and interrupts all running threads; halting future work.
@@ -168,6 +173,16 @@ public interface DisplayPowerControllerInterface {
     */
    int getDisplayId();

    /**
     * Get the ID of the display that is the leader of this DPC.
     *
     * Note that this is different than the display associated with the DPC. The leader is another
     * display which we follow for things like brightness.
     *
     * Must be called while holding the SyncRoot lock.
     */
    int getLeadDisplayId();

    /**
     * Set the brightness to follow if this is an additional display in a set of concurrent
     * displays.
@@ -187,7 +202,8 @@ public interface DisplayPowerControllerInterface {
    void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower);

    /**
     * Clear all the additional displays following the brightness value of this display.
     * Removes the given display from the list of brightness followers.
     * @param follower The DPC to remove from the followers list
     */
    void clearDisplayBrightnessFollowers();
    void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
}
+1 −2
Original line number Diff line number Diff line
@@ -848,9 +848,8 @@ final class LogicalDisplay {
        }
    }

    public int getLeadDisplayLocked() {
    public int getLeadDisplayIdLocked() {
        return mLeadDisplayId;

    }

    public void dumpLocked(PrintWriter pw) {
Loading