Swap default display when lid-switch is toggled.
For devices with multiple internal displays that support a lid-switch, automatically swap which DisplayDevice is associated with the default Logical Display. Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/display Bug: 130724654 Change-Id: I7280b4f49c0f11df4ecd0f2a1547c95c168265c7
This commit is contained in:
@@ -266,6 +266,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.
|
||||
*
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
@@ -58,6 +64,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.
|
||||
@@ -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();
|
||||
|
||||
@@ -80,6 +80,8 @@ class DisplayFoldController {
|
||||
}
|
||||
|
||||
void setDeviceFolded(boolean folded) {
|
||||
mDisplayManagerInternal.setDeviceFolded(folded);
|
||||
|
||||
if (mFolded != null && mFolded == folded) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user