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

Commit 7f3b118a authored by Oleg Blinnikov's avatar Oleg Blinnikov Committed by Android (Google) Code Review
Browse files

Merge "Display Enable power ON" into main

parents b4230169 b5252f70
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -833,6 +833,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub
        return sService;
    }

    /**
     * Override the {@link IBatteryStats} service, for testing.
     */
    @VisibleForTesting
    public static void overrideService(IBatteryStats service) {
        sService = service;
    }

    @Override
    public int getServiceType() {
        return ServiceType.BATTERY_STATS;
+5 −0
Original line number Diff line number Diff line
@@ -2301,6 +2301,11 @@ public final class DisplayManagerService extends SystemService {
        updateLogicalDisplayState(display);

        mExternalDisplayPolicy.handleLogicalDisplayAddedLocked(display);

        if (mFlags.isApplyDisplayChangedDuringDisplayAddedEnabled()) {
            applyDisplayChangedLocked(display);
        }

        if (mDisplayTopologyCoordinator != null) {
            mDisplayTopologyCoordinator.onDisplayAdded(display.getDisplayInfoLocked());
        }
+13 −0
Original line number Diff line number Diff line
@@ -222,6 +222,11 @@ public class DisplayManagerFlags {
            Flags::enableWaitingConfirmationBeforeMirroring
    );

    private final FlagState mEnableApplyDisplayChangedDuringDisplayAdded = new FlagState(
            Flags.FLAG_ENABLE_APPLY_DISPLAY_CHANGED_DURING_DISPLAY_ADDED,
            Flags::enableApplyDisplayChangedDuringDisplayAdded
    );

    private final FlagState mEnableBatteryStatsForAllDisplays = new FlagState(
            Flags.FLAG_ENABLE_BATTERY_STATS_FOR_ALL_DISPLAYS,
            Flags::enableBatteryStatsForAllDisplays
@@ -465,6 +470,13 @@ public class DisplayManagerFlags {
        return mEnableBatteryStatsForAllDisplays.isEnabled();
    }

    /**
      * @return {@code true} if need to apply display changes during display added event.
      */
    public boolean isApplyDisplayChangedDuringDisplayAddedEnabled() {
        return mEnableApplyDisplayChangedDuringDisplayAdded.isEnabled();
    }

    /**
     * @return {@code true} if autobrightness is to be blocked when stylus is being used
     */
@@ -526,6 +538,7 @@ public class DisplayManagerFlags {
        pw.println(" " + mIdleScreenConfigInSubscribingLightSensor);
        pw.println(" " + mEnableWaitingConfirmationBeforeMirroring);
        pw.println(" " + mEnableBatteryStatsForAllDisplays);
        pw.println(" " + mEnableApplyDisplayChangedDuringDisplayAdded);
        pw.println(" " + mBlockAutobrightnessChangesOnStylusUsage);
        pw.println(" " + mIsUserRefreshRateForExternalDisplayEnabled);
    }
+11 −0
Original line number Diff line number Diff line
@@ -385,6 +385,17 @@ flag {
    is_fixed_read_only: true
}

flag {
    name: "enable_apply_display_changed_during_display_added"
    namespace: "display_manager"
    description: "Apply display changes after display added"
    bug: "368131655"
    is_fixed_read_only: true
    metadata {
      purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "block_autobrightness_changes_on_stylus_usage"
    namespace: "display_manager"
+126 −4
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.test.mock.MockContentResolver;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Spline;
import android.view.ContentRecordingSession;
@@ -138,11 +139,14 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.internal.util.test.LocalServiceKeeperRule;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.am.BatteryStatsService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.display.DisplayManagerService.DeviceStateListener;
import com.android.server.display.DisplayManagerService.SyncRoot;
@@ -153,6 +157,7 @@ import com.android.server.display.layout.Layout;
import com.android.server.display.notifications.DisplayNotificationManager;
import com.android.server.input.InputManagerInternal;
import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.sensors.SensorManagerInternal;
import com.android.server.wm.WindowManagerInternal;

@@ -376,6 +381,10 @@ public class DisplayManagerServiceTest {
    @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
    @Mock DisplayManagerFlags mMockFlags;

    @Mock WindowManagerPolicy mMockedWindowManagerPolicy;

    @Mock IBatteryStats mMockedBatteryStats;

    @Rule
    public final ExtendedMockitoRule mExtendedMockitoRule =
            new ExtendedMockitoRule.Builder(this)
@@ -2759,6 +2768,78 @@ public class DisplayManagerServiceTest {
                EVENT_DISPLAY_CONNECTED, EVENT_DISPLAY_ADDED).inOrder();
    }

    @Test
    public void testConnectExternalDisplay_withDisplayManagement_allowsEnableAndDisableDisplay() {
        when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true);
        when(mMockFlags.isApplyDisplayChangedDuringDisplayAddedEnabled()).thenReturn(true);
        manageDisplaysPermission(/* granted= */ true);
        LocalServices.addService(WindowManagerPolicy.class, mMockedWindowManagerPolicy);
        BatteryStatsService.overrideService(mMockedBatteryStats);
        DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
        DisplayManagerInternal localService = displayManager.new LocalService();
        DisplayManagerService.BinderService bs = displayManager.new BinderService();
        LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper();
        FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
        bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS);
        localService.registerDisplayGroupListener(callback);

        // Create default display device
        callback.expectsEvent(EVENT_DISPLAY_ADDED);
        FakeDisplayDevice defaultDisplayDevice =
                createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL);
        callback.waitForExpectedEvent();
        LogicalDisplay defaultDisplay =
                logicalDisplayMapper.getDisplayLocked(defaultDisplayDevice, false);
        callback.clear();

        // Create external display device
        callback.expectsEvent(EVENT_DISPLAY_ADDED);
        FakeDisplayDevice displayDevice =
                createFakeDisplayDevice(displayManager, new float[]{60f}, new float[]{60f},
                        Display.TYPE_EXTERNAL, callback);
        callback.waitForExpectedEvent();
        LogicalDisplay display =
                logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true);
        assertThat(display.isEnabledLocked()).isTrue();
        callback.clear();

        callback.expectsEvent(FakeDisplayDevice.COMMITTED_DISPLAY_STATE_CHANGED);
        initDisplayPowerController(localService);
        // Initial power request, should have happened from PowerManagerService.
        localService.requestPowerState(defaultDisplay.getDisplayInfoLocked().displayGroupId,
                new DisplayManagerInternal.DisplayPowerRequest(),
                /*waitForNegativeProximity=*/ false);
        localService.requestPowerState(display.getDisplayInfoLocked().displayGroupId,
                new DisplayManagerInternal.DisplayPowerRequest(),
                /*waitForNegativeProximity=*/ false);
        displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
        callback.waitForExpectedEvent();

        assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                .isEqualTo(Display.STATE_OFF);
        assertThat(display.isEnabledLocked()).isFalse();
        assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_CONNECTED,
                EVENT_DISPLAY_REMOVED).inOrder();

        int displayId = display.getDisplayIdLocked();
        boolean enabled = display.isEnabledLocked();
        assertThat(enabled).isFalse();

        for (int i = 0; i < 9; i++) {
            callback.expectsEvent(FakeDisplayDevice.COMMITTED_DISPLAY_STATE_CHANGED);
            enabled = !enabled;
            Slog.d("DisplayManagerServiceTest", "enabled=" + enabled);
            displayManager.enableConnectedDisplay(displayId, enabled);
            callback.waitForExpectedEvent();
            assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                    .isEqualTo(enabled ? Display.STATE_ON : Display.STATE_OFF);
            assertThat(defaultDisplayDevice.getDisplayDeviceInfoLocked().committedState)
                    .isEqualTo(Display.STATE_ON);
        }
        callback.expectsEvent(FakeDisplayDevice.COMMITTED_DISPLAY_STATE_CHANGED);
        callback.waitForNonExpectedEvent();
    }

    @Test
    public void testConnectInternalDisplay_withDisplayManagement_shouldConnectAndAddDisplay() {
        when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true);
@@ -2795,7 +2876,7 @@ public class DisplayManagerServiceTest {
        displayManager.setDisplayState(display.getDisplayIdLocked(), Display.STATE_ON);

        assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                .isEqualTo(Display.STATE_ON);
                .isEqualTo(Display.STATE_UNKNOWN);

        assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
                Display.STATE_OFF)).isTrue();
@@ -2828,7 +2909,7 @@ public class DisplayManagerServiceTest {
        var displayId = display.getDisplayIdLocked();

        assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                .isEqualTo(Display.STATE_ON);
                .isEqualTo(Display.STATE_UNKNOWN);

        assertThrows(SecurityException.class,
                () -> bs.requestDisplayPower(displayId, Display.STATE_UNKNOWN));
@@ -3786,7 +3867,16 @@ public class DisplayManagerServiceTest {
                                                      float[] refreshRates,
                                                      float[] vsyncRates,
                                                      int displayType) {
        return createFakeDisplayDevice(displayManager, refreshRates, vsyncRates, displayType, null);
    }

    private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager,
                                                      float[] refreshRates,
                                                      float[] vsyncRates,
                                                      int displayType,
                                                      FakeDisplayManagerCallback callback) {
        FakeDisplayDevice displayDevice = new FakeDisplayDevice();
        displayDevice.setCallback(callback);
        DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
        int width = 100;
        int height = 200;
@@ -3796,6 +3886,7 @@ public class DisplayManagerServiceTest {
                    new Display.Mode(i + 1, width, height, refreshRates[i], vsyncRates[i],
                            new float[0], new int[0]);
        }
        displayDeviceInfo.name = "" + displayType;
        displayDeviceInfo.modeId = 1;
        displayDeviceInfo.type = displayType;
        displayDeviceInfo.renderFrameRate = displayDeviceInfo.supportedModes[0].getRefreshRate();
@@ -3903,6 +3994,19 @@ public class DisplayManagerServiceTest {
            }
        }

        void waitForNonExpectedEvent() {
            waitForNonExpectedEvent(Duration.ofSeconds(1));
        }

        void waitForNonExpectedEvent(Duration timeout) {
            try {
                assertWithMessage("Non Expected '" + mExpectedEvent + "'")
                        .that(mLatch.await(timeout.toMillis(), TimeUnit.MILLISECONDS)).isFalse();
            } catch (InterruptedException ex) {
                throw new AssertionError("Waiting for expected event interrupted", ex);
            }
        }

        private void eventSeen(String event) {
            if (event.equals(mExpectedEvent)) {
                mLatch.countDown();
@@ -3973,8 +4077,10 @@ public class DisplayManagerServiceTest {
    }

    private class FakeDisplayDevice extends DisplayDevice {
        static final String COMMITTED_DISPLAY_STATE_CHANGED = "requestDisplayStateLocked";
        private DisplayDeviceInfo mDisplayDeviceInfo;
        private Display.Mode mPreferredMode = new Display.Mode.Builder().build();
        private FakeDisplayManagerCallback mCallback;

        FakeDisplayDevice() {
            super(mMockDisplayAdapter, /* displayToken= */ null, /* uniqueId= */ "", mContext);
@@ -3982,7 +4088,7 @@ public class DisplayManagerServiceTest {

        public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
            mDisplayDeviceInfo = displayDeviceInfo;
            mDisplayDeviceInfo.committedState = Display.STATE_ON;
            mDisplayDeviceInfo.committedState = Display.STATE_UNKNOWN;
        }

        @Override
@@ -4019,7 +4125,23 @@ public class DisplayManagerServiceTest {
                final float brightnessState,
                final float sdrBrightnessState,
                @Nullable DisplayOffloadSessionImpl displayOffloadSession) {
            return () -> mDisplayDeviceInfo.committedState = state;
            return () -> {
                Slog.d("FakeDisplayDevice", mDisplayDeviceInfo.name
                        + " new state=" + state);
                if (state != mDisplayDeviceInfo.committedState) {
                    Slog.d("FakeDisplayDevice", mDisplayDeviceInfo.name
                            + " mDisplayDeviceInfo.committedState="
                            + mDisplayDeviceInfo.committedState + " set to " + state);
                    mDisplayDeviceInfo.committedState = state;
                    if (mCallback != null) {
                        mCallback.eventSeen(COMMITTED_DISPLAY_STATE_CHANGED);
                    }
                }
            };
        }

        void setCallback(FakeDisplayManagerCallback callback) {
            this.mCallback = callback;
        }
    }
}