web_view_impl.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/navigation_tracker.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetContextIdForFrame(FrameTracker* tracker, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& frame, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* context_id) { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame.empty()) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *context_id = 0; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = tracker->GetContextIdForFrame(frame, context_id); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseEventType type) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kPressedMouseEventType: 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mousePressed"; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kReleasedMouseEventType: 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseReleased"; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMovedMouseEventType: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseMoved"; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetAsString(TouchEventType type) { 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchStart: 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchStart"; 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchEnd: 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchEnd"; 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchMove: 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchMove"; 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char* GetPointStateString(TouchEventType type) { 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (type) { 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchStart: 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchPressed"; 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchEnd: 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchReleased"; 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case kTouchMove: 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return "touchMoved"; 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ""; 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseButton button) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (button) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kLeftMouseButton: 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "left"; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMiddleMouseButton: 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "middle"; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRightMouseButton: 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "right"; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kNoneMouseButton: 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "none"; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(KeyEventType type) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyDownEventType: 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyDown"; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyUpEventType: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyUp"; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRawKeyDownEventType: 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "rawKeyDown"; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kCharEventType: 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "char"; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::WebViewImpl(const std::string& id, 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int build_no, 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<DevToolsClient> client) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch build_no_(build_no), 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dom_tracker_(new DomTracker(client.get())), 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame_tracker_(new FrameTracker(client.get())), 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) navigation_tracker_(new NavigationTracker(client.get())), 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dialog_manager_(new JavaScriptDialogManager(client.get())), 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) geolocation_override_manager_( 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new GeolocationOverrideManager(client.get())), 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) heap_snapshot_taker_(new HeapSnapshotTaker(client.get())), 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) debugger_(new DebuggerTracker(client.get())), 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_(client.release()) {} 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::~WebViewImpl() {} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string WebViewImpl::GetId() { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id_; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WebViewImpl::WasCrashed() { 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return client_->WasCrashed(); 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::ConnectIfNecessary() { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->ConnectIfNecessary(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::HandleReceivedEvents() { 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return client_->HandleReceivedEvents(); 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Load(const std::string& url) { 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Javascript URLs will cause a hang while waiting for the page to stop 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // loading, so just disallow. 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(url, "javascript:", false)) 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnknownError, "unsupported protocol"); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.navigate", params); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Reload() { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("ignoreCache", false); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.reload", params); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::EvaluateScript(const std::string& frame, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::EvaluateScriptAndGetValue( 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.get(), context_id, expression, result); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CallFunction(const std::string& frame, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s])", 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> temp_result; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(frame, expression, &temp_result); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::ParseCallFunctionResult(*temp_result, result); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunction(const std::string& frame, 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, false, timeout, result); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallUserAsyncFunction(const std::string& frame, 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, true, timeout, result); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetFrameByFunction(const std::string& frame, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* out_frame) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int node_id; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, function, args, &found_node, &node_id); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kNoSuchFrame); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dom_tracker_->GetFrameIdForNode(node_id, out_frame); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochStatus WebViewImpl::DispatchMouseEvents(const std::list<MouseEvent>& events, 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& frame) { 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<MouseEvent>::const_iterator it = events.begin(); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("x", it->x); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("y", it->y); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("button", GetAsString(it->button)); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("clickCount", it->click_count); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchMouseEvent", params); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (build_no_ < 1569 && it->button == kRightMouseButton && 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch it->type == kReleasedMouseEventType) { 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::ListValue args; 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->x); 251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->y); 252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->modifiers); 253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Value> result; 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = CallFunction( 255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch frame, kDispatchContextMenuEventScript, args, &result); 256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (status.IsError()) 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status; 258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Status WebViewImpl::DispatchTouchEvent(const TouchEvent& event) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue params; 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.SetString("type", GetAsString(event.type)); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> point_list(new base::ListValue); 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> point(new base::DictionaryValue); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetString("state", GetPointStateString(event.type)); 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("x", event.x); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point->SetInteger("y", event.y); 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) point_list->Set(0, point.release()); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.Set("touchPoints", point_list.release()); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return client_->SendCommand("Input.dispatchTouchEvent", params); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 276d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochStatus WebViewImpl::DispatchTouchEvents(const std::list<TouchEvent>& events) { 277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (std::list<TouchEvent>::const_iterator it = events.begin(); 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch it != events.end(); ++it) { 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Status status = DispatchTouchEvent(*it); 280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (status.IsError()) 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return status; 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Status(kOk); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchKeyEvents(const std::list<KeyEvent>& events) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<KeyEvent>::const_iterator it = events.begin(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->modifiers & kNumLockKeyModifierMask) { 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("isKeypad", true); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->modifiers & ~kNumLockKeyModifierMask); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("text", it->modified_text); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("unmodifiedText", it->unmodified_text); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("nativeVirtualKeyCode", it->key_code); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("windowsVirtualKeyCode", it->key_code); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchKeyEvent", params); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetCookies(scoped_ptr<base::ListValue>* cookies) { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.getCookies", params, &result); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* cookies_tmp; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetList("cookies", &cookies_tmp)) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DevTools didn't return cookies"); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cookies->reset(cookies_tmp->DeepCopy()); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DeleteCookie(const std::string& name, 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url) { 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("cookieName", name); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.deleteCookie", params); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id, 332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::TimeDelta& timeout, 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool stop_load_on_timeout) { 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Waiting for pending navigations..."; 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = client_->HandleEventsUntil( 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Unretained(this), 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) timeout); 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (status.code() == kTimeout && stop_load_on_timeout) { 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Timed out. Stopping navigation..."; 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> unused_value; 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EvaluateScript(std::string(), "window.stop();", &unused_value); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Status new_status = client_->HandleEventsUntil( 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::TimeDelta::FromSeconds(10)); 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_status.IsError()) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status = new_status; 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(0) << "Done waiting for pending navigations"; 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::IsPendingNavigation(const std::string& frame_id, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_pending) { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return navigation_tracker_->IsPendingNavigation(frame_id, is_pending); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dialog_manager_.get(); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) { 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return geolocation_override_manager_->OverrideGeolocation(geoposition); 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CaptureScreenshot(std::string* screenshot) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.captureScreenshot", params, &result); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("data", screenshot)) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "expected string 'data' in response"); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::SetFileInputFiles( 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& frame, 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& element, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<base::FilePath>& files) { 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue file_list; 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < files.size(); ++i) { 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!files[i].IsAbsolute()) { 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not absolute: " + files[i].AsUTF8Unsafe()); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (files[i].ReferencesParent()) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not canonical: " + files[i].AsUTF8Unsafe()); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_list.AppendString(files[i].value()); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int context_id; 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &context_id); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue args; 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.Append(element.DeepCopy()); 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int node_id; 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, "function(element) { return element; }", 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args, &found_node, &node_id); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "no node ID for file input"); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue params; 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("nodeId", node_id); 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.Set("files", file_list.DeepCopy()); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_->SendCommand("DOM.setFileInputFiles", params); 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Status WebViewImpl::TakeHeapSnapshot(scoped_ptr<base::Value>* snapshot) { 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return heap_snapshot_taker_->TakeSnapshot(snapshot); 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunctionInternal(const std::string& frame, 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_user_supplied, 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue async_args; 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendString("return (" + function + ").apply(null, arguments);"); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.Append(args.DeepCopy()); 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendBoolean(is_user_supplied); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendInteger(timeout.InMilliseconds()); 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> tmp; 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction( 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, kExecuteAsyncScriptScript, async_args, &tmp); 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* kDocUnloadError = "document unloaded while waiting for result"; 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string kQueryResult = base::StringPrintf( 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "function() {" 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var info = document.$chrome_asyncScriptInfo;" 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!info)" 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: %d, value: '%s'};" 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var result = info.result;" 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!result)" 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: 0};" 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " delete info.result;" 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return result;" 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}", 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kJavaScriptError, 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDocUnloadError); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue no_args; 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> query_value; 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction(frame, kQueryResult, no_args, &query_value); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) { 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.code() == kNoSuchFrame) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kJavaScriptError, kDocUnloadError); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* result_info = NULL; 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!query_value->GetAsDictionary(&result_info)) 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info is not a dictionary"); 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int status_code; 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_info->GetInteger("status", &status_code)) 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info has no int 'status'"); 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status_code != kOk) { 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_info->GetString("value", &message); 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Value* value = NULL; 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result_info->Get("value", &value)) { 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->reset(value->DeepCopy()); 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id, 48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* is_not_pending) { 48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_pending; 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) navigation_tracker_->IsPendingNavigation(frame_id, &is_pending); 49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status.IsError()) 49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An alert may block the pending navigation. 49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_pending && dialog_manager_->IsDialogOpen()) 49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnexpectedAlertOpen); 49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *is_not_pending = !is_pending; 49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kOk); 50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScript(DevToolsClient* client, 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvaluateScriptReturnType return_type, 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue>* result) { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("expression", expression); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_id) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("contextId", context_id); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("returnByValue", return_type == ReturnByValue); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client->SendCommandAndGetResult( 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate", params, &cmd_result); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_thrown; 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetBoolean("wasThrown", &was_thrown)) 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'wasThrown'"); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (was_thrown) { 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description = "unknown"; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_result->GetString("result.description", &description); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate threw exception: " + description); 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* unscoped_result; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetDictionary("result", &unscoped_result)) 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "evaluate missing dictionary 'result'"); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_result->DeepCopy()); 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetObject(DevToolsClient* client, 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* got_object, 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* object_id) { 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByObject, 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &result); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result->HasKey("objectId")) { 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = false; 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("objectId", object_id)) 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "evaluate has invalid 'objectId'"); 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = true; 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetValue(DevToolsClient* client, 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> temp_result; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByValue, 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &temp_result); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->GetString("type", &type)) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing string 'type'"); 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == "undefined") { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(base::Value::CreateNullValue()); 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->Get("value", &value)) 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'value'"); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(value->DeepCopy()); 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ParseCallFunctionResult(const base::Value& temp_result, 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict; 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result.GetAsDictionary(&dict)) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "call function result must be a dictionary"); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int status_code; 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetInteger("status", &status_code)) { 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing int 'status'"); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_code != kOk) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->GetString("value", &message); 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* unscoped_value; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->Get("value", &unscoped_value)) { 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing 'value'"); 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_value->DeepCopy()); 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetNodeIdFromFunction(DevToolsClient* client, 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* found_node, 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* node_id) { 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 614ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(zachconrad): Second null should be array of shadow host ids. 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(%s).apply(null, [null, %s, %s, true])", 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_object; 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string element_id; 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = internal::EvaluateScriptAndGetObject( 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client, context_id, expression, &got_object, &element_id); 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_object) { 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = false; 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = client->SendCommandAndGetResult( 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DOM.requestNode", params, &cmd_result); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the remote object before doing anything else. 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status release_status = 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->SendCommand("Runtime.releaseObject", params); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (release_status.IsError()) { 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to release remote object: " 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << release_status.message(); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetInteger("nodeId", node_id)) 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DOM.requestNode missing int 'nodeId'"); 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = true; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace internal 660