Merge "Introduce DisplayGroup"

This commit is contained in:
Sean Stout
2020-10-28 04:30:04 +00:00
committed by Android (Google) Code Review
8 changed files with 122 additions and 0 deletions

View File

@@ -326,6 +326,15 @@ public final class DisplayManager {
@TestApi
public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
/**
* Virtual display flags: Indicates that the display should not be a part of the default
* DisplayGroup and instead be part of a new DisplayGroup.
*
* @see #createVirtualDisplay
* @hide
*/
public static final int VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP = 1 << 11;
/** @hide */
public DisplayManager(Context context) {
mContext = context;

View File

@@ -261,6 +261,15 @@ public final class Display {
@TestApi
public static final int FLAG_TRUSTED = 1 << 7;
/**
* Flag: Indicates that the display should not be a part of the default DisplayGroup and
* instead be part of a new DisplayGroup.
*
* @hide
* @see #getFlags()
*/
public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 8;
/**
* Display flag: Indicates that the contents of the display should not be scaled
* to fit the physical screen dimensions. Used for development only to emulate

View File

@@ -129,6 +129,14 @@ final class DisplayDeviceInfo {
*/
public static final int FLAG_TRUSTED = 1 << 13;
/**
* Flag: Indicates that the display should not be a part of the default {@link DisplayGroup} and
* instead be part of a new {@link DisplayGroup}.
*
* @hide
*/
public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 14;
/**
* Touch attachment: Display does not receive touch.
*/

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 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 java.util.ArrayList;
import java.util.List;
/**
* Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
* operations.
*/
public class DisplayGroup {
final List<LogicalDisplay> mDisplays = new ArrayList<>();
void addDisplay(LogicalDisplay display) {
if (!mDisplays.contains(display)) {
mDisplays.add(display);
}
}
boolean removeDisplay(LogicalDisplay display) {
return mDisplays.remove(display);
}
}

View File

@@ -23,6 +23,7 @@ import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
@@ -2024,6 +2025,9 @@ public final class DisplayManagerService extends SystemService {
if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
}
if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
}
if (projection != null) {
try {
@@ -2062,6 +2066,14 @@ public final class DisplayManagerService extends SystemService {
}
}
if (callingUid != Process.SYSTEM_UID
&& (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
+ "create a virtual display which is not in the default DisplayGroup.");
}
}
if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}

View File

@@ -280,6 +280,9 @@ final class LogicalDisplay {
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_OWN_DISPLAY_GROUP;
}
Rect maskingInsets = getMaskingInsets(deviceInfo);
int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;

View File

@@ -35,6 +35,9 @@ import java.util.function.Consumer;
* Responsible for creating {@link LogicalDisplay}s and associating them to the
* {@link DisplayDevice} objects supplied through {@link DisplayAdapter.Listener}.
*
* Additionally this class will keep track of which {@link DisplayGroup} each
* {@link LogicalDisplay} belongs to.
*
* For devices with a single internal display, the mapping is done once and left
* alone. For devices with multiple built-in displays, such as foldable devices,
* {@link LogicalDisplay}s can be remapped to different {@link DisplayDevice}s.
@@ -91,6 +94,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
new SparseArray<LogicalDisplay>();
private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
/** A mapping from logical display id to display group. */
private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
private final DisplayDeviceRepository mDisplayDeviceRepo;
private final PersistentDataStore mPersistentDataStore;
private final Listener mListener;
@@ -296,6 +302,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
mLogicalDisplays.put(displayId, display);
final DisplayGroup displayGroup;
if (isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
displayGroup = new DisplayGroup();
} else {
displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
}
displayGroup.addDisplay(display);
mDisplayGroups.append(displayId, displayGroup);
mListener.onLogicalDisplayEventLocked(display,
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED);
}
@@ -314,10 +329,31 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
display.updateLocked(mDisplayDeviceRepo);
if (!display.isValidLocked()) {
mLogicalDisplays.removeAt(i);
mDisplayGroups.removeReturnOld(displayId).removeDisplay(display);
mListener.onLogicalDisplayEventLocked(display,
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED);
} else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
final int flags = display.getDisplayInfoLocked().flags;
final DisplayGroup defaultDisplayGroup = mDisplayGroups.get(
Display.DEFAULT_DISPLAY);
if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
// The display should have its own DisplayGroup.
if (defaultDisplayGroup.removeDisplay(display)) {
final DisplayGroup displayGroup = new DisplayGroup();
displayGroup.addDisplay(display);
mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
}
} else {
// The display should be a part of the default DisplayGroup.
final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
if (displayGroup != defaultDisplayGroup) {
displayGroup.removeDisplay(display);
defaultDisplayGroup.addDisplay(display);
mDisplayGroups.put(displayId, defaultDisplayGroup);
}
}
final String oldUniqueId = mTempDisplayInfo.uniqueId;
final String newUniqueId = display.getDisplayInfoLocked().uniqueId;
final int eventMsg = TextUtils.equals(oldUniqueId, newUniqueId)

View File

@@ -19,6 +19,7 @@ package com.android.server.display;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
@@ -27,6 +28,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOUL
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
import android.content.Context;
@@ -386,6 +388,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
} else {
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
mInfo.flags |= FLAG_OWN_DISPLAY_GROUP;
}
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {