Merge "Assign display groups to individual physical displays"

This commit is contained in:
Eric Jeong
2023-02-10 16:43:52 +00:00
committed by Android (Google) Code Review
11 changed files with 260 additions and 38 deletions

View File

@@ -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.
*

View File

@@ -125,6 +125,7 @@ class DeviceStateToLayoutMap {
DisplayAddress.fromPhysicalDisplayId(d.getAddress().longValue()),
d.isDefaultDisplay(),
d.isEnabled(),
d.getDisplayGroup(),
mIdProducer,
d.getBrightnessThrottlingMapId(),
leadDisplayId);

View File

@@ -4239,6 +4239,23 @@ public final class DisplayManagerService extends SystemService {
.getHostUsiVersion();
}
}
@Override
public IntArray getDisplayGroupIds() {
Set<Integer> 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

View File

@@ -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.
*
* <p>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);
}

View File

@@ -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<String, Integer> 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) {

View File

@@ -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;

View File

@@ -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.

View File

@@ -56,5 +56,12 @@
<xs:attribute name="enabled" type="xs:boolean" use="optional" />
<xs:attribute name="defaultDisplay" type="xs:boolean" use="optional" />
<xs:attribute name="refreshRateZoneId" type="xs:string" use="optional" />
<xs:attribute name="displayGroup" use="optional" default="">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="|[_a-zA-Z0-9]+(\.[_a-zA-Z0-9]+)*" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>

View File

@@ -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);

View File

@@ -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 {
+ "<display enabled=\"false\">\n"
+ "<address>78910</address>\n"
+ "</display>\n"
+ "<display enabled=\"true\" displayGroup=\"group1\">\n"
+ "<address>98765</address>\n"
+ "</display>\n"
+ "<display enabled=\"false\" displayGroup=\"group2\">\n"
+ "<address>786</address>\n"
+ "</display>\n"
+ "</layout>\n"
+ "<layout>\n"
@@ -207,4 +224,3 @@ public class DeviceStateToLayoutMapTest {
+ "</layouts>\n";
}
}

View File

@@ -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<LogicalDisplay> 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);