1 /*
2  * Copyright (C) 2018 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 #pragma once
18 
19 #include <array>
20 #include <cstdint>
21 #include <optional>
22 #include <string>
23 #include <string_view>
24 #include <vector>
25 
26 #include <ui/DeviceProductInfo.h>
27 #include <ui/PhysicalDisplayId.h>
28 
29 #define LEGACY_DISPLAY_TYPE_PRIMARY 0
30 #define LEGACY_DISPLAY_TYPE_EXTERNAL 1
31 
32 namespace android {
33 
34 struct DisplayId {
35     using Type = PhysicalDisplayId;
36     Type value;
37 
38     uint16_t manufacturerId() const;
39 
40     static DisplayId fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t modelHash);
41 };
42 
43 inline bool operator==(DisplayId lhs, DisplayId rhs) {
44     return lhs.value == rhs.value;
45 }
46 
47 inline bool operator!=(DisplayId lhs, DisplayId rhs) {
48     return !(lhs == rhs);
49 }
50 
to_string(DisplayId displayId)51 inline std::string to_string(DisplayId displayId) {
52     return std::to_string(displayId.value);
53 }
54 
55 using DisplayIdentificationData = std::vector<uint8_t>;
56 
57 struct DisplayIdentificationInfo {
58     DisplayId id;
59     std::string name;
60     std::optional<DeviceProductInfo> deviceProductInfo;
61 };
62 
63 struct ExtensionBlock {
64     uint8_t tag;
65     uint8_t revisionNumber;
66 };
67 
68 struct HdmiPhysicalAddress {
69     // The address describes the path from the display sink in the network of connected HDMI
70     // devices. The format of the address is "a.b.c.d". For example, address 2.1.0.0 means we are
71     // connected to port 1 of a device which is connected to port 2 of the sink.
72     uint8_t a, b, c, d;
73 };
74 
75 struct HdmiVendorDataBlock {
76     HdmiPhysicalAddress physicalAddress;
77 };
78 
79 struct Cea861ExtensionBlock : ExtensionBlock {
80     std::optional<HdmiVendorDataBlock> hdmiVendorDataBlock;
81 };
82 
83 struct Edid {
84     uint16_t manufacturerId;
85     uint16_t productId;
86     PnpId pnpId;
87     uint32_t modelHash;
88     std::string_view displayName;
89     uint8_t manufactureOrModelYear;
90     uint8_t manufactureWeek;
91     std::optional<Cea861ExtensionBlock> cea861Block;
92 };
93 
94 bool isEdid(const DisplayIdentificationData&);
95 std::optional<Edid> parseEdid(const DisplayIdentificationData&);
96 std::optional<PnpId> getPnpId(uint16_t manufacturerId);
97 std::optional<PnpId> getPnpId(DisplayId);
98 
99 std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
100         uint8_t port, const DisplayIdentificationData&);
101 
102 DisplayId getFallbackDisplayId(uint8_t port);
103 DisplayId getVirtualDisplayId(uint32_t id);
104 
105 } // namespace android
106 
107 namespace std {
108 
109 template <>
110 struct hash<android::DisplayId> {
111     size_t operator()(android::DisplayId displayId) const {
112         return hash<android::DisplayId::Type>()(displayId.value);
113     }
114 };
115 
116 } // namespace std
117