15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_proxy.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_constants.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_json_requests.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/browser_proxy.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/tab_proxy.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/window_proxy.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_descriptors.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(port): Enable when dialog_delegate is ported. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_delegate.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kChannelErrorVersionString[] = "***CHANNEL_ERROR***"; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object allows messages received on the background thread to be 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// properly triaged. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutomationMessageFilter : public IPC::ChannelProxy::MessageFilter { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit AutomationMessageFilter(AutomationProxy* server) : server_(server) {} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return true to indicate that the message was handled, or false to let 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the message be handled in the default way. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(AutomationMessageFilter, message) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_GENERIC(AutomationMsg_Hello, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAutomationHello(message)) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_GENERIC( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationMsg_InitialLoadsComplete, server_->SignalInitialLoads()) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AutomationMsg_InitialNewTabUILoadComplete, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewTabLoaded) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_GENERIC( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationMsg_InvalidateHandle, server_->InvalidateHandle(message)) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->SetChannel(channel); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnFilterRemoved() OVERRIDE { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->ResetChannel(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnChannelError() OVERRIDE { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->SignalAppLaunch(kChannelErrorVersionString); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->SignalNewTabUITab(-1); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NewTabLoaded(int load_time) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->SignalNewTabUITab(load_time); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnAutomationHello(const IPC::Message& hello_message) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_version; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(hello_message); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hello_message.ReadString(&iter, &server_version)) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We got an AutomationMsg_Hello from an old automation provider 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that doesn't send version info. Leave server_version as an empty 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string to signal a version mismatch. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Pre-versioning protocol detected in automation provider."; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->SignalAppLaunch(server_version); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationProxy* server_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationProxy::AutomationProxy(base::TimeDelta action_timeout, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool disconnect_on_failure) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : app_launched_(true, false), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_loads_complete_(true, false), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_tab_ui_load_complete_(true, false), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_event_(new base::WaitableEvent(true, false)), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perform_version_check_(false), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disconnect_on_failure_(disconnect_on_failure), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_disconnected_on_failure_(false), 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action_timeout_(action_timeout), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_thread_id_(0) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // base::WaitableEvent::TimedWait() will choke if we give it a negative value. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Zero also seems unreasonable, since we need to wait for IPC, but at 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // least it is legal... ;-) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(action_timeout.InMilliseconds(), 0); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_thread_id_ = base::PlatformThread::CurrentId(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeHandleTracker(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeThread(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationProxy::~AutomationProxy() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destruction order is important. Thread has to outlive the channel and 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tracker has to outlive the thread since we access the tracker inside 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AutomationMessageFilter::OnMessageReceived. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Disconnect(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.reset(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_.reset(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string AutomationProxy::GenerateChannelID() { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The channel counter keeps us out of trouble if we create and destroy 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // several AutomationProxies sequentially over the course of a test run. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Creating the channel sometimes failed before when running a lot of 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tests in sequence, and our theory is that sometimes the channel ID 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wasn't getting freed up in time for the next test.) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int channel_counter = 0; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ostringstream buf; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf << "ChromeTestingInterface:" << base::GetCurrentProcId() << 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "." << ++channel_counter; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buf.str(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::InitializeThread() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Thread> thread( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::Thread("AutomationProxy_BackgroundThread")); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool thread_result = thread->StartWithOptions(options); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thread_result); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.swap(thread); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::InitializeChannel(const std::string& channel_id, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_named_interface) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(shutdown_event_.get() != NULL); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(iyengar) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The shutdown event could be global on the same lines as the automation 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provider, where we use the shutdown event provided by the chrome browser 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process. 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) channel_.reset(new IPC::SyncChannel(this, // we are the listener 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) thread_->message_loop_proxy().get(), 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shutdown_event_.get())); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(new AutomationMessageFilter(this)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the pipe synchronously so that Chrome doesn't try to connect to an 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unready server. Note this is done after adding a message filter to 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // guarantee that it doesn't miss any messages when we are the client. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See crbug.com/102894. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Init( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_named_interface ? IPC::Channel::MODE_NAMED_CLIENT 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : IPC::Channel::MODE_SERVER, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /* create_pipe_now */); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::InitializeHandleTracker() { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_.reset(new AutomationHandleTracker()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationLaunchResult AutomationProxy::WaitForAppLaunch() { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationLaunchResult result = AUTOMATION_SUCCESS; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_launched_.TimedWait(action_timeout_)) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (server_version_ == kChannelErrorVersionString) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = AUTOMATION_CHANNEL_ERROR; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (perform_version_check_) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain our own version number and compare it to what the automation 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provider sent. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(version_info.is_valid()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we use a simple string comparison since we expect the version 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be a punctuated numeric string. Consider using base/Version if we 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ever need something more complicated here. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (server_version_ != version_info.Version()) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = AUTOMATION_VERSION_MISMATCH; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = AUTOMATION_TIMEOUT; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::SignalAppLaunch(const std::string& version_string) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_version_ = version_string; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_launched_.Signal(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::WaitForProcessLauncherThreadToGoIdle() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new AutomationMsg_WaitForProcessLauncherThreadToGoIdle()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::WaitForInitialLoads() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return initial_loads_complete_.TimedWait(action_timeout_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::WaitForInitialNewTabUILoad(int* load_time) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_tab_ui_load_complete_.TimedWait(action_timeout_)) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *load_time = new_tab_ui_load_time_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_tab_ui_load_complete_.Reset(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::SignalInitialLoads() { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_loads_complete_.Signal(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::SignalNewTabUITab(int load_time) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_tab_ui_load_time_ = load_time; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_tab_ui_load_complete_.Signal(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::GetBrowserWindowCount(int* num_windows) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_windows) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new AutomationMsg_BrowserWindowCount(num_windows)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::GetNormalBrowserWindowCount(int* num_windows) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_windows) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new AutomationMsg_NormalBrowserWindowCount(num_windows)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::WaitForWindowCountToBecome(int count) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait_success = false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new AutomationMsg_WaitForBrowserWindowCountToBecome( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count, &wait_success))) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return wait_success; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::IsURLDisplayed(GURL url) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_count; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetBrowserWindowCount(&window_count)) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < window_count; i++) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<BrowserProxy> window = GetBrowserWindow(i); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window.get()) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_count; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window->GetTabCount(&tab_count)) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < tab_count; j++) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TabProxy> tab = window->GetTab(j); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab.get()) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL tab_url; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab->GetCurrentURL(&tab_url)) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_url == url) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::GetMetricEventDuration(const std::string& event_name, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* duration_ms) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new AutomationMsg_GetMetricEventDuration(event_name, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration_ms)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::SendProxyConfig(const std::string& new_proxy_config) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new AutomationMsg_SetProxyConfig(new_proxy_config)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::Disconnect() { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(shutdown_event_.get() != NULL); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_event_->Signal(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::OnMessageReceived(const IPC::Message& msg) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This won't get called unless AutomationProxy is run from 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inside a message loop. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::OnChannelError() { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Channel error in AutomationProxy."; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disconnect_on_failure_) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Disconnect(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<BrowserProxy> AutomationProxy::GetBrowserWindow( 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_index) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int handle = 0; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new AutomationMsg_BrowserWindow(window_index, &handle))) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProxyObjectFromHandle<BrowserProxy>(handle); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::SyncChannel* AutomationProxy::channel() { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_.get(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::Send(IPC::Message* message) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(message, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(action_timeout_.InMilliseconds())); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::Send(IPC::Message* message, int timeout_ms) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!channel_.get()) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Automation channel has been closed; dropping message!"; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = channel_->SendWithTimeout(message, timeout_ms); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success && disconnect_on_failure_) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send failed (possibly due to a timeout). Browser is likely in a weird 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // state, and further IPC requests are extremely likely to fail (possibly 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout, which would make tests slower). Disconnect the channel now 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to avoid the slowness. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_disconnected_on_failure_ = true; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Disconnecting channel after error!"; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Disconnect(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::InvalidateHandle(const IPC::Message& message) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(message); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int handle; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.ReadInt(&iter, &handle)) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_->InvalidateHandle(handle); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::OpenNewBrowserWindow(Browser::Type type, bool show) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AutomationMsg_OpenNewBrowserWindowOfType(static_cast<int>(type), 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> scoped_refptr<T> AutomationProxy::ProxyObjectFromHandle( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int handle) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handle) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get AddRef-ed pointer to the object if handle is already seen. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* p = static_cast<T*>(tracker_->GetResource(handle)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!p) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = new T(this, tracker_.get(), handle); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->AddRef(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since there is no scoped_refptr::attach. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<T> result; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.swap(&p); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::SetChannel(IPC::Channel* channel) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tracker_.get()) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_->put_channel(channel); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationProxy::ResetChannel() { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tracker_.get()) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_->put_channel(NULL); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool AutomationProxy::BeginTracing(const std::string& category_patterns) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = false; 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool send_success = Send(new AutomationMsg_BeginTracing(category_patterns, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &result)); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return send_success && result; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::EndTracing(std::string* json_trace_output) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_trace_chunks = 0; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new AutomationMsg_EndTracing(&num_trace_chunks, &success)) || 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !success) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string chunk; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceResultBuffer buffer; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceResultBuffer::SimpleOutput output; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.SetOutputCallback(output.GetCallback()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jbates): See bug 100255, IPC send fails if message is too big. This 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code can be simplified if that limitation is fixed. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Workaround IPC payload size limitation by getting chunks. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.Start(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_trace_chunks; ++i) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The broswer side AutomationProvider resets state at BeginTracing, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so it can recover even after this fails mid-way. 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new AutomationMsg_GetTracingOutput(&chunk, &success)) || 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !success) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.AddFragment(chunk); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.Finish(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *json_trace_output = output.json_output; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationProxy::SendJSONRequest(const std::string& request, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* response) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = false; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendAutomationJSONRequest(this, request, timeout_ms, response, &result)) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 450