Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: ui/display/util/edid_parser.cc

Issue 1151583002: Generate display product id with EDID manufacturer product code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move code as requested by oshima@ Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/display/util/edid_parser.h ('k') | ui/display/util/edid_parser_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/display/util/edid_parser.h" 5 #include "ui/display/util/edid_parser.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/hash.h" 9 #include "base/hash.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 11 matching lines...) Expand all
22 // treated as swap. The 'serial number' field in EDID isn't used here because 22 // treated as swap. The 'serial number' field in EDID isn't used here because
23 // it is not guaranteed to have unique number and it may have the same fixed 23 // it is not guaranteed to have unique number and it may have the same fixed
24 // value (like 0). 24 // value (like 0).
25 int64_t GetID(uint16_t manufacturer_id, 25 int64_t GetID(uint16_t manufacturer_id,
26 uint32_t product_code_hash, 26 uint32_t product_code_hash,
27 uint8_t output_index) { 27 uint8_t output_index) {
28 return ((static_cast<int64_t>(manufacturer_id) << 40) | 28 return ((static_cast<int64_t>(manufacturer_id) << 40) |
29 (static_cast<int64_t>(product_code_hash) << 8) | output_index); 29 (static_cast<int64_t>(product_code_hash) << 8) | output_index);
30 } 30 }
31 31
32 // Returns a 64-bit identifier for this model of display, using 32 // Returns a 32-bit identifier for this model of display, using
33 // |manufacturer_id| and |product_code_hash|. 33 // |manufacturer_id| and |product_code|.
34 int64_t GetProductID(uint16_t manufacturer_id, uint32_t product_code_hash) { 34 uint32_t GetProductID(uint16_t manufacturer_id, uint16_t product_code) {
35 return ((static_cast<int64_t>(manufacturer_id) << 32) | 35 return ((static_cast<uint32_t>(manufacturer_id) << 16) |
36 (static_cast<int64_t>(product_code_hash))); 36 (static_cast<uint32_t>(product_code)));
37 } 37 }
38 38
39 } // namespace 39 } // namespace
40 40
41 bool GetDisplayIdFromEDID(const std::vector<uint8_t>& edid, 41 bool GetDisplayIdFromEDID(const std::vector<uint8_t>& edid,
42 uint8_t output_index, 42 uint8_t output_index,
43 int64_t* display_id_out, 43 int64_t* display_id_out,
44 int64_t* product_id_out) { 44 int64_t* product_id_out) {
45 uint16_t manufacturer_id = 0; 45 uint16_t manufacturer_id = 0;
46 uint16_t product_code = 0;
46 std::string product_name; 47 std::string product_name;
47 48
48 // ParseOutputDeviceData fails if it doesn't have product_name. 49 // ParseOutputDeviceData fails if it doesn't have product_name.
49 ParseOutputDeviceData(edid, &manufacturer_id, &product_name, nullptr, 50 ParseOutputDeviceData(edid, &manufacturer_id, &product_code, &product_name,
50 nullptr); 51 nullptr, nullptr);
51 52
52 // Generates product specific value from product_name instead of product code.
53 // See crbug.com/240341
54 uint32_t product_code_hash = product_name.empty() ?
55 0 : base::Hash(product_name);
56 if (manufacturer_id != 0) { 53 if (manufacturer_id != 0) {
54 // Generates product specific value from product_name instead of product
55 // code.
56 // See crbug.com/240341
57 uint32_t product_code_hash =
58 product_name.empty() ? 0 : base::Hash(product_name);
57 // An ID based on display's index will be assigned later if this call 59 // An ID based on display's index will be assigned later if this call
58 // fails. 60 // fails.
59 *display_id_out = GetID( 61 *display_id_out = GetID(
60 manufacturer_id, product_code_hash, output_index); 62 manufacturer_id, product_code_hash, output_index);
63 // product_id is 64-bit signed so it can store -1 as kInvalidProductID and
64 // not match a valid product id which will all be in the lowest 32-bits.
61 if (product_id_out) 65 if (product_id_out)
62 *product_id_out = GetProductID(manufacturer_id, product_code_hash); 66 *product_id_out = GetProductID(manufacturer_id, product_code);
63 return true; 67 return true;
64 } 68 }
65 return false; 69 return false;
66 } 70 }
67 71
68 bool ParseOutputDeviceData(const std::vector<uint8_t>& edid, 72 bool ParseOutputDeviceData(const std::vector<uint8_t>& edid,
69 uint16_t* manufacturer_id, 73 uint16_t* manufacturer_id,
74 uint16_t* product_code,
70 std::string* human_readable_name, 75 std::string* human_readable_name,
71 gfx::Size* active_pixel_out, 76 gfx::Size* active_pixel_out,
72 gfx::Size* physical_display_size_out) { 77 gfx::Size* physical_display_size_out) {
73 // See http://en.wikipedia.org/wiki/Extended_display_identification_data 78 // See http://en.wikipedia.org/wiki/Extended_display_identification_data
74 // for the details of EDID data format. We use the following data: 79 // for the details of EDID data format. We use the following data:
75 // bytes 8-9: manufacturer EISA ID, in big-endian 80 // bytes 8-9: manufacturer EISA ID, in big-endian
81 // bytes 10-11: manufacturer product code, in little-endian
76 // bytes 54-125: four descriptors (18-bytes each) which may contain 82 // bytes 54-125: four descriptors (18-bytes each) which may contain
77 // the display name. 83 // the display name.
78 const unsigned int kManufacturerOffset = 8; 84 const unsigned int kManufacturerOffset = 8;
79 const unsigned int kManufacturerLength = 2; 85 const unsigned int kManufacturerLength = 2;
86 const unsigned int kProductCodeOffset = 10;
87 const unsigned int kProductCodeLength = 2;
80 const unsigned int kDescriptorOffset = 54; 88 const unsigned int kDescriptorOffset = 54;
81 const unsigned int kNumDescriptors = 4; 89 const unsigned int kNumDescriptors = 4;
82 const unsigned int kDescriptorLength = 18; 90 const unsigned int kDescriptorLength = 18;
83 // The specifier types. 91 // The specifier types.
84 const unsigned char kMonitorNameDescriptor = 0xfc; 92 const unsigned char kMonitorNameDescriptor = 0xfc;
85 93
86 if (manufacturer_id) { 94 if (manufacturer_id) {
87 if (edid.size() < kManufacturerOffset + kManufacturerLength) { 95 if (edid.size() < kManufacturerOffset + kManufacturerLength) {
88 LOG(ERROR) << "too short EDID data: manifacturer id"; 96 LOG(ERROR) << "too short EDID data: manufacturer id";
89 return false; 97 return false;
90 } 98 }
91 99
92 *manufacturer_id = 100 *manufacturer_id =
93 *reinterpret_cast<const uint16_t*>(&edid[kManufacturerOffset]); 101 *reinterpret_cast<const uint16_t*>(&edid[kManufacturerOffset]);
94 #if defined(ARCH_CPU_LITTLE_ENDIAN) 102 #if defined(ARCH_CPU_LITTLE_ENDIAN)
95 *manufacturer_id = base::ByteSwap(*manufacturer_id); 103 *manufacturer_id = base::ByteSwap(*manufacturer_id);
96 #endif 104 #endif
97 } 105 }
98 106
107 if (product_code) {
108 if (edid.size() < kProductCodeOffset + kProductCodeLength) {
109 LOG(ERROR) << "too short EDID data: manufacturer product code";
110 return false;
111 }
112
113 *product_code =
114 *reinterpret_cast<const uint16_t*>(&edid[kProductCodeOffset]);
115 }
116
99 if (human_readable_name) 117 if (human_readable_name)
100 human_readable_name->clear(); 118 human_readable_name->clear();
101 119
102 for (unsigned int i = 0; i < kNumDescriptors; ++i) { 120 for (unsigned int i = 0; i < kNumDescriptors; ++i) {
103 if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength) 121 if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength)
104 break; 122 break;
105 123
106 size_t offset = kDescriptorOffset + i * kDescriptorLength; 124 size_t offset = kDescriptorOffset + i * kDescriptorLength;
107 125
108 // Detailed Timing Descriptor: 126 // Detailed Timing Descriptor:
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 *flag = false; 266 *flag = false;
249 } 267 }
250 return true; 268 return true;
251 } 269 }
252 } 270 }
253 271
254 return false; 272 return false;
255 } 273 }
256 274
257 } // namespace ui 275 } // namespace ui
OLDNEW
« no previous file with comments | « ui/display/util/edid_parser.h ('k') | ui/display/util/edid_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698