Index: chrome/test/chromedriver/chrome/browser_info.cc |
diff --git a/chrome/test/chromedriver/chrome/browser_info.cc b/chrome/test/chromedriver/chrome/browser_info.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e78c1eb279f955b1c90c940fe6ea07d10f45d6b0 |
--- /dev/null |
+++ b/chrome/test/chromedriver/chrome/browser_info.cc |
@@ -0,0 +1,120 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/test/chromedriver/chrome/browser_info.h" |
+ |
+#include "base/json/json_reader.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_split.h" |
+#include "base/strings/string_util.h" |
+#include "base/values.h" |
+ |
+BrowserInfo::BrowserInfo() |
+ : browser_name(std::string()), |
+ browser_version(std::string()), |
+ build_no(kToTBuildNo), |
+ blink_revision(kToTBlinkRevision) { |
+} |
+ |
+BrowserInfo::BrowserInfo(std::string browser_name, |
+ std::string browser_version, |
+ int build_no, |
+ int blink_revision) |
+ : browser_name(browser_name), |
+ browser_version(browser_version), |
+ build_no(build_no), |
+ blink_revision(blink_revision) { |
+} |
+ |
+Status ParseBrowserInfo(const std::string& data, BrowserInfo* browser_info) { |
+ scoped_ptr<base::Value> value(base::JSONReader::Read(data)); |
+ if (!value.get()) |
+ return Status(kUnknownError, "version info not in JSON"); |
+ |
+ base::DictionaryValue* dict; |
+ if (!value->GetAsDictionary(&dict)) |
+ return Status(kUnknownError, "version info not a dictionary"); |
+ |
+ std::string browser; |
+ if (!dict->GetString("Browser", &browser)) { |
+ return Status(kUnknownError, |
+ "version info doesn't include string 'Browser'"); |
+ } |
+ |
+ std::string blink_version; |
+ if (!dict->GetString("WebKit-Version", &blink_version)) { |
+ return Status(kUnknownError, |
+ "version info doesn't include string 'WebKit-Version'"); |
+ } |
+ |
+ Status status = ParseBrowserString(browser, &browser_info->browser_name, |
+ &browser_info->browser_version, &browser_info->build_no); |
+ |
+ if (status.IsError()) |
+ return status; |
+ |
+ return ParseBlinkVersionString(blink_version, &browser_info->blink_revision); |
+} |
+ |
+Status ParseBrowserString(const std::string& browser_string, |
+ std::string* browser_name, |
+ std::string* browser_version, |
+ int* build_no) { |
+ if (browser_string.empty()) { |
+ *browser_name = "content shell"; |
+ return Status(kOk); |
+ } |
+ |
+ if (browser_string.find("Version/") == 0u) { |
+ *browser_name = "webview"; |
+ return Status(kOk); |
+ } |
+ |
+ std::string prefix = "Chrome/"; |
+ if (browser_string.find(prefix) == 0u) { |
+ *browser_name = "chrome"; |
+ *browser_version = browser_string.substr(prefix.length()); |
+ |
+ std::vector<std::string> version_parts; |
+ base::SplitString(*browser_version, '.', &version_parts); |
+ if (version_parts.size() != 4 || |
+ !base::StringToInt(version_parts[2], build_no)) { |
+ return Status(kUnknownError, |
+ "unrecognized Chrome version: " + *browser_version); |
+ } |
+ |
+ return Status(kOk); |
+ } |
+ |
+ return Status(kUnknownError, |
+ "unrecognized Chrome version: " + browser_string); |
+} |
+ |
+Status ParseBlinkVersionString(const std::string& blink_version, |
+ int* blink_revision) { |
+ size_t before = blink_version.find('@'); |
+ size_t after = blink_version.find(')'); |
+ if (before == std::string::npos || after == std::string::npos) { |
+ return Status(kUnknownError, |
+ "unrecognized Blink version string: " + blink_version); |
+ } |
+ |
+ // Chrome OS reports its Blink revision as a (non-abbreviated) git hash. In |
+ // this case, ignore it and don't set |blink_revision|. For Chrome (and for |
+ // Chrome OS) we use the build number instead of the blink revision for |
+ // decisions about backwards compatibility. |
+ std::string revision = blink_version.substr(before + 1, after - before - 1); |
+ if (!IsGitHash(revision) && !base::StringToInt(revision, blink_revision)) { |
+ return Status(kUnknownError, "unrecognized Blink revision: " + revision); |
+ } |
+ |
+ return Status(kOk); |
+} |
+ |
+bool IsGitHash(const std::string& revision) { |
+ const int kGitHashLength = 40; |
+ return revision.size() == kGitHashLength |
+ && base::ContainsOnlyChars(revision, "0123456789abcdefABCDEF"); |
+} |