| 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/tab_proxy.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/json/json_string_value_serializer.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/strings/string16.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "base/threading/platform_thread.h" | |
| 14 #include "chrome/common/automation_constants.h" | |
| 15 #include "chrome/common/automation_messages.h" | |
| 16 #include "chrome/test/automation/automation_proxy.h" | |
| 17 #include "chrome/test/automation/browser_proxy.h" | |
| 18 #include "url/gurl.h" | |
| 19 | |
| 20 TabProxy::TabProxy(AutomationMessageSender* sender, | |
| 21 AutomationHandleTracker* tracker, | |
| 22 int handle) | |
| 23 : AutomationResourceProxy(tracker, sender, handle) { | |
| 24 } | |
| 25 | |
| 26 bool TabProxy::GetTabTitle(std::wstring* title) const { | |
| 27 if (!is_valid()) | |
| 28 return false; | |
| 29 | |
| 30 if (!title) { | |
| 31 NOTREACHED(); | |
| 32 return false; | |
| 33 } | |
| 34 | |
| 35 int tab_title_size_response = 0; | |
| 36 | |
| 37 bool succeeded = sender_->Send( | |
| 38 new AutomationMsg_TabTitle(handle_, &tab_title_size_response, title)); | |
| 39 return succeeded; | |
| 40 } | |
| 41 | |
| 42 bool TabProxy::GetTabIndex(int* index) const { | |
| 43 if (!is_valid()) | |
| 44 return false; | |
| 45 | |
| 46 if (!index) { | |
| 47 NOTREACHED(); | |
| 48 return false; | |
| 49 } | |
| 50 | |
| 51 return sender_->Send(new AutomationMsg_TabIndex(handle_, index)); | |
| 52 } | |
| 53 | |
| 54 int TabProxy::FindInPage(const std::wstring& search_string, | |
| 55 FindInPageDirection forward, | |
| 56 FindInPageCase match_case, | |
| 57 bool find_next, | |
| 58 int* ordinal) { | |
| 59 if (!is_valid()) | |
| 60 return -1; | |
| 61 | |
| 62 AutomationMsg_Find_Params params; | |
| 63 params.search_string = base::WideToUTF16Hack(search_string); | |
| 64 params.find_next = find_next; | |
| 65 params.match_case = (match_case == CASE_SENSITIVE); | |
| 66 params.forward = (forward == FWD); | |
| 67 | |
| 68 int matches = 0; | |
| 69 int ordinal2 = 0; | |
| 70 bool succeeded = sender_->Send(new AutomationMsg_Find(handle_, | |
| 71 params, | |
| 72 &ordinal2, | |
| 73 &matches)); | |
| 74 if (!succeeded) | |
| 75 return -1; | |
| 76 if (ordinal) | |
| 77 *ordinal = ordinal2; | |
| 78 return matches; | |
| 79 } | |
| 80 | |
| 81 AutomationMsg_NavigationResponseValues TabProxy::NavigateToURL( | |
| 82 const GURL& url) { | |
| 83 return NavigateToURLBlockUntilNavigationsComplete(url, 1); | |
| 84 } | |
| 85 | |
| 86 AutomationMsg_NavigationResponseValues | |
| 87 TabProxy::NavigateToURLBlockUntilNavigationsComplete( | |
| 88 const GURL& url, int number_of_navigations) { | |
| 89 if (!is_valid()) | |
| 90 return AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 91 | |
| 92 AutomationMsg_NavigationResponseValues navigate_response = | |
| 93 AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 94 | |
| 95 sender_->Send(new AutomationMsg_NavigateToURLBlockUntilNavigationsComplete( | |
| 96 handle_, url, number_of_navigations, &navigate_response)); | |
| 97 | |
| 98 return navigate_response; | |
| 99 } | |
| 100 | |
| 101 AutomationMsg_NavigationResponseValues TabProxy::GoBack() { | |
| 102 return GoBackBlockUntilNavigationsComplete(1); | |
| 103 } | |
| 104 | |
| 105 AutomationMsg_NavigationResponseValues | |
| 106 TabProxy::GoBackBlockUntilNavigationsComplete(int number_of_navigations) { | |
| 107 if (!is_valid()) | |
| 108 return AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 109 | |
| 110 AutomationMsg_NavigationResponseValues navigate_response = | |
| 111 AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 112 sender_->Send(new AutomationMsg_GoBackBlockUntilNavigationsComplete( | |
| 113 handle_, number_of_navigations, &navigate_response)); | |
| 114 return navigate_response; | |
| 115 } | |
| 116 | |
| 117 AutomationMsg_NavigationResponseValues TabProxy::GoForward() { | |
| 118 return GoForwardBlockUntilNavigationsComplete(1); | |
| 119 } | |
| 120 | |
| 121 AutomationMsg_NavigationResponseValues | |
| 122 TabProxy::GoForwardBlockUntilNavigationsComplete( | |
| 123 int number_of_navigations) { | |
| 124 if (!is_valid()) | |
| 125 return AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 126 | |
| 127 AutomationMsg_NavigationResponseValues navigate_response = | |
| 128 AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 129 sender_->Send(new AutomationMsg_GoForwardBlockUntilNavigationsComplete( | |
| 130 handle_, number_of_navigations, &navigate_response)); | |
| 131 return navigate_response; | |
| 132 } | |
| 133 | |
| 134 AutomationMsg_NavigationResponseValues TabProxy::Reload() { | |
| 135 if (!is_valid()) | |
| 136 return AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 137 | |
| 138 AutomationMsg_NavigationResponseValues navigate_response = | |
| 139 AUTOMATION_MSG_NAVIGATION_ERROR; | |
| 140 sender_->Send(new AutomationMsg_Reload(handle_, &navigate_response)); | |
| 141 return navigate_response; | |
| 142 } | |
| 143 | |
| 144 bool TabProxy::GetCurrentURL(GURL* url) const { | |
| 145 if (!is_valid()) | |
| 146 return false; | |
| 147 | |
| 148 if (!url) { | |
| 149 NOTREACHED(); | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 bool succeeded = false; | |
| 154 sender_->Send(new AutomationMsg_TabURL(handle_, &succeeded, url)); | |
| 155 return succeeded; | |
| 156 } | |
| 157 | |
| 158 bool TabProxy::NavigateToURLAsync(const GURL& url) { | |
| 159 if (!is_valid()) | |
| 160 return false; | |
| 161 | |
| 162 bool status = false; | |
| 163 sender_->Send(new AutomationMsg_NavigationAsync(handle_, | |
| 164 url, | |
| 165 &status)); | |
| 166 return status; | |
| 167 } | |
| 168 | |
| 169 bool TabProxy::ExecuteAndExtractString(const std::wstring& frame_xpath, | |
| 170 const std::wstring& jscript, | |
| 171 std::wstring* string_value) { | |
| 172 scoped_ptr<base::Value> root(ExecuteAndExtractValue(frame_xpath, jscript)); | |
| 173 if (root == NULL) | |
| 174 return false; | |
| 175 | |
| 176 DCHECK(root->IsType(base::Value::TYPE_LIST)); | |
| 177 base::Value* value = NULL; | |
| 178 bool succeeded = static_cast<base::ListValue*>(root.get())->Get(0, &value); | |
| 179 if (succeeded) { | |
| 180 base::string16 read_value; | |
| 181 succeeded = value->GetAsString(&read_value); | |
| 182 if (succeeded) { | |
| 183 // TODO(viettrungluu): remove conversion. (But should |jscript| be UTF-8?) | |
| 184 *string_value = base::UTF16ToWideHack(read_value); | |
| 185 } | |
| 186 } | |
| 187 return succeeded; | |
| 188 } | |
| 189 | |
| 190 bool TabProxy::ExecuteAndExtractBool(const std::wstring& frame_xpath, | |
| 191 const std::wstring& jscript, | |
| 192 bool* bool_value) { | |
| 193 scoped_ptr<base::Value> root(ExecuteAndExtractValue(frame_xpath, jscript)); | |
| 194 if (root == NULL) | |
| 195 return false; | |
| 196 | |
| 197 bool read_value = false; | |
| 198 DCHECK(root->IsType(base::Value::TYPE_LIST)); | |
| 199 base::Value* value = NULL; | |
| 200 bool succeeded = static_cast<base::ListValue*>(root.get())->Get(0, &value); | |
| 201 if (succeeded) { | |
| 202 succeeded = value->GetAsBoolean(&read_value); | |
| 203 if (succeeded) { | |
| 204 *bool_value = read_value; | |
| 205 } | |
| 206 } | |
| 207 return succeeded; | |
| 208 } | |
| 209 | |
| 210 bool TabProxy::ExecuteAndExtractInt(const std::wstring& frame_xpath, | |
| 211 const std::wstring& jscript, | |
| 212 int* int_value) { | |
| 213 scoped_ptr<base::Value> root(ExecuteAndExtractValue(frame_xpath, jscript)); | |
| 214 if (root == NULL) | |
| 215 return false; | |
| 216 | |
| 217 int read_value = 0; | |
| 218 DCHECK(root->IsType(base::Value::TYPE_LIST)); | |
| 219 base::Value* value = NULL; | |
| 220 bool succeeded = static_cast<base::ListValue*>(root.get())->Get(0, &value); | |
| 221 if (succeeded) { | |
| 222 succeeded = value->GetAsInteger(&read_value); | |
| 223 if (succeeded) { | |
| 224 *int_value = read_value; | |
| 225 } | |
| 226 } | |
| 227 return succeeded; | |
| 228 } | |
| 229 | |
| 230 base::Value* TabProxy::ExecuteAndExtractValue(const std::wstring& frame_xpath, | |
| 231 const std::wstring& jscript) { | |
| 232 if (!is_valid()) | |
| 233 return NULL; | |
| 234 | |
| 235 std::string json; | |
| 236 if (!sender_->Send(new AutomationMsg_DomOperation(handle_, frame_xpath, | |
| 237 jscript, &json))) { | |
| 238 return NULL; | |
| 239 } | |
| 240 // Wrap |json| in an array before deserializing because valid JSON has an | |
| 241 // array or an object as the root. | |
| 242 json.insert(0, "["); | |
| 243 json.append("]"); | |
| 244 | |
| 245 JSONStringValueSerializer deserializer(json); | |
| 246 return deserializer.Deserialize(NULL, NULL); | |
| 247 } | |
| 248 | |
| 249 bool TabProxy::GetCookies(const GURL& url, std::string* cookies) { | |
| 250 if (!is_valid()) | |
| 251 return false; | |
| 252 | |
| 253 int size = 0; | |
| 254 return sender_->Send(new AutomationMsg_GetCookies(url, handle_, &size, | |
| 255 cookies)); | |
| 256 } | |
| 257 | |
| 258 bool TabProxy::GetCookieByName(const GURL& url, | |
| 259 const std::string& name, | |
| 260 std::string* cookie) { | |
| 261 std::string cookies; | |
| 262 if (!GetCookies(url, &cookies)) | |
| 263 return false; | |
| 264 | |
| 265 std::string namestr = name + "="; | |
| 266 std::string::size_type idx = cookies.find(namestr); | |
| 267 if (idx != std::string::npos) { | |
| 268 cookies.erase(0, idx + namestr.length()); | |
| 269 *cookie = cookies.substr(0, cookies.find(";")); | |
| 270 } else { | |
| 271 cookie->clear(); | |
| 272 } | |
| 273 | |
| 274 return true; | |
| 275 } | |
| 276 | |
| 277 bool TabProxy::Close() { | |
| 278 return Close(false); | |
| 279 } | |
| 280 | |
| 281 bool TabProxy::Close(bool wait_until_closed) { | |
| 282 if (!is_valid()) | |
| 283 return false; | |
| 284 | |
| 285 bool succeeded = false; | |
| 286 sender_->Send(new AutomationMsg_CloseTab(handle_, wait_until_closed, | |
| 287 &succeeded)); | |
| 288 return succeeded; | |
| 289 } | |
| 290 | |
| 291 bool TabProxy::WaitForInfoBarCount(size_t target_count) { | |
| 292 if (!is_valid()) | |
| 293 return false; | |
| 294 | |
| 295 bool success = false; | |
| 296 return sender_->Send(new AutomationMsg_WaitForInfoBarCount( | |
| 297 handle_, target_count, &success)) && success; | |
| 298 } | |
| 299 | |
| 300 bool TabProxy::OverrideEncoding(const std::string& encoding) { | |
| 301 if (!is_valid()) | |
| 302 return false; | |
| 303 | |
| 304 bool succeeded = false; | |
| 305 sender_->Send(new AutomationMsg_OverrideEncoding(handle_, encoding, | |
| 306 &succeeded)); | |
| 307 return succeeded; | |
| 308 } | |
| 309 | |
| 310 | |
| 311 void TabProxy::ReloadAsync() { | |
| 312 sender_->Send(new AutomationMsg_ReloadAsync(handle_)); | |
| 313 } | |
| 314 | |
| 315 void TabProxy::StopAsync() { | |
| 316 sender_->Send(new AutomationMsg_StopAsync(handle_)); | |
| 317 } | |
| 318 | |
| 319 void TabProxy::JavaScriptStressTestControl(int cmd, int param) { | |
| 320 if (!is_valid()) | |
| 321 return; | |
| 322 | |
| 323 sender_->Send(new AutomationMsg_JavaScriptStressTestControl( | |
| 324 handle_, cmd, param)); | |
| 325 } | |
| 326 | |
| 327 void TabProxy::AddObserver(TabProxyDelegate* observer) { | |
| 328 base::AutoLock lock(list_lock_); | |
| 329 observers_list_.AddObserver(observer); | |
| 330 } | |
| 331 | |
| 332 void TabProxy::RemoveObserver(TabProxyDelegate* observer) { | |
| 333 base::AutoLock lock(list_lock_); | |
| 334 observers_list_.RemoveObserver(observer); | |
| 335 } | |
| 336 | |
| 337 // Called on Channel background thread, if TabMessages filter is installed. | |
| 338 bool TabProxy::OnMessageReceived(const IPC::Message& message) { | |
| 339 base::AutoLock lock(list_lock_); | |
| 340 FOR_EACH_OBSERVER(TabProxyDelegate, observers_list_, | |
| 341 OnMessageReceived(this, message)); | |
| 342 return true; | |
| 343 } | |
| 344 | |
| 345 void TabProxy::OnChannelError() { | |
| 346 base::AutoLock lock(list_lock_); | |
| 347 FOR_EACH_OBSERVER(TabProxyDelegate, observers_list_, OnChannelError(this)); | |
| 348 } | |
| 349 | |
| 350 TabProxy::~TabProxy() {} | |
| 351 | |
| 352 void TabProxy::FirstObjectAdded() { | |
| 353 AddRef(); | |
| 354 } | |
| 355 | |
| 356 void TabProxy::LastObjectRemoved() { | |
| 357 Release(); | |
| 358 } | |
| OLD | NEW |