OLD | NEW |
| (Empty) |
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 | |
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 | |
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 | |
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 | |
65 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 | |
89 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 | |
111 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 | |
118 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 | |
142 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 | |
159 bool BrowserProxy::ApplyAccelerator(int id) { | |
160 return RunCommandAsync(id); | |
161 } | |
162 | |
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 | |
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 | |
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 | |
200 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 | |
213 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 | |
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 | |
237 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 | |
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 | |
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<base::Value> values(base::JSONReader::ReadAndReturnError( | |
296 json_response, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error)); | |
297 if (!error.empty() || values->GetType() != base::Value::TYPE_DICTIONARY) | |
298 return false; | |
299 | |
300 base::DictionaryValue* values_dict = | |
301 static_cast<base::DictionaryValue*>(values.get()); | |
302 | |
303 base::Value* tabs_value; | |
304 if (!values_dict->Get("tabs", &tabs_value) || | |
305 tabs_value->GetType() != base::Value::TYPE_LIST) | |
306 return false; | |
307 | |
308 base::ListValue* tabs_list = static_cast<base::ListValue*>(tabs_value); | |
309 | |
310 for (size_t i = 0; i < tabs_list->GetSize(); i++) { | |
311 float stop_ms = 0; | |
312 float start_ms = 0; | |
313 base::Value* tab_value; | |
314 base::DictionaryValue* tab_dict; | |
315 | |
316 if (!tabs_list->Get(i, &tab_value) || | |
317 tab_value->GetType() != base::Value::TYPE_DICTIONARY) | |
318 return false; | |
319 tab_dict = static_cast<base::DictionaryValue*>(tab_value); | |
320 | |
321 double temp; | |
322 if (!tab_dict->GetDouble("load_start_ms", &temp)) | |
323 return false; | |
324 start_ms = static_cast<float>(temp); | |
325 // load_stop_ms can only be null if WaitForInitialLoads did not run. | |
326 if (!tab_dict->GetDouble("load_stop_ms", &temp)) | |
327 return false; | |
328 stop_ms = static_cast<float>(temp); | |
329 | |
330 if (i == 0) | |
331 *min_start_time = start_ms; | |
332 | |
333 *min_start_time = std::min(start_ms, *min_start_time); | |
334 *max_stop_time = std::max(stop_ms, *max_stop_time); | |
335 stop_times->push_back(stop_ms); | |
336 } | |
337 std::sort(stop_times->begin(), stop_times->end()); | |
338 return true; | |
339 } | |
OLD | NEW |