diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 9a092a50d6ae9..2bd06060b8d42 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -411,6 +411,11 @@ public abstract class DisplayManagerInternal { @Nullable public abstract HostUsiVersion getHostUsiVersion(int displayId); + /** + * Get all available DisplayGroupIds. + */ + public abstract IntArray getDisplayGroupIds(); + /** * Describes the requested power state of the display. * diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java index 70265295b1fba..ce29013f16230 100644 --- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java +++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java @@ -125,6 +125,7 @@ class DeviceStateToLayoutMap { DisplayAddress.fromPhysicalDisplayId(d.getAddress().longValue()), d.isDefaultDisplay(), d.isEnabled(), + d.getDisplayGroup(), mIdProducer, d.getBrightnessThrottlingMapId(), leadDisplayId); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 237e78bbb58a2..e200d1214c3d7 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -4239,6 +4239,23 @@ public final class DisplayManagerService extends SystemService { .getHostUsiVersion(); } } + + @Override + public IntArray getDisplayGroupIds() { + Set visitedIds = new ArraySet<>(); + IntArray displayGroupIds = new IntArray(); + synchronized (mSyncRoot) { + mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { + int groupId = mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked( + logicalDisplay.getDisplayIdLocked()); + if (!visitedIds.contains(groupId)) { + visitedIds.add(groupId); + displayGroupIds.add(groupId); + } + }); + } + return displayGroupIds; + } } class DesiredDisplayModeSpecsObserver diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 1086c5565227e..667c8c879018e 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; +import android.text.TextUtils; import android.util.ArraySet; import android.util.SparseArray; import android.view.Display; @@ -136,6 +137,11 @@ final class LogicalDisplay { private final Rect mTempLayerStackRect = new Rect(); private final Rect mTempDisplayRect = new Rect(); + /** + * Name of a display group to which the display is assigned. + */ + private String mDisplayGroupName; + /** * The UID mappings for refresh rate override */ @@ -869,6 +875,32 @@ final class LogicalDisplay { return mLeadDisplayId; } + /** + * Sets the name of display group to which the display is assigned. + */ + public void setDisplayGroupNameLocked(String displayGroupName) { + mDisplayGroupName = displayGroupName; + } + + /** + * Gets the name of display group to which the display is assigned. + */ + public String getDisplayGroupNameLocked() { + return mDisplayGroupName; + } + + /** + * Returns whether a display group other than the default display group needs to be assigned. + * + *

If display group name is empty or {@code Display.FLAG_OWN_DISPLAY_GROUP} is set, the + * display is assigned to the default display group. + */ + public boolean needsOwnDisplayGroupLocked() { + DisplayInfo info = getDisplayInfoLocked(); + return (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0 + || !TextUtils.isEmpty(mDisplayGroupName); + } + public void dumpLocked(PrintWriter pw) { pw.println("mDisplayId=" + mDisplayId); pw.println("mIsEnabled=" + mIsEnabled); @@ -887,6 +919,7 @@ final class LogicalDisplay { pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing); pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides)); pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids); + pw.println("mDisplayGroupName=" + mDisplayGroupName); pw.println("mBrightnessThrottlingDataId=" + mBrightnessThrottlingDataId); pw.println("mLeadDisplayId=" + mLeadDisplayId); } diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index c69586279a498..b48ba655d413a 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -133,6 +133,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { */ private final SparseIntArray mDeviceDisplayGroupIds = new SparseIntArray(); + /** + * Map of display group ids indexed by display group name. + */ + private final ArrayMap mDisplayGroupIdsByName = new ArrayMap<>(); + private final DisplayDeviceRepository mDisplayDeviceRepo; private final DeviceStateToLayoutMap mDeviceStateToLayoutMap; private final Listener mListener; @@ -640,7 +645,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0 && !nextDeviceInfo.address.equals(deviceInfo.address)) { layout.createDisplayLocked(nextDeviceInfo.address, - /* isDefault= */ true, /* isEnabled= */ true, mIdProducer, + /* isDefault= */ true, /* isEnabled= */ true, + Layout.DEFAULT_DISPLAY_GROUP_NAME, mIdProducer, /* brightnessThrottlingMapId= */ null, DEFAULT_DISPLAY); applyLayoutLocked(); return; @@ -843,8 +849,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final DisplayGroup oldGroup = getDisplayGroupLocked(groupId); // Get the new display group if a change is needed - final DisplayInfo info = display.getDisplayInfoLocked(); - final boolean needsOwnDisplayGroup = (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0; + final boolean needsOwnDisplayGroup = display.needsOwnDisplayGroupLocked(); final boolean hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP; final boolean needsDeviceDisplayGroup = !needsOwnDisplayGroup && linkedDeviceUniqueId != null; @@ -854,8 +859,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { || hasOwnDisplayGroup != needsOwnDisplayGroup || hasDeviceDisplayGroup != needsDeviceDisplayGroup) { groupId = - assignDisplayGroupIdLocked( - needsOwnDisplayGroup, needsDeviceDisplayGroup, linkedDeviceUniqueId); + assignDisplayGroupIdLocked(needsOwnDisplayGroup, + display.getDisplayGroupNameLocked(), needsDeviceDisplayGroup, + linkedDeviceUniqueId); } // Create a new group if needed @@ -1000,6 +1006,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { displayLayout.getBrightnessThrottlingMapId() == null ? DisplayDeviceConfig.DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID : displayLayout.getBrightnessThrottlingMapId()); + + newDisplay.setDisplayGroupNameLocked(displayLayout.getDisplayGroupName()); } } @@ -1053,8 +1061,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } } - private int assignDisplayGroupIdLocked( - boolean isOwnDisplayGroup, boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) { + private int assignDisplayGroupIdLocked(boolean isOwnDisplayGroup, String displayGroupName, + boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) { if (isDeviceDisplayGroup && linkedDeviceUniqueId != null) { int deviceDisplayGroupId = mDeviceDisplayGroupIds.get(linkedDeviceUniqueId); // A value of 0 indicates that no device display group was found. @@ -1064,7 +1072,13 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } return deviceDisplayGroupId; } - return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP; + if (!isOwnDisplayGroup) return Display.DEFAULT_DISPLAY_GROUP; + Integer displayGroupId = mDisplayGroupIdsByName.get(displayGroupName); + if (displayGroupId == null) { + displayGroupId = Integer.valueOf(mNextNonDefaultGroupId++); + mDisplayGroupIdsByName.put(displayGroupName, displayGroupId); + } + return displayGroupId; } private void initializeDefaultDisplayDeviceLocked(DisplayDevice device) { @@ -1079,7 +1093,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); layout.createDisplayLocked(info.address, /* isDefault= */ true, /* isEnabled= */ true, - mIdProducer, /* brightnessThrottlingMapId= */ null, NO_LEAD_DISPLAY); + Layout.DEFAULT_DISPLAY_GROUP_NAME, mIdProducer, + /* brightnessThrottlingMapId= */ null, NO_LEAD_DISPLAY); } private int assignLayerStackLocked(int displayId) { diff --git a/services/core/java/com/android/server/display/layout/Layout.java b/services/core/java/com/android/server/display/layout/Layout.java index 59d95a65d9add..f1e885e982e13 100644 --- a/services/core/java/com/android/server/display/layout/Layout.java +++ b/services/core/java/com/android/server/display/layout/Layout.java @@ -36,6 +36,8 @@ import java.util.Objects; * a foldable device is folded, and a second instance for when the device is unfolded. */ public class Layout { + public static final String DEFAULT_DISPLAY_GROUP_NAME = ""; + private static final String TAG = "Layout"; private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1; @@ -79,15 +81,19 @@ public class Layout { * @param address Address of the device. * @param isDefault Indicates if the device is meant to be the default display. * @param isEnabled Indicates if this display is usable and can be switched on + * @param displayGroupName Name of the display group to which the display is assigned. * @param idProducer Produces the logical display id. * @param brightnessThrottlingMapId Name of which throttling policy should be used. * @param leadDisplayId Display that this one follows (-1 if none). + * @exception IllegalArgumentException When a default display owns a display group other than + * DEFAULT_DISPLAY_GROUP. * @return The new Display. */ public Display createDisplayLocked( @NonNull DisplayAddress address, boolean isDefault, boolean isEnabled, - DisplayIdProducer idProducer, String brightnessThrottlingMapId, int leadDisplayId) { - return createDisplayLocked(address, isDefault, isEnabled, idProducer, + String displayGroupName, DisplayIdProducer idProducer, String brightnessThrottlingMapId, + int leadDisplayId) { + return createDisplayLocked(address, isDefault, isEnabled, displayGroupName, idProducer, brightnessThrottlingMapId, POSITION_UNKNOWN, leadDisplayId); } @@ -97,16 +103,19 @@ public class Layout { * @param address Address of the device. * @param isDefault Indicates if the device is meant to be the default display. * @param isEnabled Indicates if this display is usable and can be switched on + * @param displayGroupName Name of the display group to which the display is assigned. * @param idProducer Produces the logical display id. * @param brightnessThrottlingMapId Name of which throttling policy should be used. * @param position Indicates the position this display is facing in this layout. * @param leadDisplayId Display that this one follows (-1 if none). + * @exception IllegalArgumentException When a default display owns a display group other than + * DEFAULT_DISPLAY_GROUP. * @return The new Display. */ public Display createDisplayLocked( @NonNull DisplayAddress address, boolean isDefault, boolean isEnabled, - DisplayIdProducer idProducer, String brightnessThrottlingMapId, int position, - int leadDisplayId) { + String displayGroupName, DisplayIdProducer idProducer, String brightnessThrottlingMapId, + int position, int leadDisplayId) { if (contains(address)) { Slog.w(TAG, "Attempting to add second definition for display-device: " + address); return null; @@ -122,8 +131,14 @@ public class Layout { // Note that the logical display ID is saved into the layout, so when switching between // different layouts, a logical display can be destroyed and later recreated with the // same logical display ID. + if (displayGroupName == null) { + displayGroupName = DEFAULT_DISPLAY_GROUP_NAME; + } + if (isDefault && !displayGroupName.equals(DEFAULT_DISPLAY_GROUP_NAME)) { + throw new IllegalArgumentException("Default display should own DEFAULT_DISPLAY_GROUP"); + } final int logicalDisplayId = idProducer.getId(isDefault); - final Display display = new Display(address, logicalDisplayId, isEnabled, + final Display display = new Display(address, logicalDisplayId, isEnabled, displayGroupName, brightnessThrottlingMapId, position, leadDisplayId); mDisplays.add(display); @@ -220,6 +235,9 @@ public class Layout { // Indicates if this display is usable and can be switched on private final boolean mIsEnabled; + // Name of display group to which the display is assigned + private final String mDisplayGroupName; + // The direction the display faces // {@link DeviceStateToLayoutMap.POSITION_FRONT} or // {@link DeviceStateToLayoutMap.POSITION_REAR}. @@ -240,10 +258,12 @@ public class Layout { private String mRefreshRateZoneId; Display(@NonNull DisplayAddress address, int logicalDisplayId, boolean isEnabled, - String brightnessThrottlingMapId, int position, int leadDisplayId) { + @NonNull String displayGroupName, String brightnessThrottlingMapId, int position, + int leadDisplayId) { mAddress = address; mLogicalDisplayId = logicalDisplayId; mIsEnabled = isEnabled; + mDisplayGroupName = displayGroupName; mPosition = position; mBrightnessThrottlingMapId = brightnessThrottlingMapId; @@ -260,6 +280,7 @@ public class Layout { return "{" + "dispId: " + mLogicalDisplayId + "(" + (mIsEnabled ? "ON" : "OFF") + ")" + + ", displayGroupName: " + mDisplayGroupName + ", addr: " + mAddress + ((mPosition == POSITION_UNKNOWN) ? "" : ", position: " + mPosition) + ", brightnessThrottlingMapId: " + mBrightnessThrottlingMapId @@ -279,6 +300,7 @@ public class Layout { return otherDisplay.mIsEnabled == this.mIsEnabled && otherDisplay.mPosition == this.mPosition && otherDisplay.mLogicalDisplayId == this.mLogicalDisplayId + && this.mDisplayGroupName.equals(otherDisplay.mDisplayGroupName) && this.mAddress.equals(otherDisplay.mAddress) && Objects.equals(mBrightnessThrottlingMapId, otherDisplay.mBrightnessThrottlingMapId) @@ -292,6 +314,7 @@ public class Layout { result = 31 * result + Boolean.hashCode(mIsEnabled); result = 31 * result + mPosition; result = 31 * result + mLogicalDisplayId; + result = 31 * result + mDisplayGroupName.hashCode(); result = 31 * result + mAddress.hashCode(); result = 31 * result + mBrightnessThrottlingMapId.hashCode(); result = 31 * result + Objects.hashCode(mRefreshRateZoneId); @@ -311,6 +334,9 @@ public class Layout { return mIsEnabled; } + public String getDisplayGroupName() { + return mDisplayGroupName; + } public void setRefreshRateZoneId(@Nullable String refreshRateZoneId) { mRefreshRateZoneId = refreshRateZoneId; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index e8cb4e2076299..6fa7920ab4d7e 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -94,6 +94,7 @@ import android.service.dreams.DreamManagerInternal; import android.sysprop.InitProperties; import android.sysprop.PowerProperties; import android.util.ArrayMap; +import android.util.IntArray; import android.util.KeyValueListParser; import android.util.LongArray; import android.util.PrintWriterPrinter; @@ -1275,6 +1276,9 @@ public final class PowerManagerService extends SystemService mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager); + // Create power groups for display groups other than DEFAULT_DISPLAY_GROUP. + addPowerGroupsForNonDefaultDisplayGroupLocked(); + try { final ForegroundProfileObserver observer = new ForegroundProfileObserver(); ActivityManager.getService().registerUserSwitchObserver(observer, TAG); @@ -4278,6 +4282,37 @@ public final class PowerManagerService extends SystemService } } + @GuardedBy("mLock") + private void addPowerGroupsForNonDefaultDisplayGroupLocked() { + IntArray displayGroupIds = mDisplayManagerInternal.getDisplayGroupIds(); + if (displayGroupIds == null) { + return; + } + + for (int i = 0; i < displayGroupIds.size(); i++) { + int displayGroupId = displayGroupIds.get(i); + if (displayGroupId == Display.DEFAULT_DISPLAY_GROUP) { + // Power group for the default display group is already added. + continue; + } + if (mPowerGroups.contains(displayGroupId)) { + Slog.e(TAG, "Tried to add already existing group:" + displayGroupId); + continue; + } + PowerGroup powerGroup = new PowerGroup( + displayGroupId, + mPowerGroupWakefulnessChangeListener, + mNotifier, + mDisplayManagerInternal, + WAKEFULNESS_AWAKE, + /* ready= */ false, + /* supportsSandman= */ false, + mClock.uptimeMillis()); + mPowerGroups.append(displayGroupId, powerGroup); + } + mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS; + } + /** * Low-level function turn the device off immediately, without trying * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown. diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd index 45e10a802630e..d4556d7104296 100644 --- a/services/core/xsd/display-layout-config/display-layout-config.xsd +++ b/services/core/xsd/display-layout-config/display-layout-config.xsd @@ -56,5 +56,12 @@ + + + + + + + diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt index 2c16c3754a201..52133ab76086d 100644 --- a/services/core/xsd/display-layout-config/schema/current.txt +++ b/services/core/xsd/display-layout-config/schema/current.txt @@ -5,6 +5,7 @@ package com.android.server.display.config.layout { ctor public Display(); method public java.math.BigInteger getAddress(); method public String getBrightnessThrottlingMapId(); + method public String getDisplayGroup(); method public String getPosition(); method public String getRefreshRateZoneId(); method public boolean isDefaultDisplay(); @@ -12,6 +13,7 @@ package com.android.server.display.config.layout { method public void setAddress(java.math.BigInteger); method public void setBrightnessThrottlingMapId(String); method public void setDefaultDisplay(boolean); + method public void setDisplayGroup(String); method public void setEnabled(boolean); method public void setPosition(String); method public void setRefreshRateZoneId(String); diff --git a/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java b/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java index 8f2a1e557cdaa..a380efffb62f8 100644 --- a/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java @@ -65,14 +65,25 @@ public class DeviceStateToLayoutMapTest { Layout testLayout = new Layout(); testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(123456L), /* isDefault= */ true, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(78910L), /* isDefault= */ false, - /* isEnabled= */ false, mDisplayIdProducerMock, + /* isEnabled= */ false, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + testLayout.createDisplayLocked( + DisplayAddress.fromPhysicalDisplayId(98765L), /* isDefault= */ false, + /* isEnabled= */ true, "group1", mDisplayIdProducerMock, + /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + testLayout.createDisplayLocked( + DisplayAddress.fromPhysicalDisplayId(786L), /* isDefault= */ false, + /* isEnabled= */ false, "group2", mDisplayIdProducerMock, + /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + assertEquals(testLayout, configLayout); } @@ -83,12 +94,12 @@ public class DeviceStateToLayoutMapTest { Layout testLayout = new Layout(); testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(78910L), /* isDefault= */ true, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(123456L), /* isDefault= */ false, - /* isEnabled= */ false, mDisplayIdProducerMock, + /* isEnabled= */ false, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -103,14 +114,14 @@ public class DeviceStateToLayoutMapTest { Layout.Display display1 = testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(345L), /* isDefault= */ true, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ "concurrent", /* leadDisplayId= */ Display.DEFAULT_DISPLAY); display1.setPosition(Layout.Display.POSITION_FRONT); Layout.Display display2 = testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(678L), /* isDefault= */ false, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ "concurrent", /* leadDisplayId= */ Display.DEFAULT_DISPLAY); display2.setPosition(Layout.Display.POSITION_REAR); @@ -133,13 +144,13 @@ public class DeviceStateToLayoutMapTest { Layout testLayout = new Layout(); Layout.Display display1 = testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(345L), /* isDefault= */ true, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); display1.setRefreshRateZoneId("test1"); testLayout.createDisplayLocked( DisplayAddress.fromPhysicalDisplayId(678L), /* isDefault= */ false, - /* isEnabled= */ true, mDisplayIdProducerMock, + /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -168,6 +179,12 @@ public class DeviceStateToLayoutMapTest { + "\n" + "

78910
\n" + "\n" + + "\n" + + "
98765
\n" + + "
\n" + + "\n" + + "
786
\n" + + "
\n" + "\n" + "\n" @@ -207,4 +224,3 @@ public class DeviceStateToLayoutMapTest { + "\n"; } } - diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java index 488c533f6c63e..b698cdf108161 100644 --- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -75,6 +75,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; +import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; @@ -86,6 +87,7 @@ public class LogicalDisplayMapperTest { private static final int DEVICE_STATE_CLOSED = 0; private static final int DEVICE_STATE_OPEN = 2; private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1; + private static final File NON_EXISTING_FILE = new File("/non_existing_folder/should_not_exist"); private DisplayDeviceRepository mDisplayDeviceRepo; private LogicalDisplayMapper mLogicalDisplayMapper; @@ -102,7 +104,7 @@ public class LogicalDisplayMapperTest { @Mock IPowerManager mIPowerManagerMock; @Mock IThermalService mIThermalServiceMock; @Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy = - new DeviceStateToLayoutMap(mIdProducer); + new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE); @Captor ArgumentCaptor mDisplayCaptor; @@ -299,10 +301,12 @@ public class LogicalDisplayMapperTest { Layout layout1 = new Layout(); layout1.createDisplayLocked(info(device1).address, /* isDefault= */ true, - /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer, + /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); layout1.createDisplayLocked(info(device2).address, /* isDefault= */ false, - /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer, + /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1); assertThat(layout1.size()).isEqualTo(2); @@ -337,18 +341,21 @@ public class LogicalDisplayMapperTest { Layout layout1 = new Layout(); layout1.createDisplayLocked(info(device1).address, /* isDefault= */ true, - /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer, + /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1); final int layoutState2 = 2; Layout layout2 = new Layout(); layout2.createDisplayLocked(info(device2).address, /* isDefault= */ false, - /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer, + /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); // Device3 is the default display. layout2.createDisplayLocked(info(device3).address, /* isDefault= */ true, - /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer, + /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(layoutState2)).thenReturn(layout2); assertThat(layout2.size()).isEqualTo(2); @@ -379,6 +386,56 @@ public class LogicalDisplayMapperTest { assertThat(displayInfoLayout2Other.logicalHeight).isEqualTo(height(device2)); } + @Test + public void testGetDisplayInfoForStateLocked_multipleDisplayGroups() { + DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, + FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); + DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800, + FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); + DisplayDevice device3 = createDisplayDevice(TYPE_INTERNAL, 700, 800, + FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); + DisplayDevice device4 = createDisplayDevice(TYPE_INTERNAL, 400, 600, + FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); + + Layout layout = new Layout(); + layout.createDisplayLocked(info(device1).address, + /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null, + mIdProducer, /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + layout.createDisplayLocked(info(device2).address, + /* isDefault= */ false, /* isEnabled= */ true, "group1", mIdProducer, + /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + layout.createDisplayLocked(info(device3).address, + /* isDefault= */ false, /* isEnabled= */ true, "group1", mIdProducer, + /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + layout.createDisplayLocked(info(device4).address, + /* isDefault= */ false, /* isEnabled= */ true, "group2", mIdProducer, + /* brightnessThrottlingMapId= */ null, + /* leadDisplayId= */ Display.DEFAULT_DISPLAY); + when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout); + + LogicalDisplay display1 = add(device1); + LogicalDisplay display2 = add(device2); + LogicalDisplay display3 = add(device3); + LogicalDisplay display4 = add(device4); + + int displayGroupId1 = + mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)); + int displayGroupId2 = + mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2)); + int displayGroupId3 = + mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)); + int displayGroupId4 = + mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display4)); + assertThat(displayGroupId1).isEqualTo(DEFAULT_DISPLAY_GROUP); + assertThat(displayGroupId2).isNotEqualTo(DEFAULT_DISPLAY_GROUP); + assertThat(displayGroupId2).isEqualTo(displayGroupId3); + assertThat(displayGroupId3).isNotEqualTo(DEFAULT_DISPLAY_GROUP); + assertThat(displayGroupId2).isNotEqualTo(displayGroupId4); + } + @Test public void testSingleDisplayGroup() { LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800, @@ -571,21 +628,23 @@ public class LogicalDisplayMapperTest { Layout layout = new Layout(); layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, - true, true, mIdProducer, - /* brightnessThrottlingMapId= */ "concurrent", + /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null, + mIdProducer, /* brightnessThrottlingMapId= */ "concurrent", /* leadDisplayId= */ Display.DEFAULT_DISPLAY); layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, - false, true, mIdProducer, - /* brightnessThrottlingMapId= */ "concurrent", + /* isDefault= */ false, /* isEnabled= */ true, /* displayGroup= */ null, + mIdProducer, /* brightnessThrottlingMapId= */ "concurrent", /* leadDisplayId= */ Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout); layout = new Layout(); layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, - false, false, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isDefault= */ false, /* isEnabled= */ false, /* displayGroup= */ null, + mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, - true, true, mIdProducer, /* brightnessThrottlingMapId= */ null, + /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null, + mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout); when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout); @@ -667,6 +726,7 @@ public class LogicalDisplayMapperTest { displayAddressOne, /* isDefault= */ true, /* isEnabled= */ true, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -674,6 +734,7 @@ public class LogicalDisplayMapperTest { displayAddressTwo, /* isDefault= */ false, /* isEnabled= */ true, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -681,6 +742,7 @@ public class LogicalDisplayMapperTest { displayAddressThree, /* isDefault= */ false, /* isEnabled= */ true, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -718,6 +780,7 @@ public class LogicalDisplayMapperTest { displayAddressOne, /* isDefault= */ true, /* isEnabled= */ true, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -725,6 +788,7 @@ public class LogicalDisplayMapperTest { displayAddressTwo, /* isDefault= */ false, /* isEnabled= */ false, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -732,6 +796,7 @@ public class LogicalDisplayMapperTest { displayAddressThree, /* isDefault= */ false, /* isEnabled= */ false, + /* displayGroup= */ null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); @@ -809,10 +874,10 @@ public class LogicalDisplayMapperTest { Layout layout = new Layout(); layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address, - true, true, mIdProducer, /* brightnessThrottlingMapId= */ null, + true, true, null, mIdProducer, /* brightnessThrottlingMapId= */ null, /* leadDisplayId= */ Display.DEFAULT_DISPLAY); layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address, - false, true, mIdProducer, /* brightnessThrottlingMapId= */ null, + false, true, null, mIdProducer, /* brightnessThrottlingMapId= */ null, POSITION_REAR, Display.DEFAULT_DISPLAY); when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);