summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Orhan Uysal <uysalorhan@google.com> 2023-11-01 11:56:19 +0000
committer Orhan Uysal <uysalorhan@google.com> 2023-11-02 19:33:52 +0000
commitf55a43e060b64979bddc69cc8aa359542d0811db (patch)
treeb93a1107bde14f67035329f8c69596979342b8ae
parent6a482df3b9574573593e9435b899335668ee1b3e (diff)
Create sysprop to disable connected display dialog.
Add a system property to enable an external display on connection instead of disabling it. This will cause the UI dialog to not show up when an external display is connected. Test: Manual Test: atest DisplayManagerServiceTest Bug: 306178462 Change-Id: I06187462287566a9f4e5a1296b511577014d843f
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java13
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java47
2 files changed, 58 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e475fe63746d..ac3ae3107c65 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -102,6 +102,7 @@ import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
@@ -239,6 +240,10 @@ public final class DisplayManagerService extends SystemService {
private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
+
+ @VisibleForTesting
+ static final String ENABLE_ON_CONNECT =
+ "persist.sys.display.enable_on_connect.external";
private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
// This value needs to be in sync with the threshold
// in RefreshRateConfigs::getFrameRateDivisor.
@@ -1942,10 +1947,14 @@ public final class DisplayManagerService extends SystemService {
}
setupLogicalDisplay(display);
-
// TODO(b/292196201) Remove when the display can be disabled before DPC is created.
if (display.getDisplayInfoLocked().type == Display.TYPE_EXTERNAL) {
- display.setEnabledLocked(false);
+ if ((Build.IS_ENG || Build.IS_USERDEBUG)
+ && SystemProperties.getBoolean(ENABLE_ON_CONNECT, false)) {
+ Slog.w(TAG, "External display is enabled by default, bypassing user consent.");
+ } else {
+ display.setEnabledLocked(false);
+ }
}
sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_CONNECTED);
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 163d248fa317..c7b1abf646f0 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -28,6 +28,8 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESE
import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.server.display.DisplayManagerService.ENABLE_ON_CONNECT;
import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX;
import static com.google.common.truth.Truth.assertThat;
@@ -90,12 +92,14 @@ import android.hardware.display.VirtualDisplayConfig;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.ContentRecordingSession;
import android.view.Display;
@@ -113,6 +117,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
@@ -130,6 +135,7 @@ import com.google.common.truth.Expect;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -141,6 +147,8 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
import java.time.Duration;
import java.util.ArrayList;
@@ -322,6 +330,12 @@ public class DisplayManagerServiceTest {
@Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
@Mock DisplayManagerFlags mMockFlags;
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule =
+ new ExtendedMockitoRule.Builder(this)
+ .setStrictness(Strictness.LENIENT)
+ .spyStatic(SystemProperties.class)
+ .build();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -2406,6 +2420,39 @@ public class DisplayManagerServiceTest {
}
@Test
+ public void testConnectExternalDisplay_withDisplayManagementAndSysprop_shouldEnableDisplay() {
+ Assume.assumeTrue(Build.IS_ENG || Build.IS_USERDEBUG);
+ when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true);
+ doAnswer((Answer<Boolean>) invocationOnMock -> true)
+ .when(() -> SystemProperties.getBoolean(ENABLE_ON_CONNECT, false));
+ manageDisplaysPermission(/* granted= */ true);
+ 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);
+ callback.expectsEvent(EVENT_DISPLAY_ADDED);
+
+ // Create default display device
+ createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL);
+ callback.waitForExpectedEvent();
+ callback.clear();
+
+ callback.expectsEvent(EVENT_DISPLAY_CONNECTED);
+ FakeDisplayDevice displayDevice =
+ createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL);
+ callback.waitForExpectedEvent();
+
+ LogicalDisplay display =
+ logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ false);
+ assertThat(display.isEnabledLocked()).isTrue();
+ assertThat(callback.receivedEvents()).containsExactly(DISPLAY_GROUP_EVENT_ADDED,
+ EVENT_DISPLAY_CONNECTED, EVENT_DISPLAY_ADDED).inOrder();
+ }
+
+ @Test
public void testConnectInternalDisplay_withDisplayManagement_shouldConnectAndAddDisplay() {
when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(true);
manageDisplaysPermission(/* granted= */ true);