• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/test/automation/browser_proxy.h"
6 
7 #include <algorithm>
8 
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"
19 
20 using base::TimeDelta;
21 using base::TimeTicks;
22 
ActivateTab(int tab_index)23 bool BrowserProxy::ActivateTab(int tab_index) {
24   if (!is_valid())
25     return false;
26 
27   int activate_tab_response = -1;
28 
29   if (!sender_->Send(new AutomationMsg_ActivateTab(
30                          handle_, tab_index, &activate_tab_response))) {
31     return false;
32   }
33 
34   if (activate_tab_response >= 0)
35     return true;
36 
37   return false;
38 }
39 
BringToFront()40 bool BrowserProxy::BringToFront() {
41   if (!is_valid())
42     return false;
43 
44   bool succeeded = false;
45 
46   if (!sender_->Send(new AutomationMsg_BringBrowserToFront(
47                          handle_, &succeeded))) {
48     return false;
49   }
50 
51   return succeeded;
52 }
53 
AppendTab(const GURL & tab_url)54 bool BrowserProxy::AppendTab(const GURL& tab_url) {
55   if (!is_valid())
56     return false;
57 
58   int append_tab_response = -1;
59 
60   sender_->Send(new AutomationMsg_AppendTab(handle_, tab_url,
61                                             &append_tab_response));
62   return append_tab_response >= 0;
63 }
64 
GetActiveTabIndex(int * active_tab_index) const65 bool BrowserProxy::GetActiveTabIndex(int* active_tab_index) const {
66   if (!is_valid())
67     return false;
68 
69   if (!active_tab_index) {
70     NOTREACHED();
71     return false;
72   }
73 
74   int active_tab_index_response = -1;
75 
76   if (!sender_->Send(new AutomationMsg_ActiveTabIndex(
77                          handle_, &active_tab_index_response))) {
78     return false;
79   }
80 
81   if (active_tab_index_response >= 0) {
82     *active_tab_index = active_tab_index_response;
83     return true;
84   }
85 
86   return false;
87 }
88 
GetTab(int tab_index) const89 scoped_refptr<TabProxy> BrowserProxy::GetTab(int tab_index) const {
90   if (!is_valid())
91     return NULL;
92 
93   int tab_handle = 0;
94 
95   sender_->Send(new AutomationMsg_Tab(handle_, tab_index, &tab_handle));
96   if (!tab_handle)
97     return NULL;
98 
99   TabProxy* tab = static_cast<TabProxy*>(tracker_->GetResource(tab_handle));
100   if (!tab) {
101     tab = new TabProxy(sender_, tracker_, tab_handle);
102     tab->AddRef();
103   }
104 
105   // Since there is no scoped_refptr::attach.
106   scoped_refptr<TabProxy> result;
107   result.swap(&tab);
108   return result;
109 }
110 
GetActiveTab() const111 scoped_refptr<TabProxy> BrowserProxy::GetActiveTab() const {
112   int active_tab_index;
113   if (!GetActiveTabIndex(&active_tab_index))
114     return NULL;
115   return GetTab(active_tab_index);
116 }
117 
GetTabCount(int * num_tabs) const118 bool BrowserProxy::GetTabCount(int* num_tabs) const {
119   if (!is_valid())
120     return false;
121 
122   if (!num_tabs) {
123     NOTREACHED();
124     return false;
125   }
126 
127   int tab_count_response = -1;
128 
129   if (!sender_->Send(new AutomationMsg_TabCount(
130                          handle_, &tab_count_response))) {
131     return false;
132   }
133 
134   if (tab_count_response >= 0) {
135     *num_tabs = tab_count_response;
136     return true;
137   }
138 
139   return false;
140 }
141 
GetType(Browser::Type * type) const142 bool BrowserProxy::GetType(Browser::Type* type) const {
143   if (!is_valid())
144     return false;
145 
146   if (!type) {
147     NOTREACHED();
148     return false;
149   }
150 
151   int type_as_int;
152   if (!sender_->Send(new AutomationMsg_Type(handle_, &type_as_int)))
153     return false;
154 
155   *type = static_cast<Browser::Type>(type_as_int);
156   return true;
157 }
158 
ApplyAccelerator(int id)159 bool BrowserProxy::ApplyAccelerator(int id) {
160   return RunCommandAsync(id);
161 }
162 
WaitForTabCountToBecome(int count)163 bool BrowserProxy::WaitForTabCountToBecome(int count) {
164   bool success = false;
165   if (!sender_->Send(new AutomationMsg_WaitForTabCountToBecome(
166                          handle_, count, &success))) {
167     return false;
168   }
169 
170   return success;
171 }
172 
WaitForTabToBecomeActive(int tab,base::TimeDelta wait_timeout)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));
179     int active_tab;
180     if (GetActiveTabIndex(&active_tab) && active_tab == tab)
181       return true;
182   }
183   // If we get here, the active tab hasn't changed.
184   return false;
185 }
186 
IsFindWindowFullyVisible(bool * is_visible)187 bool BrowserProxy::IsFindWindowFullyVisible(bool* is_visible) {
188   if (!is_valid())
189     return false;
190 
191   if (!is_visible) {
192     NOTREACHED();
193     return false;
194   }
195 
196   return sender_->Send(
197       new AutomationMsg_FindWindowVisibility(handle_, is_visible));
198 }
199 
RunCommandAsync(int browser_command) const200 bool BrowserProxy::RunCommandAsync(int browser_command) const {
201   if (!is_valid())
202     return false;
203 
204   bool result = false;
205 
206   sender_->Send(new AutomationMsg_WindowExecuteCommandAsync(handle_,
207                                                             browser_command,
208                                                             &result));
209 
210   return result;
211 }
212 
RunCommand(int browser_command) const213 bool BrowserProxy::RunCommand(int browser_command) const {
214   if (!is_valid())
215     return false;
216 
217   bool result = false;
218 
219   sender_->Send(new AutomationMsg_WindowExecuteCommand(handle_,
220                                                        browser_command,
221                                                        &result));
222 
223   return result;
224 }
225 
TerminateSession()226 bool BrowserProxy::TerminateSession() {
227   if (!is_valid())
228     return false;
229 
230   bool result = false;
231 
232   sender_->Send(new AutomationMsg_TerminateSession(handle_, &result));
233 
234   return result;
235 }
236 
GetWindow() const237 scoped_refptr<WindowProxy> BrowserProxy::GetWindow() const {
238   if (!is_valid())
239     return NULL;
240 
241   bool handle_ok = false;
242   int window_handle = 0;
243 
244   sender_->Send(new AutomationMsg_WindowForBrowser(handle_, &handle_ok,
245                                                    &window_handle));
246   if (!handle_ok)
247     return NULL;
248 
249   WindowProxy* window =
250       static_cast<WindowProxy*>(tracker_->GetResource(window_handle));
251   if (!window) {
252     window = new WindowProxy(sender_, tracker_, window_handle);
253     window->AddRef();
254   }
255 
256   // Since there is no scoped_refptr::attach.
257   scoped_refptr<WindowProxy> result;
258   result.swap(&window);
259   return result;
260 }
261 
SendJSONRequest(const std::string & request,int timeout_ms,std::string * response)262 bool BrowserProxy::SendJSONRequest(const std::string& request,
263                                    int timeout_ms,
264                                    std::string* response) {
265   if (!is_valid())
266     return false;
267 
268   bool result = false;
269   if (!sender_->Send(
270       new AutomationMsg_SendJSONRequestWithBrowserHandle(handle_,
271                                                          request,
272                                                          response,
273                                                          &result),
274                                                          timeout_ms))
275     return false;
276   return result;
277 }
278 
GetInitialLoadTimes(base::TimeDelta timeout,float * min_start_time,float * max_stop_time,std::vector<float> * stop_times)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\"}";
285 
286   *max_stop_time = 0;
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.
292     return false;
293   }
294   std::string error;
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)
298     return false;
299 
300   DictionaryValue* values_dict = static_cast<DictionaryValue*>(values.get());
301 
302   Value* tabs_value;
303   if (!values_dict->Get("tabs", &tabs_value) ||
304       tabs_value->GetType() != Value::TYPE_LIST)
305     return false;
306 
307   ListValue* tabs_list = static_cast<ListValue*>(tabs_value);
308 
309   for (size_t i = 0; i < tabs_list->GetSize(); i++) {
310     float stop_ms = 0;
311     float start_ms = 0;
312     Value* tab_value;
313     DictionaryValue* tab_dict;
314 
315     if (!tabs_list->Get(i, &tab_value) ||
316         tab_value->GetType() != Value::TYPE_DICTIONARY)
317       return false;
318     tab_dict = static_cast<DictionaryValue*>(tab_value);
319 
320     double temp;
321     if (!tab_dict->GetDouble("load_start_ms", &temp))
322       return false;
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))
326       return false;
327     stop_ms = static_cast<float>(temp);
328 
329     if (i == 0)
330       *min_start_time = start_ms;
331 
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);
335   }
336   std::sort(stop_times->begin(), stop_times->end());
337   return true;
338 }
339