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

Commit c55583af authored by Santos Cordon's avatar Santos Cordon Committed by Automerger Merge Worker
Browse files

Merge "Turn OFF any changing displays during device-state transitions" into sc-dev am: b4bed4d4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14036667

Change-Id: I264869a9fbc450203fd98fdb394c23ac771f0f6b
parents ce0fd355 b4bed4d4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -657,6 +657,12 @@
    <!-- Indicate the display area rect for foldable devices in folded state. -->
    <string name="config_foldedArea"></string>

    <!-- Indicates that the device supports having more than one internal display on at the same
         time. Only applicable to devices with more than one internal display. If this option is
         set to false, DisplayManager will make additional effort to ensure no more than 1 internal
         display is powered on at the same time. -->
    <bool name="config_supportsConcurrentInternalDisplays">true</bool>

    <!-- Desk dock behavior -->

    <!-- The number of degrees to rotate the display when the device is in a desk dock.
+1 −0
Original line number Diff line number Diff line
@@ -3800,6 +3800,7 @@
  <!-- For Foldables -->
  <java-symbol type="array" name="config_foldedDeviceStates" />
  <java-symbol type="string" name="config_foldedArea" />
  <java-symbol type="bool" name="config_supportsConcurrentInternalDisplays" />

  <java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
  <java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
+24 −6
Original line number Diff line number Diff line
@@ -431,8 +431,8 @@ public final class DisplayManagerService extends SystemService {
        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
        mUiHandler = UiThread.getHandler();
        mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
        mLogicalDisplayMapper = new LogicalDisplayMapper(mDisplayDeviceRepo,
                new LogicalDisplayListener());
        mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo,
                new LogicalDisplayListener(), mSyncRoot, mHandler);
        mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
        mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
        Resources resources = mContext.getResources();
@@ -1268,7 +1268,7 @@ public final class DisplayManagerService extends SystemService {

        DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
        if (dpc != null) {
            dpc.onDisplayChangedLocked();
            dpc.onDisplayChanged();
        }
    }

@@ -1304,12 +1304,23 @@ public final class DisplayManagerService extends SystemService {
        handleLogicalDisplayChangedLocked(display);
    }

    private void handleLogicalDisplayDeviceStateTransitionLocked(@NonNull LogicalDisplay display) {
        final int displayId = display.getDisplayIdLocked();
        final DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
        if (dpc != null) {
            dpc.onDeviceStateTransition();
        }
    }

    private Runnable updateDisplayStateLocked(DisplayDevice device) {
        // Blank or unblank the display immediately to match the state requested
        // by the display power controller (if known).
        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
            if (display == null) {
                return null;
            }
            final int displayId = display.getDisplayIdLocked();
            final int state = mDisplayStates.get(displayId);

@@ -1453,9 +1464,12 @@ public final class DisplayManagerService extends SystemService {
        clearViewportsLocked();

        // Configure each display device.
        mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
        mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> {
            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
            if (device != null) {
                configureDisplayLocked(t, device);
                device.performTraversalLocked(t);
            }
        });

        // Tell the input system about these new viewports.
@@ -2159,6 +2173,10 @@ public final class DisplayManagerService extends SystemService {
                case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED:
                    handleLogicalDisplayFrameRateOverridesChangedLocked(display);
                    break;

                case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION:
                    handleLogicalDisplayDeviceStateTransitionLocked(display);
                    break;
            }
        }

+13 −3
Original line number Diff line number Diff line
@@ -780,15 +780,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
     * when displays get swapped on foldable devices.  For example, different brightness properties
     * of each display need to be properly reflected in AutomaticBrightnessController.
     */
    public void onDisplayChangedLocked() {
    public void onDisplayChanged() {
        // TODO: b/175821789 - Support high brightness on multiple (folding) displays

        mUniqueDisplayId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
        mDisplayDeviceConfig = mLogicalDisplay.getPrimaryDisplayDeviceLocked()
                .getDisplayDeviceConfig();
        loadAmbientLightSensor();
    }

    /**
     * Called when the displays are preparing to transition from one device state to another.
     * This process involves turning off some displays so we need updatePowerState() to run and
     * calculate the new state.
     */
    public void onDeviceStateTransition() {
        sendUpdatePowerState();
    }

    /**
     * Unregisters all listeners and interrupts all running threads; halting future work.
     *
@@ -1024,7 +1032,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mIgnoreProximityUntilChanged = false;
        }

        if (!mLogicalDisplay.isEnabled() || mScreenOffBecauseOfProximity) {
        if (!mLogicalDisplay.isEnabled()
                || mLogicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
                || mScreenOffBecauseOfProximity) {
            state = Display.STATE_OFF;
        }

+48 −13
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.display;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Point;
@@ -65,6 +66,33 @@ import java.util.Objects;
final class LogicalDisplay {
    private static final String TAG = "LogicalDisplay";

    /**
     * Phase indicating the logical display's existence is hidden from the rest of the framework.
     * This can happen if the current layout has specifically requested to keep this display
     * disabled.
     */
    static final int DISPLAY_PHASE_DISABLED = -1;

    /**
     * Phase indicating that the logical display is going through a layout transition.
     * When in this phase, other systems can choose to special case power-state handling of a
     * display that might be in a transition.
     */
    static final int DISPLAY_PHASE_LAYOUT_TRANSITION = 0;

    /**
     * The display is exposed to the rest of the system and its power state is determined by a
     * power-request from PowerManager.
     */
    static final int DISPLAY_PHASE_ENABLED = 1;

    @IntDef(prefix = {"DISPLAY_PHASE" }, value = {
        DISPLAY_PHASE_DISABLED,
        DISPLAY_PHASE_LAYOUT_TRANSITION,
        DISPLAY_PHASE_ENABLED
    })
    @interface DisplayPhase {}

    // The layer stack we use when the display has been blanked to prevent any
    // of its content from appearing.
    private static final int BLANK_LAYER_STACK = -1;
@@ -129,10 +157,12 @@ final class LogicalDisplay {
    private final Rect mTempDisplayRect = new Rect();

    /**
     * Indicates that the Logical display is enabled (default). See {@link #setEnabled} for
     * more information.
     * Indicates the current phase of the display. Generally, phases supersede any
     * requests from PowerManager in DPC's calculation for the display state. Only when the
     * phase is ENABLED does PowerManager's request for the display take effect.
     */
    private boolean mIsEnabled = true;
    @DisplayPhase
    private int mPhase = DISPLAY_PHASE_ENABLED;

    /**
     * The UID mappings for refresh rate override
@@ -721,27 +751,32 @@ final class LogicalDisplay {
        return old;
    }

    public void setPhase(@DisplayPhase int phase) {
        mPhase = phase;
    }

    /**
     * Sets the LogicalDisplay to be enabled or disabled. If the display is not enabled,
     * the system will always set the display to power off, regardless of the global state of the
     * device.
     * TODO: b/170498827 - Remove when updateDisplayStateLocked is updated.
     * Returns the currently set phase for this LogicalDisplay. Phases are used when transitioning
     * from one device state to another. {@see LogicalDisplayMapper}.
     */
    public void setEnabled(boolean isEnabled) {
        mIsEnabled = isEnabled;
    @DisplayPhase
    public int getPhase() {
        return mPhase;
    }

    /**
     * @return {@code true} iff the LogicalDisplay is enabled or {@code false}
     * if disabled indicating that the display has been forced to be OFF.
     * @return {@code true} if the LogicalDisplay is enabled or {@code false}
     * if disabled indicating that the display should be hidden from the rest of the apps and
     * framework.
     */
    public boolean isEnabled() {
        return mIsEnabled;
        // DISPLAY_PHASE_LAYOUT_TRANSITION is still considered an 'enabled' phase.
        return mPhase == DISPLAY_PHASE_ENABLED || mPhase == DISPLAY_PHASE_LAYOUT_TRANSITION;
    }

    public void dumpLocked(PrintWriter pw) {
        pw.println("mDisplayId=" + mDisplayId);
        pw.println("mIsEnabled=" + mIsEnabled);
        pw.println("mPhase=" + mPhase);
        pw.println("mLayerStack=" + mLayerStack);
        pw.println("mHasContent=" + mHasContent);
        pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
Loading