OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" | 5 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_split.h" | 11 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
13 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
14 #include "base/time/time.h" | 15 #include "base/time/time.h" |
15 #include "base/values.h" | 16 #include "base/values.h" |
16 #include "chrome/test/chromedriver/chrome/device_metrics.h" | 17 #include "chrome/test/chromedriver/chrome/device_metrics.h" |
17 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" | 18 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" |
18 #include "chrome/test/chromedriver/chrome/log.h" | 19 #include "chrome/test/chromedriver/chrome/log.h" |
19 #include "chrome/test/chromedriver/chrome/status.h" | 20 #include "chrome/test/chromedriver/chrome/status.h" |
20 #include "chrome/test/chromedriver/chrome/version.h" | 21 #include "chrome/test/chromedriver/chrome/version.h" |
21 #include "chrome/test/chromedriver/chrome/web_view_impl.h" | 22 #include "chrome/test/chromedriver/chrome/web_view_impl.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 socket_factory_(socket_factory), | 67 socket_factory_(socket_factory), |
67 server_url_("http://" + address.ToString()), | 68 server_url_("http://" + address.ToString()), |
68 web_socket_url_prefix_(base::StringPrintf( | 69 web_socket_url_prefix_(base::StringPrintf( |
69 "ws://%s/devtools/page/", address.ToString().c_str())), | 70 "ws://%s/devtools/page/", address.ToString().c_str())), |
70 device_metrics_(device_metrics.Pass()) {} | 71 device_metrics_(device_metrics.Pass()) {} |
71 | 72 |
72 DevToolsHttpClient::~DevToolsHttpClient() {} | 73 DevToolsHttpClient::~DevToolsHttpClient() {} |
73 | 74 |
74 Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) { | 75 Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) { |
75 base::TimeTicks deadline = base::TimeTicks::Now() + timeout; | 76 base::TimeTicks deadline = base::TimeTicks::Now() + timeout; |
76 std::string browser_version; | 77 std::string version_url = server_url_ + "/json/version"; |
77 std::string blink_version; | 78 std::string data; |
78 | 79 |
79 while (true) { | 80 while (!FetchUrlAndLog(version_url, context_getter_.get(), &data)) { |
stgao
2014/09/29 23:09:54
I see once the returned data is empty.
Add "|| dat
samuong
2014/09/30 04:03:49
Done.
| |
80 Status status = GetVersion(&browser_version, &blink_version); | 81 if (base::TimeTicks::Now() > deadline) |
81 if (status.IsOk()) | 82 return Status(kChromeNotReachable); |
82 break; | |
83 if (status.code() != kChromeNotReachable || | |
84 base::TimeTicks::Now() > deadline) { | |
85 return status; | |
86 } | |
87 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); | 83 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); |
88 } | 84 } |
89 | 85 |
90 // |blink_version| is should look something like "537.36 (@159105)", and for | 86 return internal::ParseBrowserInfo(data, &browser_info_); |
91 // this example |blink_revision| should be 159105 | |
92 size_t before = blink_version.find('@'); | |
93 size_t after = blink_version.find(')'); | |
94 if (before == std::string::npos || after == std::string::npos) { | |
95 return Status(kUnknownError, | |
96 "unrecognized Blink version: " + blink_version); | |
97 } | |
98 | |
99 std::string blink_revision_string = blink_version.substr(before + 1, | |
100 after - before - 1); | |
101 int blink_revision_int; | |
102 if (!base::StringToInt(blink_revision_string, &blink_revision_int)) { | |
103 return Status(kUnknownError, | |
104 "unrecognized Blink revision: " + blink_revision_string); | |
105 } | |
106 | |
107 browser_info_.blink_revision = blink_revision_int; | |
108 | |
109 if (browser_version.empty()) { | |
110 browser_info_.browser_name = "content shell"; | |
111 return Status(kOk); | |
112 } | |
113 if (browser_version.find("Version/") == 0u) { | |
114 browser_info_.browser_name = "webview"; | |
115 return Status(kOk); | |
116 } | |
117 std::string prefix = "Chrome/"; | |
118 if (browser_version.find(prefix) != 0u) { | |
119 return Status(kUnknownError, | |
120 "unrecognized Chrome version: " + browser_version); | |
121 } | |
122 | |
123 std::string stripped_version = browser_version.substr(prefix.length()); | |
124 int temp_build_no; | |
125 std::vector<std::string> version_parts; | |
126 base::SplitString(stripped_version, '.', &version_parts); | |
127 if (version_parts.size() != 4 || | |
128 !base::StringToInt(version_parts[2], &temp_build_no)) { | |
129 return Status(kUnknownError, | |
130 "unrecognized Chrome version: " + browser_version); | |
131 } | |
132 | |
133 browser_info_.browser_name = "chrome"; | |
134 browser_info_.browser_version = stripped_version; | |
135 browser_info_.build_no = temp_build_no; | |
136 | |
137 return Status(kOk); | |
138 } | 87 } |
139 | 88 |
140 Status DevToolsHttpClient::GetWebViewsInfo(WebViewsInfo* views_info) { | 89 Status DevToolsHttpClient::GetWebViewsInfo(WebViewsInfo* views_info) { |
141 std::string data; | 90 std::string data; |
142 if (!FetchUrlAndLog(server_url_ + "/json", context_getter_.get(), &data)) | 91 if (!FetchUrlAndLog(server_url_ + "/json", context_getter_.get(), &data)) |
143 return Status(kChromeNotReachable); | 92 return Status(kChromeNotReachable); |
144 | 93 |
145 return internal::ParseWebViewsInfo(data, views_info); | 94 return internal::ParseWebViewsInfo(data, views_info); |
146 } | 95 } |
147 | 96 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 } | 137 } |
189 | 138 |
190 const BrowserInfo* DevToolsHttpClient::browser_info() { | 139 const BrowserInfo* DevToolsHttpClient::browser_info() { |
191 return &browser_info_; | 140 return &browser_info_; |
192 } | 141 } |
193 | 142 |
194 const DeviceMetrics* DevToolsHttpClient::device_metrics() { | 143 const DeviceMetrics* DevToolsHttpClient::device_metrics() { |
195 return device_metrics_.get(); | 144 return device_metrics_.get(); |
196 } | 145 } |
197 | 146 |
198 Status DevToolsHttpClient::GetVersion(std::string* browser_version, | |
199 std::string* blink_version) { | |
200 std::string data; | |
201 if (!FetchUrlAndLog( | |
202 server_url_ + "/json/version", context_getter_.get(), &data)) | |
203 return Status(kChromeNotReachable); | |
204 | |
205 return internal::ParseVersionInfo(data, browser_version, blink_version); | |
206 } | |
207 | |
208 Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) { | 147 Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) { |
209 WebViewsInfo views_info; | 148 WebViewsInfo views_info; |
210 Status status = GetWebViewsInfo(&views_info); | 149 Status status = GetWebViewsInfo(&views_info); |
211 if (status.IsError()) | 150 if (status.IsError()) |
212 return status; | 151 return status; |
213 | 152 |
214 // Close frontends. Usually frontends are docked in the same page, although | 153 // Close frontends. Usually frontends are docked in the same page, although |
215 // some may be in tabs (undocked, chrome://inspect, the DevTools | 154 // some may be in tabs (undocked, chrome://inspect, the DevTools |
216 // discovery page, etc.). Tabs can be closed via the DevTools HTTP close | 155 // discovery page, etc.). Tabs can be closed via the DevTools HTTP close |
217 // URL, but docked frontends can only be closed, by design, by connecting | 156 // URL, but docked frontends can only be closed, by design, by connecting |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 type = WebViewInfo::kOther; | 275 type = WebViewInfo::kOther; |
337 else | 276 else |
338 return Status(kUnknownError, | 277 return Status(kUnknownError, |
339 "DevTools returned unknown type:" + type_as_string); | 278 "DevTools returned unknown type:" + type_as_string); |
340 temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type)); | 279 temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type)); |
341 } | 280 } |
342 *views_info = WebViewsInfo(temp_views_info); | 281 *views_info = WebViewsInfo(temp_views_info); |
343 return Status(kOk); | 282 return Status(kOk); |
344 } | 283 } |
345 | 284 |
346 Status ParseVersionInfo(const std::string& data, | 285 Status ParseBrowserInfo(const std::string& data, BrowserInfo* browser_info) { |
347 std::string* browser_version, | |
348 std::string* blink_version) { | |
349 scoped_ptr<base::Value> value(base::JSONReader::Read(data)); | 286 scoped_ptr<base::Value> value(base::JSONReader::Read(data)); |
350 if (!value.get()) | 287 if (!value.get()) |
351 return Status(kUnknownError, "version info not in JSON"); | 288 return Status(kUnknownError, "version info not in JSON"); |
289 | |
352 base::DictionaryValue* dict; | 290 base::DictionaryValue* dict; |
353 if (!value->GetAsDictionary(&dict)) | 291 if (!value->GetAsDictionary(&dict)) |
354 return Status(kUnknownError, "version info not a dictionary"); | 292 return Status(kUnknownError, "version info not a dictionary"); |
355 if (!dict->GetString("Browser", browser_version)) { | 293 |
356 return Status( | 294 std::string browser; |
357 kUnknownError, | 295 if (!dict->GetString("Browser", &browser)) { |
358 "Chrome version must be >= " + GetMinimumSupportedChromeVersion(), | 296 return Status(kUnknownError, |
359 Status(kUnknownError, "version info doesn't include string 'Browser'")); | 297 "version info doesn't include string 'Browser'"); |
360 } | 298 } |
361 if (!dict->GetString("WebKit-Version", blink_version)) { | 299 |
300 std::string blink_version; | |
301 if (!dict->GetString("WebKit-Version", &blink_version)) { | |
362 return Status(kUnknownError, | 302 return Status(kUnknownError, |
363 "version info doesn't include string 'WebKit-Version'"); | 303 "version info doesn't include string 'WebKit-Version'"); |
364 } | 304 } |
305 | |
306 Status status = internal::ParseBrowserString(browser, | |
307 &browser_info->browser_name, | |
308 &browser_info->browser_version, | |
309 &browser_info->build_no); | |
310 | |
311 if (status.IsError()) | |
312 return status; | |
313 | |
314 return internal::ParseBlinkVersionString(blink_version, | |
315 &browser_info->blink_revision); | |
316 } | |
317 | |
318 Status ParseBrowserString(const std::string& browser_string, | |
319 std::string* browser_name, | |
320 std::string* browser_version, | |
321 int* build_no) { | |
322 if (browser_string.empty()) { | |
323 *browser_name = "content shell"; | |
324 return Status(kOk); | |
325 } | |
326 | |
327 if (browser_string.find("Version/") == 0u) { | |
328 *browser_name = "webview"; | |
329 return Status(kOk); | |
330 } | |
331 | |
332 std::string prefix = "Chrome/"; | |
333 if (browser_string.find(prefix) == 0u) { | |
334 *browser_name = std::string("chrome"); | |
stgao
2014/09/29 23:09:54
remove std::string?
samuong
2014/09/30 04:03:49
Done.
| |
335 *browser_version = browser_string.substr(prefix.length()); | |
336 | |
337 std::vector<std::string> version_parts; | |
338 base::SplitString(*browser_version, '.', &version_parts); | |
339 if (version_parts.size() != 4 || | |
340 !base::StringToInt(version_parts[2], build_no)) { | |
341 return Status(kUnknownError, | |
342 "unrecognized Chrome version: " + *browser_version); | |
343 } | |
344 | |
345 return Status(kOk); | |
346 } | |
347 | |
348 return Status(kUnknownError, | |
349 "unrecognized Chrome version: " + browser_string); | |
350 } | |
351 | |
352 Status ParseBlinkVersionString(const std::string& blink_version, | |
353 int* blink_revision) { | |
354 size_t before = blink_version.find('@'); | |
355 size_t after = blink_version.find(')'); | |
356 if (before == std::string::npos || after == std::string::npos) { | |
357 return Status(kUnknownError, | |
358 "unrecognized Blink version string: " + blink_version); | |
359 } | |
360 | |
361 // Chrome OS reports its Blink revision as a (non-abbreviated) git hash. In | |
362 // this case, ignore it and use the default blink revision, otherwise convert | |
stgao
2014/09/29 23:09:54
Will using the default blink revision support back
samuong
2014/09/30 04:03:48
This is just the code to parse the version json an
| |
363 // the svn revision number to an int. | |
364 std::string revision = blink_version.substr(before + 1, after - before - 1); | |
365 if (!IsGitHash(revision) && !base::StringToInt(revision, blink_revision)) { | |
366 return Status(kUnknownError, "unrecognized Blink revision: " + revision); | |
367 } | |
368 | |
365 return Status(kOk); | 369 return Status(kOk); |
366 } | 370 } |
367 | 371 |
372 bool IsGitHash(const std::string& revision) { | |
373 const int kGitHashLength = 40; | |
stgao
2014/09/29 23:09:54
Constant variable could be defined outside of meth
samuong
2014/09/30 04:03:48
Is there any reason you prefer this? Defining it i
stgao
2014/09/30 18:13:37
The style guide says it is optional, not required.
| |
374 return revision.size() == kGitHashLength | |
375 && base::ContainsOnlyChars(revision, "0123456789abcdef"); | |
stgao
2014/09/29 23:09:54
Does the function test with uppercase and lowercas
samuong
2014/09/30 04:03:48
Done.
| |
376 } | |
377 | |
368 } // namespace internal | 378 } // namespace internal |
OLD | NEW |