diff options
3 files changed, 56 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/display/ExternalDisplayPolicy.java b/services/core/java/com/android/server/display/ExternalDisplayPolicy.java index ab7c503bcb83..a12d2481330b 100644 --- a/services/core/java/com/android/server/display/ExternalDisplayPolicy.java +++ b/services/core/java/com/android/server/display/ExternalDisplayPolicy.java @@ -42,6 +42,9 @@ import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.notifications.DisplayNotificationManager; import com.android.server.display.utils.DebugUtils; +import java.util.HashSet; +import java.util.Set; + /** * Listens for Skin thermal sensor events, disables external displays if thermal status becomes * equal or above {@link android.os.Temperature#THROTTLING_CRITICAL}, enables external displays if @@ -106,6 +109,10 @@ class ExternalDisplayPolicy { private final ExternalDisplayStatsService mExternalDisplayStatsService; @ThrottlingStatus private volatile int mStatus = THROTTLING_NONE; + //@GuardedBy("mSyncRoot") + private boolean mIsBootCompleted; + //@GuardedBy("mSyncRoot") + private final Set<Integer> mDisplayIdsWaitingForBootCompletion = new HashSet<>(); ExternalDisplayPolicy(@NonNull final Injector injector) { mInjector = injector; @@ -121,6 +128,17 @@ class ExternalDisplayPolicy { * Starts listening for temperature changes. */ void onBootCompleted() { + synchronized (mSyncRoot) { + mIsBootCompleted = true; + for (var displayId : mDisplayIdsWaitingForBootCompletion) { + var logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId); + if (logicalDisplay != null) { + handleExternalDisplayConnectedLocked(logicalDisplay); + } + } + mDisplayIdsWaitingForBootCompletion.clear(); + } + if (!mFlags.isConnectedDisplayManagementEnabled()) { if (DEBUG) { Slog.d(TAG, "External display management is not enabled on your device:" @@ -189,6 +207,11 @@ class ExternalDisplayPolicy { return; } + if (!mIsBootCompleted) { + mDisplayIdsWaitingForBootCompletion.add(logicalDisplay.getDisplayIdLocked()); + return; + } + mExternalDisplayStatsService.onDisplayConnected(logicalDisplay); if ((Build.IS_ENG || Build.IS_USERDEBUG) @@ -227,7 +250,12 @@ class ExternalDisplayPolicy { return; } - mExternalDisplayStatsService.onDisplayDisconnected(logicalDisplay.getDisplayIdLocked()); + var displayId = logicalDisplay.getDisplayIdLocked(); + if (mDisplayIdsWaitingForBootCompletion.remove(displayId)) { + return; + } + + mExternalDisplayStatsService.onDisplayDisconnected(displayId); } /** diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index b142334db9e9..18f03113c01c 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -2408,6 +2408,7 @@ public class DisplayManagerServiceTest { when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true); manageDisplaysPermission(/* granted= */ true); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); + displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); DisplayManagerInternal localService = displayManager.new LocalService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); @@ -2440,6 +2441,7 @@ public class DisplayManagerServiceTest { .when(() -> SystemProperties.getBoolean(ENABLE_ON_CONNECT, false)); manageDisplaysPermission(/* granted= */ true); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); + displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); DisplayManagerInternal localService = displayManager.new LocalService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); @@ -2487,6 +2489,7 @@ public class DisplayManagerServiceTest { when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true); manageDisplaysPermission(/* granted= */ true); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); + displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); @@ -2652,6 +2655,7 @@ public class DisplayManagerServiceTest { when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true); manageDisplaysPermission(/* granted= */ true); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); + displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); DisplayManagerService.BinderService bs = displayManager.new BinderService(); DisplayManagerInternal localService = displayManager.new LocalService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); @@ -2699,6 +2703,7 @@ public class DisplayManagerServiceTest { when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true); manageDisplaysPermission(/* granted= */ true); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); + displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); diff --git a/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java b/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java index 1529a087c284..1a71e77a3b1b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java @@ -228,13 +228,27 @@ public class ExternalDisplayPolicyTest { @Test public void testOnExternalDisplayAvailable() { - when(mMockedLogicalDisplay.isEnabledLocked()).thenReturn(false); + mExternalDisplayPolicy.handleExternalDisplayConnectedLocked(mMockedLogicalDisplay); + assertNotAskedToEnableDisplay(); + verify(mMockedExternalDisplayStatsService, never()).onDisplayConnected(any()); + + mExternalDisplayPolicy.onBootCompleted(); assertAskedToEnableDisplay(); verify(mMockedExternalDisplayStatsService).onDisplayConnected(eq(mMockedLogicalDisplay)); } @Test + public void testOnExternalDisplayUnpluggedBeforeBootCompletes() { + mExternalDisplayPolicy.handleExternalDisplayConnectedLocked(mMockedLogicalDisplay); + mExternalDisplayPolicy.handleLogicalDisplayDisconnectedLocked(mMockedLogicalDisplay); + mExternalDisplayPolicy.onBootCompleted(); + assertNotAskedToEnableDisplay(); + verify(mMockedExternalDisplayStatsService, never()).onDisplayConnected(any()); + verify(mMockedExternalDisplayStatsService, never()).onDisplayDisconnected(anyInt()); + } + + @Test public void testOnExternalDisplayAvailable_criticalThermalCondition() throws RemoteException { // Disallow external displays due to thermals. @@ -303,8 +317,14 @@ public class ExternalDisplayPolicyTest { mDisplayEventCaptor.capture()); assertThat(mLogicalDisplayCaptor.getValue()).isEqualTo(mMockedLogicalDisplay); assertThat(mDisplayEventCaptor.getValue()).isEqualTo(EVENT_DISPLAY_CONNECTED); + verify(mMockedLogicalDisplay).setEnabledLocked(false); clearInvocations(mMockedLogicalDisplayMapper); - when(mMockedLogicalDisplay.isEnabledLocked()).thenReturn(true); + clearInvocations(mMockedLogicalDisplay); + } + + private void assertNotAskedToEnableDisplay() { + verify(mMockedInjector, never()).sendExternalDisplayEventLocked(any(), anyInt()); + verify(mMockedLogicalDisplay, never()).setEnabledLocked(anyBoolean()); } private void assertIsExternalDisplayAllowed(final boolean enabled) { |