Plumb display connection type to DMS
Secondary physical displays are now properly categorized as TYPE_INTERNAL or TYPE_EXTERNAL, rather than assumed to be external. LocalDisplayAdapter distinguishes between primary/secondary and internal/external categories when populating DisplayInfo. Bug: 134771872 Test: dumpsys display Change-Id: Id43a72411131588897f29b8d8db417f8c9e78259
This commit is contained in:
@@ -80,7 +80,7 @@ public final class DisplayManager {
|
||||
* Display category: Presentation displays.
|
||||
* <p>
|
||||
* This category can be used to identify secondary displays that are suitable for
|
||||
* use as presentation displays such as HDMI or Wireless displays. Applications
|
||||
* use as presentation displays such as external or wireless displays. Applications
|
||||
* may automatically project their content to presentation displays to provide
|
||||
* richer second screen experiences.
|
||||
* </p>
|
||||
@@ -100,7 +100,7 @@ public final class DisplayManager {
|
||||
* When this flag is set, the virtual display is public.
|
||||
* </p><p>
|
||||
* A public virtual display behaves just like most any other display that is connected
|
||||
* to the system such as an HDMI or Wireless display. Applications can open
|
||||
* to the system such as an external or wireless display. Applications can open
|
||||
* windows on the display and the system may mirror the contents of other displays
|
||||
* onto it.
|
||||
* </p><p>
|
||||
@@ -364,7 +364,7 @@ public final class DisplayManager {
|
||||
addAllDisplaysLocked(mTempDisplays, displayIds);
|
||||
} else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
|
||||
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
|
||||
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI);
|
||||
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL);
|
||||
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
|
||||
addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ import java.util.List;
|
||||
* </ul>
|
||||
* </p><p>
|
||||
* A logical display does not necessarily represent a particular physical display device
|
||||
* such as the built-in screen or an external monitor. The contents of a logical
|
||||
* such as the internal display or an external display. The contents of a logical
|
||||
* display may be presented on one or more physical displays according to the devices
|
||||
* that are currently attached and whether mirroring has been enabled.
|
||||
* </p>
|
||||
@@ -104,8 +104,7 @@ public final class Display {
|
||||
private int mCachedAppHeightCompat;
|
||||
|
||||
/**
|
||||
* The default Display id, which is the id of the built-in primary display
|
||||
* assuming there is one.
|
||||
* The default Display id, which is the id of the primary display assuming there is one.
|
||||
*/
|
||||
public static final int DEFAULT_DISPLAY = 0;
|
||||
|
||||
@@ -188,7 +187,7 @@ public final class Display {
|
||||
* Display flag: Indicates that the display is a presentation display.
|
||||
* <p>
|
||||
* This flag identifies secondary displays that are suitable for
|
||||
* use as presentation displays such as HDMI or Wireless displays. Applications
|
||||
* use as presentation displays such as external or wireless displays. Applications
|
||||
* may automatically project their content to presentation displays to provide
|
||||
* richer second screen experiences.
|
||||
* </p>
|
||||
@@ -257,17 +256,17 @@ public final class Display {
|
||||
public static final int TYPE_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Display type: Built-in display.
|
||||
* Display type: Physical display connected through an internal port.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TYPE_BUILT_IN = 1;
|
||||
public static final int TYPE_INTERNAL = 1;
|
||||
|
||||
/**
|
||||
* Display type: HDMI display.
|
||||
* Display type: Physical display connected through an external port.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static final int TYPE_HDMI = 2;
|
||||
public static final int TYPE_EXTERNAL = 2;
|
||||
|
||||
/**
|
||||
* Display type: WiFi display.
|
||||
@@ -562,8 +561,8 @@ public final class Display {
|
||||
* @return The display type.
|
||||
*
|
||||
* @see #TYPE_UNKNOWN
|
||||
* @see #TYPE_BUILT_IN
|
||||
* @see #TYPE_HDMI
|
||||
* @see #TYPE_INTERNAL
|
||||
* @see #TYPE_EXTERNAL
|
||||
* @see #TYPE_WIFI
|
||||
* @see #TYPE_OVERLAY
|
||||
* @see #TYPE_VIRTUAL
|
||||
@@ -1251,10 +1250,10 @@ public final class Display {
|
||||
switch (type) {
|
||||
case TYPE_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
case TYPE_BUILT_IN:
|
||||
return "BUILT_IN";
|
||||
case TYPE_HDMI:
|
||||
return "HDMI";
|
||||
case TYPE_INTERNAL:
|
||||
return "INTERNAL";
|
||||
case TYPE_EXTERNAL:
|
||||
return "EXTERNAL";
|
||||
case TYPE_WIFI:
|
||||
return "WIFI";
|
||||
case TYPE_OVERLAY:
|
||||
|
||||
@@ -1285,12 +1285,15 @@ public final class SurfaceControl implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public static final class DisplayInfo {
|
||||
public boolean isInternal;
|
||||
public float density;
|
||||
public boolean secure;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DisplayInfo{density=" + density + ", secure=" + secure + "}";
|
||||
return "DisplayInfo{isInternal=" + isInternal
|
||||
+ ", density=" + density
|
||||
+ ", secure=" + secure + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ static const char* const OutOfResourcesException =
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID ctor;
|
||||
jfieldID isInternal;
|
||||
jfieldID density;
|
||||
jfieldID secure;
|
||||
} gDisplayInfoClassInfo;
|
||||
@@ -781,6 +782,8 @@ static jobject nativeGetDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj)
|
||||
}
|
||||
|
||||
jobject object = env->NewObject(gDisplayInfoClassInfo.clazz, gDisplayInfoClassInfo.ctor);
|
||||
env->SetBooleanField(object, gDisplayInfoClassInfo.isInternal,
|
||||
info.connectionType == DisplayConnectionType::Internal);
|
||||
env->SetFloatField(object, gDisplayInfoClassInfo.density, info.density);
|
||||
env->SetBooleanField(object, gDisplayInfoClassInfo.secure, info.secure);
|
||||
return object;
|
||||
@@ -1528,6 +1531,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
|
||||
jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayInfo");
|
||||
gDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
|
||||
gDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
|
||||
gDisplayInfoClassInfo.isInternal = GetFieldIDOrDie(env, infoClazz, "isInternal", "Z");
|
||||
gDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
|
||||
gDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
* The display manager service relies on a collection of {@link DisplayAdapter} components,
|
||||
* for discovering and configuring physical display devices attached to the system.
|
||||
* There are separate display adapters for each manner that devices are attached:
|
||||
* one display adapter for built-in local displays, one for simulated non-functional
|
||||
* one display adapter for physical displays, one for simulated non-functional
|
||||
* displays when the system is headless, one for simulated overlay displays used for
|
||||
* development, one for wifi displays, etc.
|
||||
* </p><p>
|
||||
@@ -231,7 +231,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
private int mGlobalDisplayState = Display.STATE_ON;
|
||||
|
||||
// The overall display brightness.
|
||||
// For now, this only applies to the built-in display but we may split it up eventually.
|
||||
// For now, this only applies to the default display but we may split it up eventually.
|
||||
private float mGlobalDisplayBrightness;
|
||||
|
||||
// Set to true when there are pending display changes that have yet to be applied
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.view.Display;
|
||||
import android.view.DisplayAddress;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.DisplayEventReceiver;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.internal.BrightnessSynchronizer;
|
||||
@@ -53,7 +52,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A display adapter for the local displays managed by Surface Flinger.
|
||||
* A display adapter for the local displays managed by SurfaceFlinger.
|
||||
* <p>
|
||||
* Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
|
||||
* </p>
|
||||
@@ -129,10 +128,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
|
||||
if (device == null) {
|
||||
// Display was added.
|
||||
final boolean isInternal = mDevices.size() == 0;
|
||||
final boolean isDefaultDisplay = mDevices.size() == 0;
|
||||
device = new LocalDisplayDevice(displayToken, physicalDisplayId, info,
|
||||
configs, activeConfig, configSpecs, colorModes, activeColorMode,
|
||||
hdrCapabilities, isInternal);
|
||||
hdrCapabilities, isDefaultDisplay);
|
||||
mDevices.put(physicalDisplayId, device);
|
||||
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
} else if (device.updateDisplayProperties(configs, activeConfig,
|
||||
@@ -175,7 +174,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private final LogicalLight mBacklight;
|
||||
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
|
||||
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
|
||||
private final boolean mIsInternal;
|
||||
private final boolean mIsDefaultDisplay;
|
||||
|
||||
private DisplayDeviceInfo mInfo;
|
||||
private boolean mHavePendingChanges;
|
||||
@@ -207,15 +206,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
SurfaceControl.DisplayInfo info, SurfaceControl.DisplayConfig[] configs,
|
||||
int activeConfigId, SurfaceControl.DesiredDisplayConfigSpecs configSpecs,
|
||||
int[] colorModes, int activeColorMode, Display.HdrCapabilities hdrCapabilities,
|
||||
boolean isInternal) {
|
||||
boolean isDefaultDisplay) {
|
||||
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
|
||||
mPhysicalDisplayId = physicalDisplayId;
|
||||
mIsInternal = isInternal;
|
||||
mIsDefaultDisplay = isDefaultDisplay;
|
||||
mDisplayInfo = info;
|
||||
updateDisplayProperties(configs, activeConfigId, configSpecs, colorModes,
|
||||
activeColorMode, hdrCapabilities);
|
||||
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
|
||||
if (mIsInternal) {
|
||||
if (mIsDefaultDisplay) {
|
||||
LightsManager lights = LocalServices.getService(LightsManager.class);
|
||||
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
|
||||
} else {
|
||||
@@ -523,11 +522,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
final Resources res = getOverlayContext().getResources();
|
||||
if (mIsInternal) {
|
||||
mInfo.name = res.getString(
|
||||
com.android.internal.R.string.display_manager_built_in_display_name);
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
|
||||
| DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
|
||||
|
||||
if (mIsDefaultDisplay) {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
|
||||
|
||||
if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
|
||||
|| (Build.IS_EMULATOR
|
||||
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
|
||||
@@ -539,28 +537,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
|
||||
mInfo.width, mInfo.height);
|
||||
mInfo.type = Display.TYPE_BUILT_IN;
|
||||
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
|
||||
} else {
|
||||
mInfo.displayCutout = null;
|
||||
mInfo.type = Display.TYPE_HDMI;
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
|
||||
mInfo.name = getContext().getResources().getString(
|
||||
com.android.internal.R.string.display_manager_hdmi_display_name);
|
||||
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
|
||||
|
||||
// For demonstration purposes, allow rotation of the external display.
|
||||
// In the future we might allow the user to configure this directly.
|
||||
if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
|
||||
mInfo.rotation = Surface.ROTATION_270;
|
||||
}
|
||||
|
||||
// For demonstration purposes, allow rotation of the external display
|
||||
// to follow the built-in display.
|
||||
if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
|
||||
}
|
||||
|
||||
if (!res.getBoolean(
|
||||
com.android.internal.R.bool.config_localDisplaysMirrorContent)) {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
|
||||
@@ -570,6 +547,20 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDisplayInfo.isInternal) {
|
||||
mInfo.type = Display.TYPE_INTERNAL;
|
||||
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
|
||||
mInfo.name = res.getString(
|
||||
com.android.internal.R.string.display_manager_built_in_display_name);
|
||||
} else {
|
||||
mInfo.type = Display.TYPE_EXTERNAL;
|
||||
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
|
||||
mInfo.name = getContext().getResources().getString(
|
||||
com.android.internal.R.string.display_manager_hdmi_display_name);
|
||||
}
|
||||
}
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
|
||||
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
|
||||
import static android.view.Display.TYPE_BUILT_IN;
|
||||
import static android.view.Display.TYPE_INTERNAL;
|
||||
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
|
||||
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
||||
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
|
||||
@@ -2986,11 +2986,12 @@ public class DisplayPolicy {
|
||||
|
||||
/**
|
||||
* Return corner radius in pixels that should be used on windows in order to cover the display.
|
||||
* The radius is only valid for built-in displays since the one who configures window corner
|
||||
* radius cannot know the corner radius of non-built-in display.
|
||||
*
|
||||
* The radius is only valid for internal displays, since the corner radius of external displays
|
||||
* is not known at build time when window corners are configured.
|
||||
*/
|
||||
float getWindowCornerRadius() {
|
||||
return mDisplayContent.getDisplay().getType() == TYPE_BUILT_IN
|
||||
return mDisplayContent.getDisplay().getType() == TYPE_INTERNAL
|
||||
? ScreenDecorationsUtils.getWindowCornerRadius(mContext.getResources()) : 0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ public class DisplayManagerServiceTest {
|
||||
assertEquals(1, displayIds.length);
|
||||
final int displayId = displayIds[0];
|
||||
DisplayInfo info = bs.getDisplayInfo(displayId);
|
||||
assertEquals(info.type, Display.TYPE_BUILT_IN);
|
||||
assertEquals(info.type, Display.TYPE_INTERNAL);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user