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/browser_proxy.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_constants.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_proxy.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/tab_proxy.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/window_proxy.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::ActivateTab(int tab_index) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int activate_tab_response = -1;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_ActivateTab(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle_, tab_index, &activate_tab_response))) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (activate_tab_response >= 0)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::BringToFront() {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool succeeded = false;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_BringBrowserToFront(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle_, &succeeded))) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return succeeded;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::AppendTab(const GURL& tab_url) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int append_tab_response = -1;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_AppendTab(handle_, tab_url,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            &append_tab_response));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return append_tab_response >= 0;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::GetActiveTabIndex(int* active_tab_index) const {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!active_tab_index) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_tab_index_response = -1;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_ActiveTabIndex(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle_, &active_tab_index_response))) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (active_tab_index_response >= 0) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *active_tab_index = active_tab_index_response;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<TabProxy> BrowserProxy::GetTab(int tab_index) const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab_handle = 0;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_Tab(handle_, tab_index, &tab_handle));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!tab_handle)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabProxy* tab = static_cast<TabProxy*>(tracker_->GetResource(tab_handle));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!tab) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab = new TabProxy(sender_, tracker_, tab_handle);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab->AddRef();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since there is no scoped_refptr::attach.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> result;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.swap(&tab);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<TabProxy> BrowserProxy::GetActiveTab() const {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_tab_index;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetActiveTabIndex(&active_tab_index))
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetTab(active_tab_index);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::GetTabCount(int* num_tabs) const {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!num_tabs) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab_count_response = -1;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_TabCount(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle_, &tab_count_response))) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tab_count_response >= 0) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *num_tabs = tab_count_response;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::GetType(Browser::Type* type) const {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!type) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int type_as_int;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_Type(handle_, &type_as_int)))
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *type = static_cast<Browser::Type>(type_as_int);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::ApplyAccelerator(int id) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RunCommandAsync(id);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::WaitForTabCountToBecome(int count) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(new AutomationMsg_WaitForTabCountToBecome(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle_, count, &success))) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::WaitForTabToBecomeActive(int tab,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            base::TimeDelta wait_timeout) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeTicks start = TimeTicks::Now();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (TimeTicks::Now() - start < wait_timeout) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(automation::kSleepTime));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int active_tab;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GetActiveTabIndex(&active_tab) && active_tab == tab)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we get here, the active tab hasn't changed.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::IsFindWindowFullyVisible(bool* is_visible) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_visible) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sender_->Send(
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new AutomationMsg_FindWindowVisibility(handle_, is_visible));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::RunCommandAsync(int browser_command) const {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_WindowExecuteCommandAsync(handle_,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            browser_command,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            &result));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::RunCommand(int browser_command) const {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_WindowExecuteCommand(handle_,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       browser_command,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &result));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::TerminateSession() {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_TerminateSession(handle_, &result));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<WindowProxy> BrowserProxy::GetWindow() const {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handle_ok = false;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_handle = 0;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new AutomationMsg_WindowForBrowser(handle_, &handle_ok,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &window_handle));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!handle_ok)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowProxy* window =
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<WindowProxy*>(tracker_->GetResource(window_handle));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window = new WindowProxy(sender_, tracker_, window_handle);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->AddRef();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since there is no scoped_refptr::attach.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<WindowProxy> result;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.swap(&window);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::SendJSONRequest(const std::string& request,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int timeout_ms,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   std::string* response) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid())
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sender_->Send(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new AutomationMsg_SendJSONRequestWithBrowserHandle(handle_,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         request,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         response,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &result),
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         timeout_ms))
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserProxy::GetInitialLoadTimes(base::TimeDelta timeout,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       float* min_start_time,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       float* max_stop_time,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::vector<float>* stop_times) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json_response;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kJSONCommand = "{\"command\": \"GetInitialLoadTimes\"}";
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *max_stop_time = 0;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *min_start_time = -1;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendJSONRequest(
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kJSONCommand, timeout.InMilliseconds(), &json_response)) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Older browser versions do not support GetInitialLoadTimes.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fail gracefully and do not record them in this case.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Value> values(base::JSONReader::ReadAndReturnError(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      json_response, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!error.empty() || values->GetType() != Value::TYPE_DICTIONARY)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* values_dict = static_cast<DictionaryValue*>(values.get());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* tabs_value;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!values_dict->Get("tabs", &tabs_value) ||
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabs_value->GetType() != Value::TYPE_LIST)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListValue* tabs_list = static_cast<ListValue*>(tabs_value);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < tabs_list->GetSize(); i++) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float stop_ms = 0;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float start_ms = 0;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Value* tab_value;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* tab_dict;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tabs_list->Get(i, &tab_value) ||
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab_value->GetType() != Value::TYPE_DICTIONARY)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_dict = static_cast<DictionaryValue*>(tab_value);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double temp;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tab_dict->GetDouble("load_start_ms", &temp))
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start_ms = static_cast<float>(temp);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // load_stop_ms can only be null if WaitForInitialLoads did not run.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tab_dict->GetDouble("load_stop_ms", &temp))
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stop_ms = static_cast<float>(temp);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i == 0)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *min_start_time = start_ms;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *min_start_time = std::min(start_ms, *min_start_time);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *max_stop_time = std::max(stop_ms, *max_stop_time);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stop_times->push_back(stop_ms);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(stop_times->begin(), stop_times->end());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
339