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

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: 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 // Generates product specific value from product_name instead of product code.
53 // See crbug.com/240341 54 // See crbug.com/240341
54 uint32_t product_code_hash = product_name.empty() ? 55 uint32_t product_code_hash = product_name.empty() ?
55 0 : base::Hash(product_name); 56 0 : base::Hash(product_name);
oshima 2015/05/20 15:37:33 would you mind moving this code inside following i
robert.bradford 2015/05/20 17:13:58 Done.
56 if (manufacturer_id != 0) { 57 if (manufacturer_id != 0) {
57 // An ID based on display's index will be assigned later if this call 58 // An ID based on display's index will be assigned later if this call
58 // fails. 59 // fails.
59 *display_id_out = GetID( 60 *display_id_out = GetID(
60 manufacturer_id, product_code_hash, output_index); 61 manufacturer_id, product_code_hash, output_index);
62 // product_id is 64-bit signed so it can store -1 as kInvalidProductID and
63 // not match a valid product id which will all be in the lowest 32-bits.
61 if (product_id_out) 64 if (product_id_out)
62 *product_id_out = GetProductID(manufacturer_id, product_code_hash); 65 *product_id_out = GetProductID(manufacturer_id, product_code);
63 return true; 66 return true;
64 } 67 }
65 return false; 68 return false;
66 } 69 }
67 70
68 bool ParseOutputDeviceData(const std::vector<uint8_t>& edid, 71 bool ParseOutputDeviceData(const std::vector<uint8_t>& edid,
69 uint16_t* manufacturer_id, 72 uint16_t* manufacturer_id,
73 uint16_t* product_code,
70 std::string* human_readable_name, 74 std::string* human_readable_name,
71 gfx::Size* active_pixel_out, 75 gfx::Size* active_pixel_out,
72 gfx::Size* physical_display_size_out) { 76 gfx::Size* physical_display_size_out) {
73 // See http://en.wikipedia.org/wiki/Extended_display_identification_data 77 // See http://en.wikipedia.org/wiki/Extended_display_identification_data
74 // for the details of EDID data format. We use the following data: 78 // for the details of EDID data format. We use the following data:
75 // bytes 8-9: manufacturer EISA ID, in big-endian 79 // bytes 8-9: manufacturer EISA ID, in big-endian
80 // bytes 10-11: manufacturer product code, in little-endian
76 // bytes 54-125: four descriptors (18-bytes each) which may contain 81 // bytes 54-125: four descriptors (18-bytes each) which may contain
77 // the display name. 82 // the display name.
78 const unsigned int kManufacturerOffset = 8; 83 const unsigned int kManufacturerOffset = 8;
79 const unsigned int kManufacturerLength = 2; 84 const unsigned int kManufacturerLength = 2;
85 const unsigned int kProductCodeOffset = 10;
86 const unsigned int kProductCodeLength = 2;
80 const unsigned int kDescriptorOffset = 54; 87 const unsigned int kDescriptorOffset = 54;
81 const unsigned int kNumDescriptors = 4; 88 const unsigned int kNumDescriptors = 4;
82 const unsigned int kDescriptorLength = 18; 89 const unsigned int kDescriptorLength = 18;
83 // The specifier types. 90 // The specifier types.
84 const unsigned char kMonitorNameDescriptor = 0xfc; 91 const unsigned char kMonitorNameDescriptor = 0xfc;
85 92
86 if (manufacturer_id) { 93 if (manufacturer_id) {
87 if (edid.size() < kManufacturerOffset + kManufacturerLength) { 94 if (edid.size() < kManufacturerOffset + kManufacturerLength) {
88 LOG(ERROR) << "too short EDID data: manifacturer id"; 95 LOG(ERROR) << "too short EDID data: manufacturer id";
89 return false; 96 return false;
90 } 97 }
91 98
92 *manufacturer_id = 99 *manufacturer_id =
93 *reinterpret_cast<const uint16_t*>(&edid[kManufacturerOffset]); 100 *reinterpret_cast<const uint16_t*>(&edid[kManufacturerOffset]);
94 #if defined(ARCH_CPU_LITTLE_ENDIAN) 101 #if defined(ARCH_CPU_LITTLE_ENDIAN)
95 *manufacturer_id = base::ByteSwap(*manufacturer_id); 102 *manufacturer_id = base::ByteSwap(*manufacturer_id);
96 #endif 103 #endif
97 } 104 }
98 105
106 if (product_code) {
107 if (edid.size() < kProductCodeOffset + kProductCodeLength) {
108 LOG(ERROR) << "too short EDID data: manufacturer product code";
109 return false;
110 }
111
112 *product_code =
113 *reinterpret_cast<const uint16_t*>(&edid[kProductCodeOffset]);
114 }
115
99 if (human_readable_name) 116 if (human_readable_name)
100 human_readable_name->clear(); 117 human_readable_name->clear();
101 118
102 for (unsigned int i = 0; i < kNumDescriptors; ++i) { 119 for (unsigned int i = 0; i < kNumDescriptors; ++i) {
103 if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength) 120 if (edid.size() < kDescriptorOffset + (i + 1) * kDescriptorLength)
104 break; 121 break;
105 122
106 size_t offset = kDescriptorOffset + i * kDescriptorLength; 123 size_t offset = kDescriptorOffset + i * kDescriptorLength;
107 124
108 // Detailed Timing Descriptor: 125 // Detailed Timing Descriptor:
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 *flag = false; 265 *flag = false;
249 } 266 }
250 return true; 267 return true;
251 } 268 }
252 } 269 }
253 270
254 return false; 271 return false;
255 } 272 }
256 273
257 } // namespace ui 274 } // 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