| 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 |