diff options
10 files changed, 281 insertions, 14 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index defcab7c3035..a86c5cbd2451 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -267,6 +267,12 @@ public abstract class DisplayManagerInternal { public abstract void ignoreProximitySensorUntilChanged(); /** + * Sets the folded state of the device. + * TODO: b/168208522 - Remove in favor of DisplayStatePolicy when that is available. + */ + public abstract void setDeviceFolded(boolean isFolded); + + /** * Describes the requested power state of the display. * * This object is intended to describe the general characteristics of the diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a334be301a46..c4d096320607 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4443,4 +4443,13 @@ <!-- WindowsManager JetPack display features --> <string name="config_display_features" translatable="false" /> + + <!-- Physical Display IDs of the display-devices that are swapped when a folding device folds. + This list is expected to contain two elements: the first is the display to use + when the device is folded, the second is the display to use when unfolded. If the array + is empty or the display IDs are not recognized, this feature is turned off and the value + ignored. + TODO: b/170470621 - remove once we can have multiple Internal displays in DMS as + well as a notification from DisplayStateManager. --> + <string-array name="config_internalFoldedPhysicalDisplayIds" translatable="false" /> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 54101e6b369f..9858f5e7c585 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4076,4 +4076,5 @@ <java-symbol type="array" name="config_keep_warming_services" /> <java-symbol type="string" name="config_display_features" /> + <java-symbol type="array" name="config_internalFoldedPhysicalDisplayIds" /> </resources> diff --git a/services/core/java/com/android/server/display/DisplayDeviceRepository.java b/services/core/java/com/android/server/display/DisplayDeviceRepository.java index aa4db29e0d49..5c0fceb9b795 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceRepository.java +++ b/services/core/java/com/android/server/display/DisplayDeviceRepository.java @@ -112,6 +112,17 @@ class DisplayDeviceRepository implements DisplayAdapter.Listener { } } + public DisplayDevice getByIdLocked(@NonNull String uniqueId) { + final int count = mDisplayDevices.size(); + for (int i = 0; i < count; i++) { + final DisplayDevice d = mDisplayDevices.get(i); + if (uniqueId.equals(d.getUniqueId())) { + return d; + } + } + return null; + } + private void handleDisplayDeviceAdded(DisplayDevice device) { synchronized (mSyncRoot) { DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index ffce3be4b769..a600292eca31 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -324,7 +324,7 @@ public final class DisplayManagerService extends SystemService { mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); mUiHandler = UiThread.getHandler(); mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore); - mLogicalDisplayMapper = new LogicalDisplayMapper(mDisplayDeviceRepo, + mLogicalDisplayMapper = new LogicalDisplayMapper(context, mDisplayDeviceRepo, new LogicalDisplayListener(), mPersistentDataStore); mDisplayModeDirector = new DisplayModeDirector(context, mHandler); Resources resources = mContext.getResources(); @@ -576,6 +576,7 @@ public final class DisplayManagerService extends SystemService { Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" + Display.stateToString(state) + ", brightness=" + brightnessState + ")"); + mGlobalDisplayState = state; mGlobalDisplayBrightness = brightnessState; applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); @@ -983,6 +984,15 @@ public final class DisplayManagerService extends SystemService { scheduleTraversalLocked(false); } + private void handleLogicalDisplaySwappedLocked(@NonNull LogicalDisplay display) { + final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); + final Runnable work = updateDisplayStateLocked(device); + if (work != null) { + mHandler.post(work); + } + handleLogicalDisplayChangedLocked(display); + } + private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> { Runnable runnable = updateDisplayStateLocked(device); @@ -997,10 +1007,15 @@ public final class DisplayManagerService extends SystemService { // by the display power controller (if known). DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { - // TODO - multi-display - The rules regarding what display state to apply to each + // TODO - b/170498827 The rules regarding what display state to apply to each // display will depend on the configuration/mapping of logical displays. - return device.requestDisplayStateLocked( - mGlobalDisplayState, mGlobalDisplayBrightness); + // Clean up LogicalDisplay.isEnabled() mechanism once this is fixed. + int state = mGlobalDisplayState; + final LogicalDisplay display = mLogicalDisplayMapper.getLocked(device); + if (display != null && !display.isEnabled()) { + state = Display.STATE_OFF; + } + return device.requestDisplayStateLocked(state, mGlobalDisplayBrightness); } return null; } @@ -1346,6 +1361,12 @@ public final class DisplayManagerService extends SystemService { } } + void setFoldOverride(Boolean isFolded) { + synchronized (mSyncRoot) { + mLogicalDisplayMapper.setFoldOverrideLocked(isFolded); + } + } + private void clearViewportsLocked() { mViewports.clear(); } @@ -1698,6 +1719,10 @@ public final class DisplayManagerService extends SystemService { case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED: handleLogicalDisplayRemovedLocked(display); break; + + case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_SWAPPED: + handleLogicalDisplaySwappedLocked(display); + break; } } @@ -2538,6 +2563,13 @@ public final class DisplayManagerService extends SystemService { public void ignoreProximitySensorUntilChanged() { mDisplayPowerController.ignoreProximitySensorUntilChanged(); } + + @Override + public void setDeviceFolded(boolean isFolded) { + synchronized (mSyncRoot) { + mLogicalDisplayMapper.setDeviceFoldedLocked(isFolded); + } + } } class DesiredDisplayModeSpecsObserver diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index 0c6c797b917a..111664a078df 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -56,6 +56,8 @@ class DisplayManagerShellCommand extends ShellCommand { return setDisplayWhiteBalanceLoggingEnabled(false); case "dwb-set-cct": return setAmbientColorTemperatureOverride(); + case "set-fold": + return setFoldOverride(); default: return handleDefaultCommands(cmd); } @@ -82,6 +84,8 @@ class DisplayManagerShellCommand extends ShellCommand { pw.println(" Disable display white-balance logging."); pw.println(" dwb-set-cct CCT"); pw.println(" Sets the ambient color temperature override to CCT (use -1 to disable)."); + pw.println(" set-fold [fold|unfold|reset]"); + pw.println(" Simulates the 'fold' state of a device. 'reset' for default behavior."); pw.println(); Intent.printIntentArgsHelp(pw , ""); } @@ -148,4 +152,26 @@ class DisplayManagerShellCommand extends ShellCommand { mService.setAmbientColorTemperatureOverride(cct); return 0; } + + private int setFoldOverride() { + String state = getNextArg(); + if (state == null) { + getErrPrintWriter().println("Error: no parameter specified for set-fold"); + return 1; + } + final Boolean isFolded; + if ("fold".equals(state)) { + isFolded = true; + } else if ("unfold".equals(state)) { + isFolded = false; + } else if ("reset".equals(state)) { + isFolded = null; + } else { + getErrPrintWriter().println("Error: Invalid fold state request: " + state); + return 1; + } + + mService.setFoldOverride(isFolded); + return 0; + } } diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index bf8b891cffb8..a17a294cd1d7 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -16,9 +16,11 @@ package com.android.server.display; +import android.annotation.NonNull; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; +import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; @@ -57,6 +59,7 @@ import java.util.Objects; * </p> */ 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 @@ -114,6 +117,12 @@ final class LogicalDisplay { private final Rect mTempLayerStackRect = new Rect(); private final Rect mTempDisplayRect = new Rect(); + /** + * Indicates that the Logical display is enabled (default). See {@link #setEnabled} for + * more information. + */ + private boolean mIsEnabled = true; + public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) { mDisplayId = displayId; mLayerStack = layerStack; @@ -575,6 +584,44 @@ final class LogicalDisplay { mDisplayScalingDisabled = disableScaling; } + /** + * Swap the underlying {@link DisplayDevice} with the specificed LogicalDisplay. + * + * @param targetDisplay The display with which to swap display-devices. + * @return {@code true} if the displays were swapped, {@code false} otherwise. + */ + 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; + } + + final DisplayDevice tmpDevice = mPrimaryDisplayDevice; + mPrimaryDisplayDevice = targetDisplay.mPrimaryDisplayDevice; + targetDisplay.mPrimaryDisplayDevice = tmpDevice; + return true; + } + + /** + * Sets the LogicalDisplay to be enabled or disabled. If the display is not enabled, + * the system will always set the display to power off, regardless of the global state of the + * device. + * TODO: b/170498827 - Remove when updateDisplayStateLocked is updated. + */ + public void setEnabled(boolean isEnabled) { + mIsEnabled = isEnabled; + } + + /** + * @return {@code true} iff the LogicalDisplay is enabled or {@code false} + * if disabled indicating that the display has been forced to be OFF. + */ + public boolean isEnabled() { + return mIsEnabled; + } + public void dumpLocked(PrintWriter pw) { pw.println("mDisplayId=" + mDisplayId); pw.println("mLayerStack=" + mLayerStack); diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 8a90a142a765..942a12ebf64e 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -16,7 +16,9 @@ package com.android.server.display; +import android.content.Context; import android.os.SystemProperties; +import android.text.TextUtils; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -26,6 +28,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.io.PrintWriter; import java.util.Arrays; +import java.util.Objects; import java.util.function.Consumer; /** @@ -39,9 +42,12 @@ import java.util.function.Consumer; class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private static final String TAG = "LogicalDisplayMapper"; + private static final boolean DEBUG = false; + public static final int LOGICAL_DISPLAY_EVENT_ADDED = 1; public static final int LOGICAL_DISPLAY_EVENT_CHANGED = 2; public static final int LOGICAL_DISPLAY_EVENT_REMOVED = 3; + public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4; /** * Temporary display info, used for comparing display configurations. @@ -59,6 +65,24 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final boolean mSingleDisplayDemoMode; /** + * Physical Display ID of the DisplayDevice to associate with the default LogicalDisplay + * when {@link mIsFolded} is set to {@code true}. + */ + private String mDisplayIdToUseWhenFolded; + + /** + * Physical Display ID of the DisplayDevice to associate with the default LogicalDisplay + * when {@link mIsFolded} is set to {@code false}. + */ + private String mDisplayIdToUseWhenUnfolded; + + /** Overrides the folded state of the device. For use with ADB commands. */ + private Boolean mIsFoldedOverride; + + /** Saves the last device fold state. */ + private boolean mIsFolded; + + /** * 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? @@ -71,13 +95,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final PersistentDataStore mPersistentDataStore; private final Listener mListener; - LogicalDisplayMapper(DisplayDeviceRepository repo, Listener listener, + LogicalDisplayMapper(Context context, DisplayDeviceRepository repo, Listener listener, PersistentDataStore persistentDataStore) { mDisplayDeviceRepo = repo; mPersistentDataStore = persistentDataStore; mListener = listener; mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); mDisplayDeviceRepo.addListener(this); + + loadFoldedDisplayConfig(context); } @Override @@ -141,23 +167,104 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } } + public void setDeviceFoldedLocked(boolean isFolded) { + mIsFolded = isFolded; + if (mIsFoldedOverride != null) { + isFolded = mIsFoldedOverride.booleanValue(); + } + + if (mDisplayIdToUseWhenFolded == null || mDisplayIdToUseWhenUnfolded == null + || mLogicalDisplays.size() < 2) { + // Do nothing if this behavior is disabled or there are less than two displays. + return; + } + + final DisplayDevice deviceFolded = + mDisplayDeviceRepo.getByIdLocked(mDisplayIdToUseWhenFolded); + final DisplayDevice deviceUnfolded = + mDisplayDeviceRepo.getByIdLocked(mDisplayIdToUseWhenUnfolded); + if (deviceFolded == null || deviceUnfolded == null) { + // If the expected devices for folding functionality are not present, return early. + return; + } + + // Find the associated LogicalDisplays for the configured "folding" DeviceDisplays. + final LogicalDisplay displayFolded = getLocked(deviceFolded); + final LogicalDisplay displayUnfolded = getLocked(deviceUnfolded); + if (displayFolded == null || displayFolded == null) { + // If the expected displays are not present, return early. + return; + } + + // Find out which display is currently default and which is disabled. + final LogicalDisplay defaultDisplay = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); + final LogicalDisplay disabledDisplay; + if (defaultDisplay == displayFolded) { + disabledDisplay = displayUnfolded; + } else if (defaultDisplay == displayUnfolded) { + disabledDisplay = displayFolded; + } else { + // If neither folded or unfolded displays are currently set to the default display, we + // are in an unknown state and it's best to log the error and bail. + Slog.e(TAG, "Unexpected: when attempting to swap displays, neither of the two" + + " configured displays were set up as the default display. Default: " + + defaultDisplay.getDisplayInfoLocked() + ", ConfiguredDisplays: [ folded=" + + displayFolded.getDisplayInfoLocked() + ", unfolded=" + + displayUnfolded.getDisplayInfoLocked() + " ]"); + return; + } + + if (isFolded == (defaultDisplay == displayFolded)) { + // Nothing to do, already in the right state. + return; + } + + // Everything was checked and we need to swap, lets swap. + displayFolded.swapDisplaysLocked(displayUnfolded); + + // 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); + disabledDisplay.setEnabled(false); + + // Update the world + updateLogicalDisplaysLocked(); + + if (DEBUG) { + Slog.d(TAG, "Folded displays: isFolded: " + isFolded + ", defaultDisplay? " + + defaultDisplay.getDisplayInfoLocked()); + } + } + public void dumpLocked(PrintWriter pw) { pw.println("LogicalDisplayMapper:"); - pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); - pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); + ipw.increaseIndent(); + + ipw.println("mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); + ipw.println("mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); final int logicalDisplayCount = mLogicalDisplays.size(); - pw.println(); - pw.println(" Logical Displays: size=" + logicalDisplayCount); + ipw.println(); + ipw.println("Logical Displays: size=" + logicalDisplayCount); - IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); - ipw.increaseIndent(); for (int i = 0; i < logicalDisplayCount; i++) { int displayId = mLogicalDisplays.keyAt(i); LogicalDisplay display = mLogicalDisplays.valueAt(i); - pw.println(" Display " + displayId + ":"); + ipw.println("Display " + displayId + ":"); + ipw.increaseIndent(); display.dumpLocked(ipw); + ipw.decreaseIndent(); + ipw.println(); + } + } + + void setFoldOverrideLocked(Boolean isFolded) { + if (!Objects.equals(isFolded, mIsFoldedOverride)) { + mIsFoldedOverride = isFolded; + setDeviceFoldedLocked(mIsFolded); } } @@ -211,8 +318,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mListener.onLogicalDisplayEventLocked(display, LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED); } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { - mListener.onLogicalDisplayEventLocked(display, - LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED); + 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 { // 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 @@ -236,6 +346,21 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return displayId; } + private void loadFoldedDisplayConfig(Context context) { + final String[] displayIds = context.getResources().getStringArray( + com.android.internal.R.array.config_internalFoldedPhysicalDisplayIds); + + if (displayIds.length != 2 || TextUtils.isEmpty(displayIds[0]) + || TextUtils.isEmpty(displayIds[1])) { + Slog.w(TAG, "Folded display configuration invalid: [" + Arrays.toString(displayIds) + + "]"); + return; + } + + mDisplayIdToUseWhenFolded = displayIds[0]; + mDisplayIdToUseWhenUnfolded = displayIds[1]; + } + public interface Listener { void onLogicalDisplayEventLocked(LogicalDisplay display, int event); void onTraversalRequested(); diff --git a/services/core/java/com/android/server/policy/DisplayFoldController.java b/services/core/java/com/android/server/policy/DisplayFoldController.java index 0db3d78fed5b..0ca6e5923f1b 100644 --- a/services/core/java/com/android/server/policy/DisplayFoldController.java +++ b/services/core/java/com/android/server/policy/DisplayFoldController.java @@ -80,6 +80,8 @@ class DisplayFoldController { } void setDeviceFolded(boolean folded) { + mDisplayManagerInternal.setDeviceFolded(folded); + if (mFolded != null && mFolded == folded) { return; } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0313aaeef0d6..b74de1347224 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -117,6 +117,7 @@ import android.database.ContentObserver; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManagerInternal; import android.hardware.hdmi.HdmiAudioSystemClient; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; @@ -366,6 +367,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { StatusBarManagerInternal mStatusBarManagerInternal; AudioManagerInternal mAudioManagerInternal; DisplayManager mDisplayManager; + DisplayManagerInternal mDisplayManagerInternal; boolean mPreloadedRecentApps; final Object mServiceAquireLock = new Object(); Vibrator mVibrator; // Vibrator for giving feedback of orientation changes @@ -469,6 +471,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLidKeyboardAccessibility; int mLidNavigationAccessibility; private boolean mLidControlsDisplayFold; + private boolean mShouldSwapDisplaysOnLidSwitch; int mShortPressOnPowerBehavior; int mLongPressOnPowerBehavior; int mVeryLongPressOnPowerBehavior; @@ -1752,6 +1755,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); + mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mPackageManager = mContext.getPackageManager(); mHasFeatureWatch = mPackageManager.hasSystemFeature(FEATURE_WATCH); mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK); @@ -1845,6 +1849,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.integer.config_lidNavigationAccessibility); mLidControlsDisplayFold = mContext.getResources().getBoolean( com.android.internal.R.bool.config_lidControlsDisplayFold); + mShouldSwapDisplaysOnLidSwitch = mContext.getResources().getStringArray( + com.android.internal.R.array.config_internalFoldedPhysicalDisplayIds).length == 2; mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromKey); @@ -5035,6 +5041,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { final int lidState = mDefaultDisplayPolicy.getLidState(); if (mLidControlsDisplayFold && mDisplayFoldController != null) { mDisplayFoldController.requestDeviceFolded(lidState == LID_CLOSED); + } else if (mShouldSwapDisplaysOnLidSwitch) { + mDisplayManagerInternal.setDeviceFolded(lidState == LID_CLOSED); } else if (lidState == LID_CLOSED) { int lidBehavior = getLidBehavior(); switch (lidBehavior) { |