1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 /** Display identifier that is stable across reboots. 25 * 26 * @hide 27 */ 28 public abstract class DisplayAddress implements Parcelable { 29 /** 30 * Creates an address for a physical display given its stable ID. 31 * 32 * A physical display ID is stable if the display can be identified using EDID information. 33 * 34 * @param physicalDisplayId A physical display ID. 35 * @return The {@link Physical} address. 36 * @see SurfaceControl#getPhysicalDisplayIds 37 */ 38 @NonNull fromPhysicalDisplayId(long physicalDisplayId)39 public static Physical fromPhysicalDisplayId(long physicalDisplayId) { 40 return new Physical(physicalDisplayId); 41 } 42 43 /** 44 * Creates an address for a network display given its MAC address. 45 * 46 * @param macAddress A MAC address in colon notation. 47 * @return The {@link Network} address. 48 */ 49 @NonNull fromMacAddress(String macAddress)50 public static Network fromMacAddress(String macAddress) { 51 return new Network(macAddress); 52 } 53 54 /** 55 * Address for a physically connected display. 56 * 57 * A {@link Physical} address is represented by a 64-bit identifier combining the port and model 58 * of a display. The port, located in the least significant byte, uniquely identifies a physical 59 * connector on the device for display output like eDP or HDMI. The model, located in the upper 60 * bits, uniquely identifies a display model across manufacturers by encoding EDID information. 61 * While the port is always stable, the model may not be available if EDID identification is not 62 * supported by the platform, in which case the address is not unique. 63 */ 64 public static final class Physical extends DisplayAddress { 65 private static final long UNKNOWN_MODEL = 0; 66 private static final int MODEL_SHIFT = 8; 67 private static final int PORT_MASK = 0xFF; 68 69 private final long mPhysicalDisplayId; 70 71 /** 72 * Physical port to which the display is connected. 73 */ getPort()74 public byte getPort() { 75 return (byte) mPhysicalDisplayId; 76 } 77 78 /** 79 * Model identifier unique across manufacturers. 80 * 81 * @return The model ID, or {@code null} if the model cannot be identified. 82 */ 83 @Nullable getModel()84 public Long getModel() { 85 final long model = mPhysicalDisplayId >>> MODEL_SHIFT; 86 return model == UNKNOWN_MODEL ? null : model; 87 } 88 89 @Override equals(Object other)90 public boolean equals(Object other) { 91 return other instanceof Physical 92 && mPhysicalDisplayId == ((Physical) other).mPhysicalDisplayId; 93 } 94 95 @Override toString()96 public String toString() { 97 final StringBuilder builder = new StringBuilder("{") 98 .append("port=").append(getPort() & PORT_MASK); 99 100 final Long model = getModel(); 101 if (model != null) { 102 builder.append(", model=0x").append(Long.toHexString(model)); 103 } 104 105 return builder.append("}").toString(); 106 } 107 108 @Override hashCode()109 public int hashCode() { 110 return Long.hashCode(mPhysicalDisplayId); 111 } 112 113 @Override writeToParcel(Parcel out, int flags)114 public void writeToParcel(Parcel out, int flags) { 115 out.writeLong(mPhysicalDisplayId); 116 } 117 Physical(long physicalDisplayId)118 private Physical(long physicalDisplayId) { 119 mPhysicalDisplayId = physicalDisplayId; 120 } 121 122 public static final @NonNull Parcelable.Creator<Physical> CREATOR = 123 new Parcelable.Creator<Physical>() { 124 @Override 125 public Physical createFromParcel(Parcel in) { 126 return new Physical(in.readLong()); 127 } 128 129 @Override 130 public Physical[] newArray(int size) { 131 return new Physical[size]; 132 } 133 }; 134 } 135 136 /** 137 * Address for a network-connected display. 138 */ 139 public static final class Network extends DisplayAddress { 140 private final String mMacAddress; 141 142 @Override equals(Object other)143 public boolean equals(Object other) { 144 return other instanceof Network && mMacAddress.equals(((Network) other).mMacAddress); 145 } 146 147 @Override toString()148 public String toString() { 149 return mMacAddress; 150 } 151 152 @Override hashCode()153 public int hashCode() { 154 return mMacAddress.hashCode(); 155 } 156 157 @Override writeToParcel(Parcel out, int flags)158 public void writeToParcel(Parcel out, int flags) { 159 out.writeString(mMacAddress); 160 } 161 Network(String macAddress)162 private Network(String macAddress) { 163 mMacAddress = macAddress; 164 } 165 166 public static final @NonNull Parcelable.Creator<Network> CREATOR = 167 new Parcelable.Creator<Network>() { 168 @Override 169 public Network createFromParcel(Parcel in) { 170 return new Network(in.readString()); 171 } 172 173 @Override 174 public Network[] newArray(int size) { 175 return new Network[size]; 176 } 177 }; 178 } 179 180 @Override describeContents()181 public int describeContents() { 182 return 0; 183 } 184 } 185