gpu_control_list.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_info.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_info.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace gpu {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Break a version string into segments.  Return true if each segment is
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// a valid number.
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProcessVersionString(const std::string& version_string,
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          char splitter,
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          std::vector<std::string>* version) {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version);
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(version_string, splitter, version);
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version->size() == 0)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the splitter is '-', we assume it's a date with format "mm-dd-yyyy";
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we split it into the order of "yyyy", "mm", "dd".
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (splitter == '-') {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string year = (*version)[version->size() - 1];
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = version->size() - 1; i > 0; --i) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*version)[i] = (*version)[i - 1];
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*version)[0] = year;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < version->size(); ++i) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned num = 0;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!base::StringToUint((*version)[i], &num))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Compare two number strings using numerical ordering.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Return  0 if number = number_ref,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//         1 if number > number_ref,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        -1 if number < number_ref.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int CompareNumericalNumberStrings(
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& number, const std::string& number_ref) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned value1 = 0;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned value2 = 0;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool valid = base::StringToUint(number, &value1);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(valid);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  valid = base::StringToUint(number_ref, &value2);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(valid);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value1 == value2)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value1 > value2)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 1;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return -1;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Compare two number strings using lexical ordering.
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Return  0 if number = number_ref,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//         1 if number > number_ref,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        -1 if number < number_ref.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We only compare as many digits as number_ref contains.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// If number_ref is xxx, it's considered as xxx*
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For example: CompareLexicalNumberStrings("121", "12") returns 0,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//              CompareLexicalNumberStrings("12", "121") returns -1.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int CompareLexicalNumberStrings(
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& number, const std::string& number_ref) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < number_ref.length(); ++i) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned value1 = 0;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < number.length())
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value1 = number[i] - '0';
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned value2 = number_ref[i] - '0';
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value1 > value2)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 1;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value1 < value2)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return -1;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const GPUInfo::GPUDevice& gpu) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (vendor_id == 0)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (vendor_id != gpu.vendor_id)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool device_specified = false;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < device_id_list.size(); ++i) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (device_id_list[i] == 0)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (device_id_list[i] == gpu.device_id)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_specified = true;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return device_specified;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable";
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuStyleStringOptimus[] = "optimus";
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringPrimary[] = "primary";
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringSecondary[] = "secondary";
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMultiGpuCategoryStringAny[] = "any";
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kVersionStyleStringNumerical[] = "numerical";
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kVersionStyleStringLexical[] = "lexical";
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOp[] = "op";
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace anonymous
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::VersionInfo(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : version_style_(kVersionStyleNumerical) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  op_ = StringToNumericOp(version_op);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown || op_ == kAny)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  version_style_ = StringToVersionStyle(version_style);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_string, '.', &version_)) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!ProcessVersionString(version_string2, '.', &version2_))
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      op_ = kUnknown;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::~VersionInfo() {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::Contains(
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string) const {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Contains(version_string, '.');
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::Contains(
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string, char splitter) const {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> version;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_string, splitter, &version))
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int relation = Compare(version, version_, version_style_);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation == 0);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kLT)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation < 0);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kLE)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation <= 0);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kGT)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation > 0);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (op_ == kGE)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (relation >= 0);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // op_ == kBetween
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (relation < 0)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Compare(version, version2_, version_style_) <= 0;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::IsValid() const {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (op_ != kUnknown && version_style_ != kVersionStyleUnknown);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::VersionInfo::IsLexical() const {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_style_ == kVersionStyleLexical;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GpuControlList::VersionInfo::Compare(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& version,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& version_ref,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VersionStyle version_style) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version.size() > 0 && version_ref.size() > 0);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(version_style != kVersionStyleUnknown);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < version_ref.size(); ++i) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i >= version.size())
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return 0;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int ret = 0;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We assume both versions are checked by ProcessVersionString().
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i > 0 && version_style == kVersionStyleLexical)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ret = CompareLexicalNumberStrings(version[i], version_ref[i]);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ret = CompareNumericalNumberStrings(version[i], version_ref[i]);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ret != 0)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ret;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::VersionStyle
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::VersionInfo::StringToVersionStyle(
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version_style.empty() || version_style == kVersionStyleStringNumerical)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kVersionStyleNumerical;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (version_style == kVersionStyleStringLexical)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kVersionStyleLexical;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kVersionStyleUnknown;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsInfo::OsInfo(const std::string& os,
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_op,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_string,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& version_string2) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  type_ = StringToOsType(os);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_ != kOsUnknown) {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    version_info_.reset(new VersionInfo(
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        version_op, std::string(), version_string, version_string2));
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsInfo::~OsInfo() {}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::OsInfo::Contains(OsType type,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::string& version) const {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsValid())
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_ != type && type_ != kOsAny)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_info_->Contains(version);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::OsInfo::IsValid() const {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type_ != kOsUnknown && version_info_->IsValid();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::OsInfo::type() const {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type_;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::OsInfo::StringToOsType(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& os) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os == "win")
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsWin;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "macosx")
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsMacosx;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "android")
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAndroid;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "linux")
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsLinux;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "chromeos")
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsChromeOS;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (os == "any")
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAny;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsUnknown;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::MachineModelInfo::MachineModelInfo(
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name_op,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name_value,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  name_info_.reset(new StringInfo(name_op, name_value));
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  version_info_.reset(new VersionInfo(
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      version_op, std::string(), version_string, version_string2));
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::MachineModelInfo::~MachineModelInfo() {}
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::MachineModelInfo::Contains(
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name, const std::string& version) const {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsValid())
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!name_info_->Contains(name))
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_info_->Contains(version);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::MachineModelInfo::IsValid() const {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return name_info_->IsValid() && version_info_->IsValid();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::StringInfo::StringInfo(const std::string& string_op,
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const std::string& string_value) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  op_ = StringToOp(string_op);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  value_ = StringToLowerASCII(string_value);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::StringInfo::Contains(const std::string& value) const {
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string my_value = StringToLowerASCII(value);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (op_) {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kContains:
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return strstr(my_value.c_str(), value_.c_str()) != NULL;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kBeginWith:
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return StartsWithASCII(my_value, value_, false);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kEndWith:
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return EndsWith(my_value, value_, false);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kEQ:
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return value_ == my_value;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::StringInfo::IsValid() const {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return op_ != kUnknown;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::StringInfo::Op GpuControlList::StringInfo::StringToOp(
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& string_op) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_op == "=")
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kEQ;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (string_op == "contains")
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kContains;
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (string_op == "beginwith")
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kBeginWith;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (string_op == "endwith")
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kEndWith;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kUnknown;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::FloatInfo::FloatInfo(const std::string& float_op,
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const std::string& float_value,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const std::string& float_value2)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : op_(kUnknown),
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(0.f),
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value2_(0.f) {
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  op_ = StringToNumericOp(float_op);
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (op_ == kAny)
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double dvalue = 0;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::StringToDouble(float_value, &dvalue)) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  value_ = static_cast<float>(dvalue);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween) {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!base::StringToDouble(float_value2, &dvalue)) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      op_ = kUnknown;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    value2_ = static_cast<float>(dvalue);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::FloatInfo::Contains(float value) const {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value == value_);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLT)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value < value_);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLE)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value <= value_);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGT)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value > value_);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGE)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value >= value_);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(op_ == kBetween);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ((value_ <= value && value <= value2_) ||
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          (value2_ <= value && value <= value_));
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::FloatInfo::IsValid() const {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return op_ != kUnknown;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::IntInfo::IntInfo(const std::string& int_op,
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& int_value,
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& int_value2)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : op_(kUnknown),
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(0),
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value2_(0) {
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  op_ = StringToNumericOp(int_op);
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (op_ == kAny)
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::StringToInt(int_value, &value_)) {
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kBetween &&
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToInt(int_value2, &value2_))
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    op_ = kUnknown;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::IntInfo::Contains(int value) const {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kUnknown)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kAny)
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kEQ)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value == value_);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLT)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value < value_);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kLE)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value <= value_);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGT)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value > value_);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op_ == kGE)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (value >= value_);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(op_ == kBetween);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ((value_ <= value && value <= value2_) ||
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          (value2_ <= value && value <= value_));
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::IntInfo::IsValid() const {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return op_ != kUnknown;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::ScopedGpuControlListEntry
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::GetEntryFromValue(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* value, bool top_level,
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FeatureMap& feature_map,
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool supports_feature_type_all) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(value);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedGpuControlListEntry entry(new GpuControlListEntry());
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t dictionary_entry_count = 0;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 id;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) ||
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !entry->SetId(id)) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed id entry " << entry->id();
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool disabled;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetBoolean("disabled", &disabled)) {
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry->SetDisabled(disabled);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string description;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("description", &description)) {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry->description_ = description;
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry->description_ = "The GPU is unavailable for an unexplained reason.";
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* cr_bugs;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("cr_bugs", &cr_bugs)) {
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < cr_bugs->GetSize(); ++i) {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int bug_id;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (cr_bugs->GetInteger(i, &bug_id)) {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry->cr_bugs_.push_back(bug_id);
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed cr_bugs entry " << entry->id();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* webkit_bugs;
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("webkit_bugs", &webkit_bugs)) {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) {
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int bug_id;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (webkit_bugs->GetInteger(i, &bug_id)) {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry->webkit_bugs_.push_back(bug_id);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id();
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* os_value = NULL;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("os", &os_value)) {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_type;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_op = "any";
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_string;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version_string2;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os_value->GetString("type", &os_type);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* os_version_value = NULL;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (os_value->GetDictionary("version", &os_version_value)) {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os_version_value->GetString(kOp, &os_version_op);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os_version_value->GetString("number", &os_version_string);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os_version_value->GetString("number2", &os_version_string2);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          os_version_string2)) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed os entry " << entry->id();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string vendor_id;
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("vendor_id", &vendor_id)) {
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetVendorId(vendor_id)) {
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed vendor_id entry " << entry->id();
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* device_id_list;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetList("device_id", &device_id_list)) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < device_id_list->GetSize(); ++i) {
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string device_id;
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!device_id_list->GetString(i, &device_id) ||
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !entry->AddDeviceId(device_id)) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed device_id entry " << entry->id();
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string multi_gpu_style;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("multi_gpu_style", &multi_gpu_style)) {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetMultiGpuStyle(multi_gpu_style)) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id();
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string multi_gpu_category;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetString("multi_gpu_category", &multi_gpu_category)) {
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetMultiGpuCategory(multi_gpu_category)) {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id();
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* driver_vendor_value = NULL;
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("driver_vendor", &driver_vendor_value)) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string vendor_op;
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string vendor_value;
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_vendor_value->GetString(kOp, &vendor_op);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_vendor_value->GetString("value", &vendor_value);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) {
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_vendor entry " << entry->id();
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* driver_version_value = NULL;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("driver_version", &driver_version_value)) {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_op = "any";
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_style;
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_string;
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_version_string2;
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString(kOp, &driver_version_op);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString("style", &driver_version_style);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString("number", &driver_version_string);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_version_value->GetString("number2", &driver_version_string2);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetDriverVersionInfo(driver_version_op,
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_style,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_string,
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     driver_version_string2)) {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_version entry " << entry->id();
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* driver_date_value = NULL;
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("driver_date", &driver_date_value)) {
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_op = "any";
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_string;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string driver_date_string2;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_date_value->GetString(kOp, &driver_date_op);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_date_value->GetString("number", &driver_date_string);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    driver_date_value->GetString("number2", &driver_date_string2);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  driver_date_string2)) {
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed driver_date entry " << entry->id();
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* gl_vendor_value = NULL;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("gl_vendor", &gl_vendor_value)) {
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string vendor_op;
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string vendor_value;
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_vendor_value->GetString(kOp, &vendor_op);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_vendor_value->GetString("value", &vendor_value);
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_vendor entry " << entry->id();
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* gl_renderer_value = NULL;
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("gl_renderer", &gl_renderer_value)) {
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string renderer_op;
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string renderer_value;
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_renderer_value->GetString(kOp, &renderer_op);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_renderer_value->GetString("value", &renderer_value);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_renderer entry " << entry->id();
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
615b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const base::DictionaryValue* gl_extensions_value = NULL;
616b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (value->GetDictionary("gl_extensions", &gl_extensions_value)) {
617b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    std::string extensions_op;
618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    std::string extensions_value;
619b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    gl_extensions_value->GetString(kOp, &extensions_op);
620b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    gl_extensions_value->GetString("value", &extensions_value);
621b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!entry->SetGLExtensionsInfo(extensions_op, extensions_value)) {
622b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      LOG(WARNING) << "Malformed gl_extensions entry " << entry->id();
623b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return NULL;
624b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
625b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    dictionary_entry_count++;
626b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
627b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* cpu_brand_value = NULL;
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("cpu_info", &cpu_brand_value)) {
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string cpu_op;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string cpu_value;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cpu_brand_value->GetString(kOp, &cpu_op);
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cpu_brand_value->GetString("value", &cpu_value);
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetCpuBrand(cpu_op, cpu_value)) {
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed cpu_brand entry " << entry->id();
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_graphics_value = NULL;
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_graphics", &perf_graphics_value)) {
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString(kOp, &op);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString("value", &float_value);
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_graphics_value->GetString("value2", &float_value2);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) {
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_graphics entry " << entry->id();
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_gaming_value = NULL;
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_gaming", &perf_gaming_value)) {
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString(kOp, &op);
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString("value", &float_value);
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_gaming_value->GetString("value2", &float_value2);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) {
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_gaming entry " << entry->id();
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* perf_overall_value = NULL;
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("perf_overall", &perf_overall_value)) {
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string float_value2;
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString(kOp, &op);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString("value", &float_value);
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    perf_overall_value->GetString("value2", &float_value2);
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) {
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed perf_overall entry " << entry->id();
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* machine_model_value = NULL;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("machine_model", &machine_model_value)) {
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string name_op;
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string name_value;
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* name = NULL;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (machine_model_value->GetDictionary("name", &name)) {
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name->GetString(kOp, &name_op);
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name->GetString("value", &name_value);
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_op = "any";
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string;
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string2;
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* version_value = NULL;
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (machine_model_value->GetDictionary("version", &version_value)) {
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_value->GetString(kOp, &version_op);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_value->GetString("number", &version_string);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_value->GetString("number2", &version_string2);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetMachineModelInfo(
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            name_op, name_value, version_op, version_string, version_string2)) {
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed machine_model entry " << entry->id();
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* gpu_count_value = NULL;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("gpu_count", &gpu_count_value)) {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string op;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string int_value;
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string int_value2;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString(kOp, &op);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString("value", &int_value);
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_count_value->GetString("value2", &int_value2);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!entry->SetGpuCountInfo(op, int_value, int_value2)) {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Malformed gpu_count entry " << entry->id();
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dictionary_entry_count++;
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* feature_value = NULL;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetList("features", &feature_value)) {
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::vector<std::string> feature_list;
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < feature_value->GetSize(); ++i) {
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string feature;
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (feature_value->GetString(i, &feature)) {
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          feature_list.push_back(feature);
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed feature entry " << entry->id();
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!entry->SetFeatures(
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              feature_list, feature_map, supports_feature_type_all)) {
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LOG(WARNING) << "Malformed feature entry " << entry->id();
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return NULL;
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (top_level) {
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* exception_list_value = NULL;
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetList("exceptions", &exception_list_value)) {
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < exception_list_value->GetSize(); ++i) {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const base::DictionaryValue* exception_value = NULL;
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!exception_list_value->GetDictionary(i, &exception_value)) {
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed exceptions entry " << entry->id();
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ScopedGpuControlListEntry exception(GetEntryFromValue(
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            exception_value, false, feature_map, supports_feature_type_all));
761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (exception.get() == NULL) {
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Malformed exceptions entry " << entry->id();
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return NULL;
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // Exception should inherit vendor_id from parent, otherwise if only
766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // device_ids are specified in Exception, the info will be incomplete.
767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (exception->vendor_id_ == 0 && entry->vendor_id_ != 0)
768868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          exception->vendor_id_ = entry->vendor_id_;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (exception->contains_unknown_fields_) {
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(WARNING) << "Exception with unknown fields " << entry->id();
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          entry->contains_unknown_fields_ = true;
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          entry->AddException(exception);
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* browser_version_value = NULL;
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // browser_version is processed in LoadGpuControlList().
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetDictionary("browser_version", &browser_version_value))
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dictionary_entry_count++;
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->size() != dictionary_entry_count) {
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Entry with unknown fields " << entry->id();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry->contains_unknown_fields_ = true;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return entry;
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::GpuControlListEntry()
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(0),
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disabled_(false),
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      vendor_id_(0),
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      multi_gpu_style_(kMultiGpuStyleNone),
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      multi_gpu_category_(kMultiGpuCategoryPrimary),
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contains_unknown_fields_(false),
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contains_unknown_features_(false) {
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::~GpuControlListEntry() { }
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetId(uint32 id) {
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (id != 0) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id_ = id;
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GpuControlListEntry::SetDisabled(bool disabled) {
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  disabled_ = disabled;
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetOsInfo(
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& os,
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os_info_->IsValid();
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetVendorId(
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_id_string) {
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vendor_id_ = 0;
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::HexStringToInt(vendor_id_string,
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              reinterpret_cast<int*>(&vendor_id_));
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::AddDeviceId(
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id_string) {
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 device_id = 0;
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::HexStringToInt(device_id_string,
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           reinterpret_cast<int*>(&device_id))) {
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_id_list_.push_back(device_id);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetMultiGpuStyle(
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& multi_gpu_style_string) {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleNone)
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  multi_gpu_style_ = style;
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetMultiGpuCategory(
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& multi_gpu_category_string) {
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MultiGpuCategory category =
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StringToMultiGpuCategory(multi_gpu_category_string);
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryNone)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  multi_gpu_category_ = category;
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverVendorInfo(
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_op,
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_value) {
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  driver_vendor_info_.reset(new StringInfo(vendor_op, vendor_value));
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return driver_vendor_info_->IsValid();
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverVersionInfo(
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_style,
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  driver_version_info_.reset(new VersionInfo(
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_op, version_style, version_string, version_string2));
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return driver_version_info_->IsValid();
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetDriverDateInfo(
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_op,
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_string,
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& date_string2) {
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  driver_date_info_.reset(
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new VersionInfo(date_op, std::string(), date_string, date_string2));
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return driver_date_info_->IsValid();
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLVendorInfo(
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_op,
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& vendor_value) {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gl_vendor_info_.reset(new StringInfo(vendor_op, vendor_value));
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gl_vendor_info_->IsValid();
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLRendererInfo(
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& renderer_op,
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& renderer_value) {
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gl_renderer_info_.reset(new StringInfo(renderer_op, renderer_value));
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gl_renderer_info_->IsValid();
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGLExtensionsInfo(
903b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const std::string& extensions_op,
904b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const std::string& extensions_value) {
905b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gl_extensions_info_.reset(new StringInfo(extensions_op, extensions_value));
906b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return gl_extensions_info_->IsValid();
907b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
908b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetCpuBrand(
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& cpu_op,
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& cpu_value) {
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cpu_brand_.reset(new StringInfo(cpu_op, cpu_value));
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cpu_brand_->IsValid();
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)
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetMachineModelInfo(
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name_op,
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name_value,
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_op,
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string,
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version_string2) {
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine_model_info_.reset(new MachineModelInfo(
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name_op, name_value, version_op, version_string, version_string2));
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return machine_model_info_->IsValid();
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetGpuCountInfo(
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op,
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& int_string,
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& int_string2) {
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_count_info_.reset(new IntInfo(op, int_string, int_string2));
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gpu_count_info_->IsValid();
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::SetFeatures(
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<std::string>& feature_strings,
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FeatureMap& feature_map,
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool supports_feature_type_all) {
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t size = feature_strings.size();
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size == 0)
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  features_.clear();
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < size; ++i) {
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int feature = 0;
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (supports_feature_type_all && feature_strings[i] == "all") {
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (FeatureMap::const_iterator iter = feature_map.begin();
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           iter != feature_map.end(); ++iter)
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        features_.insert(iter->second);
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (StringToFeature(feature_strings[i], &feature, feature_map))
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      features_.insert(feature);
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      contains_unknown_features_ = true;
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GpuControlListEntry::AddException(
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedGpuControlListEntry exception) {
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  exceptions_.push_back(exception);
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::MultiGpuStyle
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::StringToMultiGpuStyle(
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& style) {
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleStringOptimus)
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuStyleOptimus;
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (style == kMultiGpuStyleStringAMDSwitchable)
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuStyleAMDSwitchable;
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMultiGpuStyleNone;
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::MultiGpuCategory
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlListEntry::StringToMultiGpuCategory(
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& category) {
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringPrimary)
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategoryPrimary;
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringSecondary)
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategorySecondary;
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (category == kMultiGpuCategoryStringAny)
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kMultiGpuCategoryAny;
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMultiGpuCategoryNone;
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::Contains(
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OsType os_type, const std::string& os_version,
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) const {
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(os_type != kOsAny);
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_not_primary_gpu =
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu);
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_not_secondary_gpu = true;
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_not_secondary_gpu = is_not_secondary_gpu &&
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (multi_gpu_category_) {
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuCategoryPrimary:
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_not_primary_gpu)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuCategorySecondary:
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_not_secondary_gpu)
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuCategoryAny:
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_not_primary_gpu && is_not_secondary_gpu)
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuCategoryNone:
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (multi_gpu_style_) {
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleOptimus:
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!gpu_info.optimus)
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleAMDSwitchable:
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!gpu_info.amd_switchable)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kMultiGpuStyleNone:
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_vendor_info_.get() != NULL && !gpu_info.driver_vendor.empty() &&
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !driver_vendor_info_->Contains(gpu_info.driver_vendor))
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_version_info_.get() != NULL && !gpu_info.driver_version.empty()) {
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!driver_version_info_->Contains(gpu_info.driver_version))
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_date_info_.get() != NULL && !gpu_info.driver_date.empty()) {
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!driver_date_info_->Contains(gpu_info.driver_date, '-'))
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gl_vendor_info_.get() != NULL && !gpu_info.gl_vendor.empty() &&
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !gl_vendor_info_->Contains(gpu_info.gl_vendor))
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gl_renderer_info_.get() != NULL && !gpu_info.gl_renderer.empty() &&
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !gl_renderer_info_->Contains(gpu_info.gl_renderer))
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1070b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (gl_extensions_info_.get() != NULL && !gpu_info.gl_extensions.empty() &&
1071b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      !gl_extensions_info_->Contains(gpu_info.gl_extensions))
1072b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return false;
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_graphics_info_.get() != NULL &&
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.graphics == 0.0 ||
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics)))
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_gaming_info_.get() != NULL &&
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.gaming == 0.0 ||
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming)))
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (perf_overall_info_.get() != NULL &&
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gpu_info.performance_stats.overall == 0.0 ||
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       !perf_overall_info_->Contains(gpu_info.performance_stats.overall)))
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (machine_model_info_.get() != NULL) {
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> name_version;
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::SplitString(gpu_info.machine_model, ' ', &name_version);
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (name_version.size() == 2 &&
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !machine_model_info_->Contains(name_version[0], name_version[1]))
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gpu_count_info_.get() != NULL &&
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !gpu_count_info_->Contains(gpu_info.secondary_gpus.size() + 1))
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (cpu_brand_.get() != NULL) {
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::CPU cpu_info;
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!cpu_brand_->Contains(cpu_info.cpu_brand()))
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < exceptions_.size(); ++i) {
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (exceptions_[i]->Contains(os_type, os_version, gpu_info) &&
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !exceptions_[i]->NeedsMoreInfo(gpu_info))
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::NeedsMoreInfo(
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) const {
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We only check for missing info that might be collected with a gl context.
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If certain info is missing due to some error, say, we fail to collect
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // vendor_id/device_id, then even if we launch GPU process and create a gl
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // context, we won't gather such missing info, so we still return false.
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_vendor_info_.get() && gpu_info.driver_vendor.empty())
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (driver_version_info_.get() && gpu_info.driver_version.empty())
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gl_vendor_info_.get() && gpu_info.gl_vendor.empty())
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gl_renderer_info_.get() && gpu_info.gl_renderer.empty())
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < exceptions_.size(); ++i) {
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (exceptions_[i]->NeedsMoreInfo(gpu_info))
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::GpuControlListEntry::GetOsType() const {
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os_info_.get() == NULL)
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kOsAny;
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return os_info_->type();
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32 GpuControlList::GpuControlListEntry::id() const {
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id_;
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::disabled() const {
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return disabled_;
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::set<int>& GpuControlList::GpuControlListEntry::features() const {
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return features_;
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::GpuControlListEntry::StringToFeature(
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& feature_name, int* feature_id,
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FeatureMap& feature_map) {
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FeatureMap::const_iterator iter = feature_map.find(feature_name);
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != feature_map.end()) {
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *feature_id = iter->second;
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::GpuControlList()
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : max_entry_id_(0),
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contains_unknown_fields_(false),
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      needs_more_info_(false),
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      supports_feature_type_all_(false) {
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::~GpuControlList() {
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::LoadList(
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& json_context, GpuControlList::OsFilter os_filter) {
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string browser_version_string = "0";
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return LoadList(browser_version_string, json_context, os_filter);
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::LoadList(
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& browser_version_string,
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& json_context,
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuControlList::OsFilter os_filter) {
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> pieces;
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(browser_version_string, '.', &pieces))
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_version_ = browser_version_string;
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> root;
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root.reset(base::JSONReader::Read(json_context));
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (root.get() == NULL || !root->IsType(base::Value::TYPE_DICTIONARY))
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* root_dictionary =
1192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<base::DictionaryValue*>(root.get());
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(root_dictionary);
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return LoadList(*root_dictionary, os_filter);
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuControlList::LoadList(const base::DictionaryValue& parsed_json,
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              GpuControlList::OsFilter os_filter) {
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ScopedGpuControlListEntry> entries;
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parsed_json.GetString("version", &version_);
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> pieces;
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(version_, '.', &pieces))
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* list = NULL;
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!parsed_json.GetList("entries", &list))
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 max_entry_id = 0;
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool contains_unknown_fields = false;
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < list->GetSize(); ++i) {
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* list_item = NULL;
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool valid = list->GetDictionary(i, &list_item);
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!valid || list_item == NULL)
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check browser version compatibility: if the entry is not for the
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // current browser version, don't process it.
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserVersionSupport browser_version_support =
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsEntrySupportedByCurrentBrowserVersion(list_item);
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_version_support == kMalformed)
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_version_support == kUnsupported)
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(browser_version_support == kSupported);
1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ScopedGpuControlListEntry entry(GpuControlListEntry::GetEntryFromValue(
1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        list_item, true, feature_map_, supports_feature_type_all_));
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (entry.get() == NULL)
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->id() > max_entry_id)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_entry_id = entry->id();
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If an unknown field is encountered, skip the entry; if an unknown
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // feature is encountered, ignore the feature, but keep the entry.
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->contains_unknown_fields()) {
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contains_unknown_fields = true;
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->contains_unknown_features())
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contains_unknown_fields = true;
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entries.push_back(entry);
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Clear();
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OsType my_os = GetOsType();
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < entries.size(); ++i) {
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OsType entry_os = entries[i]->GetOsType();
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (os_filter == GpuControlList::kAllOs ||
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entry_os == kOsAny || entry_os == my_os)
1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      entries_.push_back(entries[i]);
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  max_entry_id_ = max_entry_id;
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contains_unknown_fields_ = contains_unknown_fields;
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::set<int> GpuControlList::MakeDecision(
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuControlList::OsType os,
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string os_version,
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GPUInfo& gpu_info) {
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  active_entries_.clear();
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<int> features;
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  needs_more_info_ = false;
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<int> possible_features;
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os == kOsAny)
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os = GetOsType();
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (os_version.empty()) {
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os_version = base::SysInfo::OperatingSystemVersion();
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t pos = os_version.find_first_not_of("0123456789.");
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pos != std::string::npos)
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      os_version = os_version.substr(0, pos);
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> pieces;
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ProcessVersionString(os_version, '.', &pieces))
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    os_version = "0";
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < entries_.size(); ++i) {
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (entries_[i]->Contains(os, os_version, gpu_info)) {
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!entries_[i]->disabled()) {
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MergeFeatureSets(&possible_features, entries_[i]->features());
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (!entries_[i]->NeedsMoreInfo(gpu_info))
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          MergeFeatureSets(&features, entries_[i]->features());
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      active_entries_.push_back(entries_[i]);
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (possible_features.size() > features.size())
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_more_info_ = true;
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return features;
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GetDecisionEntries(
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint32>* entry_ids, bool disabled) const {
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(entry_ids);
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry_ids->clear();
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < active_entries_.size(); ++i) {
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (disabled == active_entries_[i]->disabled())
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      entry_ids->push_back(active_entries_[i]->id());
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::GetReasons(base::ListValue* problem_list) const {
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(problem_list);
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < active_entries_.size(); ++i) {
1308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GpuControlListEntry* entry = active_entries_[i].get();
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->disabled())
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* problem = new base::DictionaryValue();
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->SetString("description", entry->description());
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ListValue* cr_bugs = new base::ListValue();
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < entry->cr_bugs().size(); ++j)
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cr_bugs->Append(new base::FundamentalValue(entry->cr_bugs()[j]));
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->Set("crBugs", cr_bugs);
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ListValue* webkit_bugs = new base::ListValue();
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) {
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      webkit_bugs->Append(new base::FundamentalValue(entry->webkit_bugs()[j]));
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem->Set("webkitBugs", webkit_bugs);
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    problem_list->Append(problem);
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t GpuControlList::num_entries() const {
1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return entries_.size();
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32 GpuControlList::max_entry_id() const {
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_entry_id_;
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string GpuControlList::version() const {
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version_;
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::OsType GpuControlList::GetOsType() {
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsChromeOS;
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN)
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsWin;
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_ANDROID)
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsAndroid;
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_LINUX) || defined(OS_OPENBSD)
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsLinux;
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_MACOSX)
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsMacosx;
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kOsUnknown;
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuControlList::Clear() {
1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entries_.clear();
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  active_entries_.clear();
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  max_entry_id_ = 0;
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contains_unknown_fields_ = false;
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::BrowserVersionSupport
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::IsEntrySupportedByCurrentBrowserVersion(
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* value) {
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(value);
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::DictionaryValue* browser_version_value = NULL;
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetDictionary("browser_version", &browser_version_value)) {
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_op = "any";
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string;
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string version_string2;
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_version_value->GetString(kOp, &version_op);
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_version_value->GetString("number", &version_string);
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_version_value->GetString("number2", &version_string2);
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<VersionInfo> browser_version_info;
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    browser_version_info.reset(new VersionInfo(
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        version_op, std::string(), version_string, version_string2));
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!browser_version_info->IsValid())
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kMalformed;
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_version_info->Contains(browser_version_))
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSupported;
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kUnsupported;
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kSupported;
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuControlList::NumericOp GpuControlList::StringToNumericOp(
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& op) {
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "=")
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kEQ;
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "<")
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kLT;
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "<=")
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kLE;
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == ">")
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kGT;
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == ">=")
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kGE;
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "any")
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAny;
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (op == "between")
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kBetween;
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kUnknown;
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuControlList::AddSupportedFeature(
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& feature_name, int feature_id) {
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  feature_map_[feature_name] = feature_id;
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuControlList::set_supports_feature_type_all(bool supported) {
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  supports_feature_type_all_ = supported;
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace gpu
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1420