OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/gpu_blacklist.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/json/json_reader.h" | |
9 #include "base/logging.h" | |
10 #include "base/string_number_conversions.h" | |
11 #include "base/string_split.h" | |
12 #include "base/string_util.h" | |
13 #include "base/sys_info.h" | |
14 #include "base/version.h" | |
15 #include "chrome/browser/gpu_util.h" | |
16 #include "chrome/common/chrome_version_info.h" | |
17 #include "content/public/browser/gpu_data_manager.h" | |
18 #include "content/public/common/content_switches.h" | |
19 #include "content/public/common/gpu_info.h" | |
20 | |
21 using content::GpuDataManager; | |
22 using content::GpuFeatureType; | |
23 | |
24 namespace { | |
25 | |
26 // Encode a date as Version, where [0] is year, [1] is month, and [2] is day. | |
27 void GetDateFromString(const std::string& date_string, Version* version) { | |
28 // TODO(zmo): verify if in Windows registry, driver dates are always in the | |
29 // format of "mm-dd-yyyy". | |
30 std::vector<std::string> pieces; | |
31 base::SplitString(date_string, '-', &pieces); | |
32 if (pieces.size() != 3) { | |
33 *version = Version(); | |
34 return; | |
35 } | |
36 std::string date_as_version_string = pieces[2]; | |
37 for (size_t i = 0; i < 2; ++i) { | |
38 date_as_version_string += "."; | |
39 date_as_version_string += pieces[i]; | |
40 } | |
41 *version = Version(date_as_version_string); | |
42 } | |
43 | |
44 // We assume the input format is major.minor, and we treat major version | |
45 // as numerical and minor as lexical. | |
46 // Otherwise we simply return the original string. | |
47 // For example, if input numerical is 8.103, returned lexical is 8.1.0.3. | |
48 std::string NumericalToLexical(const std::string& numerical) { | |
49 std::string lexical; | |
50 bool valid = true; | |
51 size_t pos = numerical.find_first_of('.'); | |
52 if (pos != std::string::npos && pos + 1 < numerical.length()) { | |
53 lexical = numerical.substr(0, pos); | |
54 for (size_t i = pos + 1; i < numerical.length(); ++i) { | |
55 if (!IsAsciiDigit(numerical[i])) { | |
56 valid = false; | |
57 break; | |
58 } | |
59 lexical += '.'; | |
60 lexical += numerical[i]; | |
61 } | |
62 } else { | |
63 valid = false; | |
64 } | |
65 if (valid) | |
66 return lexical; | |
67 return numerical; | |
68 } | |
69 | |
70 bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list, | |
71 const content::GPUInfo::GPUDevice& gpu) { | |
72 if (vendor_id == 0) | |
73 return false; | |
74 if (vendor_id != gpu.vendor_id) | |
75 return true; | |
76 bool device_specified = false; | |
77 for (size_t i = 0; i < device_id_list.size(); ++i) { | |
78 if (device_id_list[i] == 0) | |
79 continue; | |
80 if (device_id_list[i] == gpu.device_id) | |
81 return false; | |
82 device_specified = true; | |
83 } | |
84 return device_specified; | |
85 } | |
86 | |
87 const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable"; | |
88 const char kMultiGpuStyleStringOptimus[] = "optimus"; | |
89 | |
90 const char kMultiGpuCategoryStringPrimary[] = "primary"; | |
91 const char kMultiGpuCategoryStringSecondary[] = "secondary"; | |
92 const char kMultiGpuCategoryStringAny[] = "any"; | |
93 | |
94 const char kVersionStyleStringNumerical[] = "numerical"; | |
95 const char kVersionStyleStringLexical[] = "lexical"; | |
96 | |
97 } // namespace anonymous | |
98 | |
99 GpuBlacklist::VersionInfo::VersionInfo( | |
100 const std::string& version_op, | |
101 const std::string& version_style, | |
102 const std::string& version_string, | |
103 const std::string& version_string2) | |
104 : version_style_(kVersionStyleNumerical) { | |
105 op_ = StringToNumericOp(version_op); | |
106 if (op_ == kUnknown || op_ == kAny) | |
107 return; | |
108 version_style_ = StringToVersionStyle(version_style); | |
109 std::string processed_version_string, processed_version_string2; | |
110 if (version_style_ == kVersionStyleLexical) { | |
111 processed_version_string = NumericalToLexical(version_string); | |
112 processed_version_string2 = NumericalToLexical(version_string2); | |
113 } else { | |
114 processed_version_string = version_string; | |
115 processed_version_string2 = version_string2; | |
116 } | |
117 version_.reset(new Version(processed_version_string)); | |
118 if (!version_->IsValid()) { | |
119 op_ = kUnknown; | |
120 return; | |
121 } | |
122 if (op_ == kBetween) { | |
123 version2_.reset(new Version(processed_version_string2)); | |
124 if (!version2_->IsValid()) | |
125 op_ = kUnknown; | |
126 } | |
127 } | |
128 | |
129 GpuBlacklist::VersionInfo::~VersionInfo() { | |
130 } | |
131 | |
132 bool GpuBlacklist::VersionInfo::Contains(const Version& version) const { | |
133 if (op_ == kUnknown) | |
134 return false; | |
135 if (op_ == kAny) | |
136 return true; | |
137 if (op_ == kEQ) { | |
138 // Handles cases where 10.6 is considered as containing 10.6.*. | |
139 const std::vector<uint16>& components_reference = version_->components(); | |
140 const std::vector<uint16>& components = version.components(); | |
141 for (size_t i = 0; i < components_reference.size(); ++i) { | |
142 if (i >= components.size() && components_reference[i] != 0) | |
143 return false; | |
144 if (components[i] != components_reference[i]) | |
145 return false; | |
146 } | |
147 return true; | |
148 } | |
149 int relation = version.CompareTo(*version_); | |
150 if (op_ == kEQ) | |
151 return (relation == 0); | |
152 else if (op_ == kLT) | |
153 return (relation < 0); | |
154 else if (op_ == kLE) | |
155 return (relation <= 0); | |
156 else if (op_ == kGT) | |
157 return (relation > 0); | |
158 else if (op_ == kGE) | |
159 return (relation >= 0); | |
160 // op_ == kBetween | |
161 if (relation < 0) | |
162 return false; | |
163 return version.CompareTo(*version2_) <= 0; | |
164 } | |
165 | |
166 bool GpuBlacklist::VersionInfo::IsValid() const { | |
167 return (op_ != kUnknown && version_style_ != kVersionStyleUnknown); | |
168 } | |
169 | |
170 bool GpuBlacklist::VersionInfo::IsLexical() const { | |
171 return version_style_ == kVersionStyleLexical; | |
172 } | |
173 | |
174 // static | |
175 GpuBlacklist::VersionInfo::VersionStyle | |
176 GpuBlacklist::VersionInfo::StringToVersionStyle( | |
177 const std::string& version_style) { | |
178 if (version_style.empty() || version_style == kVersionStyleStringNumerical) | |
179 return kVersionStyleNumerical; | |
180 if (version_style == kVersionStyleStringLexical) | |
181 return kVersionStyleLexical; | |
182 return kVersionStyleUnknown; | |
183 } | |
184 | |
185 GpuBlacklist::OsInfo::OsInfo(const std::string& os, | |
186 const std::string& version_op, | |
187 const std::string& version_string, | |
188 const std::string& version_string2) { | |
189 type_ = StringToOsType(os); | |
190 if (type_ != kOsUnknown) { | |
191 version_info_.reset( | |
192 new VersionInfo(version_op, "", version_string, version_string2)); | |
193 } | |
194 } | |
195 | |
196 GpuBlacklist::OsInfo::~OsInfo() {} | |
197 | |
198 bool GpuBlacklist::OsInfo::Contains(OsType type, | |
199 const Version& version) const { | |
200 if (!IsValid()) | |
201 return false; | |
202 if (type_ != type && type_ != kOsAny) | |
203 return false; | |
204 return version_info_->Contains(version); | |
205 } | |
206 | |
207 bool GpuBlacklist::OsInfo::IsValid() const { | |
208 return type_ != kOsUnknown && version_info_->IsValid(); | |
209 } | |
210 | |
211 GpuBlacklist::OsType GpuBlacklist::OsInfo::type() const { | |
212 return type_; | |
213 } | |
214 | |
215 GpuBlacklist::OsType GpuBlacklist::OsInfo::StringToOsType( | |
216 const std::string& os) { | |
217 if (os == "win") | |
218 return kOsWin; | |
219 else if (os == "macosx") | |
220 return kOsMacosx; | |
221 else if (os == "linux") | |
222 return kOsLinux; | |
223 else if (os == "chromeos") | |
224 return kOsChromeOS; | |
225 else if (os == "any") | |
226 return kOsAny; | |
227 return kOsUnknown; | |
228 } | |
229 | |
230 GpuBlacklist::StringInfo::StringInfo(const std::string& string_op, | |
231 const std::string& string_value) { | |
232 op_ = StringToOp(string_op); | |
233 value_ = StringToLowerASCII(string_value); | |
234 } | |
235 | |
236 bool GpuBlacklist::StringInfo::Contains(const std::string& value) const { | |
237 std::string my_value = StringToLowerASCII(value); | |
238 switch (op_) { | |
239 case kContains: | |
240 return strstr(my_value.c_str(), value_.c_str()) != NULL; | |
241 case kBeginWith: | |
242 return StartsWithASCII(my_value, value_, false); | |
243 case kEndWith: | |
244 return EndsWith(my_value, value_, false); | |
245 case kEQ: | |
246 return value_ == my_value; | |
247 default: | |
248 return false; | |
249 } | |
250 } | |
251 | |
252 bool GpuBlacklist::StringInfo::IsValid() const { | |
253 return op_ != kUnknown; | |
254 } | |
255 | |
256 GpuBlacklist::StringInfo::Op GpuBlacklist::StringInfo::StringToOp( | |
257 const std::string& string_op) { | |
258 if (string_op == "=") | |
259 return kEQ; | |
260 else if (string_op == "contains") | |
261 return kContains; | |
262 else if (string_op == "beginwith") | |
263 return kBeginWith; | |
264 else if (string_op == "endwith") | |
265 return kEndWith; | |
266 return kUnknown; | |
267 } | |
268 | |
269 GpuBlacklist::FloatInfo::FloatInfo(const std::string& float_op, | |
270 const std::string& float_value, | |
271 const std::string& float_value2) | |
272 : op_(kUnknown), | |
273 value_(0.f), | |
274 value2_(0.f) { | |
275 double dvalue = 0; | |
276 if (!base::StringToDouble(float_value, &dvalue)) { | |
277 op_ = kUnknown; | |
278 return; | |
279 } | |
280 value_ = static_cast<float>(dvalue); | |
281 op_ = StringToNumericOp(float_op); | |
282 if (op_ == kBetween) { | |
283 if (!base::StringToDouble(float_value2, &dvalue)) { | |
284 op_ = kUnknown; | |
285 return; | |
286 } | |
287 value2_ = static_cast<float>(dvalue); | |
288 } | |
289 } | |
290 | |
291 bool GpuBlacklist::FloatInfo::Contains(float value) const { | |
292 if (op_ == kUnknown) | |
293 return false; | |
294 if (op_ == kAny) | |
295 return true; | |
296 if (op_ == kEQ) | |
297 return (value == value_); | |
298 if (op_ == kLT) | |
299 return (value < value_); | |
300 if (op_ == kLE) | |
301 return (value <= value_); | |
302 if (op_ == kGT) | |
303 return (value > value_); | |
304 if (op_ == kGE) | |
305 return (value >= value_); | |
306 DCHECK(op_ == kBetween); | |
307 return ((value_ <= value && value <= value2_) || | |
308 (value2_ <= value && value <= value_)); | |
309 } | |
310 | |
311 bool GpuBlacklist::FloatInfo::IsValid() const { | |
312 return op_ != kUnknown; | |
313 } | |
314 | |
315 // static | |
316 GpuBlacklist::ScopedGpuBlacklistEntry | |
317 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue( | |
318 const DictionaryValue* value, bool top_level) { | |
319 DCHECK(value); | |
320 ScopedGpuBlacklistEntry entry(new GpuBlacklistEntry()); | |
321 | |
322 size_t dictionary_entry_count = 0; | |
323 | |
324 if (top_level) { | |
325 uint32 id; | |
326 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) || | |
327 !entry->SetId(id)) { | |
328 LOG(WARNING) << "Malformed id entry " << entry->id(); | |
329 return NULL; | |
330 } | |
331 dictionary_entry_count++; | |
332 | |
333 bool disabled; | |
334 if (value->GetBoolean("disabled", &disabled)) { | |
335 entry->SetDisabled(disabled); | |
336 dictionary_entry_count++; | |
337 } | |
338 } | |
339 | |
340 std::string description; | |
341 if (value->GetString("description", &description)) { | |
342 entry->description_ = description; | |
343 dictionary_entry_count++; | |
344 } else { | |
345 entry->description_ = "The GPU is unavailable for an unexplained reason."; | |
346 } | |
347 | |
348 const ListValue* cr_bugs; | |
349 if (value->GetList("cr_bugs", &cr_bugs)) { | |
350 for (size_t i = 0; i < cr_bugs->GetSize(); ++i) { | |
351 int bug_id; | |
352 if (cr_bugs->GetInteger(i, &bug_id)) { | |
353 entry->cr_bugs_.push_back(bug_id); | |
354 } else { | |
355 LOG(WARNING) << "Malformed cr_bugs entry " << entry->id(); | |
356 return NULL; | |
357 } | |
358 } | |
359 dictionary_entry_count++; | |
360 } | |
361 | |
362 const ListValue* webkit_bugs; | |
363 if (value->GetList("webkit_bugs", &webkit_bugs)) { | |
364 for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) { | |
365 int bug_id; | |
366 if (webkit_bugs->GetInteger(i, &bug_id)) { | |
367 entry->webkit_bugs_.push_back(bug_id); | |
368 } else { | |
369 LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id(); | |
370 return NULL; | |
371 } | |
372 } | |
373 dictionary_entry_count++; | |
374 } | |
375 | |
376 const DictionaryValue* os_value = NULL; | |
377 if (value->GetDictionary("os", &os_value)) { | |
378 std::string os_type; | |
379 std::string os_version_op = "any"; | |
380 std::string os_version_string; | |
381 std::string os_version_string2; | |
382 os_value->GetString("type", &os_type); | |
383 const DictionaryValue* os_version_value = NULL; | |
384 if (os_value->GetDictionary("version", &os_version_value)) { | |
385 os_version_value->GetString("op", &os_version_op); | |
386 os_version_value->GetString("number", &os_version_string); | |
387 os_version_value->GetString("number2", &os_version_string2); | |
388 } | |
389 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string, | |
390 os_version_string2)) { | |
391 LOG(WARNING) << "Malformed os entry " << entry->id(); | |
392 return NULL; | |
393 } | |
394 dictionary_entry_count++; | |
395 } | |
396 | |
397 std::string vendor_id; | |
398 if (value->GetString("vendor_id", &vendor_id)) { | |
399 if (!entry->SetVendorId(vendor_id)) { | |
400 LOG(WARNING) << "Malformed vendor_id entry " << entry->id(); | |
401 return NULL; | |
402 } | |
403 dictionary_entry_count++; | |
404 } | |
405 | |
406 const ListValue* device_id_list; | |
407 if (value->GetList("device_id", &device_id_list)) { | |
408 for (size_t i = 0; i < device_id_list->GetSize(); ++i) { | |
409 std::string device_id; | |
410 if (!device_id_list->GetString(i, &device_id) || | |
411 !entry->AddDeviceId(device_id)) { | |
412 LOG(WARNING) << "Malformed device_id entry " << entry->id(); | |
413 return NULL; | |
414 } | |
415 } | |
416 dictionary_entry_count++; | |
417 } | |
418 | |
419 std::string multi_gpu_style; | |
420 if (value->GetString("multi_gpu_style", &multi_gpu_style)) { | |
421 if (!entry->SetMultiGpuStyle(multi_gpu_style)) { | |
422 LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id(); | |
423 return NULL; | |
424 } | |
425 dictionary_entry_count++; | |
426 } | |
427 | |
428 std::string multi_gpu_category; | |
429 if (value->GetString("multi_gpu_category", &multi_gpu_category)) { | |
430 if (!entry->SetMultiGpuCategory(multi_gpu_category)) { | |
431 LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id(); | |
432 return NULL; | |
433 } | |
434 dictionary_entry_count++; | |
435 } | |
436 | |
437 const DictionaryValue* driver_vendor_value = NULL; | |
438 if (value->GetDictionary("driver_vendor", &driver_vendor_value)) { | |
439 std::string vendor_op; | |
440 std::string vendor_value; | |
441 driver_vendor_value->GetString("op", &vendor_op); | |
442 driver_vendor_value->GetString("value", &vendor_value); | |
443 if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) { | |
444 LOG(WARNING) << "Malformed driver_vendor entry " << entry->id(); | |
445 return NULL; | |
446 } | |
447 dictionary_entry_count++; | |
448 } | |
449 | |
450 const DictionaryValue* driver_version_value = NULL; | |
451 if (value->GetDictionary("driver_version", &driver_version_value)) { | |
452 std::string driver_version_op = "any"; | |
453 std::string driver_version_style; | |
454 std::string driver_version_string; | |
455 std::string driver_version_string2; | |
456 driver_version_value->GetString("op", &driver_version_op); | |
457 driver_version_value->GetString("style", &driver_version_style); | |
458 driver_version_value->GetString("number", &driver_version_string); | |
459 driver_version_value->GetString("number2", &driver_version_string2); | |
460 if (!entry->SetDriverVersionInfo(driver_version_op, | |
461 driver_version_style, | |
462 driver_version_string, | |
463 driver_version_string2)) { | |
464 LOG(WARNING) << "Malformed driver_version entry " << entry->id(); | |
465 return NULL; | |
466 } | |
467 dictionary_entry_count++; | |
468 } | |
469 | |
470 const DictionaryValue* driver_date_value = NULL; | |
471 if (value->GetDictionary("driver_date", &driver_date_value)) { | |
472 std::string driver_date_op = "any"; | |
473 std::string driver_date_string; | |
474 std::string driver_date_string2; | |
475 driver_date_value->GetString("op", &driver_date_op); | |
476 driver_date_value->GetString("number", &driver_date_string); | |
477 driver_date_value->GetString("number2", &driver_date_string2); | |
478 if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string, | |
479 driver_date_string2)) { | |
480 LOG(WARNING) << "Malformed driver_date entry " << entry->id(); | |
481 return NULL; | |
482 } | |
483 dictionary_entry_count++; | |
484 } | |
485 | |
486 const DictionaryValue* gl_vendor_value = NULL; | |
487 if (value->GetDictionary("gl_vendor", &gl_vendor_value)) { | |
488 std::string vendor_op; | |
489 std::string vendor_value; | |
490 gl_vendor_value->GetString("op", &vendor_op); | |
491 gl_vendor_value->GetString("value", &vendor_value); | |
492 if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) { | |
493 LOG(WARNING) << "Malformed gl_vendor entry " << entry->id(); | |
494 return NULL; | |
495 } | |
496 dictionary_entry_count++; | |
497 } | |
498 | |
499 const DictionaryValue* gl_renderer_value = NULL; | |
500 if (value->GetDictionary("gl_renderer", &gl_renderer_value)) { | |
501 std::string renderer_op; | |
502 std::string renderer_value; | |
503 gl_renderer_value->GetString("op", &renderer_op); | |
504 gl_renderer_value->GetString("value", &renderer_value); | |
505 if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) { | |
506 LOG(WARNING) << "Malformed gl_renderer entry " << entry->id(); | |
507 return NULL; | |
508 } | |
509 dictionary_entry_count++; | |
510 } | |
511 | |
512 const DictionaryValue* perf_graphics_value = NULL; | |
513 if (value->GetDictionary("perf_graphics", &perf_graphics_value)) { | |
514 std::string op; | |
515 std::string float_value; | |
516 std::string float_value2; | |
517 perf_graphics_value->GetString("op", &op); | |
518 perf_graphics_value->GetString("value", &float_value); | |
519 perf_graphics_value->GetString("value2", &float_value2); | |
520 if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) { | |
521 LOG(WARNING) << "Malformed perf_graphics entry " << entry->id(); | |
522 return NULL; | |
523 } | |
524 dictionary_entry_count++; | |
525 } | |
526 | |
527 const DictionaryValue* perf_gaming_value = NULL; | |
528 if (value->GetDictionary("perf_gaming", &perf_gaming_value)) { | |
529 std::string op; | |
530 std::string float_value; | |
531 std::string float_value2; | |
532 perf_gaming_value->GetString("op", &op); | |
533 perf_gaming_value->GetString("value", &float_value); | |
534 perf_gaming_value->GetString("value2", &float_value2); | |
535 if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) { | |
536 LOG(WARNING) << "Malformed perf_gaming entry " << entry->id(); | |
537 return NULL; | |
538 } | |
539 dictionary_entry_count++; | |
540 } | |
541 | |
542 const DictionaryValue* perf_overall_value = NULL; | |
543 if (value->GetDictionary("perf_overall", &perf_overall_value)) { | |
544 std::string op; | |
545 std::string float_value; | |
546 std::string float_value2; | |
547 perf_overall_value->GetString("op", &op); | |
548 perf_overall_value->GetString("value", &float_value); | |
549 perf_overall_value->GetString("value2", &float_value2); | |
550 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) { | |
551 LOG(WARNING) << "Malformed perf_overall entry " << entry->id(); | |
552 return NULL; | |
553 } | |
554 dictionary_entry_count++; | |
555 } | |
556 | |
557 if (top_level) { | |
558 const ListValue* blacklist_value = NULL; | |
559 if (!value->GetList("blacklist", &blacklist_value)) { | |
560 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | |
561 return NULL; | |
562 } | |
563 std::vector<std::string> blacklist; | |
564 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) { | |
565 std::string feature; | |
566 if (blacklist_value->GetString(i, &feature)) { | |
567 blacklist.push_back(feature); | |
568 } else { | |
569 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | |
570 return NULL; | |
571 } | |
572 } | |
573 if (!entry->SetBlacklistedFeatures(blacklist)) { | |
574 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | |
575 return NULL; | |
576 } | |
577 dictionary_entry_count++; | |
578 } | |
579 | |
580 if (top_level) { | |
581 const ListValue* exception_list_value = NULL; | |
582 if (value->GetList("exceptions", &exception_list_value)) { | |
583 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { | |
584 const DictionaryValue* exception_value = NULL; | |
585 if (!exception_list_value->GetDictionary(i, &exception_value)) { | |
586 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); | |
587 return NULL; | |
588 } | |
589 ScopedGpuBlacklistEntry exception( | |
590 GetGpuBlacklistEntryFromValue(exception_value, false)); | |
591 if (exception == NULL) { | |
592 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); | |
593 return NULL; | |
594 } | |
595 if (exception->contains_unknown_fields_) { | |
596 LOG(WARNING) << "Exception with unknown fields " << entry->id(); | |
597 entry->contains_unknown_fields_ = true; | |
598 } else { | |
599 entry->AddException(exception); | |
600 } | |
601 } | |
602 dictionary_entry_count++; | |
603 } | |
604 | |
605 const DictionaryValue* browser_version_value = NULL; | |
606 // browser_version is processed in LoadGpuBlacklist(). | |
607 if (value->GetDictionary("browser_version", &browser_version_value)) | |
608 dictionary_entry_count++; | |
609 } | |
610 | |
611 if (value->size() != dictionary_entry_count) { | |
612 LOG(WARNING) << "Entry with unknown fields " << entry->id(); | |
613 entry->contains_unknown_fields_ = true; | |
614 } | |
615 return entry; | |
616 } | |
617 | |
618 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() | |
619 : id_(0), | |
620 disabled_(false), | |
621 vendor_id_(0), | |
622 multi_gpu_style_(kMultiGpuStyleNone), | |
623 multi_gpu_category_(kMultiGpuCategoryPrimary), | |
624 feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN), | |
625 contains_unknown_fields_(false), | |
626 contains_unknown_features_(false) { | |
627 } | |
628 | |
629 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { } | |
630 | |
631 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { | |
632 if (id != 0) { | |
633 id_ = id; | |
634 return true; | |
635 } | |
636 return false; | |
637 } | |
638 | |
639 void GpuBlacklist::GpuBlacklistEntry::SetDisabled(bool disabled) { | |
640 disabled_ = disabled; | |
641 } | |
642 | |
643 bool GpuBlacklist::GpuBlacklistEntry::SetOsInfo( | |
644 const std::string& os, | |
645 const std::string& version_op, | |
646 const std::string& version_string, | |
647 const std::string& version_string2) { | |
648 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2)); | |
649 return os_info_->IsValid(); | |
650 } | |
651 | |
652 bool GpuBlacklist::GpuBlacklistEntry::SetVendorId( | |
653 const std::string& vendor_id_string) { | |
654 vendor_id_ = 0; | |
655 return base::HexStringToInt(vendor_id_string, | |
656 reinterpret_cast<int*>(&vendor_id_)); | |
657 } | |
658 | |
659 bool GpuBlacklist::GpuBlacklistEntry::AddDeviceId( | |
660 const std::string& device_id_string) { | |
661 uint32 device_id = 0; | |
662 if (base::HexStringToInt(device_id_string, | |
663 reinterpret_cast<int*>(&device_id))) { | |
664 device_id_list_.push_back(device_id); | |
665 return true; | |
666 } | |
667 return false; | |
668 } | |
669 | |
670 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuStyle( | |
671 const std::string& multi_gpu_style_string) { | |
672 MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string); | |
673 if (style == kMultiGpuStyleNone) | |
674 return false; | |
675 multi_gpu_style_ = style; | |
676 return true; | |
677 } | |
678 | |
679 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuCategory( | |
680 const std::string& multi_gpu_category_string) { | |
681 MultiGpuCategory category = | |
682 StringToMultiGpuCategory(multi_gpu_category_string); | |
683 if (category == kMultiGpuCategoryNone) | |
684 return false; | |
685 multi_gpu_category_ = category; | |
686 return true; | |
687 } | |
688 | |
689 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVendorInfo( | |
690 const std::string& vendor_op, | |
691 const std::string& vendor_value) { | |
692 driver_vendor_info_.reset( | |
693 new StringInfo(vendor_op, vendor_value)); | |
694 return driver_vendor_info_->IsValid(); | |
695 } | |
696 | |
697 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVersionInfo( | |
698 const std::string& version_op, | |
699 const std::string& version_style, | |
700 const std::string& version_string, | |
701 const std::string& version_string2) { | |
702 driver_version_info_.reset(new VersionInfo( | |
703 version_op, version_style, version_string, version_string2)); | |
704 return driver_version_info_->IsValid(); | |
705 } | |
706 | |
707 bool GpuBlacklist::GpuBlacklistEntry::SetDriverDateInfo( | |
708 const std::string& date_op, | |
709 const std::string& date_string, | |
710 const std::string& date_string2) { | |
711 driver_date_info_.reset( | |
712 new VersionInfo(date_op, "", date_string, date_string2)); | |
713 return driver_date_info_->IsValid(); | |
714 } | |
715 | |
716 bool GpuBlacklist::GpuBlacklistEntry::SetGLVendorInfo( | |
717 const std::string& vendor_op, | |
718 const std::string& vendor_value) { | |
719 gl_vendor_info_.reset( | |
720 new StringInfo(vendor_op, vendor_value)); | |
721 return gl_vendor_info_->IsValid(); | |
722 } | |
723 | |
724 bool GpuBlacklist::GpuBlacklistEntry::SetGLRendererInfo( | |
725 const std::string& renderer_op, | |
726 const std::string& renderer_value) { | |
727 gl_renderer_info_.reset( | |
728 new StringInfo(renderer_op, renderer_value)); | |
729 return gl_renderer_info_->IsValid(); | |
730 } | |
731 | |
732 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGraphicsInfo( | |
733 const std::string& op, | |
734 const std::string& float_string, | |
735 const std::string& float_string2) { | |
736 perf_graphics_info_.reset( | |
737 new FloatInfo(op, float_string, float_string2)); | |
738 return perf_graphics_info_->IsValid(); | |
739 } | |
740 | |
741 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGamingInfo( | |
742 const std::string& op, | |
743 const std::string& float_string, | |
744 const std::string& float_string2) { | |
745 perf_gaming_info_.reset( | |
746 new FloatInfo(op, float_string, float_string2)); | |
747 return perf_gaming_info_->IsValid(); | |
748 } | |
749 | |
750 bool GpuBlacklist::GpuBlacklistEntry::SetPerfOverallInfo( | |
751 const std::string& op, | |
752 const std::string& float_string, | |
753 const std::string& float_string2) { | |
754 perf_overall_info_.reset( | |
755 new FloatInfo(op, float_string, float_string2)); | |
756 return perf_overall_info_->IsValid(); | |
757 } | |
758 | |
759 bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures( | |
760 const std::vector<std::string>& blacklisted_features) { | |
761 size_t size = blacklisted_features.size(); | |
762 if (size == 0) | |
763 return false; | |
764 int feature_type = content::GPU_FEATURE_TYPE_UNKNOWN; | |
765 for (size_t i = 0; i < size; ++i) { | |
766 GpuFeatureType type = | |
767 gpu_util::StringToGpuFeatureType(blacklisted_features[i]); | |
768 switch (type) { | |
769 case content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS: | |
770 case content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING: | |
771 case content::GPU_FEATURE_TYPE_WEBGL: | |
772 case content::GPU_FEATURE_TYPE_MULTISAMPLING: | |
773 case content::GPU_FEATURE_TYPE_FLASH3D: | |
774 case content::GPU_FEATURE_TYPE_FLASH_STAGE3D: | |
775 case content::GPU_FEATURE_TYPE_TEXTURE_SHARING: | |
776 case content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE: | |
777 case content::GPU_FEATURE_TYPE_ALL: | |
778 feature_type |= type; | |
779 break; | |
780 case content::GPU_FEATURE_TYPE_UNKNOWN: | |
781 contains_unknown_features_ = true; | |
782 break; | |
783 } | |
784 } | |
785 feature_type_ = static_cast<GpuFeatureType>(feature_type); | |
786 return true; | |
787 } | |
788 | |
789 void GpuBlacklist::GpuBlacklistEntry::AddException( | |
790 ScopedGpuBlacklistEntry exception) { | |
791 exceptions_.push_back(exception); | |
792 } | |
793 | |
794 // static | |
795 GpuBlacklist::GpuBlacklistEntry::MultiGpuStyle | |
796 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuStyle( | |
797 const std::string& style) { | |
798 if (style == kMultiGpuStyleStringOptimus) | |
799 return kMultiGpuStyleOptimus; | |
800 if (style == kMultiGpuStyleStringAMDSwitchable) | |
801 return kMultiGpuStyleAMDSwitchable; | |
802 return kMultiGpuStyleNone; | |
803 } | |
804 | |
805 // static | |
806 GpuBlacklist::GpuBlacklistEntry::MultiGpuCategory | |
807 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuCategory( | |
808 const std::string& category) { | |
809 if (category == kMultiGpuCategoryStringPrimary) | |
810 return kMultiGpuCategoryPrimary; | |
811 if (category == kMultiGpuCategoryStringSecondary) | |
812 return kMultiGpuCategorySecondary; | |
813 if (category == kMultiGpuCategoryStringAny) | |
814 return kMultiGpuCategoryAny; | |
815 return kMultiGpuCategoryNone; | |
816 } | |
817 | |
818 bool GpuBlacklist::GpuBlacklistEntry::Contains( | |
819 OsType os_type, const Version& os_version, | |
820 const content::GPUInfo& gpu_info) const { | |
821 DCHECK(os_type != kOsAny); | |
822 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version)) | |
823 return false; | |
824 bool is_not_primary_gpu = | |
825 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu); | |
826 bool is_not_secondary_gpu = true; | |
827 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { | |
828 is_not_secondary_gpu = is_not_secondary_gpu && | |
829 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]); | |
830 } | |
831 switch (multi_gpu_category_) { | |
832 case kMultiGpuCategoryPrimary: | |
833 if (is_not_primary_gpu) | |
834 return false; | |
835 break; | |
836 case kMultiGpuCategorySecondary: | |
837 if (is_not_secondary_gpu) | |
838 return false; | |
839 break; | |
840 case kMultiGpuCategoryAny: | |
841 if (is_not_primary_gpu && is_not_secondary_gpu) | |
842 return false; | |
843 break; | |
844 default: | |
845 break; | |
846 } | |
847 switch (multi_gpu_style_) { | |
848 case kMultiGpuStyleOptimus: | |
849 if (!gpu_info.optimus) | |
850 return false; | |
851 break; | |
852 case kMultiGpuStyleAMDSwitchable: | |
853 if (!gpu_info.amd_switchable) | |
854 return false; | |
855 break; | |
856 default: | |
857 break; | |
858 } | |
859 if (driver_vendor_info_.get() != NULL && | |
860 !driver_vendor_info_->Contains(gpu_info.driver_vendor)) | |
861 return false; | |
862 if (driver_version_info_.get() != NULL) { | |
863 std::string processed_driver_version; | |
864 if (driver_version_info_->IsLexical()) | |
865 processed_driver_version = NumericalToLexical(gpu_info.driver_version); | |
866 else | |
867 processed_driver_version = gpu_info.driver_version; | |
868 Version driver_version(processed_driver_version); | |
869 if (!driver_version.IsValid() || | |
870 !driver_version_info_->Contains(driver_version)) | |
871 return false; | |
872 } | |
873 if (driver_date_info_.get() != NULL) { | |
874 Version driver_date; | |
875 GetDateFromString(gpu_info.driver_date, &driver_date); | |
876 if (!driver_date.IsValid() || !driver_date_info_->Contains(driver_date)) | |
877 return false; | |
878 } | |
879 if (gl_vendor_info_.get() != NULL && | |
880 !gl_vendor_info_->Contains(gpu_info.gl_vendor)) | |
881 return false; | |
882 if (gl_renderer_info_.get() != NULL && | |
883 !gl_renderer_info_->Contains(gpu_info.gl_renderer)) | |
884 return false; | |
885 if (perf_graphics_info_.get() != NULL && | |
886 (gpu_info.performance_stats.graphics == 0.0 || | |
887 !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics))) | |
888 return false; | |
889 if (perf_gaming_info_.get() != NULL && | |
890 (gpu_info.performance_stats.gaming == 0.0 || | |
891 !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming))) | |
892 return false; | |
893 if (perf_overall_info_.get() != NULL && | |
894 (gpu_info.performance_stats.overall == 0.0 || | |
895 !perf_overall_info_->Contains(gpu_info.performance_stats.overall))) | |
896 return false; | |
897 for (size_t i = 0; i < exceptions_.size(); ++i) { | |
898 if (exceptions_[i]->Contains(os_type, os_version, gpu_info)) | |
899 return false; | |
900 } | |
901 return true; | |
902 } | |
903 | |
904 GpuBlacklist::OsType GpuBlacklist::GpuBlacklistEntry::GetOsType() const { | |
905 if (os_info_.get() == NULL) | |
906 return kOsAny; | |
907 return os_info_->type(); | |
908 } | |
909 | |
910 uint32 GpuBlacklist::GpuBlacklistEntry::id() const { | |
911 return id_; | |
912 } | |
913 | |
914 bool GpuBlacklist::GpuBlacklistEntry::disabled() const { | |
915 return disabled_; | |
916 } | |
917 | |
918 GpuFeatureType GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureType() const { | |
919 return feature_type_; | |
920 } | |
921 | |
922 // static | |
923 GpuBlacklist* GpuBlacklist::GetInstance() { | |
924 return Singleton<GpuBlacklist>::get(); | |
925 } | |
926 | |
927 GpuBlacklist::GpuBlacklist() | |
928 : max_entry_id_(0), | |
929 contains_unknown_fields_(false) { | |
930 GpuDataManager::GetInstance()->AddObserver(this); | |
931 } | |
932 | |
933 GpuBlacklist::~GpuBlacklist() { | |
934 Clear(); | |
935 GpuDataManager::GetInstance()->RemoveObserver(this); | |
936 } | |
937 | |
938 bool GpuBlacklist::LoadGpuBlacklist( | |
939 const std::string& json_context, GpuBlacklist::OsFilter os_filter) { | |
940 chrome::VersionInfo chrome_version_info; | |
941 std::string chrome_version_string = | |
942 chrome_version_info.is_valid() ? chrome_version_info.Version() : "0"; | |
943 return LoadGpuBlacklist(chrome_version_string, json_context, os_filter); | |
944 } | |
945 | |
946 bool GpuBlacklist::LoadGpuBlacklist( | |
947 const std::string& browser_version_string, | |
948 const std::string& json_context, | |
949 GpuBlacklist::OsFilter os_filter) { | |
950 browser_version_.reset(new Version(browser_version_string)); | |
951 DCHECK(browser_version_->IsValid()); | |
952 | |
953 scoped_ptr<Value> root; | |
954 root.reset(base::JSONReader::Read(json_context)); | |
955 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) | |
956 return false; | |
957 | |
958 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get()); | |
959 DCHECK(root_dictionary); | |
960 return LoadGpuBlacklist(*root_dictionary, os_filter); | |
961 } | |
962 | |
963 bool GpuBlacklist::LoadGpuBlacklist( | |
964 const DictionaryValue& parsed_json, GpuBlacklist::OsFilter os_filter) { | |
965 std::vector<ScopedGpuBlacklistEntry> entries; | |
966 | |
967 std::string version_string; | |
968 parsed_json.GetString("version", &version_string); | |
969 version_.reset(new Version(version_string)); | |
970 if (!version_->IsValid()) | |
971 return false; | |
972 | |
973 const ListValue* list = NULL; | |
974 if (!parsed_json.GetList("entries", &list)) | |
975 return false; | |
976 | |
977 uint32 max_entry_id = 0; | |
978 bool contains_unknown_fields = false; | |
979 for (size_t i = 0; i < list->GetSize(); ++i) { | |
980 const DictionaryValue* list_item = NULL; | |
981 bool valid = list->GetDictionary(i, &list_item); | |
982 if (!valid || list_item == NULL) | |
983 return false; | |
984 // Check browser version compatibility: if the entry is not for the | |
985 // current browser version, don't process it. | |
986 BrowserVersionSupport browser_version_support = | |
987 IsEntrySupportedByCurrentBrowserVersion(list_item); | |
988 if (browser_version_support == kMalformed) | |
989 return false; | |
990 if (browser_version_support == kUnsupported) | |
991 continue; | |
992 DCHECK(browser_version_support == kSupported); | |
993 ScopedGpuBlacklistEntry entry( | |
994 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true)); | |
995 if (entry == NULL) | |
996 return false; | |
997 if (entry->id() > max_entry_id) | |
998 max_entry_id = entry->id(); | |
999 // If an unknown field is encountered, skip the entry; if an unknown | |
1000 // feature is encountered, ignore the feature, but keep the entry. | |
1001 if (entry->contains_unknown_fields()) { | |
1002 contains_unknown_fields = true; | |
1003 continue; | |
1004 } | |
1005 if (entry->contains_unknown_features()) | |
1006 contains_unknown_fields = true; | |
1007 entries.push_back(entry); | |
1008 } | |
1009 | |
1010 Clear(); | |
1011 OsType my_os = GetOsType(); | |
1012 for (size_t i = 0; i < entries.size(); ++i) { | |
1013 OsType entry_os = entries[i]->GetOsType(); | |
1014 if (os_filter == GpuBlacklist::kAllOs || | |
1015 entry_os == kOsAny || entry_os == my_os) | |
1016 blacklist_.push_back(entries[i]); | |
1017 } | |
1018 max_entry_id_ = max_entry_id; | |
1019 contains_unknown_fields_ = contains_unknown_fields; | |
1020 return true; | |
1021 } | |
1022 | |
1023 GpuFeatureType GpuBlacklist::DetermineGpuFeatureType( | |
1024 GpuBlacklist::OsType os, | |
1025 Version* os_version, | |
1026 const content::GPUInfo& gpu_info) { | |
1027 active_entries_.clear(); | |
1028 int type = 0; | |
1029 | |
1030 if (os == kOsAny) | |
1031 os = GetOsType(); | |
1032 scoped_ptr<Version> my_os_version; | |
1033 if (os_version == NULL) { | |
1034 std::string version_string = base::SysInfo::OperatingSystemVersion(); | |
1035 size_t pos = version_string.find_first_not_of("0123456789."); | |
1036 if (pos != std::string::npos) | |
1037 version_string = version_string.substr(0, pos); | |
1038 my_os_version.reset(new Version(version_string)); | |
1039 os_version = my_os_version.get(); | |
1040 } | |
1041 DCHECK(os_version != NULL); | |
1042 | |
1043 for (size_t i = 0; i < blacklist_.size(); ++i) { | |
1044 if (blacklist_[i]->Contains(os, *os_version, gpu_info)) { | |
1045 if (!blacklist_[i]->disabled()) | |
1046 type |= blacklist_[i]->GetGpuFeatureType(); | |
1047 active_entries_.push_back(blacklist_[i]); | |
1048 } | |
1049 } | |
1050 return static_cast<GpuFeatureType>(type); | |
1051 } | |
1052 | |
1053 void GpuBlacklist::UpdateGpuDataManager() { | |
1054 content::GpuFeatureType feature_type = DetermineGpuFeatureType( | |
1055 GpuBlacklist::kOsAny, NULL, GpuDataManager::GetInstance()->GetGPUInfo()); | |
1056 GpuDataManager::GetInstance()->SetPreliminaryBlacklistedFeatures( | |
1057 feature_type); | |
1058 gpu_util::UpdateStats(); | |
1059 } | |
1060 | |
1061 void GpuBlacklist::GetGpuFeatureTypeEntries( | |
1062 content::GpuFeatureType feature, | |
1063 std::vector<uint32>& entry_ids, | |
1064 bool disabled) const { | |
1065 entry_ids.clear(); | |
1066 for (size_t i = 0; i < active_entries_.size(); ++i) { | |
1067 if (((feature & active_entries_[i]->GetGpuFeatureType()) != 0) && | |
1068 disabled == active_entries_[i]->disabled()) | |
1069 entry_ids.push_back(active_entries_[i]->id()); | |
1070 } | |
1071 } | |
1072 | |
1073 void GpuBlacklist::GetBlacklistReasons(ListValue* problem_list) const { | |
1074 DCHECK(problem_list); | |
1075 for (size_t i = 0; i < active_entries_.size(); ++i) { | |
1076 GpuBlacklistEntry* entry = active_entries_[i]; | |
1077 if (entry->disabled()) | |
1078 continue; | |
1079 DictionaryValue* problem = new DictionaryValue(); | |
1080 | |
1081 problem->SetString("description", entry->description()); | |
1082 | |
1083 ListValue* cr_bugs = new ListValue(); | |
1084 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) | |
1085 cr_bugs->Append(Value::CreateIntegerValue(entry->cr_bugs()[j])); | |
1086 problem->Set("crBugs", cr_bugs); | |
1087 | |
1088 ListValue* webkit_bugs = new ListValue(); | |
1089 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) { | |
1090 webkit_bugs->Append(Value::CreateIntegerValue( | |
1091 entry->webkit_bugs()[j])); | |
1092 } | |
1093 problem->Set("webkitBugs", webkit_bugs); | |
1094 | |
1095 problem_list->Append(problem); | |
1096 } | |
1097 } | |
1098 | |
1099 size_t GpuBlacklist::num_entries() const { | |
1100 return blacklist_.size(); | |
1101 } | |
1102 | |
1103 uint32 GpuBlacklist::max_entry_id() const { | |
1104 return max_entry_id_; | |
1105 } | |
1106 | |
1107 std::string GpuBlacklist::GetVersion() const { | |
1108 if (version_.get() == NULL) | |
1109 return std::string(); | |
1110 const std::vector<uint16>& components_reference = version_->components(); | |
1111 if (components_reference.size() != 2) | |
1112 return std::string(); | |
1113 | |
1114 std::string version_string = | |
1115 base::UintToString(static_cast<unsigned>(components_reference[0])) + | |
1116 "." + | |
1117 base::UintToString(static_cast<unsigned>(components_reference[1])); | |
1118 return version_string; | |
1119 } | |
1120 | |
1121 GpuBlacklist::OsType GpuBlacklist::GetOsType() { | |
1122 #if defined(OS_CHROMEOS) | |
1123 return kOsChromeOS; | |
1124 #elif defined(OS_WIN) | |
1125 return kOsWin; | |
1126 #elif defined(OS_LINUX) || defined(OS_OPENBSD) | |
1127 return kOsLinux; | |
1128 #elif defined(OS_MACOSX) | |
1129 return kOsMacosx; | |
1130 #else | |
1131 return kOsUnknown; | |
1132 #endif | |
1133 } | |
1134 | |
1135 void GpuBlacklist::Clear() { | |
1136 blacklist_.clear(); | |
1137 active_entries_.clear(); | |
1138 max_entry_id_ = 0; | |
1139 contains_unknown_fields_ = false; | |
1140 } | |
1141 | |
1142 GpuBlacklist::BrowserVersionSupport | |
1143 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion( | |
1144 const DictionaryValue* value) { | |
1145 DCHECK(value); | |
1146 const DictionaryValue* browser_version_value = NULL; | |
1147 if (value->GetDictionary("browser_version", &browser_version_value)) { | |
1148 std::string version_op = "any"; | |
1149 std::string version_string; | |
1150 std::string version_string2; | |
1151 browser_version_value->GetString("op", &version_op); | |
1152 browser_version_value->GetString("number", &version_string); | |
1153 browser_version_value->GetString("number2", &version_string2); | |
1154 scoped_ptr<VersionInfo> browser_version_info; | |
1155 browser_version_info.reset( | |
1156 new VersionInfo(version_op, "", version_string, version_string2)); | |
1157 if (!browser_version_info->IsValid()) | |
1158 return kMalformed; | |
1159 if (browser_version_info->Contains(*browser_version_)) | |
1160 return kSupported; | |
1161 return kUnsupported; | |
1162 } | |
1163 return kSupported; | |
1164 } | |
1165 | |
1166 void GpuBlacklist::OnGpuInfoUpdate() { | |
1167 UpdateGpuDataManager(); | |
1168 } | |
1169 | |
1170 // static | |
1171 GpuBlacklist::NumericOp GpuBlacklist::StringToNumericOp( | |
1172 const std::string& op) { | |
1173 if (op == "=") | |
1174 return kEQ; | |
1175 if (op == "<") | |
1176 return kLT; | |
1177 if (op == "<=") | |
1178 return kLE; | |
1179 if (op == ">") | |
1180 return kGT; | |
1181 if (op == ">=") | |
1182 return kGE; | |
1183 if (op == "any") | |
1184 return kAny; | |
1185 if (op == "between") | |
1186 return kBetween; | |
1187 return kUnknown; | |
1188 } | |
OLD | NEW |