1 /*
2  * Copyright (C) 2020 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.hardware.display;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Objects;
29 
30 /**
31  * Product-specific information about the display or the directly connected device on the
32  * display chain. For example, if the display is transitively connected, this field may contain
33  * product information about the intermediate device.
34  */
35 public final class DeviceProductInfo implements Parcelable {
36     /** @hide */
37     @IntDef(prefix = {"CONNECTION_TO_SINK_"}, value = {
38             CONNECTION_TO_SINK_UNKNOWN,
39             CONNECTION_TO_SINK_BUILT_IN,
40             CONNECTION_TO_SINK_DIRECT,
41             CONNECTION_TO_SINK_TRANSITIVE
42     })
43     @Retention(RetentionPolicy.SOURCE)
44     public @interface ConnectionToSinkType { }
45 
46     /** The device connection to the display sink is unknown. */
47     public static final int CONNECTION_TO_SINK_UNKNOWN =
48             IDeviceProductInfoConstants.CONNECTION_TO_SINK_UNKNOWN;
49 
50     /** The display sink is built-in to the device */
51     public static final int CONNECTION_TO_SINK_BUILT_IN =
52             IDeviceProductInfoConstants.CONNECTION_TO_SINK_BUILT_IN;
53 
54     /** The device is directly connected to the display sink. */
55     public static final int CONNECTION_TO_SINK_DIRECT =
56             IDeviceProductInfoConstants.CONNECTION_TO_SINK_DIRECT;
57 
58     /** The device is transitively connected to the display sink. */
59     public static final int CONNECTION_TO_SINK_TRANSITIVE =
60             IDeviceProductInfoConstants.CONNECTION_TO_SINK_TRANSITIVE;
61 
62     private final String mName;
63     private final String mManufacturerPnpId;
64     private final String mProductId;
65     private final Integer mModelYear;
66     private final ManufactureDate mManufactureDate;
67     private final @ConnectionToSinkType int mConnectionToSinkType;
68 
69     /** @hide */
DeviceProductInfo( String name, String manufacturerPnpId, String productId, Integer modelYear, ManufactureDate manufactureDate, int connectionToSinkType)70     public DeviceProductInfo(
71             String name,
72             String manufacturerPnpId,
73             String productId,
74             Integer modelYear,
75             ManufactureDate manufactureDate,
76             int connectionToSinkType) {
77         mName = name;
78         mManufacturerPnpId = manufacturerPnpId;
79         mProductId = productId;
80         mModelYear = modelYear;
81         mManufactureDate = manufactureDate;
82         mConnectionToSinkType = connectionToSinkType;
83     }
84 
DeviceProductInfo( @ullable String name, @NonNull String manufacturerPnpId, @NonNull String productId, @IntRange(from = 1990) int modelYear, @ConnectionToSinkType int connectionToSinkType)85     public DeviceProductInfo(
86             @Nullable String name,
87             @NonNull String manufacturerPnpId,
88             @NonNull String productId,
89             @IntRange(from = 1990) int modelYear,
90             @ConnectionToSinkType int connectionToSinkType) {
91         mName = name;
92         mManufacturerPnpId = Objects.requireNonNull(manufacturerPnpId);
93         mProductId = Objects.requireNonNull(productId);
94         mModelYear = modelYear;
95         mManufactureDate = null;
96         mConnectionToSinkType = connectionToSinkType;
97     }
98 
DeviceProductInfo(Parcel in)99     private DeviceProductInfo(Parcel in) {
100         mName = in.readString();
101         mManufacturerPnpId = in.readString();
102         mProductId = (String) in.readValue(null);
103         mModelYear = (Integer) in.readValue(null);
104         mManufactureDate = (ManufactureDate) in.readValue(null);
105         mConnectionToSinkType = in.readInt();
106     }
107 
108     /**
109      * @return Display name.
110      */
111     @Nullable
getName()112     public String getName() {
113         return mName;
114     }
115 
116     /**
117      * Returns the Manufacturer Plug and Play ID. This ID identifies the manufacture according to
118      * the list: https://uefi.org/PNP_ID_List. It consist of 3 characters, each character
119      * is an uppercase letter (A-Z).
120      * @return Manufacturer Plug and Play ID.
121      */
122     @NonNull
getManufacturerPnpId()123     public String getManufacturerPnpId() {
124         return mManufacturerPnpId;
125     }
126 
127     /**
128      * @return Manufacturer product ID.
129      */
130     @NonNull
getProductId()131     public String getProductId() {
132         return mProductId;
133     }
134 
135     /**
136      * @return Model year of the device. Return -1 if not available. Typically,
137      * one of model year or manufacture year is available.
138      */
139     @IntRange(from = -1)
getModelYear()140     public int getModelYear()  {
141         return mModelYear != null ? mModelYear : -1;
142     }
143 
144     /**
145      * @return The year of manufacture, or -1 it is not available. Typically,
146      * one of model year or manufacture year is available.
147      */
148     @IntRange(from = -1)
getManufactureYear()149     public int getManufactureYear()  {
150         if (mManufactureDate == null) {
151             return -1;
152         }
153         return mManufactureDate.mYear != null ? mManufactureDate.mYear : -1;
154     }
155 
156     /**
157      * @return The week of manufacture which ranges from 1 to 53, or -1 it is not available.
158      * Typically, it is not present if model year is available.
159      */
160     @IntRange(from = -1, to = 53)
getManufactureWeek()161     public int getManufactureWeek() {
162         if (mManufactureDate == null) {
163             return -1;
164         }
165         return mManufactureDate.mWeek != null ?  mManufactureDate.mWeek : -1;
166     }
167 
168     /**
169      * @return Manufacture date. Typically exactly one of model year or manufacture
170      * date will be present.
171      *
172      * @hide
173      */
getManufactureDate()174     public ManufactureDate getManufactureDate() {
175         return mManufactureDate;
176     }
177 
178     /**
179      * @return How the current device is connected to the display sink. For example, the display
180      * can be connected immediately to the device or there can be a receiver in between.
181      */
182     @ConnectionToSinkType
getConnectionToSinkType()183     public int getConnectionToSinkType() {
184         return mConnectionToSinkType;
185     }
186 
187     @Override
toString()188     public String toString() {
189         return "DeviceProductInfo{"
190                 + "name="
191                 + mName
192                 + ", manufacturerPnpId="
193                 + mManufacturerPnpId
194                 + ", productId="
195                 + mProductId
196                 + ", modelYear="
197                 + mModelYear
198                 + ", manufactureDate="
199                 + mManufactureDate
200                 + ", connectionToSinkType="
201                 + mConnectionToSinkType
202                 + '}';
203     }
204 
205     @Override
equals(@ullable Object o)206     public boolean equals(@Nullable Object o) {
207         if (this == o) return true;
208         if (o == null || getClass() != o.getClass()) return false;
209         DeviceProductInfo that = (DeviceProductInfo) o;
210         return Objects.equals(mName, that.mName)
211                 && Objects.equals(mManufacturerPnpId, that.mManufacturerPnpId)
212                 && Objects.equals(mProductId, that.mProductId)
213                 && Objects.equals(mModelYear, that.mModelYear)
214                 && Objects.equals(mManufactureDate, that.mManufactureDate)
215                 && mConnectionToSinkType == that.mConnectionToSinkType;
216     }
217 
218     @Override
hashCode()219     public int hashCode() {
220         return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate,
221                 mConnectionToSinkType);
222     }
223 
224     @NonNull public static final Creator<DeviceProductInfo> CREATOR =
225             new Creator<DeviceProductInfo>() {
226                 @Override
227                 public DeviceProductInfo createFromParcel(Parcel in) {
228                     return new DeviceProductInfo(in);
229                 }
230 
231                 @Override
232                 public DeviceProductInfo[] newArray(int size) {
233                     return new DeviceProductInfo[size];
234                 }
235             };
236 
237     @Override
describeContents()238     public int describeContents() {
239         return 0;
240     }
241 
242     @Override
writeToParcel(@onNull Parcel dest, int flags)243     public void writeToParcel(@NonNull Parcel dest, int flags) {
244         dest.writeString(mName);
245         dest.writeString(mManufacturerPnpId);
246         dest.writeValue(mProductId);
247         dest.writeValue(mModelYear);
248         dest.writeValue(mManufactureDate);
249         dest.writeInt(mConnectionToSinkType);
250     }
251 
252     /**
253      * Stores information about the date of manufacture.
254      *
255      * @hide
256      */
257     public static class ManufactureDate implements Parcelable {
258         private final Integer mWeek;
259         private final Integer mYear;
260 
ManufactureDate(Integer week, Integer year)261         public ManufactureDate(Integer week, Integer year) {
262             mWeek = week;
263             mYear = year;
264         }
265 
ManufactureDate(Parcel in)266         protected ManufactureDate(Parcel in) {
267             mWeek = (Integer) in.readValue(null);
268             mYear = (Integer) in.readValue(null);
269         }
270 
271         @Override
writeToParcel(Parcel dest, int flags)272         public void writeToParcel(Parcel dest, int flags) {
273             dest.writeValue(mWeek);
274             dest.writeValue(mYear);
275         }
276 
277         @Override
describeContents()278         public int describeContents() {
279             return 0;
280         }
281 
282         public static final Creator<ManufactureDate> CREATOR =
283                 new Creator<ManufactureDate>() {
284                     @Override
285                     public ManufactureDate createFromParcel(Parcel in) {
286                         return new ManufactureDate(in);
287                     }
288 
289                     @Override
290                     public ManufactureDate[] newArray(int size) {
291                         return new ManufactureDate[size];
292                     }
293                 };
294 
getYear()295         public Integer getYear() {
296             return mYear;
297         }
298 
getWeek()299         public Integer getWeek() {
300             return mWeek;
301         }
302 
303         @Override
toString()304         public String toString() {
305             return "ManufactureDate{week=" + mWeek + ", year=" + mYear + '}';
306         }
307 
308         @Override
equals(@ullable Object o)309         public boolean equals(@Nullable Object o) {
310             if (this == o) return true;
311             if (o == null || getClass() != o.getClass()) return false;
312             ManufactureDate that = (ManufactureDate) o;
313             return Objects.equals(mWeek, that.mWeek) && Objects.equals(mYear, that.mYear);
314         }
315 
316         @Override
hashCode()317         public int hashCode() {
318             return Objects.hash(mWeek, mYear);
319         }
320     }
321 }
322