OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/automation/testing_automation_provider.h" | 5 #include "chrome/browser/automation/testing_automation_provider.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "chrome/app/chrome_dll_resource.h" |
8 #include "chrome/browser/automation/automation_browser_tracker.h" | 9 #include "chrome/browser/automation/automation_browser_tracker.h" |
9 #include "chrome/browser/automation/automation_provider_list.h" | 10 #include "chrome/browser/automation/automation_provider_list.h" |
10 #include "chrome/browser/automation/automation_provider_observers.h" | 11 #include "chrome/browser/automation/automation_provider_observers.h" |
11 #include "chrome/browser/automation/automation_tab_tracker.h" | 12 #include "chrome/browser/automation/automation_tab_tracker.h" |
12 #include "chrome/browser/browser_window.h" | 13 #include "chrome/browser/browser_window.h" |
| 14 #include "chrome/browser/login_prompt.h" |
13 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
14 #include "chrome/common/net/url_request_context_getter.h" | 16 #include "chrome/common/net/url_request_context_getter.h" |
15 #include "chrome/common/notification_service.h" | 17 #include "chrome/common/notification_service.h" |
16 #include "chrome/test/automation/automation_messages.h" | 18 #include "chrome/test/automation/automation_messages.h" |
17 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 class GetCookiesTask : public Task { | 23 class GetCookiesTask : public Task { |
22 public: | 24 public: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 const std::string name_; | 119 const std::string name_; |
118 const scoped_refptr<URLRequestContextGetter> context_getter_; | 120 const scoped_refptr<URLRequestContextGetter> context_getter_; |
119 | 121 |
120 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask); | 122 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask); |
121 }; | 123 }; |
122 | 124 |
123 } // namespace | 125 } // namespace |
124 | 126 |
125 | 127 |
126 TestingAutomationProvider::TestingAutomationProvider(Profile* profile) | 128 TestingAutomationProvider::TestingAutomationProvider(Profile* profile) |
127 : AutomationProvider(profile) { | 129 : AutomationProvider(profile), |
| 130 redirect_query_(0) { |
128 BrowserList::AddObserver(this); | 131 BrowserList::AddObserver(this); |
129 registrar_.Add(this, NotificationType::SESSION_END, | 132 registrar_.Add(this, NotificationType::SESSION_END, |
130 NotificationService::AllSources()); | 133 NotificationService::AllSources()); |
131 } | 134 } |
132 | 135 |
133 TestingAutomationProvider::~TestingAutomationProvider() { | 136 TestingAutomationProvider::~TestingAutomationProvider() { |
134 BrowserList::RemoveObserver(this); | 137 BrowserList::RemoveObserver(this); |
135 } | 138 } |
136 | 139 |
137 void TestingAutomationProvider::OnMessageReceived( | 140 void TestingAutomationProvider::OnMessageReceived( |
138 const IPC::Message& message) { | 141 const IPC::Message& message) { |
139 IPC_BEGIN_MESSAGE_MAP(TestingAutomationProvider, message) | 142 IPC_BEGIN_MESSAGE_MAP(TestingAutomationProvider, message) |
140 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser) | 143 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser) |
141 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync, | 144 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync, |
142 CloseBrowserAsync) | 145 CloseBrowserAsync) |
143 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab) | 146 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab) |
144 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab) | 147 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab) |
145 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex) | 148 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex) |
146 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab) | 149 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab) |
147 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies) | 150 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies) |
148 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie) | 151 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie) |
149 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie) | 152 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie) |
150 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog, | 153 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog, |
151 ShowCollectedCookiesDialog) | 154 ShowCollectedCookiesDialog) |
152 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL) | 155 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL) |
153 IPC_MESSAGE_HANDLER_DELAY_REPLY( | 156 IPC_MESSAGE_HANDLER_DELAY_REPLY( |
154 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete, | 157 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete, |
155 NavigateToURLBlockUntilNavigationsComplete) | 158 NavigateToURLBlockUntilNavigationsComplete) |
| 159 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync) |
| 160 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition, |
| 161 NavigationAsyncWithDisposition) |
| 162 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack) |
| 163 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward) |
| 164 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload) |
| 165 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth) |
| 166 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth) |
| 167 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth) |
| 168 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom, |
| 169 GetRedirectsFrom) |
| 170 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount) |
| 171 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount, |
| 172 GetNormalBrowserWindowCount) |
156 | 173 |
157 IPC_MESSAGE_UNHANDLED(AutomationProvider::OnMessageReceived(message)); | 174 IPC_MESSAGE_UNHANDLED(AutomationProvider::OnMessageReceived(message)); |
158 IPC_END_MESSAGE_MAP() | 175 IPC_END_MESSAGE_MAP() |
159 } | 176 } |
160 | 177 |
161 void TestingAutomationProvider::OnChannelError() { | 178 void TestingAutomationProvider::OnChannelError() { |
162 BrowserList::CloseAllBrowsersAndExit(); | 179 BrowserList::CloseAllBrowsersAndExit(); |
163 AutomationProvider::OnChannelError(); | 180 AutomationProvider::OnChannelError(); |
164 } | 181 } |
165 | 182 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED); | 346 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED); |
330 return; | 347 return; |
331 } | 348 } |
332 } | 349 } |
333 | 350 |
334 AutomationMsg_NavigateToURL::WriteReplyParams( | 351 AutomationMsg_NavigateToURL::WriteReplyParams( |
335 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); | 352 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); |
336 Send(reply_message); | 353 Send(reply_message); |
337 } | 354 } |
338 | 355 |
| 356 void TestingAutomationProvider::NavigationAsync(int handle, |
| 357 const GURL& url, |
| 358 bool* status) { |
| 359 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status); |
| 360 } |
| 361 |
| 362 void TestingAutomationProvider::NavigationAsyncWithDisposition( |
| 363 int handle, |
| 364 const GURL& url, |
| 365 WindowOpenDisposition disposition, |
| 366 bool* status) { |
| 367 *status = false; |
| 368 |
| 369 if (tab_tracker_->ContainsHandle(handle)) { |
| 370 NavigationController* tab = tab_tracker_->GetResource(handle); |
| 371 |
| 372 // Simulate what a user would do. Activate the tab and then navigate. |
| 373 // We could allow navigating in a background tab in future. |
| 374 Browser* browser = FindAndActivateTab(tab); |
| 375 |
| 376 if (browser) { |
| 377 // Don't add any listener unless a callback mechanism is desired. |
| 378 // TODO(vibhor): Do this if such a requirement arises in future. |
| 379 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED); |
| 380 *status = true; |
| 381 } |
| 382 } |
| 383 } |
| 384 |
| 385 void TestingAutomationProvider::GoBack(int handle, |
| 386 IPC::Message* reply_message) { |
| 387 if (tab_tracker_->ContainsHandle(handle)) { |
| 388 NavigationController* tab = tab_tracker_->GetResource(handle); |
| 389 Browser* browser = FindAndActivateTab(tab); |
| 390 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) { |
| 391 AddNavigationStatusListener(tab, reply_message, 1, false); |
| 392 browser->GoBack(CURRENT_TAB); |
| 393 return; |
| 394 } |
| 395 } |
| 396 |
| 397 AutomationMsg_GoBack::WriteReplyParams( |
| 398 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); |
| 399 Send(reply_message); |
| 400 } |
| 401 |
| 402 void TestingAutomationProvider::GoForward(int handle, |
| 403 IPC::Message* reply_message) { |
| 404 if (tab_tracker_->ContainsHandle(handle)) { |
| 405 NavigationController* tab = tab_tracker_->GetResource(handle); |
| 406 Browser* browser = FindAndActivateTab(tab); |
| 407 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) { |
| 408 AddNavigationStatusListener(tab, reply_message, 1, false); |
| 409 browser->GoForward(CURRENT_TAB); |
| 410 return; |
| 411 } |
| 412 } |
| 413 |
| 414 AutomationMsg_GoForward::WriteReplyParams( |
| 415 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); |
| 416 Send(reply_message); |
| 417 } |
| 418 |
| 419 void TestingAutomationProvider::Reload(int handle, |
| 420 IPC::Message* reply_message) { |
| 421 if (tab_tracker_->ContainsHandle(handle)) { |
| 422 NavigationController* tab = tab_tracker_->GetResource(handle); |
| 423 Browser* browser = FindAndActivateTab(tab); |
| 424 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) { |
| 425 AddNavigationStatusListener(tab, reply_message, 1, false); |
| 426 browser->Reload(CURRENT_TAB); |
| 427 return; |
| 428 } |
| 429 } |
| 430 |
| 431 AutomationMsg_Reload::WriteReplyParams( |
| 432 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); |
| 433 Send(reply_message); |
| 434 } |
| 435 |
| 436 void TestingAutomationProvider::SetAuth(int tab_handle, |
| 437 const std::wstring& username, |
| 438 const std::wstring& password, |
| 439 IPC::Message* reply_message) { |
| 440 if (tab_tracker_->ContainsHandle(tab_handle)) { |
| 441 NavigationController* tab = tab_tracker_->GetResource(tab_handle); |
| 442 LoginHandlerMap::iterator iter = login_handler_map_.find(tab); |
| 443 |
| 444 if (iter != login_handler_map_.end()) { |
| 445 // If auth is needed again after this, assume login has failed. This is |
| 446 // not strictly correct, because a navigation can require both proxy and |
| 447 // server auth, but it should be OK for now. |
| 448 LoginHandler* handler = iter->second; |
| 449 AddNavigationStatusListener(tab, reply_message, 1, false); |
| 450 handler->SetAuth(username, password); |
| 451 return; |
| 452 } |
| 453 } |
| 454 |
| 455 AutomationMsg_SetAuth::WriteReplyParams( |
| 456 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED); |
| 457 Send(reply_message); |
| 458 } |
| 459 |
| 460 void TestingAutomationProvider::CancelAuth(int tab_handle, |
| 461 IPC::Message* reply_message) { |
| 462 if (tab_tracker_->ContainsHandle(tab_handle)) { |
| 463 NavigationController* tab = tab_tracker_->GetResource(tab_handle); |
| 464 LoginHandlerMap::iterator iter = login_handler_map_.find(tab); |
| 465 |
| 466 if (iter != login_handler_map_.end()) { |
| 467 // If auth is needed again after this, something is screwy. |
| 468 LoginHandler* handler = iter->second; |
| 469 AddNavigationStatusListener(tab, reply_message, 1, false); |
| 470 handler->CancelAuth(); |
| 471 return; |
| 472 } |
| 473 } |
| 474 |
| 475 AutomationMsg_CancelAuth::WriteReplyParams( |
| 476 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED); |
| 477 Send(reply_message); |
| 478 } |
| 479 |
| 480 void TestingAutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) { |
| 481 *needs_auth = false; |
| 482 |
| 483 if (tab_tracker_->ContainsHandle(tab_handle)) { |
| 484 NavigationController* tab = tab_tracker_->GetResource(tab_handle); |
| 485 LoginHandlerMap::iterator iter = login_handler_map_.find(tab); |
| 486 |
| 487 if (iter != login_handler_map_.end()) { |
| 488 // The LoginHandler will be in our map IFF the tab needs auth. |
| 489 *needs_auth = true; |
| 490 } |
| 491 } |
| 492 } |
| 493 |
| 494 void TestingAutomationProvider::GetRedirectsFrom(int tab_handle, |
| 495 const GURL& source_url, |
| 496 IPC::Message* reply_message) { |
| 497 DCHECK(!redirect_query_) << "Can only handle one redirect query at once."; |
| 498 if (tab_tracker_->ContainsHandle(tab_handle)) { |
| 499 NavigationController* tab = tab_tracker_->GetResource(tab_handle); |
| 500 HistoryService* history_service = |
| 501 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 502 |
| 503 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " << |
| 504 "has no history service"; |
| 505 if (history_service) { |
| 506 DCHECK(reply_message_ == NULL); |
| 507 reply_message_ = reply_message; |
| 508 // Schedule a history query for redirects. The response will be sent |
| 509 // asynchronously from the callback the history system uses to notify us |
| 510 // that it's done: OnRedirectQueryComplete. |
| 511 redirect_query_ = history_service->QueryRedirectsFrom( |
| 512 source_url, &consumer_, |
| 513 NewCallback(this, |
| 514 &TestingAutomationProvider::OnRedirectQueryComplete)); |
| 515 return; // Response will be sent when query completes. |
| 516 } |
| 517 } |
| 518 |
| 519 // Send failure response. |
| 520 std::vector<GURL> empty; |
| 521 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty); |
| 522 Send(reply_message); |
| 523 } |
| 524 |
| 525 void TestingAutomationProvider::GetBrowserWindowCount(int* window_count) { |
| 526 *window_count = static_cast<int>(BrowserList::size()); |
| 527 } |
| 528 |
| 529 void TestingAutomationProvider::GetNormalBrowserWindowCount(int* window_count) { |
| 530 *window_count = static_cast<int>( |
| 531 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL)); |
| 532 } |
| 533 |
| 534 // TODO(brettw) change this to accept GURLs when history supports it |
| 535 void TestingAutomationProvider::OnRedirectQueryComplete( |
| 536 HistoryService::Handle request_handle, |
| 537 GURL from_url, |
| 538 bool success, |
| 539 history::RedirectList* redirects) { |
| 540 DCHECK(request_handle == redirect_query_); |
| 541 DCHECK(reply_message_ != NULL); |
| 542 |
| 543 std::vector<GURL> redirects_gurl; |
| 544 reply_message_->WriteBool(success); |
| 545 if (success) { |
| 546 for (size_t i = 0; i < redirects->size(); i++) |
| 547 redirects_gurl.push_back(redirects->at(i)); |
| 548 } |
| 549 |
| 550 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl); |
| 551 |
| 552 Send(reply_message_); |
| 553 redirect_query_ = 0; |
| 554 reply_message_ = NULL; |
| 555 } |
| 556 |
339 void TestingAutomationProvider::OnBrowserAdded(const Browser* browser) { | 557 void TestingAutomationProvider::OnBrowserAdded(const Browser* browser) { |
340 } | 558 } |
341 | 559 |
342 void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) { | 560 void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) { |
343 // For backwards compatibility with the testing automation interface, we | 561 // For backwards compatibility with the testing automation interface, we |
344 // want the automation provider (and hence the process) to go away when the | 562 // want the automation provider (and hence the process) to go away when the |
345 // last browser goes away. | 563 // last browser goes away. |
346 if (BrowserList::size() == 1 && !CommandLine::ForCurrentProcess()->HasSwitch( | 564 if (BrowserList::size() == 1 && !CommandLine::ForCurrentProcess()->HasSwitch( |
347 switches::kKeepAliveForTest)) { | 565 switches::kKeepAliveForTest)) { |
348 // If you change this, update Observer for NotificationType::SESSION_END | 566 // If you change this, update Observer for NotificationType::SESSION_END |
349 // below. | 567 // below. |
350 MessageLoop::current()->PostTask(FROM_HERE, | 568 MessageLoop::current()->PostTask(FROM_HERE, |
351 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider)); | 569 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider)); |
352 } | 570 } |
353 } | 571 } |
354 | 572 |
355 void TestingAutomationProvider::Observe(NotificationType type, | 573 void TestingAutomationProvider::Observe(NotificationType type, |
356 const NotificationSource& source, | 574 const NotificationSource& source, |
357 const NotificationDetails& details) { | 575 const NotificationDetails& details) { |
358 DCHECK(type == NotificationType::SESSION_END); | 576 DCHECK(type == NotificationType::SESSION_END); |
359 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit | 577 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit |
360 // before the task runs resulting in this object not being deleted. This | 578 // before the task runs resulting in this object not being deleted. This |
361 // Release balance out the Release scheduled by OnBrowserRemoving. | 579 // Release balance out the Release scheduled by OnBrowserRemoving. |
362 Release(); | 580 Release(); |
363 } | 581 } |
364 | 582 |
365 void TestingAutomationProvider::OnRemoveProvider() { | 583 void TestingAutomationProvider::OnRemoveProvider() { |
366 AutomationProviderList::GetInstance()->RemoveProvider(this); | 584 AutomationProviderList::GetInstance()->RemoveProvider(this); |
367 } | 585 } |
OLD | NEW |