Loading services/core/java/com/android/server/display/DisplayGroup.java +11 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ public class DisplayGroup { private final List<LogicalDisplay> mDisplays = new ArrayList<>(); private final int mGroupId; private String mGroupName; private int mChangeCount; DisplayGroup(int groupId) { Loading @@ -43,6 +45,14 @@ public class DisplayGroup { return mGroupId; } public String getGroupName() { return mGroupName; } public void setGroupName(String groupName) { mGroupName = groupName; } /** * Adds the provided {@code display} to the Group * Loading Loading @@ -107,6 +117,7 @@ public class DisplayGroup { LogicalDisplay logicalDisplay = mDisplays.get(i); ipw.println("Display " + logicalDisplay.getDisplayIdLocked() + " " + logicalDisplay.getPrimaryDisplayDeviceLocked()); ipw.println("Group name: " + getGroupName()); } } } services/core/java/com/android/server/display/DisplayGroupAllocator.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 android.content.Context; import android.util.SparseArray; import android.view.Display; import com.android.server.wm.DesktopModeHelper; /** * DisplayGroupAllocator helps select which display groups new displays should be added to, * when they are added to the system. It takes into account attributes of the display, as well * as which display groups already exist. */ class DisplayGroupAllocator { private static final String TAG = "DisplayGroupAllocator"; private boolean mCanDeviceEnterDesktopMode; private boolean mCanDefaultDisplayEnterDesktopMode; private Context mContext; private final Injector mInjector; private int mReason; public static final String GROUP_TYPE_PRIMARY = ""; public static final String GROUP_TYPE_SECONDARY = "secondary_mode"; public static final int REASON_NON_DESKTOP = 0; public static final int REASON_PROJECTED = 1; public static final int REASON_EXTENDED = 2; public static final int REASON_FALLBACK = 3; DisplayGroupAllocator(Context context) { this(context, new Injector()); } DisplayGroupAllocator(Context context, Injector injector) { mInjector = injector; mContext = context; } public void initLater(Context context) { mContext = context; mCanDeviceEnterDesktopMode = mInjector.canEnterDesktopMode(mContext); mCanDefaultDisplayEnterDesktopMode = mInjector.canInternalDisplayHostDesktops(mContext); } /** * Decides which group type is needed for a given display content mode. * Locked on DisplayManager mSyncRoot. * Sets mReason, for logging purposes. */ public String decideRequiredGroupTypeLocked(LogicalDisplay display, int type) { mReason = getContentModeForDisplayLocked(display, type); return switch (mReason) { case REASON_NON_DESKTOP, REASON_EXTENDED, REASON_FALLBACK -> GROUP_TYPE_PRIMARY; case REASON_PROJECTED -> GROUP_TYPE_SECONDARY; default -> GROUP_TYPE_PRIMARY; }; } /** * Returns the first suitable group for a display to be sorted into, given the required group * type. * @param requiredGroupType which content mode group this display should be used in * @param displayGroups array of existing display groups. * @return Id of group that display should be sorted into */ public static int calculateGroupId(String requiredGroupType, SparseArray<DisplayGroup> displayGroups) { // go through display groups, find one group with the correct tag. final int size = displayGroups.size(); int calculatedGroup = Display.INVALID_DISPLAY_GROUP; for (int i = 0; i < size; i++) { final DisplayGroup displayGroup = displayGroups.valueAt(i); if (displayGroup.getGroupName().equals(requiredGroupType)) { calculatedGroup = displayGroups.keyAt(i); break; } } return calculatedGroup; } /** * Calculates whether this display supports desktop mode */ public boolean isDesktopModeSupportedOnDisplayLocked(LogicalDisplay display, int type) { if (!mCanDeviceEnterDesktopMode) { return false; } if (type == Display.TYPE_INTERNAL) { return mCanDefaultDisplayEnterDesktopMode; } if (type == Display.TYPE_EXTERNAL || type == Display.TYPE_OVERLAY) { return mInjector.canDisplayHostTasksLocked(display); } return false; } /** * Decides on the content mode that the display should be using. */ public int getContentModeForDisplayLocked(LogicalDisplay display, int type) { // conditions for non desktop mode; // desktop mode not supported on device or this display // or display is internal, and should be in a different group to the // projected and extended mode displays. if (!mCanDeviceEnterDesktopMode || type == Display.TYPE_INTERNAL) { return REASON_NON_DESKTOP; } // conditions for projected mode; // desktop mode supported on device, external display, but not internal if (mCanDeviceEnterDesktopMode && isDesktopModeSupportedOnDisplayLocked(display, type) && !mCanDefaultDisplayEnterDesktopMode) { return REASON_PROJECTED; } // conditions for extended mode; // desktop mode supported on both displays if (mCanDeviceEnterDesktopMode && isDesktopModeSupportedOnDisplayLocked(display, type) && mCanDefaultDisplayEnterDesktopMode) { return REASON_EXTENDED; } return REASON_FALLBACK; } public int getReason() { return mReason; } static class Injector { private boolean canEnterDesktopMode(Context context) { return DesktopModeHelper.canEnterDesktopMode(context); } boolean canInternalDisplayHostDesktops(Context context) { return DesktopModeHelper.canInternalDisplayHostDesktops(context); } boolean canDisplayHostTasksLocked(LogicalDisplay display) { return display.canHostTasksLocked(); } } } services/core/java/com/android/server/display/LogicalDisplay.java +1 −1 Original line number Diff line number Diff line Loading @@ -1129,7 +1129,7 @@ final class LogicalDisplay { /** * Gets the name of display group to which the display is assigned. */ public String getDisplayGroupNameLocked() { public String getLayoutGroupNameLocked() { return mDisplayGroupName; } Loading services/core/java/com/android/server/display/LogicalDisplayMapper.java +38 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURAT import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.server.display.DisplayGroupAllocator.GROUP_TYPE_PRIMARY; import static com.android.server.display.DisplayGroupAllocator.calculateGroupId; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -216,6 +219,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final DisplayManagerFlags mFlags; private final SyntheticModeManager mSyntheticModeManager; private final FeatureFlags mDeviceStateManagerFlags; private final Context mContext; private final DisplayGroupAllocator mDisplayGroupAllocator; LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, FoldGracePeriodProvider foldGracePeriodProvider, Loading @@ -226,7 +231,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { handler, new DeviceStateToLayoutMap((isDefault) -> isDefault ? DEFAULT_DISPLAY : sNextNonDefaultDisplayId++, flags), flags, new SyntheticModeManager(flags)); new SyntheticModeManager(flags), new DisplayGroupAllocator(context)); } LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, Loading @@ -234,8 +239,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { @NonNull DisplayDeviceRepository repo, @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot, @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap, DisplayManagerFlags flags, SyntheticModeManager syntheticModeManager) { DisplayManagerFlags flags, SyntheticModeManager syntheticModeManager, DisplayGroupAllocator displayGroupAllocator) { mSyncRoot = syncRoot; mContext = context; mPowerManager = context.getSystemService(PowerManager.class); mInteractive = mPowerManager.isInteractive(); mHandler = new LogicalDisplayMapperHandler(handler.getLooper()); Loading @@ -256,6 +263,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mFlags = flags; mSyntheticModeManager = syntheticModeManager; mDeviceStateManagerFlags = new FeatureFlagsImpl(); mDisplayGroupAllocator = displayGroupAllocator; } @Override Loading Loading @@ -586,6 +594,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (!mDeviceStateToBeAppliedAfterBoot.equals(INVALID_DEVICE_STATE)) { setDeviceStateLocked(mDeviceStateToBeAppliedAfterBoot); } mDisplayGroupAllocator.initLater(mContext); } } Loading Loading @@ -1077,12 +1086,25 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final DisplayGroup oldGroup = getDisplayGroupLocked(groupId); // groupName directly from LogicalDisplay (not from DisplayInfo) final String groupName = display.getDisplayGroupNameLocked(); String groupName = display.getLayoutGroupNameLocked(); // DisplayDeviceInfo is safe to use, it is updated earlier final DisplayDeviceInfo displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked(); int decidedGroupId = Display.INVALID_DISPLAY_GROUP; // Choose a display group based on the content mode type of the display. String requiredGroupType = GROUP_TYPE_PRIMARY; if (mFlags.isSeparateTimeoutsEnabled() && TextUtils.isEmpty(groupName)) { requiredGroupType = mDisplayGroupAllocator.decideRequiredGroupTypeLocked( display, displayDeviceInfo.type); decidedGroupId = calculateGroupId(requiredGroupType, mDisplayGroups); groupName = requiredGroupType; } // Get the new display group if a change is needed, if display group name is empty and // {@code DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP} is not set, the display is assigned // to the default display group. // {@code DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP} is not set, and required group type // has not been decided, the display is assigned to the default display group. final boolean needsOwnDisplayGroup = (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0 || !TextUtils.isEmpty(groupName); Loading @@ -1094,17 +1116,19 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { deviceDisplayGroupId != null && groupId == deviceDisplayGroupId; if (groupId == Display.INVALID_DISPLAY_GROUP || hasOwnDisplayGroup != needsOwnDisplayGroup || hasDeviceDisplayGroup != needsDeviceDisplayGroup) { || hasDeviceDisplayGroup != needsDeviceDisplayGroup || decidedGroupId != Display.INVALID_DISPLAY_GROUP) { groupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup, display.getDisplayGroupNameLocked(), needsDeviceDisplayGroup, linkedDeviceUniqueId); display.getLayoutGroupNameLocked(), needsDeviceDisplayGroup, linkedDeviceUniqueId, decidedGroupId); } // Create a new group if needed DisplayGroup newGroup = getDisplayGroupLocked(groupId); if (newGroup == null) { newGroup = new DisplayGroup(groupId); newGroup.setGroupName(groupName); mDisplayGroups.append(groupId, newGroup); } if (oldGroup != newGroup) { Loading @@ -1115,7 +1139,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { display.updateDisplayGroupIdLocked(groupId); Slog.i(TAG, "Setting new display group " + groupId + " for display " + displayId + ", from previous group: " + (oldGroup != null ? oldGroup.getGroupId() : "null")); + (oldGroup != null ? oldGroup.getGroupId() : "null") + ", for reason: " + mDisplayGroupAllocator.getReason()); } } Loading Loading @@ -1314,7 +1339,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } private int assignDisplayGroupIdLocked(boolean isOwnDisplayGroup, String displayGroupName, boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) { boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId, int decidedGroupId) { if (decidedGroupId != Display.INVALID_DISPLAY_GROUP) { return decidedGroupId; } if (isDeviceDisplayGroup && linkedDeviceUniqueId != null) { int deviceDisplayGroupId = mDeviceDisplayGroupIds.get(linkedDeviceUniqueId); // A value of 0 indicates that no device display group was found. Loading services/core/java/com/android/server/wm/DesktopModeHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.window.flags.Flags; * Constants for desktop mode feature */ public final class DesktopModeHelper { /** * Flag to indicate whether to restrict desktop mode to supported devices. */ Loading Loading @@ -66,8 +67,7 @@ public final class DesktopModeHelper { /** * Return {@code true} if the current device can hosts desktop sessions on its internal display. */ @VisibleForTesting private static boolean canInternalDisplayHostDesktops(@NonNull Context context) { public static boolean canInternalDisplayHostDesktops(@NonNull Context context) { return context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops); } Loading Loading @@ -98,7 +98,7 @@ public final class DesktopModeHelper { /** * Return {@code true} if desktop mode can be entered on the current device. */ static boolean canEnterDesktopMode(@NonNull Context context) { public static boolean canEnterDesktopMode(@NonNull Context context) { return (isDeviceEligibleForDesktopMode(context) && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE.isTrue()) || isDesktopModeEnabledByDevOption(context); Loading Loading
services/core/java/com/android/server/display/DisplayGroup.java +11 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ public class DisplayGroup { private final List<LogicalDisplay> mDisplays = new ArrayList<>(); private final int mGroupId; private String mGroupName; private int mChangeCount; DisplayGroup(int groupId) { Loading @@ -43,6 +45,14 @@ public class DisplayGroup { return mGroupId; } public String getGroupName() { return mGroupName; } public void setGroupName(String groupName) { mGroupName = groupName; } /** * Adds the provided {@code display} to the Group * Loading Loading @@ -107,6 +117,7 @@ public class DisplayGroup { LogicalDisplay logicalDisplay = mDisplays.get(i); ipw.println("Display " + logicalDisplay.getDisplayIdLocked() + " " + logicalDisplay.getPrimaryDisplayDeviceLocked()); ipw.println("Group name: " + getGroupName()); } } }
services/core/java/com/android/server/display/DisplayGroupAllocator.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 android.content.Context; import android.util.SparseArray; import android.view.Display; import com.android.server.wm.DesktopModeHelper; /** * DisplayGroupAllocator helps select which display groups new displays should be added to, * when they are added to the system. It takes into account attributes of the display, as well * as which display groups already exist. */ class DisplayGroupAllocator { private static final String TAG = "DisplayGroupAllocator"; private boolean mCanDeviceEnterDesktopMode; private boolean mCanDefaultDisplayEnterDesktopMode; private Context mContext; private final Injector mInjector; private int mReason; public static final String GROUP_TYPE_PRIMARY = ""; public static final String GROUP_TYPE_SECONDARY = "secondary_mode"; public static final int REASON_NON_DESKTOP = 0; public static final int REASON_PROJECTED = 1; public static final int REASON_EXTENDED = 2; public static final int REASON_FALLBACK = 3; DisplayGroupAllocator(Context context) { this(context, new Injector()); } DisplayGroupAllocator(Context context, Injector injector) { mInjector = injector; mContext = context; } public void initLater(Context context) { mContext = context; mCanDeviceEnterDesktopMode = mInjector.canEnterDesktopMode(mContext); mCanDefaultDisplayEnterDesktopMode = mInjector.canInternalDisplayHostDesktops(mContext); } /** * Decides which group type is needed for a given display content mode. * Locked on DisplayManager mSyncRoot. * Sets mReason, for logging purposes. */ public String decideRequiredGroupTypeLocked(LogicalDisplay display, int type) { mReason = getContentModeForDisplayLocked(display, type); return switch (mReason) { case REASON_NON_DESKTOP, REASON_EXTENDED, REASON_FALLBACK -> GROUP_TYPE_PRIMARY; case REASON_PROJECTED -> GROUP_TYPE_SECONDARY; default -> GROUP_TYPE_PRIMARY; }; } /** * Returns the first suitable group for a display to be sorted into, given the required group * type. * @param requiredGroupType which content mode group this display should be used in * @param displayGroups array of existing display groups. * @return Id of group that display should be sorted into */ public static int calculateGroupId(String requiredGroupType, SparseArray<DisplayGroup> displayGroups) { // go through display groups, find one group with the correct tag. final int size = displayGroups.size(); int calculatedGroup = Display.INVALID_DISPLAY_GROUP; for (int i = 0; i < size; i++) { final DisplayGroup displayGroup = displayGroups.valueAt(i); if (displayGroup.getGroupName().equals(requiredGroupType)) { calculatedGroup = displayGroups.keyAt(i); break; } } return calculatedGroup; } /** * Calculates whether this display supports desktop mode */ public boolean isDesktopModeSupportedOnDisplayLocked(LogicalDisplay display, int type) { if (!mCanDeviceEnterDesktopMode) { return false; } if (type == Display.TYPE_INTERNAL) { return mCanDefaultDisplayEnterDesktopMode; } if (type == Display.TYPE_EXTERNAL || type == Display.TYPE_OVERLAY) { return mInjector.canDisplayHostTasksLocked(display); } return false; } /** * Decides on the content mode that the display should be using. */ public int getContentModeForDisplayLocked(LogicalDisplay display, int type) { // conditions for non desktop mode; // desktop mode not supported on device or this display // or display is internal, and should be in a different group to the // projected and extended mode displays. if (!mCanDeviceEnterDesktopMode || type == Display.TYPE_INTERNAL) { return REASON_NON_DESKTOP; } // conditions for projected mode; // desktop mode supported on device, external display, but not internal if (mCanDeviceEnterDesktopMode && isDesktopModeSupportedOnDisplayLocked(display, type) && !mCanDefaultDisplayEnterDesktopMode) { return REASON_PROJECTED; } // conditions for extended mode; // desktop mode supported on both displays if (mCanDeviceEnterDesktopMode && isDesktopModeSupportedOnDisplayLocked(display, type) && mCanDefaultDisplayEnterDesktopMode) { return REASON_EXTENDED; } return REASON_FALLBACK; } public int getReason() { return mReason; } static class Injector { private boolean canEnterDesktopMode(Context context) { return DesktopModeHelper.canEnterDesktopMode(context); } boolean canInternalDisplayHostDesktops(Context context) { return DesktopModeHelper.canInternalDisplayHostDesktops(context); } boolean canDisplayHostTasksLocked(LogicalDisplay display) { return display.canHostTasksLocked(); } } }
services/core/java/com/android/server/display/LogicalDisplay.java +1 −1 Original line number Diff line number Diff line Loading @@ -1129,7 +1129,7 @@ final class LogicalDisplay { /** * Gets the name of display group to which the display is assigned. */ public String getDisplayGroupNameLocked() { public String getLayoutGroupNameLocked() { return mDisplayGroupName; } Loading
services/core/java/com/android/server/display/LogicalDisplayMapper.java +38 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURAT import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.server.display.DisplayGroupAllocator.GROUP_TYPE_PRIMARY; import static com.android.server.display.DisplayGroupAllocator.calculateGroupId; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -216,6 +219,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final DisplayManagerFlags mFlags; private final SyntheticModeManager mSyntheticModeManager; private final FeatureFlags mDeviceStateManagerFlags; private final Context mContext; private final DisplayGroupAllocator mDisplayGroupAllocator; LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, FoldGracePeriodProvider foldGracePeriodProvider, Loading @@ -226,7 +231,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { handler, new DeviceStateToLayoutMap((isDefault) -> isDefault ? DEFAULT_DISPLAY : sNextNonDefaultDisplayId++, flags), flags, new SyntheticModeManager(flags)); new SyntheticModeManager(flags), new DisplayGroupAllocator(context)); } LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, Loading @@ -234,8 +239,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { @NonNull DisplayDeviceRepository repo, @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot, @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap, DisplayManagerFlags flags, SyntheticModeManager syntheticModeManager) { DisplayManagerFlags flags, SyntheticModeManager syntheticModeManager, DisplayGroupAllocator displayGroupAllocator) { mSyncRoot = syncRoot; mContext = context; mPowerManager = context.getSystemService(PowerManager.class); mInteractive = mPowerManager.isInteractive(); mHandler = new LogicalDisplayMapperHandler(handler.getLooper()); Loading @@ -256,6 +263,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mFlags = flags; mSyntheticModeManager = syntheticModeManager; mDeviceStateManagerFlags = new FeatureFlagsImpl(); mDisplayGroupAllocator = displayGroupAllocator; } @Override Loading Loading @@ -586,6 +594,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (!mDeviceStateToBeAppliedAfterBoot.equals(INVALID_DEVICE_STATE)) { setDeviceStateLocked(mDeviceStateToBeAppliedAfterBoot); } mDisplayGroupAllocator.initLater(mContext); } } Loading Loading @@ -1077,12 +1086,25 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final DisplayGroup oldGroup = getDisplayGroupLocked(groupId); // groupName directly from LogicalDisplay (not from DisplayInfo) final String groupName = display.getDisplayGroupNameLocked(); String groupName = display.getLayoutGroupNameLocked(); // DisplayDeviceInfo is safe to use, it is updated earlier final DisplayDeviceInfo displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked(); int decidedGroupId = Display.INVALID_DISPLAY_GROUP; // Choose a display group based on the content mode type of the display. String requiredGroupType = GROUP_TYPE_PRIMARY; if (mFlags.isSeparateTimeoutsEnabled() && TextUtils.isEmpty(groupName)) { requiredGroupType = mDisplayGroupAllocator.decideRequiredGroupTypeLocked( display, displayDeviceInfo.type); decidedGroupId = calculateGroupId(requiredGroupType, mDisplayGroups); groupName = requiredGroupType; } // Get the new display group if a change is needed, if display group name is empty and // {@code DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP} is not set, the display is assigned // to the default display group. // {@code DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP} is not set, and required group type // has not been decided, the display is assigned to the default display group. final boolean needsOwnDisplayGroup = (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0 || !TextUtils.isEmpty(groupName); Loading @@ -1094,17 +1116,19 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { deviceDisplayGroupId != null && groupId == deviceDisplayGroupId; if (groupId == Display.INVALID_DISPLAY_GROUP || hasOwnDisplayGroup != needsOwnDisplayGroup || hasDeviceDisplayGroup != needsDeviceDisplayGroup) { || hasDeviceDisplayGroup != needsDeviceDisplayGroup || decidedGroupId != Display.INVALID_DISPLAY_GROUP) { groupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup, display.getDisplayGroupNameLocked(), needsDeviceDisplayGroup, linkedDeviceUniqueId); display.getLayoutGroupNameLocked(), needsDeviceDisplayGroup, linkedDeviceUniqueId, decidedGroupId); } // Create a new group if needed DisplayGroup newGroup = getDisplayGroupLocked(groupId); if (newGroup == null) { newGroup = new DisplayGroup(groupId); newGroup.setGroupName(groupName); mDisplayGroups.append(groupId, newGroup); } if (oldGroup != newGroup) { Loading @@ -1115,7 +1139,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { display.updateDisplayGroupIdLocked(groupId); Slog.i(TAG, "Setting new display group " + groupId + " for display " + displayId + ", from previous group: " + (oldGroup != null ? oldGroup.getGroupId() : "null")); + (oldGroup != null ? oldGroup.getGroupId() : "null") + ", for reason: " + mDisplayGroupAllocator.getReason()); } } Loading Loading @@ -1314,7 +1339,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } private int assignDisplayGroupIdLocked(boolean isOwnDisplayGroup, String displayGroupName, boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) { boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId, int decidedGroupId) { if (decidedGroupId != Display.INVALID_DISPLAY_GROUP) { return decidedGroupId; } if (isDeviceDisplayGroup && linkedDeviceUniqueId != null) { int deviceDisplayGroupId = mDeviceDisplayGroupIds.get(linkedDeviceUniqueId); // A value of 0 indicates that no device display group was found. Loading
services/core/java/com/android/server/wm/DesktopModeHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.window.flags.Flags; * Constants for desktop mode feature */ public final class DesktopModeHelper { /** * Flag to indicate whether to restrict desktop mode to supported devices. */ Loading Loading @@ -66,8 +67,7 @@ public final class DesktopModeHelper { /** * Return {@code true} if the current device can hosts desktop sessions on its internal display. */ @VisibleForTesting private static boolean canInternalDisplayHostDesktops(@NonNull Context context) { public static boolean canInternalDisplayHostDesktops(@NonNull Context context) { return context.getResources().getBoolean(R.bool.config_canInternalDisplayHostDesktops); } Loading Loading @@ -98,7 +98,7 @@ public final class DesktopModeHelper { /** * Return {@code true} if desktop mode can be entered on the current device. */ static boolean canEnterDesktopMode(@NonNull Context context) { public static boolean canEnterDesktopMode(@NonNull Context context) { return (isDeviceEligibleForDesktopMode(context) && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE.isTrue()) || isDesktopModeEnabledByDevOption(context); Loading