Merge "More initialisation for external displays Change the FLAG_DEFAULT_DISPLAY to FLAG_SUPPORTS_DEFAULT_DISPLAY When the default display of the default layout is removed, find another display and make it default" into tm-dev

This commit is contained in:
Piotr Wilczyński
2022-03-25 10:07:55 +00:00
committed by Android (Google) Code Review
10 changed files with 172 additions and 78 deletions

View File

@@ -30,9 +30,8 @@ import android.util.Slog;
import android.util.Spline; import android.util.Spline;
import android.view.DisplayAddress; import android.view.DisplayAddress;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.BrightnessThresholds; import com.android.server.display.config.BrightnessThresholds;
import com.android.server.display.config.BrightnessThrottlingMap; import com.android.server.display.config.BrightnessThrottlingMap;
@@ -296,9 +295,9 @@ public class DisplayDeviceConfig {
* @return A configuration instance for the specified display. * @return A configuration instance for the specified display.
*/ */
public static DisplayDeviceConfig create(Context context, long physicalDisplayId, public static DisplayDeviceConfig create(Context context, long physicalDisplayId,
boolean isDefaultDisplay) { boolean isFirstDisplay) {
final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId, final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId,
isDefaultDisplay); isFirstDisplay);
config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context)); config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context));
return config; return config;
@@ -323,7 +322,7 @@ public class DisplayDeviceConfig {
} }
private static DisplayDeviceConfig createWithoutDefaultValues(Context context, private static DisplayDeviceConfig createWithoutDefaultValues(Context context,
long physicalDisplayId, boolean isDefaultDisplay) { long physicalDisplayId, boolean isFirstDisplay) {
DisplayDeviceConfig config; DisplayDeviceConfig config;
config = loadConfigFromDirectory(context, Environment.getProductDirectory(), config = loadConfigFromDirectory(context, Environment.getProductDirectory(),
@@ -341,7 +340,7 @@ public class DisplayDeviceConfig {
// If no config can be loaded from any ddc xml at all, // If no config can be loaded from any ddc xml at all,
// prepare a whole config using the global config.xml. // prepare a whole config using the global config.xml.
// Guaranteed not null // Guaranteed not null
return create(context, isDefaultDisplay); return create(context, isFirstDisplay);
} }
private static DisplayConfiguration loadDefaultConfigurationXml(Context context) { private static DisplayConfiguration loadDefaultConfigurationXml(Context context) {

View File

@@ -39,7 +39,7 @@ final class DisplayDeviceInfo {
* Flag: Indicates that this display device should be considered the default display * Flag: Indicates that this display device should be considered the default display
* device of the system. * device of the system.
*/ */
public static final int FLAG_DEFAULT_DISPLAY = 1 << 0; public static final int FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY = 1 << 0;
/** /**
* Flag: Indicates that the orientation of this display device is coupled to the * Flag: Indicates that the orientation of this display device is coupled to the
@@ -538,8 +538,8 @@ final class DisplayDeviceInfo {
private static String flagsToString(int flags) { private static String flagsToString(int flags) {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
msg.append(", FLAG_DEFAULT_DISPLAY"); msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY");
} }
if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
msg.append(", FLAG_ROTATES_WITH_CONTENT"); msg.append(", FLAG_ROTATES_WITH_CONTENT");

View File

@@ -397,8 +397,7 @@ public final class DisplayManagerService extends SystemService {
private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>(); private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
// The default color mode for default displays. Overrides the usual // The default color mode for default displays. Overrides the usual
// Display.Display.COLOR_MODE_DEFAULT for displays with the // Display.Display.COLOR_MODE_DEFAULT for local displays.
// DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
private final int mDefaultDisplayDefaultColorMode; private final int mDefaultDisplayDefaultColorMode;
// Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
@@ -1682,8 +1681,7 @@ public final class DisplayManagerService extends SystemService {
if (display.getPrimaryDisplayDeviceLocked() == device) { if (display.getPrimaryDisplayDeviceLocked() == device) {
int colorMode = mPersistentDataStore.getColorMode(device); int colorMode = mPersistentDataStore.getColorMode(device);
if (colorMode == Display.COLOR_MODE_INVALID) { if (colorMode == Display.COLOR_MODE_INVALID) {
if ((device.getDisplayDeviceInfoLocked().flags if (display.getDisplayIdLocked() == Display.DEFAULT_DISPLAY) {
& DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
colorMode = mDefaultDisplayDefaultColorMode; colorMode = mDefaultDisplayDefaultColorMode;
} else { } else {
colorMode = Display.COLOR_MODE_DEFAULT; colorMode = Display.COLOR_MODE_DEFAULT;

View File

@@ -141,9 +141,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
LocalDisplayDevice device = mDevices.get(physicalDisplayId); LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) { if (device == null) {
// Display was added. // Display was added.
final boolean isDefaultDisplay = mDevices.size() == 0; final boolean isFirstDisplay = mDevices.size() == 0;
device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo, device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo,
dynamicInfo, modeSpecs, isDefaultDisplay); dynamicInfo, modeSpecs, isFirstDisplay);
mDevices.put(physicalDisplayId, device); mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED); sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo, } else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo,
@@ -187,7 +187,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>(); private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
private final DisplayModeDirector.DesiredDisplayModeSpecs mDisplayModeSpecs = private final DisplayModeDirector.DesiredDisplayModeSpecs mDisplayModeSpecs =
new DisplayModeDirector.DesiredDisplayModeSpecs(); new DisplayModeDirector.DesiredDisplayModeSpecs();
private final boolean mIsDefaultDisplay; private final boolean mIsFirstDisplay;
private final BacklightAdapter mBacklightAdapter; private final BacklightAdapter mBacklightAdapter;
private final SidekickInternal mSidekickInternal; private final SidekickInternal mSidekickInternal;
@@ -226,14 +226,14 @@ final class LocalDisplayAdapter extends DisplayAdapter {
LocalDisplayDevice(IBinder displayToken, long physicalDisplayId, LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
SurfaceControl.StaticDisplayInfo staticDisplayInfo, SurfaceControl.StaticDisplayInfo staticDisplayInfo,
SurfaceControl.DynamicDisplayInfo dynamicInfo, SurfaceControl.DynamicDisplayInfo dynamicInfo,
SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isDefaultDisplay) { SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isFirstDisplay) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId, super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId,
getContext()); getContext());
mPhysicalDisplayId = physicalDisplayId; mPhysicalDisplayId = physicalDisplayId;
mIsDefaultDisplay = isDefaultDisplay; mIsFirstDisplay = isFirstDisplay;
updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs); updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs);
mSidekickInternal = LocalServices.getService(SidekickInternal.class); mSidekickInternal = LocalServices.getService(SidekickInternal.class);
mBacklightAdapter = new BacklightAdapter(displayToken, isDefaultDisplay, mBacklightAdapter = new BacklightAdapter(displayToken, isFirstDisplay,
mSurfaceControlProxy); mSurfaceControlProxy);
mActiveDisplayModeAtStartId = dynamicInfo.activeDisplayModeId; mActiveDisplayModeAtStartId = dynamicInfo.activeDisplayModeId;
} }
@@ -480,7 +480,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
// Load display device config // Load display device config
final Context context = getOverlayContext(); final Context context = getOverlayContext();
mDisplayDeviceConfig = DisplayDeviceConfig.create(context, mPhysicalDisplayId, mDisplayDeviceConfig = DisplayDeviceConfig.create(context, mPhysicalDisplayId,
mIsDefaultDisplay); mIsFirstDisplay);
// Load brightness HWC quirk // Load brightness HWC quirk
mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk( mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk(
@@ -652,9 +652,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
final Resources res = getOverlayContext().getResources(); final Resources res = getOverlayContext().getResources();
if (mIsDefaultDisplay) { mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
if (mIsFirstDisplay) {
if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound) if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
|| (Build.IS_EMULATOR || (Build.IS_EMULATOR
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) { && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
@@ -1438,9 +1438,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
/** /**
* @param displayToken Token for display associated with this backlight. * @param displayToken Token for display associated with this backlight.
* @param isDefaultDisplay {@code true} if it is the default display. * @param isFirstDisplay {@code true} if it is the first display.
*/ */
BacklightAdapter(IBinder displayToken, boolean isDefaultDisplay, BacklightAdapter(IBinder displayToken, boolean isFirstDisplay,
SurfaceControlProxy surfaceControlProxy) { SurfaceControlProxy surfaceControlProxy) {
mDisplayToken = displayToken; mDisplayToken = displayToken;
mSurfaceControlProxy = surfaceControlProxy; mSurfaceControlProxy = surfaceControlProxy;
@@ -1448,7 +1448,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mUseSurfaceControlBrightness = mSurfaceControlProxy mUseSurfaceControlBrightness = mSurfaceControlProxy
.getDisplayBrightnessSupport(mDisplayToken); .getDisplayBrightnessSupport(mDisplayToken);
if (!mUseSurfaceControlBrightness && isDefaultDisplay) { if (!mUseSurfaceControlBrightness && isFirstDisplay) {
LightsManager lights = LocalServices.getService(LightsManager.class); LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT); mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
} else { } else {

View File

@@ -16,6 +16,8 @@
package com.android.server.display; package com.android.server.display;
import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.hardware.devicestate.DeviceStateManager; import android.hardware.devicestate.DeviceStateManager;
@@ -204,6 +206,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked()); Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
} }
handleDisplayDeviceRemovedLocked(device);
updateLogicalDisplaysLocked(); updateLogicalDisplaysLocked();
break; break;
} }
@@ -529,12 +532,12 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private void handleDisplayDeviceAddedLocked(DisplayDevice device) { private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
// Internal Displays need to have additional initialization. // The default Display needs to have additional initialization.
// This initializes a default dynamic display layout for INTERNAL // This initializes a default dynamic display layout for the default
// devices, which is used as a fallback in case no static layout definitions // device, which is used as a fallback in case no static layout definitions
// exist or cannot be loaded. // exist or cannot be loaded.
if (deviceInfo.type == Display.TYPE_INTERNAL) { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
initializeInternalDisplayDeviceLocked(device); initializeDefaultDisplayDeviceLocked(device);
} }
// Create a logical display for the new display device // Create a logical display for the new display device
@@ -545,6 +548,38 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
updateLogicalDisplaysLocked(); updateLogicalDisplaysLocked();
} }
private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
Layout.Display layoutDisplay = layout.getById(DEFAULT_DISPLAY);
if (layoutDisplay == null) {
return;
}
DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
if (layoutDisplay.getAddress().equals(deviceInfo.address)) {
layout.removeDisplayLocked(DEFAULT_DISPLAY);
// Need to find another local display and make it default
for (int i = 0; i < mLogicalDisplays.size(); i++) {
LogicalDisplay nextDisplay = mLogicalDisplays.valueAt(i);
DisplayDevice nextDevice = nextDisplay.getPrimaryDisplayDeviceLocked();
if (nextDevice == null) {
continue;
}
DisplayDeviceInfo nextDeviceInfo = nextDevice.getDisplayDeviceInfoLocked();
if ((nextDeviceInfo.flags
& DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0
&& !nextDeviceInfo.address.equals(deviceInfo.address)) {
layout.createDisplayLocked(nextDeviceInfo.address,
/* isDefault= */ true, /* isEnabled= */ true);
applyLayoutLocked();
return;
}
}
}
}
/** /**
* Updates the rest of the display system once all the changes are applied for display * Updates the rest of the display system once all the changes are applied for display
* devices and logical displays. The includes releasing invalid/empty LogicalDisplays, * devices and logical displays. The includes releasing invalid/empty LogicalDisplays,
@@ -900,16 +935,18 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP; return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP;
} }
private void initializeInternalDisplayDeviceLocked(DisplayDevice device) { private void initializeDefaultDisplayDeviceLocked(DisplayDevice device) {
// We always want to make sure that our default layout creates a logical // We always want to make sure that our default layout creates a logical
// display for every internal display device that is found. // display for the default display device that is found.
// To that end, when we are notified of a new internal display, we add it to // To that end, when we are notified of a new default display, we add it to
// the default layout definition if it is not already there. // the default layout definition if it is not already there.
final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT); final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
if (layout.getById(DEFAULT_DISPLAY) != null) {
// The layout should only have one default display
return;
}
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
final boolean isDefault = (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; layout.createDisplayLocked(info.address, /* isDefault= */ true, /* isEnabled= */ true);
final boolean isEnabled = isDefault || mSupportsConcurrentInternalDisplays;
layout.createDisplayLocked(info.address, isDefault, isEnabled);
} }
private int assignLayerStackLocked(int displayId) { private int assignLayerStackLocked(int displayId) {

View File

@@ -67,7 +67,7 @@ public class Layout {
// See if we're dealing with the "default" display // See if we're dealing with the "default" display
if (isDefault && getById(DEFAULT_DISPLAY) != null) { if (isDefault && getById(DEFAULT_DISPLAY) != null) {
Slog.w(TAG, "Ignoring attempt to add a second default display: " + address); Slog.w(TAG, "Ignoring attempt to add a second default display: " + address);
isDefault = false; return null;
} }
// Assign a logical display ID and create the new display. // Assign a logical display ID and create the new display.
@@ -75,10 +75,20 @@ public class Layout {
// different layouts, a logical display can be destroyed and later recreated with the // different layouts, a logical display can be destroyed and later recreated with the
// same logical display ID. // same logical display ID.
final int logicalDisplayId = assignDisplayIdLocked(isDefault); final int logicalDisplayId = assignDisplayIdLocked(isDefault);
final Display layout = new Display(address, logicalDisplayId, isEnabled); final Display display = new Display(address, logicalDisplayId, isEnabled);
mDisplays.add(layout); mDisplays.add(display);
return layout; return display;
}
/**
* @param id The ID of the display to remove.
*/
public void removeDisplayLocked(int id) {
Display display = getById(id);
if (display != null) {
mDisplays.remove(display);
}
} }
/** /**

View File

@@ -178,7 +178,7 @@ public class LocalDisplayAdapterTest {
// This should be public // This should be public
assertDisplayPrivateFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), assertDisplayPrivateFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(),
PORT_A, false); PORT_A, false);
// This should be public // This should be private
assertDisplayPrivateFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), assertDisplayPrivateFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(),
PORT_B, true); PORT_B, true);
// This should be public // This should be public

View File

@@ -393,7 +393,8 @@ public class DisplayManagerServiceTest {
displayDeviceInfo.displayCutout = new DisplayCutout( displayDeviceInfo.displayCutout = new DisplayCutout(
Insets.of(0, 10, 0, 0), Insets.of(0, 10, 0, 0),
zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
displayDeviceInfo.address = new TestUtils.TestDisplayAddress();
displayDevice.setDisplayDeviceInfo(displayDeviceInfo); displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
displayManager.getDisplayDeviceRepository() displayManager.getDisplayDeviceRepository()
.onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
@@ -1307,7 +1308,8 @@ public class DisplayManagerServiceTest {
displayDeviceInfo.displayCutout = new DisplayCutout( displayDeviceInfo.displayCutout = new DisplayCutout(
Insets.of(0, 10, 0, 0), Insets.of(0, 10, 0, 0),
zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
displayDeviceInfo.address = new TestUtils.TestDisplayAddress();
displayDevice.setDisplayDeviceInfo(displayDeviceInfo); displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
displayManager.getDisplayDeviceRepository() displayManager.getDisplayDeviceRepository()
.onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);

View File

@@ -42,7 +42,6 @@ import android.content.res.Resources;
import android.os.Handler; import android.os.Handler;
import android.os.IPowerManager; import android.os.IPowerManager;
import android.os.IThermalService; import android.os.IThermalService;
import android.os.Parcel;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.Process; import android.os.Process;
import android.os.test.TestLooper; import android.os.test.TestLooper;
@@ -146,7 +145,7 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testDisplayDeviceAddAndRemove_Internal() { public void testDisplayDeviceAddAndRemove_Internal() {
DisplayDevice device = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, DisplayDevice device = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
// add // add
LogicalDisplay displayAdded = add(device); LogicalDisplay displayAdded = add(device);
@@ -179,7 +178,7 @@ public class LogicalDisplayMapperTest {
public void testDisplayDeviceAdd_TwoInternalOneDefault() { public void testDisplayDeviceAdd_TwoInternalOneDefault() {
DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0); DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0);
DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1); LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address); assertEquals(info(display1).address, info(device1).address);
@@ -193,9 +192,9 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testDisplayDeviceAdd_TwoInternalBothDefault() { public void testDisplayDeviceAdd_TwoInternalBothDefault() {
DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1); LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address); assertEquals(info(display1).address, info(device1).address);
@@ -207,10 +206,58 @@ public class LogicalDisplayMapperTest {
assertNotEquals(DEFAULT_DISPLAY, id(display2)); assertNotEquals(DEFAULT_DISPLAY, id(display2));
} }
@Test
public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
DisplayDevice device = createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
// add
LogicalDisplay displayAdded = add(device);
assertEquals(info(displayAdded).address, info(device).address);
assertEquals(Display.DEFAULT_DISPLAY, id(displayAdded));
// remove
mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_REMOVED);
verify(mListenerMock).onLogicalDisplayEventLocked(
mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED));
LogicalDisplay displayRemoved = mDisplayCaptor.getValue();
assertEquals(DEFAULT_DISPLAY, id(displayRemoved));
assertEquals(displayAdded, displayRemoved);
}
@Test
public void testDisplayDeviceAddAndRemove_SwitchDefault() {
DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
assertEquals(DEFAULT_DISPLAY, id(display1));
LogicalDisplay display2 = add(device2);
assertEquals(info(display2).address, info(device2).address);
// We can only have one default display
assertEquals(DEFAULT_DISPLAY, id(display1));
// remove
mDisplayDeviceRepo.onDisplayDeviceEvent(device1, DISPLAY_DEVICE_EVENT_REMOVED);
verify(mListenerMock).onLogicalDisplayEventLocked(
mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED));
LogicalDisplay displayRemoved = mDisplayCaptor.getValue();
// Display 1 is still the default logical display
assertEquals(DEFAULT_DISPLAY, id(display1));
// The logical displays had their devices swapped and Display 2 was removed
assertEquals(display2, displayRemoved);
assertEquals(info(display1).address, info(device2).address);
}
@Test @Test
public void testGetDisplayIdsLocked() { public void testGetDisplayIdsLocked() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0)); add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0)); add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
@@ -223,19 +270,19 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testGetDisplayInfoForStateLocked_oneDisplayGroup_internalType() { public void testGetDisplayInfoForStateLocked_oneDisplayGroup_internalType() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 700, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 700, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked( Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP); DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
assertThat(displayInfos.size()).isEqualTo(3); assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) { for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY); assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP); assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
assertThat(displayInfo.logicalWidth).isAnyOf(600, 200, 700); assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800); assertThat(displayInfo.logicalHeight).isEqualTo(800);
} }
} }
@@ -243,19 +290,19 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testGetDisplayInfoForStateLocked_oneDisplayGroup_differentTypes() { public void testGetDisplayInfoForStateLocked_oneDisplayGroup_differentTypes() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_EXTERNAL, 700, 800, add(createDisplayDevice(Display.TYPE_EXTERNAL, 700, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked( Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP); DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
assertThat(displayInfos.size()).isEqualTo(2); assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) { for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY); assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP); assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
assertThat(displayInfo.logicalWidth).isAnyOf(600, 200); assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800); assertThat(displayInfo.logicalHeight).isEqualTo(800);
} }
} }
@@ -263,19 +310,19 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testGetDisplayInfoForStateLocked_multipleDisplayGroups_defaultGroup() { public void testGetDisplayInfoForStateLocked_multipleDisplayGroups_defaultGroup() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800, add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_VIRTUAL, 700, 800, add(createDisplayDevice(Display.TYPE_VIRTUAL, 700, 800,
DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP)); DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked( Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP); DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
assertThat(displayInfos.size()).isEqualTo(2); assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) { for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY); assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP); assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
assertThat(displayInfo.logicalWidth).isAnyOf(600, 200); assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800); assertThat(displayInfo.logicalHeight).isEqualTo(800);
} }
} }
@@ -283,7 +330,7 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testSingleDisplayGroup() { public void testSingleDisplayGroup() {
LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0)); LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0)); LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
@@ -298,7 +345,7 @@ public class LogicalDisplayMapperTest {
@Test @Test
public void testMultipleDisplayGroups() { public void testMultipleDisplayGroups() {
LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY)); DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0)); LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
@@ -371,7 +418,7 @@ public class LogicalDisplayMapperTest {
///////////////// /////////////////
private TestDisplayDevice createDisplayDevice(int type, int width, int height, int flags) { private TestDisplayDevice createDisplayDevice(int type, int width, int height, int flags) {
return createDisplayDevice(new DisplayAddressImpl(), type, width, height, flags); return createDisplayDevice(new TestUtils.TestDisplayAddress(), type, width, height, flags);
} }
private TestDisplayDevice createDisplayDevice( private TestDisplayDevice createDisplayDevice(
@@ -385,7 +432,7 @@ public class LogicalDisplayMapperTest {
displayDeviceInfo.supportedModes = new Display.Mode[1]; displayDeviceInfo.supportedModes = new Display.Mode[1];
displayDeviceInfo.supportedModes[0] = new Display.Mode(1, width, height, 60f); displayDeviceInfo.supportedModes[0] = new Display.Mode(1, width, height, 60f);
displayDeviceInfo.modeId = 1; displayDeviceInfo.modeId = 1;
displayDeviceInfo.address = new DisplayAddressImpl(); displayDeviceInfo.address = address;
return device; return device;
} }
@@ -427,18 +474,8 @@ public class LogicalDisplayMapperTest {
assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved)); assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved));
} }
/**
* Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
* display-address implementation in our code. Intentionally uses default object (reference)
* equality rules.
*/
class DisplayAddressImpl extends DisplayAddress {
@Override
public void writeToParcel(Parcel out, int flags) { }
}
class TestDisplayDevice extends DisplayDevice { class TestDisplayDevice extends DisplayDevice {
private DisplayDeviceInfo mInfo = new DisplayDeviceInfo(); private DisplayDeviceInfo mInfo;
private DisplayDeviceInfo mSentInfo; private DisplayDeviceInfo mSentInfo;
TestDisplayDevice() { TestDisplayDevice() {

View File

@@ -18,7 +18,9 @@ package com.android.server.display;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.os.Parcel;
import android.os.SystemClock; import android.os.SystemClock;
import android.view.DisplayAddress;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -57,4 +59,13 @@ public final class TestUtils {
return sensor; return sensor;
} }
/**
* Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
* display-address implementation in our code. Intentionally uses default object (reference)
* equality rules.
*/
public static class TestDisplayAddress extends DisplayAddress {
@Override
public void writeToParcel(Parcel out, int flags) { }
}
} }