Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: chrome/browser/automation/automation_provider.cc

Issue 176004: Move observers out of automation_provider.cc to declutter the file. (Closed)
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/automation/automation_provider_observers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/automation_provider.h" 5 #include "chrome/browser/automation/automation_provider.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "app/message_box_flags.h" 10 #include "app/message_box_flags.h"
11 #include "base/file_version_info.h" 11 #include "base/file_version_info.h"
12 #include "base/json_reader.h" 12 #include "base/json_reader.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/stl_util-inl.h" 15 #include "base/stl_util-inl.h"
16 #include "base/string_util.h" 16 #include "base/string_util.h"
17 #include "base/thread.h" 17 #include "base/thread.h"
18 #include "base/values.h" 18 #include "base/values.h"
19 #include "chrome/app/chrome_dll_resource.h" 19 #include "chrome/app/chrome_dll_resource.h"
20 #include "chrome/browser/app_modal_dialog.h" 20 #include "chrome/browser/app_modal_dialog.h"
21 #include "chrome/browser/app_modal_dialog_queue.h" 21 #include "chrome/browser/app_modal_dialog_queue.h"
22 #include "chrome/browser/automation/automation_extension_function.h" 22 #include "chrome/browser/automation/automation_extension_function.h"
23 #include "chrome/browser/automation/automation_provider_list.h" 23 #include "chrome/browser/automation/automation_provider_list.h"
24 #include "chrome/browser/automation/automation_provider_observers.h"
24 #include "chrome/browser/automation/extension_automation_constants.h" 25 #include "chrome/browser/automation/extension_automation_constants.h"
25 #include "chrome/browser/automation/extension_port_container.h" 26 #include "chrome/browser/automation/extension_port_container.h"
26 #include "chrome/browser/blocked_popup_container.h" 27 #include "chrome/browser/blocked_popup_container.h"
27 #include "chrome/browser/browser_process.h" 28 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/browser_window.h" 29 #include "chrome/browser/browser_window.h"
29 #include "chrome/browser/dom_operation_notification_details.h" 30 #include "chrome/browser/dom_operation_notification_details.h"
30 #include "chrome/browser/debugger/devtools_manager.h" 31 #include "chrome/browser/debugger/devtools_manager.h"
31 #include "chrome/browser/download/download_manager.h" 32 #include "chrome/browser/download/download_manager.h"
32 #include "chrome/browser/download/download_shelf.h" 33 #include "chrome/browser/download/download_shelf.h"
33 #include "chrome/browser/extensions/extension_message_service.h" 34 #include "chrome/browser/extensions/extension_message_service.h"
(...skipping 29 matching lines...) Expand all
63 #include "chrome/browser/printing/print_job.h" 64 #include "chrome/browser/printing/print_job.h"
64 #endif // defined(OS_WIN) 65 #endif // defined(OS_WIN)
65 66
66 #if !defined(OS_MACOSX) 67 #if !defined(OS_MACOSX)
67 // TODO(port): Port these to the mac. 68 // TODO(port): Port these to the mac.
68 #include "chrome/browser/automation/ui_controls.h" 69 #include "chrome/browser/automation/ui_controls.h"
69 #endif // !defined(OS_MACOSX) 70 #endif // !defined(OS_MACOSX)
70 71
71 using base::Time; 72 using base::Time;
72 73
73 class InitialLoadObserver : public NotificationObserver {
74 public:
75 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
76 : automation_(automation),
77 outstanding_tab_count_(tab_count) {
78 if (outstanding_tab_count_ > 0) {
79 registrar_.Add(this, NotificationType::LOAD_START,
80 NotificationService::AllSources());
81 registrar_.Add(this, NotificationType::LOAD_STOP,
82 NotificationService::AllSources());
83 }
84 }
85
86 ~InitialLoadObserver() {
87 }
88
89 void ConditionMet() {
90 registrar_.RemoveAll();
91 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
92 }
93
94 virtual void Observe(NotificationType type,
95 const NotificationSource& source,
96 const NotificationDetails& details) {
97 if (type == NotificationType::LOAD_START) {
98 if (outstanding_tab_count_ > loading_tabs_.size())
99 loading_tabs_.insert(source.map_key());
100 } else if (type == NotificationType::LOAD_STOP) {
101 if (outstanding_tab_count_ > finished_tabs_.size()) {
102 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
103 finished_tabs_.insert(source.map_key());
104 if (outstanding_tab_count_ == finished_tabs_.size())
105 ConditionMet();
106 }
107 } else {
108 NOTREACHED();
109 }
110 }
111
112 private:
113 typedef std::set<uintptr_t> TabSet;
114
115 NotificationRegistrar registrar_;
116
117 AutomationProvider* automation_;
118 size_t outstanding_tab_count_;
119 TabSet loading_tabs_;
120 TabSet finished_tabs_;
121 };
122
123 // Watches for NewTabUI page loads for performance timing purposes.
124 class NewTabUILoadObserver : public NotificationObserver {
125 public:
126 explicit NewTabUILoadObserver(AutomationProvider* automation)
127 : automation_(automation) {
128 registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
129 NotificationService::AllSources());
130 }
131
132 ~NewTabUILoadObserver() {
133 }
134
135 virtual void Observe(NotificationType type,
136 const NotificationSource& source,
137 const NotificationDetails& details) {
138 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
139 Details<int> load_time(details);
140 automation_->Send(
141 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
142 } else {
143 NOTREACHED();
144 }
145 }
146
147 private:
148 NotificationRegistrar registrar_;
149 AutomationProvider* automation_;
150 };
151
152 class NavigationControllerRestoredObserver : public NotificationObserver {
153 public:
154 NavigationControllerRestoredObserver(AutomationProvider* automation,
155 NavigationController* controller,
156 IPC::Message* reply_message)
157 : automation_(automation),
158 controller_(controller),
159 reply_message_(reply_message) {
160 if (FinishedRestoring()) {
161 SendDone();
162 } else {
163 registrar_.Add(this, NotificationType::LOAD_STOP,
164 NotificationService::AllSources());
165 }
166 }
167
168 ~NavigationControllerRestoredObserver() {
169 }
170
171 virtual void Observe(NotificationType type,
172 const NotificationSource& source,
173 const NotificationDetails& details) {
174 if (FinishedRestoring()) {
175 SendDone();
176 registrar_.RemoveAll();
177 }
178 }
179
180 private:
181 bool FinishedRestoring() {
182 return (!controller_->needs_reload() && !controller_->pending_entry() &&
183 !controller_->tab_contents()->is_loading());
184 }
185
186 void SendDone() {
187 DCHECK(reply_message_ != NULL);
188 automation_->Send(reply_message_);
189 }
190
191 NotificationRegistrar registrar_;
192 AutomationProvider* automation_;
193 NavigationController* controller_;
194 IPC::Message* reply_message_;
195
196 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
197 };
198
199 class NavigationNotificationObserver : public NotificationObserver {
200 public:
201 NavigationNotificationObserver(NavigationController* controller,
202 AutomationProvider* automation,
203 IPC::Message* reply_message,
204 int number_of_navigations)
205 : automation_(automation),
206 reply_message_(reply_message),
207 controller_(controller),
208 navigations_remaining_(number_of_navigations),
209 navigation_started_(false) {
210 DCHECK_LT(0, navigations_remaining_);
211 Source<NavigationController> source(controller_);
212 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
213 registrar_.Add(this, NotificationType::LOAD_START, source);
214 registrar_.Add(this, NotificationType::LOAD_STOP, source);
215 registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
216 registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
217 }
218
219 ~NavigationNotificationObserver() {
220 if (reply_message_) {
221 // This means we did not receive a notification for this navigation.
222 // Send over a failed navigation status back to the caller to ensure that
223 // the caller does not hang waiting for the response.
224 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
225 reply_message_, AUTOMATION_MSG_NAVIGATION_ERROR);
226 automation_->Send(reply_message_);
227 reply_message_ = NULL;
228 }
229
230 automation_->RemoveNavigationStatusListener(this);
231 }
232
233 void ConditionMet(AutomationMsg_NavigationResponseValues navigation_result) {
234 DCHECK(reply_message_ != NULL);
235
236 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
237 reply_message_, navigation_result);
238 automation_->Send(reply_message_);
239 reply_message_ = NULL;
240
241 delete this;
242 }
243
244 virtual void Observe(NotificationType type,
245 const NotificationSource& source,
246 const NotificationDetails& details) {
247 // We listen for 2 events to determine when the navigation started because:
248 // - when this is used by the WaitForNavigation method, we might be invoked
249 // afer the load has started (but not after the entry was committed, as
250 // WaitForNavigation compares times of the last navigation).
251 // - when this is used with a page requiring authentication, we will not get
252 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
253 // we need the NotificationType::LOAD_START.
254 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
255 type == NotificationType::LOAD_START) {
256 navigation_started_ = true;
257 } else if (type == NotificationType::LOAD_STOP) {
258 if (navigation_started_) {
259 navigation_started_ = false;
260 if (--navigations_remaining_ == 0)
261 ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
262 }
263 } else if (type == NotificationType::AUTH_SUPPLIED) {
264 // The LoginHandler for this tab is no longer valid.
265 automation_->RemoveLoginHandler(controller_);
266
267 // Treat this as if navigation started again, since load start/stop don't
268 // occur while authentication is ongoing.
269 navigation_started_ = true;
270 } else if (type == NotificationType::AUTH_NEEDED) {
271 #if defined(OS_WIN)
272 if (navigation_started_) {
273 // Remember the login handler that wants authentication.
274 LoginHandler* handler =
275 Details<LoginNotificationDetails>(details)->handler();
276 automation_->AddLoginHandler(controller_, handler);
277
278 // Respond that authentication is needed.
279 navigation_started_ = false;
280 ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
281 } else {
282 NOTREACHED();
283 }
284 #else
285 // TODO(port): Enable when we have LoginNotificationDetails etc.
286 NOTIMPLEMENTED();
287 #endif
288 } else {
289 NOTREACHED();
290 }
291 }
292
293 private:
294 NotificationRegistrar registrar_;
295 AutomationProvider* automation_;
296 IPC::Message* reply_message_;
297 NavigationController* controller_;
298 int navigations_remaining_;
299 bool navigation_started_;
300 };
301
302 class TabStripNotificationObserver : public NotificationObserver {
303 public:
304 TabStripNotificationObserver(NotificationType notification,
305 AutomationProvider* automation)
306 : automation_(automation),
307 notification_(notification) {
308 registrar_.Add(this, notification_, NotificationService::AllSources());
309 }
310
311 virtual ~TabStripNotificationObserver() {
312 }
313
314 virtual void Observe(NotificationType type,
315 const NotificationSource& source,
316 const NotificationDetails& details) {
317 if (type == notification_) {
318 ObserveTab(Source<NavigationController>(source).ptr());
319
320 // If verified, no need to observe anymore
321 automation_->RemoveTabStripObserver(this);
322 delete this;
323 } else {
324 NOTREACHED();
325 }
326 }
327
328 virtual void ObserveTab(NavigationController* controller) = 0;
329
330 protected:
331 NotificationRegistrar registrar_;
332 AutomationProvider* automation_;
333 NotificationType notification_;
334 };
335
336 class TabAppendedNotificationObserver : public TabStripNotificationObserver {
337 public:
338 TabAppendedNotificationObserver(Browser* parent,
339 AutomationProvider* automation,
340 IPC::Message* reply_message)
341 : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
342 automation),
343 parent_(parent),
344 reply_message_(reply_message) {
345 }
346
347 virtual void ObserveTab(NavigationController* controller) {
348 if (automation_->GetIndexForNavigationController(controller, parent_) ==
349 TabStripModel::kNoTab) {
350 // This tab notification doesn't belong to the parent_.
351 return;
352 }
353
354 automation_->AddNavigationStatusListener(controller, reply_message_, 1);
355 }
356
357 protected:
358 Browser* parent_;
359 IPC::Message* reply_message_;
360 };
361
362 class TabClosedNotificationObserver : public TabStripNotificationObserver {
363 public:
364 TabClosedNotificationObserver(AutomationProvider* automation,
365 bool wait_until_closed,
366 IPC::Message* reply_message)
367 : TabStripNotificationObserver(wait_until_closed ?
368 NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
369 automation),
370 reply_message_(reply_message),
371 for_browser_command_(false) {
372 }
373
374 virtual void ObserveTab(NavigationController* controller) {
375 if (for_browser_command_) {
376 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
377 true);
378 } else {
379 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
380 }
381 automation_->Send(reply_message_);
382 }
383
384 void set_for_browser_command(bool for_browser_command) {
385 for_browser_command_ = for_browser_command;
386 }
387
388 protected:
389 IPC::Message* reply_message_;
390 bool for_browser_command_;
391 };
392
393 class BrowserOpenedNotificationObserver : public NotificationObserver {
394 public:
395 BrowserOpenedNotificationObserver(AutomationProvider* automation,
396 IPC::Message* reply_message)
397 : automation_(automation),
398 reply_message_(reply_message),
399 for_browser_command_(false) {
400 registrar_.Add(this, NotificationType::BROWSER_OPENED,
401 NotificationService::AllSources());
402 }
403
404 ~BrowserOpenedNotificationObserver() {
405 }
406
407 virtual void Observe(NotificationType type,
408 const NotificationSource& source,
409 const NotificationDetails& details) {
410 if (type == NotificationType::BROWSER_OPENED) {
411 if (for_browser_command_) {
412 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
413 true);
414 }
415 automation_->Send(reply_message_);
416 delete this;
417 } else {
418 NOTREACHED();
419 }
420 }
421
422 void set_for_browser_command(bool for_browser_command) {
423 for_browser_command_ = for_browser_command;
424 }
425
426 private:
427 NotificationRegistrar registrar_;
428 AutomationProvider* automation_;
429 IPC::Message* reply_message_;
430 bool for_browser_command_;
431 };
432
433 class BrowserClosedNotificationObserver : public NotificationObserver {
434 public:
435 BrowserClosedNotificationObserver(Browser* browser,
436 AutomationProvider* automation,
437 IPC::Message* reply_message)
438 : automation_(automation),
439 reply_message_(reply_message),
440 for_browser_command_(false) {
441 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
442 Source<Browser>(browser));
443 }
444
445 virtual void Observe(NotificationType type,
446 const NotificationSource& source,
447 const NotificationDetails& details) {
448 DCHECK(type == NotificationType::BROWSER_CLOSED);
449 Details<bool> close_app(details);
450 DCHECK(reply_message_ != NULL);
451 if (for_browser_command_) {
452 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
453 true);
454 } else {
455 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
456 *(close_app.ptr()));
457 }
458 automation_->Send(reply_message_);
459 reply_message_ = NULL;
460 delete this;
461 }
462
463 void set_for_browser_command(bool for_browser_command) {
464 for_browser_command_ = for_browser_command;
465 }
466
467 private:
468 NotificationRegistrar registrar_;
469 AutomationProvider* automation_;
470 IPC::Message* reply_message_;
471 bool for_browser_command_;
472 };
473
474 class BrowserCountChangeNotificationObserver : public NotificationObserver {
475 public:
476 BrowserCountChangeNotificationObserver(int target_count,
477 AutomationProvider* automation,
478 IPC::Message* reply_message)
479 : target_count_(target_count),
480 automation_(automation),
481 reply_message_(reply_message) {
482 registrar_.Add(this, NotificationType::BROWSER_OPENED,
483 NotificationService::AllSources());
484 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
485 NotificationService::AllSources());
486 }
487
488 virtual void Observe(NotificationType type,
489 const NotificationSource& source,
490 const NotificationDetails& details) {
491 DCHECK(type == NotificationType::BROWSER_OPENED ||
492 type == NotificationType::BROWSER_CLOSED);
493 int current_count = static_cast<int>(BrowserList::size());
494 if (type == NotificationType::BROWSER_CLOSED) {
495 // At the time of the notification the browser being closed is not removed
496 // from the list. The real count is one less than the reported count.
497 DCHECK_LT(0, current_count);
498 current_count--;
499 }
500 if (current_count == target_count_) {
501 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
502 reply_message_, true);
503 automation_->Send(reply_message_);
504 reply_message_ = NULL;
505 delete this;
506 }
507 }
508
509 private:
510 int target_count_;
511 NotificationRegistrar registrar_;
512 AutomationProvider* automation_;
513 IPC::Message* reply_message_;
514 };
515
516 class AppModalDialogShownObserver : public NotificationObserver {
517 public:
518 AppModalDialogShownObserver(AutomationProvider* automation,
519 IPC::Message* reply_message)
520 : automation_(automation),
521 reply_message_(reply_message) {
522 registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN,
523 NotificationService::AllSources());
524 }
525
526 ~AppModalDialogShownObserver() {
527 }
528
529 virtual void Observe(NotificationType type,
530 const NotificationSource& source,
531 const NotificationDetails& details) {
532 DCHECK(type == NotificationType::APP_MODAL_DIALOG_SHOWN);
533 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
534 reply_message_, true);
535 automation_->Send(reply_message_);
536 reply_message_ = NULL;
537 delete this;
538 }
539
540 private:
541 NotificationRegistrar registrar_;
542 AutomationProvider* automation_;
543 IPC::Message* reply_message_;
544 };
545
546 namespace {
547
548 // Define mapping from command to notification
549 struct CommandNotification {
550 int command;
551 NotificationType::Type notification_type;
552 };
553
554 const struct CommandNotification command_notifications[] = {
555 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
556 {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
557 // Returns as soon as the restored tab is created. To further wait until
558 // the content page is loaded, use WaitForTabToBeRestored.
559 {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
560 };
561
562 } // namespace
563
564 class ExecuteBrowserCommandObserver : public NotificationObserver {
565 public:
566 ~ExecuteBrowserCommandObserver() {
567 }
568
569 static bool CreateAndRegisterObserver(AutomationProvider* automation,
570 Browser* browser,
571 int command,
572 IPC::Message* reply_message) {
573 bool result = true;
574 switch (command) {
575 case IDC_NEW_WINDOW:
576 case IDC_NEW_INCOGNITO_WINDOW: {
577 BrowserOpenedNotificationObserver* observer =
578 new BrowserOpenedNotificationObserver(automation, reply_message);
579 observer->set_for_browser_command(true);
580 break;
581 }
582 case IDC_CLOSE_WINDOW: {
583 BrowserClosedNotificationObserver* observer =
584 new BrowserClosedNotificationObserver(browser, automation,
585 reply_message);
586 observer->set_for_browser_command(true);
587 break;
588 }
589 case IDC_CLOSE_TAB: {
590 TabClosedNotificationObserver* observer =
591 new TabClosedNotificationObserver(automation, true, reply_message);
592 observer->set_for_browser_command(true);
593 break;
594 }
595 case IDC_BACK:
596 case IDC_FORWARD:
597 case IDC_RELOAD: {
598 automation->AddNavigationStatusListener(
599 &browser->GetSelectedTabContents()->controller(),
600 reply_message, 1);
601 break;
602 }
603 default: {
604 ExecuteBrowserCommandObserver* observer =
605 new ExecuteBrowserCommandObserver(automation, reply_message);
606 if (!observer->Register(command)) {
607 delete observer;
608 result = false;
609 }
610 break;
611 }
612 }
613 return result;
614 }
615
616 virtual void Observe(NotificationType type,
617 const NotificationSource& source,
618 const NotificationDetails& details) {
619 if (type == notification_type_) {
620 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
621 true);
622 automation_->Send(reply_message_);
623 delete this;
624 } else {
625 NOTREACHED();
626 }
627 }
628
629 private:
630 ExecuteBrowserCommandObserver(AutomationProvider* automation,
631 IPC::Message* reply_message)
632 : automation_(automation),
633 reply_message_(reply_message) {
634 }
635
636 bool Register(int command) {
637 if (!GetNotificationType(command, &notification_type_))
638 return false;
639 registrar_.Add(this, notification_type_, NotificationService::AllSources());
640 return true;
641 }
642
643 bool GetNotificationType(int command, NotificationType::Type* type) {
644 if (!type)
645 return false;
646 bool found = false;
647 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
648 if (command_notifications[i].command == command) {
649 *type = command_notifications[i].notification_type;
650 found = true;
651 break;
652 }
653 }
654 return found;
655 }
656
657 NotificationRegistrar registrar_;
658 AutomationProvider* automation_;
659 NotificationType::Type notification_type_;
660 IPC::Message* reply_message_;
661 };
662
663 class FindInPageNotificationObserver : public NotificationObserver {
664 public:
665 FindInPageNotificationObserver(AutomationProvider* automation,
666 TabContents* parent_tab,
667 IPC::Message* reply_message)
668 : automation_(automation),
669 active_match_ordinal_(-1),
670 reply_message_(reply_message) {
671 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
672 Source<TabContents>(parent_tab));
673 }
674
675 ~FindInPageNotificationObserver() {
676 }
677
678 virtual void Observe(NotificationType type,
679 const NotificationSource& source,
680 const NotificationDetails& details) {
681 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
682 Details<FindNotificationDetails> find_details(details);
683 if (find_details->request_id() == kFindInPageRequestId) {
684 // We get multiple responses and one of those will contain the ordinal.
685 // This message comes to us before the final update is sent.
686 if (find_details->active_match_ordinal() > -1)
687 active_match_ordinal_ = find_details->active_match_ordinal();
688 if (find_details->final_update()) {
689 if (reply_message_ != NULL) {
690 AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
691 active_match_ordinal_, find_details->number_of_matches());
692 automation_->Send(reply_message_);
693 reply_message_ = NULL;
694 } else {
695 DLOG(WARNING) << "Multiple final Find messages observed.";
696 }
697 } else {
698 DLOG(INFO) << "Ignoring, since we only care about the final message";
699 }
700 }
701 } else {
702 NOTREACHED();
703 }
704 }
705
706 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
707 // we wait for notification to find out what the results are. As the user is
708 // typing, new search requests can be issued and the Request ID helps us make
709 // sense of whether this is the current request or an old one. The unit tests,
710 // however, which uses this constant issues only one search at a time, so we
711 // don't need a rolling id to identify each search. But, we still need to
712 // specify one, so we just use a fixed one - its value does not matter.
713 static const int kFindInPageRequestId;
714
715 private:
716 NotificationRegistrar registrar_;
717 AutomationProvider* automation_;
718 // We will at some point (before final update) be notified of the ordinal and
719 // we need to preserve it so we can send it later.
720 int active_match_ordinal_;
721 IPC::Message* reply_message_;
722 };
723
724 const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
725
726 class DomOperationNotificationObserver : public NotificationObserver {
727 public:
728 explicit DomOperationNotificationObserver(AutomationProvider* automation)
729 : automation_(automation) {
730 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
731 NotificationService::AllSources());
732 }
733
734 ~DomOperationNotificationObserver() {
735 }
736
737 virtual void Observe(NotificationType type,
738 const NotificationSource& source,
739 const NotificationDetails& details) {
740 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
741 Details<DomOperationNotificationDetails> dom_op_details(details);
742
743 IPC::Message* reply_message = automation_->reply_message_release();
744 DCHECK(reply_message != NULL);
745
746 AutomationMsg_DomOperation::WriteReplyParams(reply_message,
747 dom_op_details->json());
748 automation_->Send(reply_message);
749 }
750 }
751
752 private:
753 NotificationRegistrar registrar_;
754 AutomationProvider* automation_;
755 };
756
757 #if defined(OS_WIN)
758 // TODO(port): Enable when printing is ported.
759 class DocumentPrintedNotificationObserver : public NotificationObserver {
760 public:
761 DocumentPrintedNotificationObserver(AutomationProvider* automation,
762 IPC::Message* reply_message)
763 : automation_(automation),
764 success_(false),
765 reply_message_(reply_message) {
766 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
767 NotificationService::AllSources());
768 }
769
770 ~DocumentPrintedNotificationObserver() {
771 DCHECK(reply_message_ != NULL);
772 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
773 automation_->Send(reply_message_);
774 automation_->RemoveNavigationStatusListener(this);
775 }
776
777 virtual void Observe(NotificationType type, const NotificationSource& source,
778 const NotificationDetails& details) {
779 using namespace printing;
780 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
781 switch (Details<JobEventDetails>(details)->type()) {
782 case JobEventDetails::JOB_DONE: {
783 // Succeeded.
784 success_ = true;
785 delete this;
786 break;
787 }
788 case JobEventDetails::USER_INIT_CANCELED:
789 case JobEventDetails::FAILED: {
790 // Failed.
791 delete this;
792 break;
793 }
794 case JobEventDetails::NEW_DOC:
795 case JobEventDetails::USER_INIT_DONE:
796 case JobEventDetails::DEFAULT_INIT_DONE:
797 case JobEventDetails::NEW_PAGE:
798 case JobEventDetails::PAGE_DONE:
799 case JobEventDetails::DOC_DONE:
800 case JobEventDetails::ALL_PAGES_REQUESTED: {
801 // Don't care.
802 break;
803 }
804 default: {
805 NOTREACHED();
806 break;
807 }
808 }
809 }
810
811 private:
812 NotificationRegistrar registrar_;
813 scoped_refptr<AutomationProvider> automation_;
814 bool success_;
815 IPC::Message* reply_message_;
816 };
817 #endif // defined(OS_WIN)
818
819 class AutomationInterstitialPage : public InterstitialPage { 74 class AutomationInterstitialPage : public InterstitialPage {
820 public: 75 public:
821 AutomationInterstitialPage(TabContents* tab, 76 AutomationInterstitialPage(TabContents* tab,
822 const GURL& url, 77 const GURL& url,
823 const std::string& contents) 78 const std::string& contents)
824 : InterstitialPage(tab, true, url), 79 : InterstitialPage(tab, true, url),
825 contents_(contents) { 80 contents_(contents) {
826 } 81 }
827 82
828 virtual std::string GetHTMLContents() { return contents_; } 83 virtual std::string GetHTMLContents() { return contents_; }
(...skipping 1974 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 for (;iter != BrowserList::end(); ++iter) { 2058 for (;iter != BrowserList::end(); ++iter) {
2804 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle(); 2059 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
2805 if (window == this_window) { 2060 if (window == this_window) {
2806 // Add() returns the existing handle for the resource if any. 2061 // Add() returns the existing handle for the resource if any.
2807 *browser_handle = browser_tracker_->Add(*iter); 2062 *browser_handle = browser_tracker_->Add(*iter);
2808 *success = true; 2063 *success = true;
2809 return; 2064 return;
2810 } 2065 }
2811 } 2066 }
2812 } 2067 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/automation/automation_provider_observers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698