1ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch// found in the LICENSE file. 4ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 5ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "chrome/test/chromedriver/chrome/browser_info.h" 6ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 7ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/json/json_reader.h" 8ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/memory/scoped_ptr.h" 9ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/strings/string_number_conversions.h" 10ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/strings/string_split.h" 11ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/strings/string_util.h" 12ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "base/values.h" 13ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 14ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben MurdochBrowserInfo::BrowserInfo() 15ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch : browser_name(std::string()), 16ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch browser_version(std::string()), 17ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch build_no(kToTBuildNo), 18ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch blink_revision(kToTBlinkRevision) { 19ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 20ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 21ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben MurdochBrowserInfo::BrowserInfo(std::string browser_name, 22ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string browser_version, 23ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch int build_no, 24ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch int blink_revision) 25ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch : browser_name(browser_name), 26ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch browser_version(browser_version), 27ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch build_no(build_no), 28ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch blink_revision(blink_revision) { 29ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 30ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 31ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben MurdochStatus ParseBrowserInfo(const std::string& data, BrowserInfo* browser_info) { 32ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch scoped_ptr<base::Value> value(base::JSONReader::Read(data)); 33ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!value.get()) 34ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, "version info not in JSON"); 35ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 36ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch base::DictionaryValue* dict; 37ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!value->GetAsDictionary(&dict)) 38ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, "version info not a dictionary"); 39ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 40ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string browser; 41ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!dict->GetString("Browser", &browser)) { 42ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, 43ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch "version info doesn't include string 'Browser'"); 44ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 45ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 46ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string blink_version; 47ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!dict->GetString("WebKit-Version", &blink_version)) { 48ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, 49ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch "version info doesn't include string 'WebKit-Version'"); 50ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 51ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 52ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch Status status = ParseBrowserString(browser, &browser_info->browser_name, 53ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch &browser_info->browser_version, &browser_info->build_no); 54ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 55ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (status.IsError()) 56ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return status; 57ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 58ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return ParseBlinkVersionString(blink_version, &browser_info->blink_revision); 59ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 60ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 61ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben MurdochStatus ParseBrowserString(const std::string& browser_string, 62ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string* browser_name, 63ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string* browser_version, 64ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch int* build_no) { 65ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (browser_string.empty()) { 66ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch *browser_name = "content shell"; 67ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kOk); 68ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 69ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 70ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (browser_string.find("Version/") == 0u) { 71ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch *browser_name = "webview"; 72ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kOk); 73ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 74ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 75ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string prefix = "Chrome/"; 76ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (browser_string.find(prefix) == 0u) { 77ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch *browser_name = "chrome"; 78ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch *browser_version = browser_string.substr(prefix.length()); 79ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 80ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::vector<std::string> version_parts; 81ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch base::SplitString(*browser_version, '.', &version_parts); 82ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (version_parts.size() != 4 || 83ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch !base::StringToInt(version_parts[2], build_no)) { 84ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, 85ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch "unrecognized Chrome version: " + *browser_version); 86ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 87ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 88ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kOk); 89ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 90ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 91ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, 92ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch "unrecognized Chrome version: " + browser_string); 93ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 94ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 95ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben MurdochStatus ParseBlinkVersionString(const std::string& blink_version, 96ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch int* blink_revision) { 97ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch size_t before = blink_version.find('@'); 98ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch size_t after = blink_version.find(')'); 99ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (before == std::string::npos || after == std::string::npos) { 100ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, 101ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch "unrecognized Blink version string: " + blink_version); 102ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 103ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 1045b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // Chrome OS reports its Blink revision as a git hash. In this case, ignore it 1055b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // and don't set |blink_revision|. For Chrome (and for Chrome OS) we use the 1065b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // build number instead of the blink revision for decisions about backwards 1075b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // compatibility. 108ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch std::string revision = blink_version.substr(before + 1, after - before - 1); 109ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch if (!IsGitHash(revision) && !base::StringToInt(revision, blink_revision)) { 110ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kUnknownError, "unrecognized Blink revision: " + revision); 111ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch } 112ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 113ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return Status(kOk); 114ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 115ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch 116ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdochbool IsGitHash(const std::string& revision) { 1175b892326406927b709cdaf6c384d4ababf456332Ben Murdoch const int kShortGitHashLength = 7; 1185b892326406927b709cdaf6c384d4ababf456332Ben Murdoch const int kFullGitHashLength = 40; 1195b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return kShortGitHashLength <= revision.size() 1205b892326406927b709cdaf6c384d4ababf456332Ben Murdoch && revision.size() <= kFullGitHashLength 121ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch && base::ContainsOnlyChars(revision, "0123456789abcdefABCDEF"); 122ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch} 123