1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/automation/browser_proxy.h"
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "base/threading/platform_thread.h"
12 #include "base/time/time.h"
13 #include "chrome/common/automation_constants.h"
14 #include "chrome/common/automation_messages.h"
15 #include "chrome/test/automation/automation_proxy.h"
16 #include "chrome/test/automation/tab_proxy.h"
17 #include "chrome/test/automation/window_proxy.h"
18 #include "ui/gfx/point.h"
20 using base::TimeDelta
;
21 using base::TimeTicks
;
23 bool BrowserProxy::ActivateTab(int tab_index
) {
27 int activate_tab_response
= -1;
29 if (!sender_
->Send(new AutomationMsg_ActivateTab(
30 handle_
, tab_index
, &activate_tab_response
))) {
34 if (activate_tab_response
>= 0)
40 bool BrowserProxy::BringToFront() {
44 bool succeeded
= false;
46 if (!sender_
->Send(new AutomationMsg_BringBrowserToFront(
47 handle_
, &succeeded
))) {
54 bool BrowserProxy::AppendTab(const GURL
& tab_url
) {
58 int append_tab_response
= -1;
60 sender_
->Send(new AutomationMsg_AppendTab(handle_
, tab_url
,
61 &append_tab_response
));
62 return append_tab_response
>= 0;
65 bool BrowserProxy::GetActiveTabIndex(int* active_tab_index
) const {
69 if (!active_tab_index
) {
74 int active_tab_index_response
= -1;
76 if (!sender_
->Send(new AutomationMsg_ActiveTabIndex(
77 handle_
, &active_tab_index_response
))) {
81 if (active_tab_index_response
>= 0) {
82 *active_tab_index
= active_tab_index_response
;
89 scoped_refptr
<TabProxy
> BrowserProxy::GetTab(int tab_index
) const {
95 sender_
->Send(new AutomationMsg_Tab(handle_
, tab_index
, &tab_handle
));
99 TabProxy
* tab
= static_cast<TabProxy
*>(tracker_
->GetResource(tab_handle
));
101 tab
= new TabProxy(sender_
, tracker_
, tab_handle
);
105 // Since there is no scoped_refptr::attach.
106 scoped_refptr
<TabProxy
> result
;
111 scoped_refptr
<TabProxy
> BrowserProxy::GetActiveTab() const {
112 int active_tab_index
;
113 if (!GetActiveTabIndex(&active_tab_index
))
115 return GetTab(active_tab_index
);
118 bool BrowserProxy::GetTabCount(int* num_tabs
) const {
127 int tab_count_response
= -1;
129 if (!sender_
->Send(new AutomationMsg_TabCount(
130 handle_
, &tab_count_response
))) {
134 if (tab_count_response
>= 0) {
135 *num_tabs
= tab_count_response
;
142 bool BrowserProxy::GetType(Browser::Type
* type
) const {
152 if (!sender_
->Send(new AutomationMsg_Type(handle_
, &type_as_int
)))
155 *type
= static_cast<Browser::Type
>(type_as_int
);
159 bool BrowserProxy::ApplyAccelerator(int id
) {
160 return RunCommandAsync(id
);
163 bool BrowserProxy::WaitForTabCountToBecome(int count
) {
164 bool success
= false;
165 if (!sender_
->Send(new AutomationMsg_WaitForTabCountToBecome(
166 handle_
, count
, &success
))) {
173 bool BrowserProxy::WaitForTabToBecomeActive(int tab
,
174 base::TimeDelta wait_timeout
) {
175 const TimeTicks start
= TimeTicks::Now();
176 while (TimeTicks::Now() - start
< wait_timeout
) {
177 base::PlatformThread::Sleep(
178 base::TimeDelta::FromMilliseconds(automation::kSleepTime
));
180 if (GetActiveTabIndex(&active_tab
) && active_tab
== tab
)
183 // If we get here, the active tab hasn't changed.
187 bool BrowserProxy::IsFindWindowFullyVisible(bool* is_visible
) {
196 return sender_
->Send(
197 new AutomationMsg_FindWindowVisibility(handle_
, is_visible
));
200 bool BrowserProxy::RunCommandAsync(int browser_command
) const {
206 sender_
->Send(new AutomationMsg_WindowExecuteCommandAsync(handle_
,
213 bool BrowserProxy::RunCommand(int browser_command
) const {
219 sender_
->Send(new AutomationMsg_WindowExecuteCommand(handle_
,
226 bool BrowserProxy::TerminateSession() {
232 sender_
->Send(new AutomationMsg_TerminateSession(handle_
, &result
));
237 scoped_refptr
<WindowProxy
> BrowserProxy::GetWindow() const {
241 bool handle_ok
= false;
242 int window_handle
= 0;
244 sender_
->Send(new AutomationMsg_WindowForBrowser(handle_
, &handle_ok
,
249 WindowProxy
* window
=
250 static_cast<WindowProxy
*>(tracker_
->GetResource(window_handle
));
252 window
= new WindowProxy(sender_
, tracker_
, window_handle
);
256 // Since there is no scoped_refptr::attach.
257 scoped_refptr
<WindowProxy
> result
;
258 result
.swap(&window
);
262 bool BrowserProxy::SendJSONRequest(const std::string
& request
,
264 std::string
* response
) {
270 new AutomationMsg_SendJSONRequestWithBrowserHandle(handle_
,
279 bool BrowserProxy::GetInitialLoadTimes(base::TimeDelta timeout
,
280 float* min_start_time
,
281 float* max_stop_time
,
282 std::vector
<float>* stop_times
) {
283 std::string json_response
;
284 const char* kJSONCommand
= "{\"command\": \"GetInitialLoadTimes\"}";
287 *min_start_time
= -1;
288 if (!SendJSONRequest(
289 kJSONCommand
, timeout
.InMilliseconds(), &json_response
)) {
290 // Older browser versions do not support GetInitialLoadTimes.
291 // Fail gracefully and do not record them in this case.
295 scoped_ptr
<Value
> values(base::JSONReader::ReadAndReturnError(
296 json_response
, base::JSON_ALLOW_TRAILING_COMMAS
, NULL
, &error
));
297 if (!error
.empty() || values
->GetType() != Value::TYPE_DICTIONARY
)
300 DictionaryValue
* values_dict
= static_cast<DictionaryValue
*>(values
.get());
303 if (!values_dict
->Get("tabs", &tabs_value
) ||
304 tabs_value
->GetType() != Value::TYPE_LIST
)
307 ListValue
* tabs_list
= static_cast<ListValue
*>(tabs_value
);
309 for (size_t i
= 0; i
< tabs_list
->GetSize(); i
++) {
313 DictionaryValue
* tab_dict
;
315 if (!tabs_list
->Get(i
, &tab_value
) ||
316 tab_value
->GetType() != Value::TYPE_DICTIONARY
)
318 tab_dict
= static_cast<DictionaryValue
*>(tab_value
);
321 if (!tab_dict
->GetDouble("load_start_ms", &temp
))
323 start_ms
= static_cast<float>(temp
);
324 // load_stop_ms can only be null if WaitForInitialLoads did not run.
325 if (!tab_dict
->GetDouble("load_stop_ms", &temp
))
327 stop_ms
= static_cast<float>(temp
);
330 *min_start_time
= start_ms
;
332 *min_start_time
= std::min(start_ms
, *min_start_time
);
333 *max_stop_time
= std::max(stop_ms
, *max_stop_time
);
334 stop_times
->push_back(stop_ms
);
336 std::sort(stop_times
->begin(), stop_times
->end());