diff options
7 files changed, 196 insertions, 13 deletions
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index e3a6bd7a6949..f021ca3f7220 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -75,7 +75,7 @@ public final class Display { private final int mLayerStack; private final int mFlags; private final int mType; - private final String mAddress; + private final DisplayAddress mAddress; private final int mOwnerUid; private final String mOwnerPackageName; private final Resources mResources; @@ -556,7 +556,7 @@ public final class Display { * @hide */ @UnsupportedAppUsage - public String getAddress() { + public DisplayAddress getAddress() { return mAddress; } diff --git a/core/java/android/view/DisplayAddress.java b/core/java/android/view/DisplayAddress.java new file mode 100644 index 000000000000..17ea4c423be5 --- /dev/null +++ b/core/java/android/view/DisplayAddress.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2019 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 android.view; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +/** Display identifier that is stable across reboots. + * + * @hide + */ +public abstract class DisplayAddress implements Parcelable { + /** + * Creates an address for a physical display given its stable ID. + * + * A physical display ID is stable if the display can be identified using EDID information. + * + * @param physicalDisplayId A physical display ID. + * @return The {@link Physical} address, or {@code null} if the ID is not stable. + * @see SurfaceControl#getPhysicalDisplayIds + */ + @Nullable + public static Physical fromPhysicalDisplayId(long physicalDisplayId) { + final Physical address = new Physical(physicalDisplayId); + return address.getModel() == 0 ? null : address; + } + + /** + * Creates an address for a network display given its MAC address. + * + * @param macAddress A MAC address in colon notation. + * @return The {@link Network} address. + */ + @NonNull + public static Network fromMacAddress(String macAddress) { + return new Network(macAddress); + } + + /** + * Address for a physically connected display. + * + * A {@link Physical} address is represented by a 64-bit identifier combining the port and model + * of a display. The port, located in the least significant byte, uniquely identifies a physical + * connector on the device for display output like eDP or HDMI. The model, located in the upper + * bits, uniquely identifies a display model across manufacturers by encoding EDID information. + */ + public static final class Physical extends DisplayAddress { + private static final int PHYSICAL_DISPLAY_ID_MODEL_SHIFT = 8; + private static final int PORT_MASK = 0xFF; + + private final long mPhysicalDisplayId; + + /** + * Physical port to which the display is connected. + */ + public byte getPort() { + return (byte) mPhysicalDisplayId; + } + + /** + * Model identifier unique across manufacturers. + */ + public long getModel() { + return mPhysicalDisplayId >>> PHYSICAL_DISPLAY_ID_MODEL_SHIFT; + } + + @Override + public boolean equals(Object other) { + return other instanceof Physical + && mPhysicalDisplayId == ((Physical) other).mPhysicalDisplayId; + } + + @Override + public String toString() { + return new StringBuilder("{") + .append("port=").append(getPort() & PORT_MASK) + .append(", model=0x").append(Long.toHexString(getModel())) + .append("}") + .toString(); + } + + @Override + public int hashCode() { + return Long.hashCode(mPhysicalDisplayId); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mPhysicalDisplayId); + } + + private Physical(long physicalDisplayId) { + mPhysicalDisplayId = physicalDisplayId; + } + + public static final Parcelable.Creator<Physical> CREATOR = + new Parcelable.Creator<Physical>() { + @Override + public Physical createFromParcel(Parcel in) { + return new Physical(in.readLong()); + } + + @Override + public Physical[] newArray(int size) { + return new Physical[size]; + } + }; + } + + /** + * Address for a network-connected display. + */ + public static final class Network extends DisplayAddress { + private final String mMacAddress; + + @Override + public boolean equals(Object other) { + return other instanceof Network && mMacAddress.equals(((Network) other).mMacAddress); + } + + @Override + public String toString() { + return mMacAddress; + } + + @Override + public int hashCode() { + return mMacAddress.hashCode(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(mMacAddress); + } + + private Network(String macAddress) { + mMacAddress = macAddress; + } + + public static final Parcelable.Creator<Network> CREATOR = + new Parcelable.Creator<Network>() { + @Override + public Network createFromParcel(Parcel in) { + return new Network(in.readString()); + } + + @Override + public Network[] newArray(int size) { + return new Network[size]; + } + }; + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 43de1f89649c..95d1a80b66ee 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -60,7 +60,7 @@ public final class DisplayInfo implements Parcelable { * Display address, or null if none. * Interpretation varies by display type. */ - public String address; + public DisplayAddress address; /** * The human-readable name of the display. @@ -383,7 +383,7 @@ public final class DisplayInfo implements Parcelable { layerStack = source.readInt(); flags = source.readInt(); type = source.readInt(); - address = source.readString(); + address = source.readParcelable(null); name = source.readString(); appWidth = source.readInt(); appHeight = source.readInt(); @@ -430,7 +430,7 @@ public final class DisplayInfo implements Parcelable { dest.writeInt(layerStack); dest.writeInt(this.flags); dest.writeInt(type); - dest.writeString(address); + dest.writeParcelable(address, flags); dest.writeString(name); dest.writeInt(appWidth); dest.writeInt(appHeight); diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 6ee5665b9e42..e9ae516cc8d0 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -19,6 +19,7 @@ package com.android.server.display; import android.graphics.Rect; import android.hardware.display.DisplayViewport; import android.os.IBinder; +import android.view.DisplayAddress; import android.view.Surface; import android.view.SurfaceControl; @@ -225,8 +226,12 @@ abstract class DisplayDevice { viewport.deviceHeight = isRotated ? info.width : info.height; viewport.uniqueId = info.uniqueId; - // TODO(b/112898898) Use an actual port here. - viewport.physicalPort = null; + + if (info.address instanceof DisplayAddress.Physical) { + viewport.physicalPort = ((DisplayAddress.Physical) info.address).getPort(); + } else { + viewport.physicalPort = null; + } } /** diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index ab64f61a3b22..729ea1772066 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -19,6 +19,7 @@ package com.android.server.display; import android.hardware.display.DisplayViewport; import android.util.DisplayMetrics; import android.view.Display; +import android.view.DisplayAddress; import android.view.DisplayCutout; import android.view.Surface; @@ -274,7 +275,7 @@ final class DisplayDeviceInfo { * Display address, or null if none. * Interpretation varies by display type. */ - public String address; + public DisplayAddress address; /** * Display state. diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 28f21f633ac4..489194726c5a 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -31,6 +31,7 @@ import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; +import android.view.DisplayAddress; import android.view.DisplayCutout; import android.view.DisplayEventReceiver; import android.view.Surface; @@ -382,6 +383,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos; mInfo.state = mState; mInfo.uniqueId = getUniqueId(); + mInfo.address = DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId); // Assume that all built-in displays that have secure output (eg. HDCP) also // support compositing from gralloc protected buffers. diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index e8d6ad455fbf..9e4c1cb57dca 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -16,9 +16,6 @@ package com.android.server.display; -import com.android.internal.util.DumpUtils; -import com.android.internal.util.IndentingPrintWriter; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -35,9 +32,13 @@ import android.os.Message; import android.os.UserHandle; import android.util.Slog; import android.view.Display; +import android.view.DisplayAddress; import android.view.Surface; import android.view.SurfaceControl; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.IndentingPrintWriter; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -581,7 +582,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { private final int mHeight; private final float mRefreshRate; private final int mFlags; - private final String mAddress; + private final DisplayAddress mAddress; private final Display.Mode mMode; private Surface mSurface; @@ -596,7 +597,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mHeight = height; mRefreshRate = refreshRate; mFlags = flags; - mAddress = address; + mAddress = DisplayAddress.fromMacAddress(address); mSurface = surface; mMode = createMode(width, height, refreshRate); } |