web_view_impl.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/web_view_impl.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/platform_thread.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/debugger_tracker.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_client_impl.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/dom_tracker.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/frame_tracker.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/geolocation_override_manager.h" 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/heap_snapshot_taker.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/js.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/navigation_tracker.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h" 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/test/chromedriver/chrome/version.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetContextIdForFrame(FrameTracker* tracker, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& frame, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* context_id) { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame.empty()) { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *context_id = 0; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = tracker->GetContextIdForFrame(frame, context_id); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseEventType type) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kPressedMouseEventType: 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mousePressed"; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kReleasedMouseEventType: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseReleased"; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMovedMouseEventType: 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseMoved"; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetAsString(TouchEventType type) { 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchStart: 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchStart"; 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchEnd: 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchEnd"; 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchMove: 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchMove"; 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetPointStateString(TouchEventType type) { 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchStart: 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchPressed"; 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchEnd: 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchReleased"; 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchMove: 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchMoved"; 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseButton button) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (button) { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kLeftMouseButton: 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "left"; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMiddleMouseButton: 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "middle"; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRightMouseButton: 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "right"; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kNoneMouseButton: 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "none"; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(KeyEventType type) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyDownEventType: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyDown"; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyUpEventType: 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyUp"; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRawKeyDownEventType: 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "rawKeyDown"; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kCharEventType: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "char"; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::WebViewImpl(const std::string& id, 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BrowserInfo* browser_info, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<DevToolsClient> client, 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const DeviceMetrics* device_metrics) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch browser_info_(browser_info), 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dom_tracker_(new DomTracker(client.get())), 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame_tracker_(new FrameTracker(client.get())), 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch navigation_tracker_(new NavigationTracker(client.get(), browser_info)), 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dialog_manager_(new JavaScriptDialogManager(client.get())), 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mobile_emulation_override_manager_( 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MobileEmulationOverrideManager(client.get(), device_metrics)), 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) geolocation_override_manager_( 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new GeolocationOverrideManager(client.get())), 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) heap_snapshot_taker_(new HeapSnapshotTaker(client.get())), 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) debugger_(new DebuggerTracker(client.get())), 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_(client.release()) {} 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::~WebViewImpl() {} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string WebViewImpl::GetId() { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id_; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WebViewImpl::WasCrashed() { 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return client_->WasCrashed(); 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::ConnectIfNecessary() { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->ConnectIfNecessary(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::HandleReceivedEvents() { 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return client_->HandleReceivedEvents(); 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Load(const std::string& url) { 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Javascript URLs will cause a hang while waiting for the page to stop 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // loading, so just disallow. 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(url, "javascript:", false)) 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnknownError, "unsupported protocol"); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.navigate", params); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Reload() { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("ignoreCache", false); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.reload", params); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::EvaluateScript(const std::string& frame, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::EvaluateScriptAndGetValue( 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.get(), context_id, expression, result); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CallFunction(const std::string& frame, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s])", 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> temp_result; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(frame, expression, &temp_result); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::ParseCallFunctionResult(*temp_result, result); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunction(const std::string& frame, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, false, timeout, result); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallUserAsyncFunction(const std::string& frame, 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, true, timeout, result); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetFrameByFunction(const std::string& frame, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* out_frame) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int node_id; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, function, args, &found_node, &node_id); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kNoSuchFrame); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dom_tracker_->GetFrameIdForNode(node_id, out_frame); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochStatus WebViewImpl::DispatchMouseEvents(const std::list<MouseEvent>& events, 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& frame) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<MouseEvent>::const_iterator it = events.begin(); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("x", it->x); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("y", it->y); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("button", GetAsString(it->button)); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("clickCount", it->click_count); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchMouseEvent", params); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (browser_info_->build_no < 1569 && it->button == kRightMouseButton && 253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch it->type == kReleasedMouseEventType) { 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::ListValue args; 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->x); 256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->y); 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->modifiers); 258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Value> result; 259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = CallFunction( 260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch frame, kDispatchContextMenuEventScript, args, &result); 261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (status.IsError()) 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status; 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Status WebViewImpl::DispatchTouchEvent(const TouchEvent& event) { 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.SetString("type", GetAsString(event.type)); 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> point_list(new base::ListValue); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> point(new base::DictionaryValue); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetString("state", GetPointStateString(event.type)); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("x", event.x); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("y", event.y); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point_list->Set(0, point.release()); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.Set("touchPoints", point_list.release()); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return client_->SendCommand("Input.dispatchTouchEvent", params); 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 281d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochStatus WebViewImpl::DispatchTouchEvents(const std::list<TouchEvent>& events) { 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (std::list<TouchEvent>::const_iterator it = events.begin(); 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch it != events.end(); ++it) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Status status = DispatchTouchEvent(*it); 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (status.IsError()) 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return status; 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Status(kOk); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchKeyEvents(const std::list<KeyEvent>& events) { 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<KeyEvent>::const_iterator it = events.begin(); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->modifiers & kNumLockKeyModifierMask) { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("isKeypad", true); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->modifiers & ~kNumLockKeyModifierMask); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("text", it->modified_text); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("unmodifiedText", it->unmodified_text); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("nativeVirtualKeyCode", it->key_code); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("windowsVirtualKeyCode", it->key_code); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchKeyEvent", params); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetCookies(scoped_ptr<base::ListValue>* cookies) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.getCookies", params, &result); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* cookies_tmp; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetList("cookies", &cookies_tmp)) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DevTools didn't return cookies"); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cookies->reset(cookies_tmp->DeepCopy()); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DeleteCookie(const std::string& name, 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("cookieName", name); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.deleteCookie", params); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id, 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::TimeDelta& timeout, 338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool stop_load_on_timeout) { 33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Waiting for pending navigations..."; 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = client_->HandleEventsUntil( 341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, 342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Unretained(this), 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) timeout); 345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (status.code() == kTimeout && stop_load_on_timeout) { 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Timed out. Stopping navigation..."; 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> unused_value; 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EvaluateScript(std::string(), "window.stop();", &unused_value); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Status new_status = client_->HandleEventsUntil( 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::TimeDelta::FromSeconds(10)); 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_status.IsError()) 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status = new_status; 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Done waiting for pending navigations"; 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::IsPendingNavigation(const std::string& frame_id, 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_pending) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return navigation_tracker_->IsPendingNavigation(frame_id, is_pending); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() { 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dialog_manager_.get(); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) { 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return geolocation_override_manager_->OverrideGeolocation(geoposition); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CaptureScreenshot(std::string* screenshot) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.captureScreenshot", params, &result); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("data", screenshot)) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "expected string 'data' in response"); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::SetFileInputFiles( 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& frame, 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& element, 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<base::FilePath>& files) { 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue file_list; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < files.size(); ++i) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!files[i].IsAbsolute()) { 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not absolute: " + files[i].AsUTF8Unsafe()); 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (files[i].ReferencesParent()) { 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not canonical: " + files[i].AsUTF8Unsafe()); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_list.AppendString(files[i].value()); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int context_id; 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &context_id); 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue args; 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.Append(element.DeepCopy()); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int node_id; 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, "function(element) { return element; }", 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args, &found_node, &node_id); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "no node ID for file input"); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue params; 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("nodeId", node_id); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.Set("files", file_list.DeepCopy()); 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_->SendCommand("DOM.setFileInputFiles", params); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Status WebViewImpl::TakeHeapSnapshot(scoped_ptr<base::Value>* snapshot) { 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return heap_snapshot_taker_->TakeSnapshot(snapshot); 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::InitProfileInternal() { 429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO: Remove Debugger.enable after Chrome 36 stable is released. 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debug = client_->SendCommand("Debugger.enable", params); 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_debug.IsError()) 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debug; 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_profiler = client_->SendCommand("Profiler.enable", params); 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_profiler.IsError()) { 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debugger = client_->SendCommand("Debugger.disable", params); 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_debugger.IsError()) 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debugger; 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_profiler; 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Status(kOk); 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::StopProfileInternal() { 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debug = client_->SendCommand("Debugger.disable", params); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_profiler = client_->SendCommand("Profiler.disable", params); 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (status_debug.IsError()) { 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debug; 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (status_profiler.IsError()) { 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_profiler; 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Status(kOk); 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::StartProfile() { 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_init = InitProfileInternal(); 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_init.IsError()) 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_init; 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return client_->SendCommand("Profiler.start", params); 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::EndProfile(scoped_ptr<base::Value>* profile_data) { 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<base::DictionaryValue> profile_result; 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status = client_->SendCommandAndGetResult( 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Profiler.stop", params, &profile_result); 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status.IsError()) { 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status disable_profile_status = StopProfileInternal(); 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (disable_profile_status.IsError()) { 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return disable_profile_status; 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return status; 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *profile_data = profile_result.PassAs<base::Value>(); 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status; 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunctionInternal(const std::string& frame, 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_user_supplied, 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue async_args; 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendString("return (" + function + ").apply(null, arguments);"); 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.Append(args.DeepCopy()); 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendBoolean(is_user_supplied); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendInteger(timeout.InMilliseconds()); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> tmp; 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction( 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, kExecuteAsyncScriptScript, async_args, &tmp); 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* kDocUnloadError = "document unloaded while waiting for result"; 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string kQueryResult = base::StringPrintf( 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "function() {" 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var info = document.$chrome_asyncScriptInfo;" 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!info)" 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: %d, value: '%s'};" 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var result = info.result;" 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!result)" 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: 0};" 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " delete info.result;" 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return result;" 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}", 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kJavaScriptError, 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDocUnloadError); 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue no_args; 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> query_value; 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction(frame, kQueryResult, no_args, &query_value); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) { 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.code() == kNoSuchFrame) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kJavaScriptError, kDocUnloadError); 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* result_info = NULL; 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!query_value->GetAsDictionary(&result_info)) 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info is not a dictionary"); 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int status_code; 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_info->GetInteger("status", &status_code)) 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info has no int 'status'"); 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status_code != kOk) { 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_info->GetString("value", &message); 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Value* value = NULL; 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result_info->Get("value", &value)) { 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->reset(value->DeepCopy()); 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id, 55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* is_not_pending) { 56090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_pending; 56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) navigation_tracker_->IsPendingNavigation(frame_id, &is_pending); 56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status.IsError()) 56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An alert may block the pending navigation. 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_pending && dialog_manager_->IsDialogOpen()) 56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnexpectedAlertOpen); 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *is_not_pending = !is_pending; 57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kOk); 57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScript(DevToolsClient* client, 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvaluateScriptReturnType return_type, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue>* result) { 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("expression", expression); 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_id) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("contextId", context_id); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("returnByValue", return_type == ReturnByValue); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client->SendCommandAndGetResult( 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate", params, &cmd_result); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_thrown; 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetBoolean("wasThrown", &was_thrown)) 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'wasThrown'"); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (was_thrown) { 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description = "unknown"; 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_result->GetString("result.description", &description); 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate threw exception: " + description); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* unscoped_result; 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetDictionary("result", &unscoped_result)) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "evaluate missing dictionary 'result'"); 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_result->DeepCopy()); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetObject(DevToolsClient* client, 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* got_object, 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* object_id) { 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByObject, 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &result); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result->HasKey("objectId")) { 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = false; 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("objectId", object_id)) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "evaluate has invalid 'objectId'"); 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = true; 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetValue(DevToolsClient* client, 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> temp_result; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByValue, 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &temp_result); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->GetString("type", &type)) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing string 'type'"); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == "undefined") { 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(base::Value::CreateNullValue()); 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value; 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->Get("value", &value)) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'value'"); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(value->DeepCopy()); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ParseCallFunctionResult(const base::Value& temp_result, 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result.GetAsDictionary(&dict)) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "call function result must be a dictionary"); 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int status_code; 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetInteger("status", &status_code)) { 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing int 'status'"); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_code != kOk) { 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->GetString("value", &message); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* unscoped_value; 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->Get("value", &unscoped_value)) { 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing 'value'"); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_value->DeepCopy()); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetNodeIdFromFunction(DevToolsClient* client, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* found_node, 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* node_id) { 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 685ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 687ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s, true])", 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_object; 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string element_id; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = internal::EvaluateScriptAndGetObject( 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client, context_id, expression, &got_object, &element_id); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_object) { 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = false; 700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = client->SendCommandAndGetResult( 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DOM.requestNode", params, &cmd_result); 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the remote object before doing anything else. 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status release_status = 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->SendCommand("Runtime.releaseObject", params); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (release_status.IsError()) { 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to release remote object: " 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << release_status.message(); 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetInteger("nodeId", node_id)) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DOM.requestNode missing int 'nodeId'"); 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = true; 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace internal 731