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" 16ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch#include "chrome/test/chromedriver/chrome/browser_info.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/debugger_tracker.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_client_impl.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/dom_tracker.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/frame_tracker.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/geolocation_override_manager.h" 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/heap_snapshot_taker.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/js.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/navigation_tracker.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.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_( 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new MobileEmulationOverrideManager(client.get(), 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_metrics, 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_info)), 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) geolocation_override_manager_( 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new GeolocationOverrideManager(client.get())), 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) heap_snapshot_taker_(new HeapSnapshotTaker(client.get())), 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) debugger_(new DebuggerTracker(client.get())), 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_(client.release()) {} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::~WebViewImpl() {} 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string WebViewImpl::GetId() { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id_; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WebViewImpl::WasCrashed() { 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return client_->WasCrashed(); 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::ConnectIfNecessary() { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->ConnectIfNecessary(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::HandleReceivedEvents() { 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return client_->HandleReceivedEvents(); 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Load(const std::string& url) { 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Javascript URLs will cause a hang while waiting for the page to stop 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // loading, so just disallow. 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(url, "javascript:", false)) 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnknownError, "unsupported protocol"); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.navigate", params); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Reload() { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("ignoreCache", false); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.reload", params); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::EvaluateScript(const std::string& frame, 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::EvaluateScriptAndGetValue( 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.get(), context_id, expression, result); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CallFunction(const std::string& frame, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s])", 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> temp_result; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(frame, expression, &temp_result); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::ParseCallFunctionResult(*temp_result, result); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunction(const std::string& frame, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, false, timeout, result); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallUserAsyncFunction(const std::string& frame, 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, true, timeout, result); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetFrameByFunction(const std::string& frame, 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* out_frame) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int node_id; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, function, args, &found_node, &node_id); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kNoSuchFrame); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dom_tracker_->GetFrameIdForNode(node_id, out_frame); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochStatus WebViewImpl::DispatchMouseEvents(const std::list<MouseEvent>& events, 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& frame) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<MouseEvent>::const_iterator it = events.begin(); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("x", it->x); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("y", it->y); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("button", GetAsString(it->button)); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("clickCount", it->click_count); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchMouseEvent", params); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (browser_info_->build_no < 1569 && it->button == kRightMouseButton && 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch it->type == kReleasedMouseEventType) { 256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::ListValue args; 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->x); 258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->y); 259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->modifiers); 260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Value> result; 261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = CallFunction( 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch frame, kDispatchContextMenuEventScript, args, &result); 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (status.IsError()) 264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status; 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Status WebViewImpl::DispatchTouchEvent(const TouchEvent& event) { 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.SetString("type", GetAsString(event.type)); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> point_list(new base::ListValue); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> point(new base::DictionaryValue); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetString("state", GetPointStateString(event.type)); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("x", event.x); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("y", event.y); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point_list->Set(0, point.release()); 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.Set("touchPoints", point_list.release()); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return client_->SendCommand("Input.dispatchTouchEvent", params); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 283d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochStatus WebViewImpl::DispatchTouchEvents(const std::list<TouchEvent>& events) { 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (std::list<TouchEvent>::const_iterator it = events.begin(); 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch it != events.end(); ++it) { 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Status status = DispatchTouchEvent(*it); 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (status.IsError()) 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return status; 289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Status(kOk); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchKeyEvents(const std::list<KeyEvent>& events) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<KeyEvent>::const_iterator it = events.begin(); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->modifiers & kNumLockKeyModifierMask) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("isKeypad", true); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->modifiers & ~kNumLockKeyModifierMask); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("text", it->modified_text); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("unmodifiedText", it->unmodified_text); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("nativeVirtualKeyCode", it->key_code); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("windowsVirtualKeyCode", it->key_code); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchKeyEvent", params); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetCookies(scoped_ptr<base::ListValue>* cookies) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.getCookies", params, &result); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* cookies_tmp; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetList("cookies", &cookies_tmp)) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DevTools didn't return cookies"); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cookies->reset(cookies_tmp->DeepCopy()); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DeleteCookie(const std::string& name, 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url) { 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("cookieName", name); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.deleteCookie", params); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id, 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::TimeDelta& timeout, 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool stop_load_on_timeout) { 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Waiting for pending navigations..."; 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = client_->HandleEventsUntil( 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, 344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Unretained(this), 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) timeout); 347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (status.code() == kTimeout && stop_load_on_timeout) { 34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Timed out. Stopping navigation..."; 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> unused_value; 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EvaluateScript(std::string(), "window.stop();", &unused_value); 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Status new_status = client_->HandleEventsUntil( 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::TimeDelta::FromSeconds(10)); 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_status.IsError()) 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status = new_status; 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Done waiting for pending navigations"; 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::IsPendingNavigation(const std::string& frame_id, 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_pending) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return navigation_tracker_->IsPendingNavigation(frame_id, is_pending); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dialog_manager_.get(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) { 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return geolocation_override_manager_->OverrideGeolocation(geoposition); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CaptureScreenshot(std::string* screenshot) { 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.captureScreenshot", params, &result); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("data", screenshot)) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "expected string 'data' in response"); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::SetFileInputFiles( 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& frame, 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& element, 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<base::FilePath>& files) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue file_list; 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < files.size(); ++i) { 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!files[i].IsAbsolute()) { 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not absolute: " + files[i].AsUTF8Unsafe()); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (files[i].ReferencesParent()) { 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not canonical: " + files[i].AsUTF8Unsafe()); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_list.AppendString(files[i].value()); 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int context_id; 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &context_id); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue args; 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.Append(element.DeepCopy()); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int node_id; 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, "function(element) { return element; }", 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args, &found_node, &node_id); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "no node ID for file input"); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue params; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("nodeId", node_id); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.Set("files", file_list.DeepCopy()); 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_->SendCommand("DOM.setFileInputFiles", params); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Status WebViewImpl::TakeHeapSnapshot(scoped_ptr<base::Value>* snapshot) { 427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return heap_snapshot_taker_->TakeSnapshot(snapshot); 428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::InitProfileInternal() { 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO: Remove Debugger.enable after Chrome 36 stable is released. 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debug = client_->SendCommand("Debugger.enable", params); 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_debug.IsError()) 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debug; 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_profiler = client_->SendCommand("Profiler.enable", params); 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_profiler.IsError()) { 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debugger = client_->SendCommand("Debugger.disable", params); 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_debugger.IsError()) 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debugger; 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_profiler; 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Status(kOk); 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::StopProfileInternal() { 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_debug = client_->SendCommand("Debugger.disable", params); 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_profiler = client_->SendCommand("Profiler.disable", params); 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (status_debug.IsError()) { 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_debug; 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (status_profiler.IsError()) { 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_profiler; 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Status(kOk); 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::StartProfile() { 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status_init = InitProfileInternal(); 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status_init.IsError()) 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status_init; 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return client_->SendCommand("Profiler.start", params); 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Status WebViewImpl::EndProfile(scoped_ptr<base::Value>* profile_data) { 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue params; 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<base::DictionaryValue> profile_result; 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status status = client_->SendCommandAndGetResult( 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Profiler.stop", params, &profile_result); 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status.IsError()) { 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Status disable_profile_status = StopProfileInternal(); 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (disable_profile_status.IsError()) { 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return disable_profile_status; 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return status; 48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *profile_data = profile_result.PassAs<base::Value>(); 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status; 494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunctionInternal(const std::string& frame, 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_user_supplied, 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue async_args; 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendString("return (" + function + ").apply(null, arguments);"); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.Append(args.DeepCopy()); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendBoolean(is_user_supplied); 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendInteger(timeout.InMilliseconds()); 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> tmp; 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction( 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, kExecuteAsyncScriptScript, async_args, &tmp); 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* kDocUnloadError = "document unloaded while waiting for result"; 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string kQueryResult = base::StringPrintf( 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "function() {" 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var info = document.$chrome_asyncScriptInfo;" 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!info)" 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: %d, value: '%s'};" 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var result = info.result;" 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!result)" 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: 0};" 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " delete info.result;" 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return result;" 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}", 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kJavaScriptError, 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDocUnloadError); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue no_args; 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> query_value; 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction(frame, kQueryResult, no_args, &query_value); 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) { 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.code() == kNoSuchFrame) 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kJavaScriptError, kDocUnloadError); 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* result_info = NULL; 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!query_value->GetAsDictionary(&result_info)) 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info is not a dictionary"); 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int status_code; 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_info->GetInteger("status", &status_code)) 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info has no int 'status'"); 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status_code != kOk) { 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_info->GetString("value", &message); 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Value* value = NULL; 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result_info->Get("value", &value)) { 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->reset(value->DeepCopy()); 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id, 56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* is_not_pending) { 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_pending; 56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = 56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) navigation_tracker_->IsPendingNavigation(frame_id, &is_pending); 56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status.IsError()) 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An alert may block the pending navigation. 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_pending && dialog_manager_->IsDialogOpen()) 56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnexpectedAlertOpen); 57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *is_not_pending = !is_pending; 57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kOk); 57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScript(DevToolsClient* client, 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvaluateScriptReturnType return_type, 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue>* result) { 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("expression", expression); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_id) 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("contextId", context_id); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("returnByValue", return_type == ReturnByValue); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client->SendCommandAndGetResult( 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate", params, &cmd_result); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_thrown; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetBoolean("wasThrown", &was_thrown)) 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'wasThrown'"); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (was_thrown) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description = "unknown"; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_result->GetString("result.description", &description); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate threw exception: " + description); 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* unscoped_result; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetDictionary("result", &unscoped_result)) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "evaluate missing dictionary 'result'"); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_result->DeepCopy()); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetObject(DevToolsClient* client, 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* got_object, 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* object_id) { 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByObject, 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &result); 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result->HasKey("objectId")) { 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = false; 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("objectId", object_id)) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "evaluate has invalid 'objectId'"); 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = true; 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetValue(DevToolsClient* client, 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> temp_result; 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByValue, 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &temp_result); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->GetString("type", &type)) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing string 'type'"); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == "undefined") { 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(base::Value::CreateNullValue()); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value; 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->Get("value", &value)) 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'value'"); 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(value->DeepCopy()); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ParseCallFunctionResult(const base::Value& temp_result, 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result.GetAsDictionary(&dict)) 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "call function result must be a dictionary"); 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int status_code; 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetInteger("status", &status_code)) { 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing int 'status'"); 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_code != kOk) { 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->GetString("value", &message); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* unscoped_value; 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->Get("value", &unscoped_value)) { 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing 'value'"); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_value->DeepCopy()); 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetNodeIdFromFunction(DevToolsClient* client, 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* found_node, 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* node_id) { 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 687ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 689ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s, true])", 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_object; 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string element_id; 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = internal::EvaluateScriptAndGetObject( 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client, context_id, expression, &got_object, &element_id); 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_object) { 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = false; 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = client->SendCommandAndGetResult( 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DOM.requestNode", params, &cmd_result); 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the remote object before doing anything else. 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status release_status = 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->SendCommand("Runtime.releaseObject", params); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (release_status.IsError()) { 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to release remote object: " 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << release_status.message(); 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetInteger("nodeId", node_id)) 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DOM.requestNode missing int 'nodeId'"); 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = true; 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace internal 733