gpu_control_list.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_control_list.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/cpu.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/stringprintf.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_info.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_info.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_util.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "third_party/re2/re2/re2.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace gpu {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Break a version string into segments.  Return true if each segment is
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// a valid number, and not all segment is 0.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProcessVersionString(const std::string& version_string,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          char splitter,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          std::vector<std::string>* version) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(version_string, splitter, version);
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version->size() == 0)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the splitter is '-', we assume it's a date with format "mm-dd-yyyy";
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we split it into the order of "yyyy", "mm", "dd".
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (splitter == '-') {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string year = (*version)[version->size() - 1];
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = version->size() - 1; i > 0; --i) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*version)[i] = (*version)[i - 1];
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*version)[0] = year;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool all_zero = true;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < version->size(); ++i) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned num = 0;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!base::StringToUint((*version)[i], &num))
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (num)
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      all_zero = false;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return !all_zero;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Compare two number strings using numerical ordering.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Return  0 if number = number_ref,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//         1 if number > number_ref,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        -1 if number < number_ref.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int CompareNumericalNumberStrings(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& number, const std::string& number_ref) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned value1 = 0;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned value2 = 0;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool valid = base::StringToUint(number, &value1);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(valid);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  valid = base::StringToUint(number_ref, &value2);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(valid);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value1 == value2)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value1 > value2)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 1;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return -1;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Compare two number strings using lexical ordering.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Return  0 if number = number_ref,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//         1 if number > number_ref,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        -1 if number < number_ref.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We only compare as many digits as number_ref contains.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// If number_ref is xxx, it's considered as xxx*
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For example: CompareLexicalNumberStrings("121", "12") returns 0,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//              CompareLexicalNumberStrings("12", "121") returns -1.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int CompareLexicalNumberStrings(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& number, const std::string& number_ref) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < number_ref.length(); ++i) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned value1 = 0;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < number.length())
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value1 = number[i] - '0';
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned value2 = number_ref[i] - '0';
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value1 > value2)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 1;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value1 < value2)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return -1;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// A mismatch is identified only if both |input| and |pattern| are not empty.
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool StringMismatch(const std::string& input, const std::string& pattern) {
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (input.empty() || pattern.empty())
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return false;
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !RE2::FullMatch(input, pattern);
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable";
1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char kMultiGpuStyleStringAMDSwitchableDiscrete[] =
1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    "amd_switchable_discrete";
1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char kMultiGpuStyleStringAMDSwitchableIntegrated[] =
1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    "amd_switchable_integrated";
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuStyleStringOptimus[] = "optimus";
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringPrimary[] = "primary";
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringSecondary[] = "secondary";
109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kMultiGpuCategoryStringActive[] = "active";
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringAny[] = "any";
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kGLTypeStringGL[] = "gl";
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kGLTypeStringGLES[] = "gles";
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kGLTypeStringANGLE[] = "angle";
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kVersionStyleStringNumerical[] = "numerical";
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kVersionStyleStringLexical[] = "lexical";
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOp[] = "op";
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace anonymous
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::VersionInfo(
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : version_style_(kVersionStyleNumerical) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  op_ = StringToNumericOp(version_op);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown || op_ == kAny)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  version_style_ = StringToVersionStyle(version_style);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_string, '.', &version_)) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!ProcessVersionString(version_string2, '.', &version2_))
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      op_ = kUnknown;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::~VersionInfo() {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::Contains(
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string) const {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Contains(version_string, '.');
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::Contains(
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string, char splitter) const {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> version;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_string, splitter, &version))
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int relation = Compare(version, version_, version_style_);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation == 0);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kLT)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation < 0);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kLE)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation <= 0);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kGT)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation > 0);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kGE)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation >= 0);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // op_ == kBetween
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (relation < 0)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Compare(version, version2_, version_style_) <= 0;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::IsValid() const {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (op_ != kUnknown && version_style_ != kVersionStyleUnknown);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::IsLexical() const {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_style_ == kVersionStyleLexical;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GpuControlList::VersionInfo::Compare(
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& version,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& version_ref,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VersionStyle version_style) {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version.size() > 0 && version_ref.size() > 0);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version_style != kVersionStyleUnknown);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < version_ref.size(); ++i) {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i >= version.size())
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 0;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int ret = 0;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We assume both versions are checked by ProcessVersionString().
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i > 0 && version_style == kVersionStyleLexical)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ret = CompareLexicalNumberStrings(version[i], version_ref[i]);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ret = CompareNumericalNumberStrings(version[i], version_ref[i]);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ret != 0)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ret;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::VersionStyle
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::StringToVersionStyle(
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version_style.empty() || version_style == kVersionStyleStringNumerical)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kVersionStyleNumerical;
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version_style == kVersionStyleStringLexical)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kVersionStyleLexical;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kVersionStyleUnknown;
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsInfo::OsInfo(const std::string& os,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_op,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_string,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_string2) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  type_ = StringToOsType(os);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_ != kOsUnknown) {
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    version_info_.reset(new VersionInfo(
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        version_op, std::string(), version_string, version_string2));
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsInfo::~OsInfo() {}
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GpuControlList::OsInfo::Contains(
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    OsType type, const std::string& version) const {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsValid())
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_ != type && type_ != kOsAny)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string processed_version;
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t pos = version.find_first_not_of("0123456789.");
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pos != std::string::npos)
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    processed_version = version.substr(0, pos);
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    processed_version = version;
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return version_info_->Contains(processed_version);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::OsInfo::IsValid() const {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type_ != kOsUnknown && version_info_->IsValid();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::OsInfo::type() const {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type_;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::OsInfo::StringToOsType(
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& os) {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os == "win")
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsWin;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "macosx")
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsMacosx;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "android")
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAndroid;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "linux")
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsLinux;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "chromeos")
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsChromeOS;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "any")
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAny;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsUnknown;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::FloatInfo::FloatInfo(const std::string& float_op,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const std::string& float_value,
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const std::string& float_value2)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : op_(kUnknown),
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(0.f),
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value2_(0.f) {
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  op_ = StringToNumericOp(float_op);
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (op_ == kAny)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double dvalue = 0;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::StringToDouble(float_value, &dvalue)) {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  value_ = static_cast<float>(dvalue);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween) {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!base::StringToDouble(float_value2, &dvalue)) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      op_ = kUnknown;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    value2_ = static_cast<float>(dvalue);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::FloatInfo::Contains(float value) const {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value == value_);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLT)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value < value_);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLE)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value <= value_);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGT)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value > value_);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGE)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value >= value_);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(op_ == kBetween);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ((value_ <= value && value <= value2_) ||
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          (value2_ <= value && value <= value_));
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::FloatInfo::IsValid() const {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return op_ != kUnknown;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::IntInfo::IntInfo(const std::string& int_op,
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& int_value,
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& int_value2)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : op_(kUnknown),
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(0),
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value2_(0) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  op_ = StringToNumericOp(int_op);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (op_ == kAny)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::StringToInt(int_value, &value_)) {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween &&
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToInt(int_value2, &value2_))
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::IntInfo::Contains(int value) const {
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value == value_);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLT)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value < value_);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLE)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value <= value_);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGT)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value > value_);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGE)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value >= value_);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(op_ == kBetween);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ((value_ <= value && value <= value2_) ||
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          (value2_ <= value && value <= value_));
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::IntInfo::IsValid() const {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return op_ != kUnknown;
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochGpuControlList::BoolInfo::BoolInfo(bool value) : value_(value) {}
363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool GpuControlList::BoolInfo::Contains(bool value) const {
365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return value_ == value;
366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::ScopedGpuControlListEntry
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::GetEntryFromValue(
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* value, bool top_level,
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FeatureMap& feature_map,
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool supports_feature_type_all) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(value);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedGpuControlListEntry entry(new GpuControlListEntry());
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t dictionary_entry_count = 0;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 id;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) ||
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !entry->SetId(id)) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed id entry " << entry->id();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool disabled;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetBoolean("disabled", &disabled)) {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry->SetDisabled(disabled);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string description;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("description", &description)) {
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry->description_ = description;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry->description_ = "The GPU is unavailable for an unexplained reason.";
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* cr_bugs;
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("cr_bugs", &cr_bugs)) {
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < cr_bugs->GetSize(); ++i) {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int bug_id;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (cr_bugs->GetInteger(i, &bug_id)) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry->cr_bugs_.push_back(bug_id);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed cr_bugs entry " << entry->id();
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* webkit_bugs;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("webkit_bugs", &webkit_bugs)) {
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int bug_id;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (webkit_bugs->GetInteger(i, &bug_id)) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry->webkit_bugs_.push_back(bug_id);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id();
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* os_value = NULL;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("os", &os_value)) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_type;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_op = "any";
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_string;
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_string2;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os_value->GetString("type", &os_type);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* os_version_value = NULL;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (os_value->GetDictionary("version", &os_version_value)) {
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os_version_value->GetString(kOp, &os_version_op);
441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      os_version_value->GetString("value", &os_version_string);
442d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      os_version_value->GetString("value2", &os_version_string2);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          os_version_string2)) {
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed os entry " << entry->id();
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string vendor_id;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("vendor_id", &vendor_id)) {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetVendorId(vendor_id)) {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed vendor_id entry " << entry->id();
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* device_id_list;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("device_id", &device_id_list)) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < device_id_list->GetSize(); ++i) {
4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      std::string device_id;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!device_id_list->GetString(i, &device_id) ||
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !entry->AddDeviceId(device_id)) {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed device_id entry " << entry->id();
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string multi_gpu_style;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("multi_gpu_style", &multi_gpu_style)) {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetMultiGpuStyle(multi_gpu_style)) {
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id();
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string multi_gpu_category;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("multi_gpu_category", &multi_gpu_category)) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetMultiGpuCategory(multi_gpu_category)) {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id();
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string driver_vendor_value;
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (value->GetString("driver_vendor", &driver_vendor_value)) {
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!entry->SetDriverVendorInfo(driver_vendor_value)) {
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_vendor entry " << entry->id();
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* driver_version_value = NULL;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("driver_version", &driver_version_value)) {
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_op = "any";
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_style;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_string;
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_string2;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString(kOp, &driver_version_op);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString("style", &driver_version_style);
509d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    driver_version_value->GetString("value", &driver_version_string);
510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    driver_version_value->GetString("value2", &driver_version_string2);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetDriverVersionInfo(driver_version_op,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_style,
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_string,
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_string2)) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_version entry " << entry->id();
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* driver_date_value = NULL;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("driver_date", &driver_date_value)) {
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_op = "any";
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_string;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_string2;
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_date_value->GetString(kOp, &driver_date_op);
527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    driver_date_value->GetString("value", &driver_date_string);
528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    driver_date_value->GetString("value2", &driver_date_string2);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  driver_date_string2)) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_date entry " << entry->id();
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::string gl_type;
538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (value->GetString("gl_type", &gl_type)) {
539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!entry->SetGLType(gl_type)) {
540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_type entry " << entry->id();
541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return NULL;
542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dictionary_entry_count++;
544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const base::DictionaryValue* gl_version_value = NULL;
547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (value->GetDictionary("gl_version", &gl_version_value)) {
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::string version_op = "any";
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::string version_string;
550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::string version_string2;
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gl_version_value->GetString(kOp, &version_op);
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gl_version_value->GetString("value", &version_string);
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gl_version_value->GetString("value2", &version_string2);
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!entry->SetGLVersionInfo(
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            version_op, version_string, version_string2)) {
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_version entry " << entry->id();
557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return NULL;
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    dictionary_entry_count++;
560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string gl_vendor_value;
5636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (value->GetString("gl_vendor", &gl_vendor_value)) {
5646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!entry->SetGLVendorInfo(gl_vendor_value)) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_vendor entry " << entry->id();
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string gl_renderer_value;
5726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (value->GetString("gl_renderer", &gl_renderer_value)) {
5736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!entry->SetGLRendererInfo(gl_renderer_value)) {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_renderer entry " << entry->id();
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string gl_extensions_value;
5816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (value->GetString("gl_extensions", &gl_extensions_value)) {
5826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!entry->SetGLExtensionsInfo(gl_extensions_value)) {
583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_extensions entry " << entry->id();
584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return NULL;
585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    dictionary_entry_count++;
587b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
588b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const base::DictionaryValue* gl_reset_notification_strategy_value = NULL;
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (value->GetDictionary("gl_reset_notification_strategy",
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           &gl_reset_notification_strategy_value)) {
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string op;
593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string int_value;
594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string int_value2;
595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gl_reset_notification_strategy_value->GetString(kOp, &op);
596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gl_reset_notification_strategy_value->GetString("value", &int_value);
597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gl_reset_notification_strategy_value->GetString("value2", &int_value2);
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!entry->SetGLResetNotificationStrategyInfo(
599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            op, int_value, int_value2)) {
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      LOG(WARNING) << "Malformed gl_reset_notification_strategy entry "
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   << entry->id();
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return NULL;
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    dictionary_entry_count++;
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string cpu_brand_value;
6086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (value->GetString("cpu_info", &cpu_brand_value)) {
6096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!entry->SetCpuBrand(cpu_brand_value)) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed cpu_brand entry " << entry->id();
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_graphics_value = NULL;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_graphics", &perf_graphics_value)) {
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString(kOp, &op);
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString("value", &float_value);
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString("value2", &float_value2);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) {
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_graphics entry " << entry->id();
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_gaming_value = NULL;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_gaming", &perf_gaming_value)) {
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString(kOp, &op);
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString("value", &float_value);
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString("value2", &float_value2);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) {
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_gaming entry " << entry->id();
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_overall_value = NULL;
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_overall", &perf_overall_value)) {
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString(kOp, &op);
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString("value", &float_value);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString("value2", &float_value2);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) {
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_overall entry " << entry->id();
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::ListValue* machine_model_name_list;
6620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (value->GetList("machine_model_name", &machine_model_name_list)) {
6630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t i = 0; i < machine_model_name_list->GetSize(); ++i) {
6640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      std::string model_name;
6650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (!machine_model_name_list->GetString(i, &model_name) ||
6660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          !entry->AddMachineModelName(model_name)) {
6670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        LOG(WARNING) << "Malformed machine_model_name entry " << entry->id();
6680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        return NULL;
6690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    dictionary_entry_count++;
6720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::DictionaryValue* machine_model_version_value = NULL;
6750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (value->GetDictionary(
6760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          "machine_model_version", &machine_model_version_value)) {
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_op = "any";
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string;
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string2;
6800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    machine_model_version_value->GetString(kOp, &version_op);
6810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    machine_model_version_value->GetString("value", &version_string);
6820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    machine_model_version_value->GetString("value2", &version_string2);
6830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!entry->SetMachineModelVersionInfo(
6840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            version_op, version_string, version_string2)) {
6850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      LOG(WARNING) << "Malformed machine_model_version entry " << entry->id();
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* gpu_count_value = NULL;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("gpu_count", &gpu_count_value)) {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string int_value;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string int_value2;
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString(kOp, &op);
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString("value", &int_value);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString("value2", &int_value2);
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetGpuCountInfo(op, int_value, int_value2)) {
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gpu_count entry " << entry->id();
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
706effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool direct_rendering;
707effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (value->GetBoolean("direct_rendering", &direct_rendering)) {
708effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    entry->SetDirectRenderingInfo(direct_rendering);
709effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dictionary_entry_count++;
710effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
711effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* feature_value = NULL;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetList("features", &feature_value)) {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::vector<std::string> feature_list;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < feature_value->GetSize(); ++i) {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string feature;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (feature_value->GetString(i, &feature)) {
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          feature_list.push_back(feature);
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed feature entry " << entry->id();
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!entry->SetFeatures(
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              feature_list, feature_map, supports_feature_type_all)) {
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed feature entry " << entry->id();
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* exception_list_value = NULL;
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetList("exceptions", &exception_list_value)) {
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < exception_list_value->GetSize(); ++i) {
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const base::DictionaryValue* exception_value = NULL;
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!exception_list_value->GetDictionary(i, &exception_value)) {
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed exceptions entry " << entry->id();
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ScopedGpuControlListEntry exception(GetEntryFromValue(
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            exception_value, false, feature_map, supports_feature_type_all));
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (exception.get() == NULL) {
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed exceptions entry " << entry->id();
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // Exception should inherit vendor_id from parent, otherwise if only
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // device_ids are specified in Exception, the info will be incomplete.
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (exception->vendor_id_ == 0 && entry->vendor_id_ != 0)
752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          exception->vendor_id_ = entry->vendor_id_;
753d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        entry->AddException(exception);
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->size() != dictionary_entry_count) {
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Entry with unknown fields " << entry->id();
761d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return NULL;
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
763010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
764010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // If GL_VERSION is specified, but no info about whether it's GL or GLES,
765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // we use the default for the platform.  See GLType enum declaration.
766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (entry->gl_version_info_.get() != NULL && entry->gl_type_ == kGLTypeNone)
767010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    entry->gl_type_ = GetDefaultGLType();
768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return entry;
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::GpuControlListEntry()
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(0),
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disabled_(false),
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      vendor_id_(0),
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      multi_gpu_style_(kMultiGpuStyleNone),
777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      multi_gpu_category_(kMultiGpuCategoryPrimary),
778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      gl_type_(kGLTypeNone) {
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::~GpuControlListEntry() { }
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetId(uint32 id) {
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (id != 0) {
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id_ = id;
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GpuControlListEntry::SetDisabled(bool disabled) {
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  disabled_ = disabled;
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetOsInfo(
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& os,
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os_info_->IsValid();
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetVendorId(
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_id_string) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vendor_id_ = 0;
807e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return base::HexStringToUInt(vendor_id_string, &vendor_id_) &&
808e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      vendor_id_ != 0;
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::AddDeviceId(
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id_string) {
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 device_id = 0;
814e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (base::HexStringToUInt(device_id_string, &device_id) && device_id != 0) {
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_id_list_.push_back(device_id);
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetMultiGpuStyle(
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& multi_gpu_style_string) {
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string);
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleNone)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  multi_gpu_style_ = style;
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetMultiGpuCategory(
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& multi_gpu_category_string) {
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MultiGpuCategory category =
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StringToMultiGpuCategory(multi_gpu_category_string);
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryNone)
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  multi_gpu_category_ = category;
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
840010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLType(
841010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& gl_type_string) {
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GLType gl_type = StringToGLType(gl_type_string);
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_type == kGLTypeNone)
844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gl_type_ = gl_type;
846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverVendorInfo(
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_value) {
8516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  driver_vendor_info_ = vendor_value;
8526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !driver_vendor_info_.empty();
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverVersionInfo(
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style,
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  driver_version_info_.reset(new VersionInfo(
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_op, version_style, version_string, version_string2));
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return driver_version_info_->IsValid();
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverDateInfo(
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_op,
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_string,
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_string2) {
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  driver_date_info_.reset(
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new VersionInfo(date_op, std::string(), date_string, date_string2));
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return driver_date_info_->IsValid();
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLVersionInfo(
875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& version_op,
876010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& version_string,
877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& version_string2) {
878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gl_version_info_.reset(new VersionInfo(
879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      version_op, std::string(), version_string, version_string2));
880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return gl_version_info_->IsValid();
881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
882010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLVendorInfo(
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_value) {
8856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gl_vendor_info_ = vendor_value;
8866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !gl_vendor_info_.empty();
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLRendererInfo(
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& renderer_value) {
8916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gl_renderer_info_ = renderer_value;
8926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !gl_renderer_info_.empty();
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
895b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLExtensionsInfo(
896b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const std::string& extensions_value) {
8976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gl_extensions_info_ = extensions_value;
8986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !gl_extensions_info_.empty();
899b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
900b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
901a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLResetNotificationStrategyInfo(
902a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& op,
903a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& int_string,
904a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& int_string2) {
905a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gl_reset_notification_strategy_info_.reset(
906a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new IntInfo(op, int_string, int_string2));
907a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return gl_reset_notification_strategy_info_->IsValid();
908a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
909a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetCpuBrand(
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& cpu_value) {
9126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cpu_brand_ = cpu_value;
9136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return !cpu_brand_.empty();
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetPerfGraphicsInfo(
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op,
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string,
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string2) {
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  perf_graphics_info_.reset(new FloatInfo(op, float_string, float_string2));
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return perf_graphics_info_->IsValid();
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetPerfGamingInfo(
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op,
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string,
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string2) {
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  perf_gaming_info_.reset(new FloatInfo(op, float_string, float_string2));
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return perf_gaming_info_->IsValid();
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetPerfOverallInfo(
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op,
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string,
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& float_string2) {
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  perf_overall_info_.reset(new FloatInfo(op, float_string, float_string2));
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return perf_overall_info_->IsValid();
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool GpuControlList::GpuControlListEntry::AddMachineModelName(
9410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string& model_name) {
9420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (model_name.empty())
9430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
9440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  machine_model_name_list_.push_back(model_name);
9450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return true;
9460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
9470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
9480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool GpuControlList::GpuControlListEntry::SetMachineModelVersionInfo(
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
9520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  machine_model_version_info_.reset(new VersionInfo(
9530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      version_op, std::string(), version_string, version_string2));
9540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return machine_model_version_info_->IsValid();
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGpuCountInfo(
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op,
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& int_string,
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& int_string2) {
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_count_info_.reset(new IntInfo(op, int_string, int_string2));
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gpu_count_info_->IsValid();
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
965effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid GpuControlList::GpuControlListEntry::SetDirectRenderingInfo(bool value) {
966effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  direct_rendering_info_.reset(new BoolInfo(value));
967effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
968effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetFeatures(
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& feature_strings,
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FeatureMap& feature_map,
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool supports_feature_type_all) {
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = feature_strings.size();
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size == 0)
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  features_.clear();
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < size; ++i) {
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int feature = 0;
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (supports_feature_type_all && feature_strings[i] == "all") {
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (FeatureMap::const_iterator iter = feature_map.begin();
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           iter != feature_map.end(); ++iter)
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        features_.insert(iter->second);
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
985d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!StringToFeature(feature_strings[i], &feature, feature_map)) {
986d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      features_.clear();
987d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
988d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
989d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    features_.insert(feature);
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GpuControlListEntry::AddException(
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedGpuControlListEntry exception) {
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exceptions_.push_back(exception);
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
999010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::GLVersionInfoMismatch(
1000010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& gl_version) const {
1001010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_version.empty())
1002010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
1003010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1004010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_version_info_.get() == NULL && gl_type_ == kGLTypeNone)
1005010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
1006010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1007010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<std::string> segments;
1008010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::SplitString(gl_version, ' ', &segments);
1009010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::string number;
1010010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GLType gl_type = kGLTypeNone;
1011010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (segments.size() > 2 &&
1012010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      segments[0] == "OpenGL" && segments[1] == "ES") {
1013010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    number = segments[2];
1014010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gl_type = kGLTypeGLES;
1015010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (segments.size() > 3 &&
1016010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        StartsWithASCII(segments[3], "(ANGLE", false)) {
1017010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      gl_type = kGLTypeANGLE;
1018010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
1019010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
1020010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    number = segments[0];
1021010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gl_type = kGLTypeGL;
1022010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1023010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1024010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_type_ != kGLTypeNone && gl_type_ != gl_type)
1025010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
1026010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_version_info_.get() != NULL && !gl_version_info_->Contains(number))
1027010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
1028010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return false;
1029010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1030010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::MultiGpuStyle
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::StringToMultiGpuStyle(
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& style) {
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleStringOptimus)
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuStyleOptimus;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleStringAMDSwitchable)
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuStyleAMDSwitchable;
10396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (style == kMultiGpuStyleStringAMDSwitchableIntegrated)
10406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return kMultiGpuStyleAMDSwitchableIntegrated;
10416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (style == kMultiGpuStyleStringAMDSwitchableDiscrete)
10426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return kMultiGpuStyleAMDSwitchableDiscrete;
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMultiGpuStyleNone;
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::MultiGpuCategory
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::StringToMultiGpuCategory(
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& category) {
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringPrimary)
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategoryPrimary;
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringSecondary)
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategorySecondary;
1054e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (category == kMultiGpuCategoryStringActive)
1055e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return kMultiGpuCategoryActive;
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringAny)
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategoryAny;
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMultiGpuCategoryNone;
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1061010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
1062010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GpuControlList::GpuControlListEntry::GLType
1063010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GpuControlList::GpuControlListEntry::StringToGLType(
1064010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& gl_type) {
1065010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_type == kGLTypeStringGL)
1066010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kGLTypeGL;
1067010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_type == kGLTypeStringGLES)
1068010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kGLTypeGLES;
1069010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (gl_type == kGLTypeStringANGLE)
1070010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kGLTypeANGLE;
1071010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeNone;
1072010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1073010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1074010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
1075010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GpuControlList::GpuControlListEntry::GLType
1076010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GpuControlList::GpuControlListEntry::GetDefaultGLType() {
1077010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_CHROMEOS)
1078010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeGL;
1079010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#elif defined(OS_LINUX) || defined(OS_OPENBSD)
1080010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeGL;
1081010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#elif defined(OS_MACOSX)
1082010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeGL;
1083010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#elif defined(OS_WIN)
1084010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeANGLE;
1085010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#elif defined(OS_ANDROID)
1086010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeGLES;
1087010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#else
1088010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return kGLTypeNone;
1089010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
1090010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1091010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void GpuControlList::GpuControlListEntry::LogControlListMatch(
10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& control_list_logging_name) const {
10944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static const char kControlListMatchMessage[] =
10954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "Control list match for rule #%u in %s.";
10961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  VLOG(1) << base::StringPrintf(kControlListMatchMessage, id_,
10971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                control_list_logging_name.c_str());
10984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::Contains(
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OsType os_type, const std::string& os_version,
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) const {
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(os_type != kOsAny);
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (vendor_id_ != 0) {
1107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    std::vector<GPUInfo::GPUDevice> candidates;
1108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    switch (multi_gpu_category_) {
1109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      case kMultiGpuCategoryPrimary:
1110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        candidates.push_back(gpu_info.gpu);
1111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
1112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      case kMultiGpuCategorySecondary:
1113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        candidates = gpu_info.secondary_gpus;
1114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
1115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      case kMultiGpuCategoryAny:
1116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        candidates = gpu_info.secondary_gpus;
1117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        candidates.push_back(gpu_info.gpu);
1118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
1119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      case kMultiGpuCategoryActive:
1120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        if (gpu_info.gpu.active)
1121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          candidates.push_back(gpu_info.gpu);
1122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        for (size_t ii = 0; ii < gpu_info.secondary_gpus.size(); ++ii) {
1123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          if (gpu_info.secondary_gpus[ii].active)
1124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            candidates.push_back(gpu_info.secondary_gpus[ii]);
1125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        }
1126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      default:
1127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
1128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
1129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    GPUInfo::GPUDevice gpu;
1131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    gpu.vendor_id = vendor_id_;
1132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    bool found = false;
1133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (device_id_list_.empty()) {
1134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      for (size_t ii = 0; ii < candidates.size(); ++ii) {
1135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        if (gpu.vendor_id == candidates[ii].vendor_id) {
1136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          found = true;
1137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          break;
1138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        }
1139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
1140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    } else {
1141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      for (size_t ii = 0; ii < device_id_list_.size(); ++ii) {
1142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        gpu.device_id = device_id_list_[ii];
1143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        for (size_t jj = 0; jj < candidates.size(); ++jj) {
1144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          if (gpu.vendor_id == candidates[jj].vendor_id &&
1145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              gpu.device_id == candidates[jj].device_id) {
1146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            found = true;
1147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            break;
1148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          }
1149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        }
1150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
1151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
1152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (!found)
1153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return false;
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (multi_gpu_style_) {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleOptimus:
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!gpu_info.optimus)
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleAMDSwitchable:
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!gpu_info.amd_switchable)
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
11636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      break;
11646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    case kMultiGpuStyleAMDSwitchableDiscrete:
11656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (!gpu_info.amd_switchable)
11666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        return false;
11676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // The discrete GPU is always the primary GPU.
11686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // This is guaranteed by GpuInfoCollector.
11696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (!gpu_info.gpu.active)
11706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        return false;
11716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      break;
11726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    case kMultiGpuStyleAMDSwitchableIntegrated:
11736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (!gpu_info.amd_switchable)
11746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        return false;
11756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // Assume the integrated GPU is the first in the secondary GPU list.
11766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (gpu_info.secondary_gpus.size() == 0 ||
11776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          !gpu_info.secondary_gpus[0].active)
11786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        return false;
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleNone:
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (StringMismatch(gpu_info.driver_vendor, driver_vendor_info_))
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_version_info_.get() != NULL && !gpu_info.driver_version.empty()) {
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!driver_version_info_->Contains(gpu_info.driver_version))
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_date_info_.get() != NULL && !gpu_info.driver_date.empty()) {
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!driver_date_info_->Contains(gpu_info.driver_date, '-'))
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (GLVersionInfoMismatch(gpu_info.gl_version))
1194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
11956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (StringMismatch(gpu_info.gl_vendor, gl_vendor_info_))
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
11976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (StringMismatch(gpu_info.gl_renderer, gl_renderer_info_))
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
11996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (StringMismatch(gpu_info.gl_extensions, gl_extensions_info_))
1200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return false;
1201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (gl_reset_notification_strategy_info_.get() != NULL &&
1202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      !gl_reset_notification_strategy_info_->Contains(
1203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          gpu_info.gl_reset_notification_strategy))
1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_graphics_info_.get() != NULL &&
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.graphics == 0.0 ||
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics)))
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_gaming_info_.get() != NULL &&
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.gaming == 0.0 ||
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming)))
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_overall_info_.get() != NULL &&
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.overall == 0.0 ||
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_overall_info_->Contains(gpu_info.performance_stats.overall)))
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
12175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!machine_model_name_list_.empty()) {
12185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (gpu_info.machine_model_name.empty())
12195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return false;
12200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool found_match = false;
12210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t ii = 0; ii < machine_model_name_list_.size(); ++ii) {
12226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (RE2::FullMatch(gpu_info.machine_model_name,
12236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                         machine_model_name_list_[ii])) {
12240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        found_match = true;
12250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        break;
12260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
12270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
12280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!found_match)
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (machine_model_version_info_.get() != NULL &&
12325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      (gpu_info.machine_model_version.empty() ||
12335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu       !machine_model_version_info_->Contains(gpu_info.machine_model_version)))
12340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gpu_count_info_.get() != NULL &&
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !gpu_count_info_->Contains(gpu_info.secondary_gpus.size() + 1))
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (direct_rendering_info_.get() != NULL &&
1239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      !direct_rendering_info_->Contains(gpu_info.direct_rendering))
1240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
12416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!cpu_brand_.empty()) {
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::CPU cpu_info;
12436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (StringMismatch(cpu_info.cpu_brand(), cpu_brand_))
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < exceptions_.size(); ++i) {
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (exceptions_[i]->Contains(os_type, os_version, gpu_info) &&
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !exceptions_[i]->NeedsMoreInfo(gpu_info))
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::NeedsMoreInfo(
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) const {
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We only check for missing info that might be collected with a gl context.
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If certain info is missing due to some error, say, we fail to collect
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // vendor_id/device_id, then even if we launch GPU process and create a gl
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // context, we won't gather such missing info, so we still return false.
12616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!driver_vendor_info_.empty() && gpu_info.driver_vendor.empty())
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_version_info_.get() && gpu_info.driver_version.empty())
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
12656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!gl_vendor_info_.empty() && gpu_info.gl_vendor.empty())
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
12676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!gl_renderer_info_.empty() && gpu_info.gl_renderer.empty())
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < exceptions_.size(); ++i) {
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (exceptions_[i]->NeedsMoreInfo(gpu_info))
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::GpuControlListEntry::GetOsType() const {
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os_info_.get() == NULL)
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAny;
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os_info_->type();
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32 GpuControlList::GpuControlListEntry::id() const {
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id_;
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::disabled() const {
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return disabled_;
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::set<int>& GpuControlList::GpuControlListEntry::features() const {
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return features_;
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void GpuControlList::GpuControlListEntry::GetFeatureNames(
1295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::ListValue* feature_names,
1296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const FeatureMap& feature_map,
1297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool supports_feature_type_all) const {
1298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(feature_names);
1299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (supports_feature_type_all && features_.size() == feature_map.size()) {
1300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    feature_names->AppendString("all");
1301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
1302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (FeatureMap::const_iterator iter = feature_map.begin();
1304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != feature_map.end(); ++iter) {
1305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (features_.count(iter->second) > 0)
1306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      feature_names->AppendString(iter->first);
1307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::StringToFeature(
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& feature_name, int* feature_id,
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FeatureMap& feature_map) {
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FeatureMap::const_iterator iter = feature_map.find(feature_name);
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != feature_map.end()) {
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *feature_id = iter->second;
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlList()
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : max_entry_id_(0),
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      needs_more_info_(false),
13254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      supports_feature_type_all_(false),
13264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      control_list_logging_enabled_(false) {
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::~GpuControlList() {
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::LoadList(
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& json_context,
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuControlList::OsFilter os_filter) {
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> root;
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root.reset(base::JSONReader::Read(json_context));
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (root.get() == NULL || !root->IsType(base::Value::TYPE_DICTIONARY))
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* root_dictionary =
1342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<base::DictionaryValue*>(root.get());
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(root_dictionary);
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return LoadList(*root_dictionary, os_filter);
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::LoadList(const base::DictionaryValue& parsed_json,
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              GpuControlList::OsFilter os_filter) {
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ScopedGpuControlListEntry> entries;
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parsed_json.GetString("version", &version_);
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> pieces;
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_, '.', &pieces))
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* list = NULL;
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!parsed_json.GetList("entries", &list))
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 max_entry_id = 0;
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < list->GetSize(); ++i) {
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* list_item = NULL;
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool valid = list->GetDictionary(i, &list_item);
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!valid || list_item == NULL)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ScopedGpuControlListEntry entry(GpuControlListEntry::GetEntryFromValue(
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        list_item, true, feature_map_, supports_feature_type_all_));
1368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (entry.get() == NULL)
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->id() > max_entry_id)
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_entry_id = entry->id();
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entries.push_back(entry);
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OsType my_os = GetOsType();
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < entries.size(); ++i) {
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OsType entry_os = entries[i]->GetOsType();
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (os_filter == GpuControlList::kAllOs ||
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry_os == kOsAny || entry_os == my_os)
1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entries_.push_back(entries[i]);
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  max_entry_id_ = max_entry_id;
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::set<int> GpuControlList::MakeDecision(
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuControlList::OsType os,
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version,
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) {
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  active_entries_.clear();
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<int> features;
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  needs_more_info_ = false;
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<int> possible_features;
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os == kOsAny)
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os = GetOsType();
1399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (os_version.empty())
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os_version = base::SysInfo::OperatingSystemVersion();
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < entries_.size(); ++i) {
1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (entries_[i]->Contains(os, os_version, gpu_info)) {
1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!entries_[i]->disabled()) {
14054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (control_list_logging_enabled_)
14064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          entries_[i]->LogControlListMatch(control_list_logging_name_);
1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MergeFeatureSets(&possible_features, entries_[i]->features());
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (!entries_[i]->NeedsMoreInfo(gpu_info))
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          MergeFeatureSets(&features, entries_[i]->features());
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      active_entries_.push_back(entries_[i]);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (possible_features.size() > features.size())
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_more_info_ = true;
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return features;
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GetDecisionEntries(
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint32>* entry_ids, bool disabled) const {
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(entry_ids);
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry_ids->clear();
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < active_entries_.size(); ++i) {
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (disabled == active_entries_[i]->disabled())
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry_ids->push_back(active_entries_[i]->id());
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void GpuControlList::GetReasons(base::ListValue* problem_list,
1432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const std::string& tag) const {
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(problem_list);
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < active_entries_.size(); ++i) {
1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GpuControlListEntry* entry = active_entries_[i].get();
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->disabled())
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* problem = new base::DictionaryValue();
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->SetString("description", entry->description());
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ListValue* cr_bugs = new base::ListValue();
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < entry->cr_bugs().size(); ++j)
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cr_bugs->Append(new base::FundamentalValue(entry->cr_bugs()[j]));
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->Set("crBugs", cr_bugs);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ListValue* webkit_bugs = new base::ListValue();
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) {
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      webkit_bugs->Append(new base::FundamentalValue(entry->webkit_bugs()[j]));
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->Set("webkitBugs", webkit_bugs);
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::ListValue* features = new base::ListValue();
1454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    entry->GetFeatureNames(features, feature_map_, supports_feature_type_all_);
1455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    problem->Set("affectedGpuSettings", features);
1456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(tag == "workarounds" || tag == "disabledFeatures");
1458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    problem->SetString("tag", tag);
1459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem_list->Append(problem);
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t GpuControlList::num_entries() const {
1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return entries_.size();
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32 GpuControlList::max_entry_id() const {
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_entry_id_;
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string GpuControlList::version() const {
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_;
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::GetOsType() {
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsChromeOS;
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsWin;
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_ANDROID)
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsAndroid;
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_LINUX) || defined(OS_OPENBSD)
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsLinux;
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_MACOSX)
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsMacosx;
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsUnknown;
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::Clear() {
1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entries_.clear();
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  active_entries_.clear();
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  max_entry_id_ = 0;
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::NumericOp GpuControlList::StringToNumericOp(
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op) {
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "=")
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kEQ;
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "<")
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kLT;
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "<=")
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kLE;
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == ">")
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kGT;
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == ">=")
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kGE;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "any")
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAny;
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "between")
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kBetween;
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kUnknown;
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuControlList::AddSupportedFeature(
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& feature_name, int feature_id) {
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  feature_map_[feature_name] = feature_id;
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuControlList::set_supports_feature_type_all(bool supported) {
1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  supports_feature_type_all_ = supported;
1525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace gpu
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1529