diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 655f42308a1f87efdad84fde1e2ddae7b39f1a7f..2a00b5a2e51358985352c1c4ff30c00cda9d6771 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -810,9 +810,6 @@ public final class DisplayInfo implements Parcelable {
if ((flags & Display.FLAG_TRUSTED) != 0) {
result.append(", FLAG_TRUSTED");
}
- if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
- result.append(", FLAG_OWN_DISPLAY_GROUP");
- }
return result.toString();
}
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 10164b0d2b1caf99d9882f21ea57c5d3355ecf9d..12cb3980f785c3b405e8c0cae7cdc3ae928ab0f1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -673,15 +673,6 @@
-->
-
-
-
-
-
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8f07a2d49ce6703fb7eab44d9b350d1547887062..dbb584dfe293a55220507e86e9810c46ba839662 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3762,7 +3762,6 @@
-
diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
index 91674cd8afa60ad2e6fd7e03a5d1cec1200da6d5..d4556ed5f9fa04a48359531c33cf3a8562b8b5bc 100644
--- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
+++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
@@ -39,6 +39,10 @@ class DeviceStateToLayoutMap {
public static final int STATE_DEFAULT = DeviceStateManager.INVALID_DEVICE_STATE;
+ // TODO - b/168208162 - Remove these when we check in static definitions for layouts
+ public static final int STATE_FOLDED = 100;
+ public static final int STATE_UNFOLDED = 101;
+
private final SparseArray mLayoutMap = new SparseArray<>();
DeviceStateToLayoutMap(Context context) {
@@ -64,7 +68,7 @@ class DeviceStateToLayoutMap {
return layout;
}
- private Layout createLayout(int state) {
+ private Layout create(int state) {
if (mLayoutMap.contains(state)) {
Slog.e(TAG, "Attempted to create a second layout for state " + state);
return null;
@@ -75,12 +79,10 @@ class DeviceStateToLayoutMap {
return layout;
}
- /**
- * Loads config.xml-specified folded configurations for foldable devices.
- */
private void loadFoldedDisplayConfig(Context context) {
final String[] strDisplayIds = context.getResources().getStringArray(
com.android.internal.R.array.config_internalFoldedPhysicalDisplayIds);
+
if (strDisplayIds.length != 2 || TextUtils.isEmpty(strDisplayIds[0])
|| TextUtils.isEmpty(strDisplayIds[1])) {
Slog.w(TAG, "Folded display configuration invalid: [" + Arrays.toString(strDisplayIds)
@@ -101,23 +103,19 @@ class DeviceStateToLayoutMap {
final int[] foldedDeviceStates = context.getResources().getIntArray(
com.android.internal.R.array.config_foldedDeviceStates);
- final int[] unfoldedDeviceStates = context.getResources().getIntArray(
- com.android.internal.R.array.config_unfoldedDeviceStates);
// Only add folded states if folded state config is not empty
- if (foldedDeviceStates.length == 0 || unfoldedDeviceStates.length == 0) {
+ if (foldedDeviceStates.length == 0) {
return;
}
- for (int state : foldedDeviceStates) {
- // Create the folded state layout
- createLayout(state).createDisplayLocked(
- DisplayAddress.fromPhysicalDisplayId(displayIds[0]), true /*isDefault*/);
- }
+ // Create the folded state layout
+ final Layout foldedLayout = create(STATE_FOLDED);
+ foldedLayout.createDisplayLocked(
+ DisplayAddress.fromPhysicalDisplayId(displayIds[0]), true /*isDefault*/);
- for (int state : unfoldedDeviceStates) {
- // Create the unfolded state layout
- createLayout(state).createDisplayLocked(
- DisplayAddress.fromPhysicalDisplayId(displayIds[1]), true /*isDefault*/);
- }
+ // Create the unfolded state layout
+ final Layout unfoldedLayout = create(STATE_UNFOLDED);
+ unfoldedLayout.createDisplayLocked(
+ DisplayAddress.fromPhysicalDisplayId(displayIds[1]), true /*isDefault*/);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayGroup.java b/services/core/java/com/android/server/display/DisplayGroup.java
index 2dcd5ccaf5575a7778359085e582d11d865b5ac6..663883ab2825b0b2dc9c370d133fe42d86026b07 100644
--- a/services/core/java/com/android/server/display/DisplayGroup.java
+++ b/services/core/java/com/android/server/display/DisplayGroup.java
@@ -30,8 +30,6 @@ public class DisplayGroup {
private final List mDisplays = new ArrayList<>();
private final int mGroupId;
- private int mChangeCount;
-
DisplayGroup(int groupId) {
mGroupId = groupId;
}
@@ -47,16 +45,11 @@ public class DisplayGroup {
* @param display the {@link LogicalDisplay} to add to the Group
*/
void addDisplayLocked(LogicalDisplay display) {
- if (!containsLocked(display)) {
- mChangeCount++;
+ if (!mDisplays.contains(display)) {
mDisplays.add(display);
}
}
- boolean containsLocked(LogicalDisplay display) {
- return mDisplays.contains(display);
- }
-
/**
* Removes the provided {@code display} from the Group.
*
@@ -64,7 +57,6 @@ public class DisplayGroup {
* @return {@code true} if the {@code display} was removed; otherwise {@code false}
*/
boolean removeDisplayLocked(LogicalDisplay display) {
- mChangeCount++;
return mDisplays.remove(display);
}
@@ -73,11 +65,6 @@ public class DisplayGroup {
return mDisplays.isEmpty();
}
- /** Returns a count of the changes made to this display group. */
- int getChangeCountLocked() {
- return mChangeCount;
- }
-
/** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */
int getSizeLocked() {
return mDisplays.size();
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6fc3e09bed0bbe5d4f69f83599c623543f7b5726..c62dd72ada70e75fa5d9661925832c01a60746af 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -485,13 +485,13 @@ public final class DisplayManagerService extends SystemService {
synchronized (mSyncRoot) {
long timeout = SystemClock.uptimeMillis()
+ mInjector.getDefaultDisplayDelayTimeout();
- while (mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) == null
+ while (mLogicalDisplayMapper.getLocked(Display.DEFAULT_DISPLAY) == null
|| mVirtualDisplayAdapter == null) {
long delay = timeout - SystemClock.uptimeMillis();
if (delay <= 0) {
throw new RuntimeException("Timeout waiting for default display "
+ "to be initialized. DefaultDisplay="
- + mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY)
+ + mLogicalDisplayMapper.getLocked(Display.DEFAULT_DISPLAY)
+ ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
}
if (DEBUG) {
@@ -549,7 +549,7 @@ public final class DisplayManagerService extends SystemService {
mSystemReady = true;
// Just in case the top inset changed before the system was ready. At this point, any
// relevant configuration should be in place.
- recordTopInsetLocked(mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY));
+ recordTopInsetLocked(mLogicalDisplayMapper.getLocked(Display.DEFAULT_DISPLAY));
updateSettingsLocked();
}
@@ -617,7 +617,7 @@ public final class DisplayManagerService extends SystemService {
@VisibleForTesting
void setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
handleLogicalDisplayChangedLocked(display);
@@ -632,7 +632,7 @@ public final class DisplayManagerService extends SystemService {
*/
private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ final LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
display.getNonOverrideDisplayInfoLocked(outInfo);
}
@@ -691,8 +691,8 @@ public final class DisplayManagerService extends SystemService {
mDisplayStates.setValueAt(index, state);
mDisplayBrightnesses.setValueAt(index, brightnessState);
- runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
- .getPrimaryDisplayDeviceLocked());
+ runnable = updateDisplayStateLocked(
+ mLogicalDisplayMapper.getLocked(displayId).getPrimaryDisplayDeviceLocked());
}
// Setting the display power state can take hundreds of milliseconds
@@ -803,9 +803,9 @@ public final class DisplayManagerService extends SystemService {
private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
- final DisplayInfo info =
+ DisplayInfo info =
getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(),
display.getDisplayInfoLocked(), callingUid);
if (info.hasAccess(callingUid)
@@ -952,7 +952,7 @@ public final class DisplayManagerService extends SystemService {
private void requestColorModeInternal(int displayId, int colorMode) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null &&
display.getRequestedColorModeLocked() != colorMode) {
display.setRequestedColorModeLocked(colorMode);
@@ -989,7 +989,7 @@ public final class DisplayManagerService extends SystemService {
mDisplayDeviceRepo.onDisplayDeviceEvent(device,
DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(device);
if (display != null) {
return display.getDisplayIdLocked();
}
@@ -1203,7 +1203,7 @@ public final class DisplayManagerService extends SystemService {
// TODO - b/170498827 The rules regarding what display state to apply to each
// display will depend on the configuration/mapping of logical displays.
// Clean up LogicalDisplay.isEnabled() mechanism once this is fixed.
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+ final LogicalDisplay display = mLogicalDisplayMapper.getLocked(device);
final int state;
final int displayId = display.getDisplayIdLocked();
@@ -1364,7 +1364,7 @@ public final class DisplayManagerService extends SystemService {
float requestedRefreshRate, int requestedModeId, boolean preferMinimalPostProcessing,
boolean inTraversal) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display == null) {
return;
}
@@ -1406,7 +1406,7 @@ public final class DisplayManagerService extends SystemService {
private void setDisplayOffsetsInternal(int displayId, int x, int y) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display == null) {
return;
}
@@ -1424,7 +1424,7 @@ public final class DisplayManagerService extends SystemService {
private void setDisplayScalingDisabledInternal(int displayId, boolean disable) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ final LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display == null) {
return;
}
@@ -1460,7 +1460,7 @@ public final class DisplayManagerService extends SystemService {
@Nullable
private IBinder getDisplayToken(int displayId) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ final LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
if (device != null) {
@@ -1478,7 +1478,7 @@ public final class DisplayManagerService extends SystemService {
if (token == null) {
return null;
}
- final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getLocked(displayId);
if (logicalDisplay == null) {
return null;
}
@@ -1611,16 +1611,15 @@ public final class DisplayManagerService extends SystemService {
// Find the logical display that the display device is showing.
// Certain displays only ever show their own content.
- LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(device);
if (!ownContent) {
if (display != null && !display.hasContentLocked()) {
// If the display does not have any content of its own, then
// automatically mirror the requested logical display contents if possible.
- display = mLogicalDisplayMapper.getDisplayLocked(
- device.getDisplayIdToMirrorLocked());
+ display = mLogicalDisplayMapper.getLocked(device.getDisplayIdToMirrorLocked());
}
if (display == null) {
- display = mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY);
+ display = mLogicalDisplayMapper.getLocked(Display.DEFAULT_DISPLAY);
}
}
@@ -1897,9 +1896,9 @@ public final class DisplayManagerService extends SystemService {
@VisibleForTesting
DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
- final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+ DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
return displayDevice.getDisplayDeviceInfoLocked();
}
return null;
@@ -1909,9 +1908,9 @@ public final class DisplayManagerService extends SystemService {
@VisibleForTesting
int getDisplayIdToMirrorInternal(int displayId) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
- final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+ DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
return displayDevice.getDisplayIdToMirrorLocked();
}
return Display.INVALID_DISPLAY;
@@ -1993,8 +1992,7 @@ public final class DisplayManagerService extends SystemService {
ArraySet uids;
synchronized (mSyncRoot) {
int displayId = msg.arg1;
- final LogicalDisplay display =
- mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
uids = display.getPendingFrameRateOverrideUids();
display.clearPendingFrameRateOverrideUids();
}
@@ -2588,7 +2586,7 @@ public final class DisplayManagerService extends SystemService {
@Override // Binder call
public boolean isMinimalPostProcessingRequested(int displayId) {
synchronized (mSyncRoot) {
- return mLogicalDisplayMapper.getDisplayLocked(displayId)
+ return mLogicalDisplayMapper.getLocked(displayId)
.getRequestedMinimalPostProcessingLocked();
}
}
@@ -2833,7 +2831,7 @@ public final class DisplayManagerService extends SystemService {
@Override
public Point getDisplayPosition(int displayId) {
synchronized (mSyncRoot) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId);
if (display != null) {
return display.getDisplayPosition();
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index d9570c710b154a6038ee3a7d4e3e6b9710dce48c..20b133ce4d0a20d3b52fa61228d6cccbf68681ac 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -17,11 +17,11 @@
package com.android.server.display;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerInternal;
import android.util.ArraySet;
+import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayEventReceiver;
@@ -64,14 +64,12 @@ import java.util.Objects;
*/
final class LogicalDisplay {
private static final String TAG = "LogicalDisplay";
+ private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
// The layer stack we use when the display has been blanked to prevent any
// of its content from appearing.
private static final int BLANK_LAYER_STACK = -1;
- private static final DisplayInfo EMPTY_DISPLAY_INFO = new DisplayInfo();
-
- private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
private final int mDisplayId;
private final int mLayerStack;
@@ -299,7 +297,7 @@ final class LogicalDisplay {
// Check whether logical display has become invalid.
if (!deviceRepo.containsLocked(mPrimaryDisplayDevice)) {
- setPrimaryDisplayDeviceLocked(null);
+ mPrimaryDisplayDevice = null;
return;
}
@@ -686,28 +684,18 @@ final class LogicalDisplay {
* @param targetDisplay The display with which to swap display-devices.
* @return {@code true} if the displays were swapped, {@code false} otherwise.
*/
- public void swapDisplaysLocked(@NonNull LogicalDisplay targetDisplay) {
- final DisplayDevice oldTargetDevice =
- targetDisplay.setPrimaryDisplayDeviceLocked(mPrimaryDisplayDevice);
- setPrimaryDisplayDeviceLocked(oldTargetDevice);
- }
-
- /**
- * Sets the primary display device to the specified device.
- *
- * @param device The new device to set.
- * @return The previously set display device.
- */
- public DisplayDevice setPrimaryDisplayDeviceLocked(@Nullable DisplayDevice device) {
- final DisplayDevice old = mPrimaryDisplayDevice;
- mPrimaryDisplayDevice = device;
-
- // Reset all our display info data
- mPrimaryDisplayDeviceInfo = null;
- mBaseDisplayInfo.copyFrom(EMPTY_DISPLAY_INFO);
- mInfo.set(null);
+ public boolean swapDisplaysLocked(@NonNull LogicalDisplay targetDisplay) {
+ final DisplayDevice targetDevice = targetDisplay.getPrimaryDisplayDeviceLocked();
+ if (mPrimaryDisplayDevice == null || targetDevice == null) {
+ Slog.e(TAG, "Missing display device during swap: " + mPrimaryDisplayDevice + " , "
+ + targetDevice);
+ return false;
+ }
- return old;
+ final DisplayDevice tmpDevice = mPrimaryDisplayDevice;
+ mPrimaryDisplayDevice = targetDisplay.mPrimaryDisplayDevice;
+ targetDisplay.mPrimaryDisplayDevice = tmpDevice;
+ return true;
}
/**
@@ -730,8 +718,8 @@ final class LogicalDisplay {
public void dumpLocked(PrintWriter pw) {
pw.println("mDisplayId=" + mDisplayId);
- pw.println("mIsEnabled=" + mIsEnabled);
pw.println("mLayerStack=" + mLayerStack);
+ pw.println("mIsEnabled=" + mIsEnabled);
pw.println("mHasContent=" + mHasContent);
pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
pw.println("mRequestedColorMode=" + mRequestedColorMode);
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 22c12e93d0cc731e6690c0403553e6922e96ba5a..a3ff534e336e12a1aba25760a3215bc9fed38425 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -17,16 +17,13 @@
package com.android.server.display;
import android.content.Context;
-import android.hardware.devicestate.DeviceStateManager;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
import android.view.Display;
-import android.view.DisplayAddress;
+import android.view.DisplayEventReceiver;
import android.view.DisplayInfo;
import com.android.server.display.layout.Layout;
@@ -77,50 +74,24 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private final boolean mSingleDisplayDemoMode;
/**
- * Map of all logical displays indexed by logical display id.
+ * List of all logical displays indexed by logical display id.
* Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
* TODO: multi-display - Move the aforementioned comment?
*/
private final SparseArray mLogicalDisplays =
new SparseArray();
- /** Map of all display groups indexed by display group id. */
- private final SparseArray mDisplayGroups = new SparseArray<>();
+ /** A mapping from logical display id to display group. */
+ private final SparseArray mDisplayIdToGroupMap = new SparseArray<>();
private final DisplayDeviceRepository mDisplayDeviceRepo;
private final DeviceStateToLayoutMap mDeviceStateToLayoutMap;
private final Listener mListener;
private final int[] mFoldedDeviceStates;
- /**
- * Has an entry for every logical display that the rest of the system has been notified about.
- * Any entry in here requires us to send a {@link LOGICAL_DISPLAY_EVENT_REMOVED} event when it
- * is deleted or {@link LOGICAL_DISPLAY_EVENT_CHANGED} when it is changed.
- */
- private final SparseBooleanArray mUpdatedLogicalDisplays = new SparseBooleanArray();
-
- /**
- * Keeps track of all the display groups that we already told other people about. IOW, if a
- * display group is in this array, then we *must* send change and remove notifications for it
- * because other components know about them. Also, what this array stores is a change counter
- * for each group, so we know if the group itself has changes since we last sent out a
- * notification. See {@link DisplayGroup#getChangeCountLocked}.
- */
- private final SparseIntArray mUpdatedDisplayGroups = new SparseIntArray();
-
- /**
- * Array used in {@link #updateLogicalDisplaysLocked} to track events that need to be sent out.
- */
- private final SparseIntArray mLogicalDisplaysToUpdate = new SparseIntArray();
-
- /**
- * Array used in {@link #updateLogicalDisplaysLocked} to track events that need to be sent out.
- */
- private final SparseIntArray mDisplayGroupsToUpdate = new SparseIntArray();
-
private int mNextNonDefaultGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
private Layout mCurrentLayout = null;
- private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE;
+ private boolean mIsFolded = false;
LogicalDisplayMapper(Context context, DisplayDeviceRepository repo, Listener listener) {
mDisplayDeviceRepo = repo;
@@ -138,23 +109,14 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
public void onDisplayDeviceEventLocked(DisplayDevice device, int event) {
switch (event) {
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_ADDED:
- if (DEBUG) {
- Slog.d(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
- }
handleDisplayDeviceAddedLocked(device);
break;
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_CHANGED:
- if (DEBUG) {
- Slog.d(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
- }
updateLogicalDisplaysLocked();
break;
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_REMOVED:
- if (DEBUG) {
- Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
- }
updateLogicalDisplaysLocked();
break;
}
@@ -165,11 +127,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mListener.onTraversalRequested();
}
- public LogicalDisplay getDisplayLocked(int displayId) {
+ public LogicalDisplay getLocked(int displayId) {
return mLogicalDisplays.get(displayId);
}
- public LogicalDisplay getDisplayLocked(DisplayDevice device) {
+ public LogicalDisplay getLocked(DisplayDevice device) {
final int count = mLogicalDisplays.size();
for (int i = 0; i < count; i++) {
LogicalDisplay display = mLogicalDisplays.valueAt(i);
@@ -204,25 +166,16 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
}
- public int getDisplayGroupIdFromDisplayIdLocked(int displayId) {
- final LogicalDisplay display = getDisplayLocked(displayId);
- if (display == null) {
- return Display.INVALID_DISPLAY_GROUP;
- }
-
- final int size = mDisplayGroups.size();
+ public DisplayGroup getDisplayGroupLocked(int groupId) {
+ final int size = mDisplayIdToGroupMap.size();
for (int i = 0; i < size; i++) {
- final DisplayGroup displayGroup = mDisplayGroups.valueAt(i);
- if (displayGroup.containsLocked(display)) {
- return mDisplayGroups.keyAt(i);
+ final DisplayGroup displayGroup = mDisplayIdToGroupMap.valueAt(i);
+ if (displayGroup.getGroupId() == groupId) {
+ return displayGroup;
}
}
- return Display.INVALID_DISPLAY_GROUP;
- }
-
- public DisplayGroup getDisplayGroupLocked(int groupId) {
- return mDisplayGroups.get(groupId);
+ return null;
}
public void dumpLocked(PrintWriter pw) {
@@ -250,333 +203,229 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
void setDeviceStateLocked(int state) {
- if (state != mDeviceState) {
- resetLayoutLocked();
- mDeviceState = state;
- applyLayoutLocked();
- updateLogicalDisplaysLocked();
+ boolean folded = false;
+ for (int i = 0; i < mFoldedDeviceStates.length; i++) {
+ if (state == mFoldedDeviceStates[i]) {
+ folded = true;
+ break;
+ }
}
+ setDeviceFoldedLocked(folded);
}
- private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
- DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
- // Internal Displays need to have additional initialization.
- // TODO: b/168208162 - This initializes a default dynamic display layout for INTERNAL
- // devices, which will eventually just be a fallback in case no static layout definitions
- // exist or cannot be loaded.
- if (deviceInfo.type == Display.TYPE_INTERNAL) {
- initializeInternalDisplayDeviceLocked(device);
- }
+ void setDeviceFoldedLocked(boolean isFolded) {
+ mIsFolded = isFolded;
- // Create a logical display for the new display device
- LogicalDisplay display = createNewLogicalDisplayLocked(
- device, Layout.assignDisplayIdLocked(false /*isDefault*/));
+ // Until we have fully functioning state mapping, use hardcoded states based on isFolded
+ final int state = mIsFolded ? DeviceStateToLayoutMap.STATE_FOLDED
+ : DeviceStateToLayoutMap.STATE_UNFOLDED;
- applyLayoutLocked();
- updateLogicalDisplaysLocked();
- }
-
- /**
- * 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,
- * creating/adjusting/removing DisplayGroups, and notifying the rest of the system of the
- * relevant changes.
- */
- private void updateLogicalDisplaysLocked() {
- // Go through all the displays and figure out if they need to be updated.
- // Loops in reverse so that displays can be removed during the loop without affecting the
- // rest of the loop.
- for (int i = mLogicalDisplays.size() - 1; i >= 0; i--) {
- final int displayId = mLogicalDisplays.keyAt(i);
- LogicalDisplay display = mLogicalDisplays.valueAt(i);
+ if (DEBUG) {
+ Slog.d(TAG, "New device state: " + state);
+ }
- mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
- display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
+ final Layout layout = mDeviceStateToLayoutMap.get(state);
+ if (layout == null) {
+ return;
+ }
+ final Layout.Display displayLayout = layout.getById(Display.DEFAULT_DISPLAY);
+ if (displayLayout == null) {
+ return;
+ }
+ final DisplayDevice newDefaultDevice =
+ mDisplayDeviceRepo.getByAddressLocked(displayLayout.getAddress());
+ if (newDefaultDevice == null) {
+ return;
+ }
- display.updateLocked(mDisplayDeviceRepo);
- final DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
- final boolean wasPreviouslyUpdated = mUpdatedLogicalDisplays.get(displayId);
+ final LogicalDisplay defaultDisplay = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
+ mCurrentLayout = layout;
- // The display is no longer valid and needs to be removed.
- if (!display.isValidLocked()) {
- mUpdatedLogicalDisplays.delete(displayId);
+ // If we're already set up accurately, return early
+ if (defaultDisplay.getPrimaryDisplayDeviceLocked() == newDefaultDevice) {
+ return;
+ }
- // Remove from group
- final DisplayGroup displayGroup = getDisplayGroupLocked(
- getDisplayGroupIdFromDisplayIdLocked(displayId));
- if (displayGroup != null) {
- displayGroup.removeDisplayLocked(display);
- }
+ // We need to swap the default display's display-device with the one that is supposed
+ // to be the default in the new layout.
+ final LogicalDisplay displayToSwap = getLocked(newDefaultDevice);
+ if (displayToSwap == null) {
+ Slog.w(TAG, "Canceling display swap - unexpected empty second display for: "
+ + newDefaultDevice);
+ return;
+ }
+ defaultDisplay.swapDisplaysLocked(displayToSwap);
- if (wasPreviouslyUpdated) {
- // The display isn't actually removed from our internal data structures until
- // after the notification is sent; see {@link #sendUpdatesForDisplaysLocked}.
- mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED);
- } else {
- // This display never left this class, safe to remove without notification
- mLogicalDisplays.removeAt(i);
- }
- continue;
-
- // The display is new.
- } else if (!wasPreviouslyUpdated) {
- assignDisplayGroupLocked(display);
- mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_ADDED);
-
- // Underlying displays device has changed to a different one.
- } else if (!TextUtils.equals(mTempDisplayInfo.uniqueId, newDisplayInfo.uniqueId)) {
- // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
- assignDisplayGroupLocked(display);
- mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_SWAPPED);
-
- // Something about the display device has changed.
- } else if (!mTempDisplayInfo.equals(newDisplayInfo)) {
- // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
- assignDisplayGroupLocked(display);
- mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
-
- // Display frame rate overrides changed.
- } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
- mLogicalDisplaysToUpdate.put(
- displayId, LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
+ // We ensure that the non-default Display is always forced to be off. This was likely
+ // already done in a previous iteration, but we do it with each swap in case something in
+ // the underlying LogicalDisplays changed: like LogicalDisplay recreation, for example.
+ defaultDisplay.setEnabled(true);
+ displayToSwap.setEnabled(false);
- // Non-override display values changed.
- } else {
- // While application shouldn't know nor care about the non-overridden info, we
- // still need to let WindowManager know so it can update its own internal state for
- // things like display cutouts.
- display.getNonOverrideDisplayInfoLocked(mTempDisplayInfo);
- if (!mTempNonOverrideDisplayInfo.equals(mTempDisplayInfo)) {
- mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
- }
- }
+ // Update the world
+ updateLogicalDisplaysLocked();
+ }
- mUpdatedLogicalDisplays.put(displayId, true);
+ private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
+ DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
+ boolean isDefault = (deviceInfo.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
+ if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
+ Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
+ isDefault = false;
}
- // Go through the groups and do the same thing. We do this after displays since group
- // information can change in the previous loop.
- // Loops in reverse so that groups can be removed during the loop without affecting the
- // rest of the loop.
- for (int i = mDisplayGroups.size() - 1; i >= 0; i--) {
- final int groupId = mDisplayGroups.keyAt(i);
- final DisplayGroup group = mDisplayGroups.valueAt(i);
- final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) < 0;
- final int changeCount = group.getChangeCountLocked();
-
- if (group.isEmptyLocked()) {
- mUpdatedDisplayGroups.delete(groupId);
- if (wasPreviouslyUpdated) {
- mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_REMOVED);
- }
- continue;
- } else if (!wasPreviouslyUpdated) {
- mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_ADDED);
- } else if (mUpdatedDisplayGroups.get(groupId) != changeCount) {
- mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_CHANGED);
- }
- mUpdatedDisplayGroups.put(groupId, changeCount);
+ if (!isDefault && mSingleDisplayDemoMode) {
+ Slog.i(TAG, "Not creating a logical display for a secondary display "
+ + " because single display demo mode is enabled: " + deviceInfo);
+ return;
}
- // Send the display and display group updates in order by message type. This is important
- // to ensure that addition and removal notifications happen in the right order.
- sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_ADDED);
- sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_REMOVED);
- sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_CHANGED);
- sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
- sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_ADDED);
- sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_SWAPPED);
- sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_CHANGED);
- sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_REMOVED);
-
- mLogicalDisplaysToUpdate.clear();
- mDisplayGroupsToUpdate.clear();
- }
-
- /**
- * Send the specified message for all relevant displays in the specified display-to-message map.
- */
- private void sendUpdatesForDisplaysLocked(int msg) {
- for (int i = mLogicalDisplaysToUpdate.size() - 1; i >= 0; --i) {
- final int currMsg = mLogicalDisplaysToUpdate.valueAt(i);
- if (currMsg != msg) {
- continue;
- }
+ final int displayId = Layout.assignDisplayIdLocked(isDefault);
+ final int layerStack = assignLayerStackLocked(displayId);
- final int id = mLogicalDisplaysToUpdate.keyAt(i);
- mListener.onLogicalDisplayEventLocked(getDisplayLocked(id), msg);
- if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) {
- // We wait until we sent the EVENT_REMOVED event before actually removing the
- // display.
- mLogicalDisplays.delete(id);
- }
+ final DisplayGroup displayGroup;
+ final boolean addNewDisplayGroup =
+ isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0;
+ if (addNewDisplayGroup) {
+ final int groupId = assignDisplayGroupIdLocked(isDefault);
+ displayGroup = new DisplayGroup(groupId);
+ } else {
+ displayGroup = mDisplayIdToGroupMap.get(Display.DEFAULT_DISPLAY);
}
- }
-
- /**
- * Send the specified message for all relevant display groups in the specified message map.
- */
- private void sendUpdatesForGroupsLocked(int msg) {
- for (int i = mDisplayGroupsToUpdate.size() - 1; i >= 0; --i) {
- final int currMsg = mDisplayGroupsToUpdate.valueAt(i);
- if (currMsg != msg) {
- continue;
- }
- final int id = mDisplayGroupsToUpdate.keyAt(i);
- mListener.onDisplayGroupEventLocked(id, msg);
- if (msg == DISPLAY_GROUP_EVENT_REMOVED) {
- // We wait until we sent the EVENT_REMOVED event before actually removing the
- // group.
- mDisplayGroups.delete(id);
- }
+ LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
+ display.updateDisplayGroupIdLocked(displayGroup.getGroupId());
+ display.updateLocked(mDisplayDeviceRepo);
+ if (!display.isValidLocked()) {
+ // This should never happen currently.
+ Slog.w(TAG, "Ignoring display device because the logical display "
+ + "created from it was not considered valid: " + deviceInfo);
+ return;
}
- }
- private void assignDisplayGroupLocked(LogicalDisplay display) {
- final int displayId = display.getDisplayIdLocked();
+ // For foldable devices, we start the internal non-default displays as disabled.
+ // TODO - b/168208162 - this will be removed when we recalculate the layout with each
+ // display-device addition.
+ if (mFoldedDeviceStates.length > 0 && deviceInfo.type == Display.TYPE_INTERNAL
+ && !isDefault) {
+ display.setEnabled(false);
+ }
- // Get current display group data
- int groupId = getDisplayGroupIdFromDisplayIdLocked(displayId);
- final DisplayGroup oldGroup = getDisplayGroupLocked(groupId);
+ mLogicalDisplays.put(displayId, display);
+ displayGroup.addDisplayLocked(display);
+ mDisplayIdToGroupMap.append(displayId, displayGroup);
- // 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 hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP;
- if (groupId == Display.INVALID_DISPLAY_GROUP
- || hasOwnDisplayGroup != needsOwnDisplayGroup) {
- groupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup);
+ if (addNewDisplayGroup) {
+ // Group added events happen before Logical Display added events.
+ mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
+ LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
}
- // Create a new group if needed
- DisplayGroup newGroup = getDisplayGroupLocked(groupId);
- if (newGroup == null) {
- newGroup = new DisplayGroup(groupId);
- mDisplayGroups.append(groupId, newGroup);
- }
+ mListener.onLogicalDisplayEventLocked(display,
+ LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED);
- // Add/remove display from the groups.
- newGroup.addDisplayLocked(display);
- if (oldGroup != null && oldGroup != newGroup) {
- oldGroup.removeDisplayLocked(display);
+ if (!addNewDisplayGroup) {
+ // Group changed events happen after Logical Display added events.
+ mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
+ LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
}
- }
- /**
- * Resets the current layout in preparation for a new layout; essentially just marks
- * all the currently layed out displays as disabled. This ensures the display devices
- * are turned off. If they are meant to be used in the new layout,
- * {@link #applyLayoutLocked()} will reenabled them.
- */
- private void resetLayoutLocked() {
- final Layout layout = mDeviceStateToLayoutMap.get(mDeviceState);
- for (int i = layout.size() - 1; i >= 0; i--) {
- final Layout.Display displayLayout = layout.getAt(i);
- final LogicalDisplay display = getDisplayLocked(displayLayout.getLogicalDisplayId());
- if (display != null) {
- enableDisplayLocked(display, false);
- }
+ if (DEBUG) {
+ Slog.d(TAG, "New Display added: " + display);
}
}
-
/**
- * Apply (or reapply) the currently selected display layout.
+ * Updates all existing logical displays given the current set of display devices.
+ * Removes invalid logical displays. Sends notifications if needed.
*/
- private void applyLayoutLocked() {
- final Layout layout = mDeviceStateToLayoutMap.get(mDeviceState);
- mCurrentLayout = layout;
- Slog.i(TAG, "Applying the display layout for device state(" + mDeviceState
- + "): " + layout);
+ private void updateLogicalDisplaysLocked() {
+ for (int i = mLogicalDisplays.size() - 1; i >= 0; i--) {
+ final int displayId = mLogicalDisplays.keyAt(i);
+ LogicalDisplay display = mLogicalDisplays.valueAt(i);
- // Go through each of the displays in the current layout set.
- final int size = layout.size();
- for (int i = 0; i < size; i++) {
- final Layout.Display displayLayout = layout.getAt(i);
-
- // If the underlying display-device we want to use for this display
- // doesn't exist, then skip it. This can happen at startup as display-devices
- // trickle in one at a time, or if the layout has an error.
- final DisplayAddress address = displayLayout.getAddress();
- final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(address);
- if (device == null) {
- Slog.w(TAG, "The display device (" + address + "), is not available"
- + " for the display state " + mDeviceState);
- continue;
- }
+ mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
+ display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
+ DisplayEventReceiver.FrameRateOverride[] frameRatesOverrides =
+ display.getFrameRateOverrides();
+ display.updateLocked(mDisplayDeviceRepo);
+ final DisplayGroup changedDisplayGroup;
+ if (!display.isValidLocked()) {
+ mLogicalDisplays.removeAt(i);
+ final DisplayGroup displayGroup = mDisplayIdToGroupMap.removeReturnOld(displayId);
+ displayGroup.removeDisplayLocked(display);
+
+ mListener.onLogicalDisplayEventLocked(display,
+ LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED);
+
+ changedDisplayGroup = displayGroup;
+ } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
+ final int flags = display.getDisplayInfoLocked().flags;
+ final DisplayGroup defaultDisplayGroup = mDisplayIdToGroupMap.get(
+ Display.DEFAULT_DISPLAY);
+ if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
+ // The display should have its own DisplayGroup.
+ if (defaultDisplayGroup.removeDisplayLocked(display)) {
+ final int groupId = assignDisplayGroupIdLocked(false);
+ final DisplayGroup displayGroup = new DisplayGroup(groupId);
+ displayGroup.addDisplayLocked(display);
+ display.updateDisplayGroupIdLocked(groupId);
+ mDisplayIdToGroupMap.append(display.getDisplayIdLocked(), displayGroup);
+ mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
+ LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
+ changedDisplayGroup = defaultDisplayGroup;
+ } else {
+ changedDisplayGroup = null;
+ }
+ } else {
+ // The display should be a part of the default DisplayGroup.
+ final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
+ if (displayGroup != defaultDisplayGroup) {
+ displayGroup.removeDisplayLocked(display);
+ defaultDisplayGroup.addDisplayLocked(display);
+ display.updateDisplayGroupIdLocked(defaultDisplayGroup.getGroupId());
+ mListener.onDisplayGroupEventLocked(defaultDisplayGroup.getGroupId(),
+ LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
+ mDisplayIdToGroupMap.put(displayId, defaultDisplayGroup);
+ changedDisplayGroup = displayGroup;
+ } else {
+ changedDisplayGroup = null;
+ }
+ }
- // Now that we have a display-device, we need a LogicalDisplay to map it to. Find the
- // right one, if it doesn't exist, create a new one.
- final int logicalDisplayId = displayLayout.getLogicalDisplayId();
- LogicalDisplay newDisplay = getDisplayLocked(logicalDisplayId);
- if (newDisplay == null) {
- newDisplay = createNewLogicalDisplayLocked(
- null /*displayDevice*/, logicalDisplayId);
+ final String oldUniqueId = mTempDisplayInfo.uniqueId;
+ final String newUniqueId = display.getDisplayInfoLocked().uniqueId;
+ final int eventMsg = TextUtils.equals(oldUniqueId, newUniqueId)
+ ? LOGICAL_DISPLAY_EVENT_CHANGED : LOGICAL_DISPLAY_EVENT_SWAPPED;
+ mListener.onLogicalDisplayEventLocked(display, eventMsg);
+ } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
+ mListener.onLogicalDisplayEventLocked(display,
+ LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
+ changedDisplayGroup = null;
+ } else {
+ // While applications shouldn't know nor care about the non-overridden info, we
+ // still need to let WindowManager know so it can update its own internal state for
+ // things like display cutouts.
+ display.getNonOverrideDisplayInfoLocked(mTempDisplayInfo);
+ if (!mTempNonOverrideDisplayInfo.equals(mTempDisplayInfo)) {
+ mListener.onLogicalDisplayEventLocked(display,
+ LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED);
+ }
+ changedDisplayGroup = null;
}
- // Now swap the underlying display devices between the old display and the new display
- final LogicalDisplay oldDisplay = getDisplayLocked(device);
- if (newDisplay != oldDisplay) {
- newDisplay.swapDisplaysLocked(oldDisplay);
+ // CHANGED and REMOVED DisplayGroup events should always fire after Display events.
+ if (changedDisplayGroup != null) {
+ final int event = changedDisplayGroup.isEmptyLocked()
+ ? LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED
+ : LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED;
+ mListener.onDisplayGroupEventLocked(changedDisplayGroup.getGroupId(), event);
}
- enableDisplayLocked(newDisplay, true);
}
}
-
- /**
- * Creates a new logical display for the specified device and display Id and adds it to the list
- * of logical displays.
- *
- * @param device The device to associate with the LogicalDisplay.
- * @param displayId The display ID to give the new display. If invalid, a new ID is assigned.
- * @param isDefault Indicates if we are creating the default display.
- * @return The new logical display if created, null otherwise.
- */
- private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice device, int displayId) {
- final int layerStack = assignLayerStackLocked(displayId);
- final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
- display.updateLocked(mDisplayDeviceRepo);
- mLogicalDisplays.put(displayId, display);
-
- // Internal displays start off disabled. The display is enabled later if it is part of the
- // currently selected display layout.
- final boolean isEnabled = device != null
- && device.getDisplayDeviceInfoLocked().type != Display.TYPE_INTERNAL;
- enableDisplayLocked(display, isEnabled);
-
- return display;
- }
-
- private void enableDisplayLocked(LogicalDisplay display, boolean isEnabled) {
- final int displayId = display.getDisplayIdLocked();
- final DisplayInfo info = display.getDisplayInfoLocked();
-
- final boolean disallowSecondaryDisplay = mSingleDisplayDemoMode
- && (info.type != Display.TYPE_INTERNAL);
- if (isEnabled && disallowSecondaryDisplay) {
- Slog.i(TAG, "Not creating a logical display for a secondary display because single"
- + " display demo mode is enabled: " + display.getDisplayInfoLocked());
- isEnabled = false;
- }
-
- display.setEnabled(isEnabled);
- }
-
- private int assignDisplayGroupIdLocked(boolean isOwnDisplayGroup) {
- return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP;
- }
-
- private void initializeInternalDisplayDeviceLocked(DisplayDevice device) {
- // We always want to make sure that our default display layout creates a logical
- // display for every internal display device that is found.
- // To that end, when we are notified of a new internal display, we add it to
- // the default definition if it is not already there.
- final Layout layoutSet = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
- final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- final boolean isDefault = (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
- layoutSet.createDisplayLocked(info.address, isDefault);
+ private int assignDisplayGroupIdLocked(boolean isDefault) {
+ return isDefault ? Display.DEFAULT_DISPLAY_GROUP : mNextNonDefaultGroupId++;
}
private int assignLayerStackLocked(int displayId) {
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
deleted file mode 100644
index 92221c9713d3cef09dbde709d84dc95fa3c2ea38..0000000000000000000000000000000000000000
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.display;
-
-import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED;
-import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED;
-import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED;
-import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED;
-import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.verify;
-
-import android.app.PropertyInvalidatedCache;
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Process;
-import android.platform.test.annotations.Presubmit;
-import android.view.Display;
-import android.view.DisplayAddress;
-import android.view.DisplayInfo;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-
-@SmallTest
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class LogicalDisplayMapperTest {
- private static int sUniqueTestDisplayId = 0;
-
- private DisplayDeviceRepository mDisplayDeviceRepo;
- private LogicalDisplayMapper mLogicalDisplayMapper;
- private Context mContext;
-
- @Mock LogicalDisplayMapper.Listener mListenerMock;
-
- @Captor ArgumentCaptor mDisplayCaptor;
-
- @Before
- public void setUp() {
- // Share classloader to allow package private access.
- System.setProperty("dexmaker.share_classloader", "true");
- MockitoAnnotations.initMocks(this);
-
- mContext = InstrumentationRegistry.getContext();
- mDisplayDeviceRepo = new DisplayDeviceRepository(
- new DisplayManagerService.SyncRoot(),
- new PersistentDataStore(new PersistentDataStore.Injector() {
- @Override
- public InputStream openRead() {
- return null;
- }
-
- @Override
- public OutputStream startWrite() {
- return null;
- }
-
- @Override
- public void finishWrite(OutputStream os, boolean success) {}
- }));
-
- // Disable binder caches in this process.
- PropertyInvalidatedCache.disableForTestMode();
-
- mLogicalDisplayMapper = new LogicalDisplayMapper(
- mContext, mDisplayDeviceRepo, mListenerMock);
- }
-
-
- /////////////////
- // Test Methods
- /////////////////
-
- @Test
- public void testDisplayDeviceAddAndRemove_Internal() {
- DisplayDevice device = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_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(Display.DEFAULT_DISPLAY, id(displayRemoved));
- assertEquals(displayAdded, displayRemoved);
- }
-
- @Test
- public void testDisplayDeviceAddAndRemove_NonInternalTypes() {
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_EXTERNAL);
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_WIFI);
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_OVERLAY);
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_VIRTUAL);
- testDisplayDeviceAddAndRemove_NonInternal(Display.TYPE_UNKNOWN);
-
- // Call the internal test again, just to verify that adding non-internal displays
- // doesn't affect the ability for an internal display to become the default display.
- testDisplayDeviceAddAndRemove_Internal();
- }
-
- @Test
- public void testDisplayDeviceAdd_TwoInternalOneDefault() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
-
- LogicalDisplay display1 = add(device1);
- assertEquals(info(display1).address, info(device1).address);
- assertNotEquals(Display.DEFAULT_DISPLAY, id(display1));
-
- LogicalDisplay display2 = add(device2);
- assertEquals(info(display2).address, info(device2).address);
- assertEquals(Display.DEFAULT_DISPLAY, id(display2));
- }
-
- @Test
- public void testDisplayDeviceAdd_TwoInternalBothDefault() {
- DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
- DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
-
- LogicalDisplay display1 = add(device1);
- assertEquals(info(display1).address, info(device1).address);
- assertEquals(Display.DEFAULT_DISPLAY, id(display1));
-
- LogicalDisplay display2 = add(device2);
- assertEquals(info(display2).address, info(device2).address);
- // Despite the flags, we can only have one default display
- assertNotEquals(Display.DEFAULT_DISPLAY, id(display2));
- }
-
- @Test
- public void testGetDisplayIdsLocked() {
- add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
- add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
- add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
-
- int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID);
- assertEquals(3, ids.length);
- Arrays.sort(ids);
- assertEquals(Display.DEFAULT_DISPLAY, ids[0]);
- }
-
- @Test
- public void testSingleDisplayGroup() {
- LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
- LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
- LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
-
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)));
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2)));
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
- }
-
- @Test
- public void testMultipleDisplayGroups() {
- LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
- LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
-
-
- TestDisplayDevice device3 = createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800,
- DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
- LogicalDisplay display3 = add(device3);
-
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1)));
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2)));
- assertNotEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
-
- // Now switch it back to the default group by removing the flag and issuing an update
- DisplayDeviceInfo info = device3.getSourceInfo();
- info.flags = info.flags & ~DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
- mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
-
- // Verify the new group is correct.
- assertEquals(Display.DEFAULT_DISPLAY_GROUP,
- mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
- }
-
-
- /////////////////
- // Helper Methods
- /////////////////
-
- private TestDisplayDevice createDisplayDevice(int type, int width, int height, int flags) {
- return createDisplayDevice(new DisplayAddressImpl(), type, width, height, flags);
- }
-
- private TestDisplayDevice createDisplayDevice(
- DisplayAddress address, int type, int width, int height, int flags) {
- TestDisplayDevice device = new TestDisplayDevice();
- DisplayDeviceInfo displayDeviceInfo = device.getSourceInfo();
- displayDeviceInfo.type = type;
- displayDeviceInfo.width = width;
- displayDeviceInfo.height = height;
- displayDeviceInfo.flags = flags;
- displayDeviceInfo.address = new DisplayAddressImpl();
- return device;
- }
-
- private DisplayDeviceInfo info(DisplayDevice device) {
- return device.getDisplayDeviceInfoLocked();
- }
-
- private DisplayInfo info(LogicalDisplay display) {
- return display.getDisplayInfoLocked();
- }
-
- private int id(LogicalDisplay display) {
- return display.getDisplayIdLocked();
- }
-
- private LogicalDisplay add(DisplayDevice device) {
- mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_ADDED);
- ArgumentCaptor displayCaptor =
- ArgumentCaptor.forClass(LogicalDisplay.class);
- verify(mListenerMock).onLogicalDisplayEventLocked(
- displayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_ADDED));
- clearInvocations(mListenerMock);
- return displayCaptor.getValue();
- }
-
- private void testDisplayDeviceAddAndRemove_NonInternal(int type) {
- DisplayDevice device = createDisplayDevice(type, 600, 800, 0);
-
- // add
- LogicalDisplay displayAdded = add(device);
- assertEquals(info(displayAdded).address, info(device).address);
- assertNotEquals(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();
- assertNotEquals(Display.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 {
- private DisplayDeviceInfo mInfo = new DisplayDeviceInfo();
- private DisplayDeviceInfo mSentInfo;
-
- TestDisplayDevice() {
- super(null, null, "test_display_" + sUniqueTestDisplayId++, mContext);
- mInfo = new DisplayDeviceInfo();
- }
-
- @Override
- public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
- if (mSentInfo == null) {
- mSentInfo = new DisplayDeviceInfo();
- mSentInfo.copyFrom(mInfo);
- }
- return mSentInfo;
- }
-
- @Override
- public void applyPendingDisplayDeviceInfoChangesLocked() {
- mSentInfo = null;
- }
-
- @Override
- public boolean hasStableUniqueId() {
- return true;
- }
-
- public DisplayDeviceInfo getSourceInfo() {
- return mInfo;
- }
- }
-}
-