172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider_observers.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <deque>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string>
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <vector>
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
12513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/callback.h"
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/file_util.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_writer.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/stringprintf.h"
183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/utf_string_conversions.h"
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/values.h"
21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider_json.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h"
254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/browser_process.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_operation_notification_details.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/save_package.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/crx_installer.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_process_manager.h"
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_tabs_module.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_updater.h"
34201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/history/top_sites.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/metric_event_duration_details.h"
36513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/notifications/balloon.h"
37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/notifications/balloon_collection.h"
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/notifications/balloon_host.h"
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/notifications/notification.h"
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/notifications/notification_ui_manager.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/printing/print_job.h"
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/template_url_model.h"
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/sessions/tab_restore_service.h"
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/tab_contents/thumbnail_generator.h"
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/translate/page_translated_details.h"
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/translate/translate_infobar_delegate.h"
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/translate/translate_tab_helper.h"
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/find_bar/find_notification_details.h"
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/login/login_prompt.h"
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/app_launcher_handler.h"
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/most_visited_handler.h"
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/new_tab_ui.h"
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/automation_messages.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
64201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "googleurl/src/gurl.h"
6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/codec/png_codec.h"
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Holds onto start and stop timestamps for a particular tab
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass InitialLoadObserver::TabTime {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit TabTime(base::TimeTicks started)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : load_start_time_(started) {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_stop_time(base::TimeTicks stopped) {
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    load_stop_time_ = stopped;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks stop_time() const {
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return load_stop_time_;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks start_time() const {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return load_start_time_;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks load_start_time_;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks load_stop_time_;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochInitialLoadObserver::InitialLoadObserver(size_t tab_count,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         AutomationProvider* automation)
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      outstanding_tab_count_(tab_count),
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      init_time_(base::TimeTicks::Now()) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (outstanding_tab_count_ > 0) {
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::LOAD_START,
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::LOAD_STOP,
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochInitialLoadObserver::~InitialLoadObserver() {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InitialLoadObserver::Observe(NotificationType type,
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const NotificationSource& source,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const NotificationDetails& details) {
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::LOAD_START) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (outstanding_tab_count_ > loading_tabs_.size())
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      loading_tabs_.insert(TabTimeMap::value_type(
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          source.map_key(),
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          TabTime(base::TimeTicks::Now())));
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (type == NotificationType::LOAD_STOP) {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (outstanding_tab_count_ > finished_tabs_.size()) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabTimeMap::iterator iter = loading_tabs_.find(source.map_key());
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (iter != loading_tabs_.end()) {
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        finished_tabs_.insert(source.map_key());
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        iter->second.set_stop_time(base::TimeTicks::Now());
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (outstanding_tab_count_ == finished_tabs_.size())
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ConditionMet();
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue* InitialLoadObserver::GetTimingInformation() const {
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* items = new ListValue;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (TabTimeMap::const_iterator it = loading_tabs_.begin();
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != loading_tabs_.end();
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++it) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* item = new DictionaryValue;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::TimeDelta delta_start = it->second.start_time() - init_time_;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    item->SetDouble("load_start_ms", delta_start.InMillisecondsF());
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (it->second.stop_time().is_null()) {
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      item->Set("load_stop_ms", Value::CreateNullValue());
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::TimeDelta delta_stop = it->second.stop_time() - init_time_;
14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      item->SetDouble("load_stop_ms", delta_stop.InMillisecondsF());
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    items->Append(item);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* return_value = new DictionaryValue;
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->Set("tabs", items);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return return_value;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InitialLoadObserver::ConditionMet() {
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.RemoveAll();
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_)
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    automation_->OnInitialTabLoadsComplete();
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewTabUILoadObserver::NewTabUILoadObserver(AutomationProvider* automation)
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewTabUILoadObserver::~NewTabUILoadObserver() {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabUILoadObserver::Observe(NotificationType type,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationSource& source,
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationDetails& details) {
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Details<int> load_time(details);
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (automation_) {
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      automation_->Send(
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new AutomationMsg_InitialNewTabUILoadComplete(*load_time.ptr()));
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNavigationControllerRestoredObserver::NavigationControllerRestoredObserver(
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller,
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      controller_(controller),
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (FinishedRestoring()) {
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SendDone();
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::LOAD_STOP,
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNavigationControllerRestoredObserver::~NavigationControllerRestoredObserver() {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NavigationControllerRestoredObserver::Observe(
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (FinishedRestoring()) {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SendDone();
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.RemoveAll();
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NavigationControllerRestoredObserver::FinishedRestoring() {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (!controller_->needs_reload() && !controller_->pending_entry() &&
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          !controller_->tab_contents()->is_loading());
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NavigationControllerRestoredObserver::SendDone() {
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_)
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationMsg_WaitForTabToBeRestored::WriteReplyParams(reply_message_.get(),
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                         true);
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  automation_->Send(reply_message_.release());
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNavigationNotificationObserver::NavigationNotificationObserver(
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller,
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message,
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int number_of_navigations,
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bool include_current_navigation,
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bool use_json_interface)
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controller_(controller),
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      navigations_remaining_(number_of_navigations),
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      navigation_started_(false),
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      use_json_interface_(use_json_interface) {
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_LT(0, navigations_remaining_);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Source<NavigationController> source(controller_);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::LOAD_START, source);
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::LOAD_STOP, source);
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::AUTH_CANCELLED, source);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (include_current_navigation && controller->tab_contents()->is_loading())
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    navigation_started_ = true;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNavigationNotificationObserver::~NavigationNotificationObserver() {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NavigationNotificationObserver::Observe(
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We listen for 2 events to determine when the navigation started because:
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - when this is used by the WaitForNavigation method, we might be invoked
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // afer the load has started (but not after the entry was committed, as
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // WaitForNavigation compares times of the last navigation).
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - when this is used with a page requiring authentication, we will not get
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we need the NotificationType::LOAD_START.
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::NAV_ENTRY_COMMITTED ||
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type == NotificationType::LOAD_START) {
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    navigation_started_ = true;
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (type == NotificationType::LOAD_STOP) {
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (navigation_started_) {
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      navigation_started_ = false;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (--navigations_remaining_ == 0)
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (type == NotificationType::AUTH_SUPPLIED ||
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             type == NotificationType::AUTH_CANCELLED) {
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The LoginHandler for this tab is no longer valid.
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    automation_->RemoveLoginHandler(controller_);
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Treat this as if navigation started again, since load start/stop don't
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // occur while authentication is ongoing.
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    navigation_started_ = true;
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (type == NotificationType::AUTH_NEEDED) {
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Remember the login handler that wants authentication.
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We do this in all cases (not just when navigation_started_ == true) so
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // tests can still wait for auth dialogs outside of navigation.
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LoginHandler* handler =
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        Details<LoginNotificationDetails>(details)->handler();
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    automation_->AddLoginHandler(controller_, handler);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Respond that authentication is needed.
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    navigation_started_ = false;
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NavigationNotificationObserver::ConditionMet(
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_NavigationResponseValues navigation_result) {
29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (use_json_interface_) {
300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      DictionaryValue dict;
301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      dict.SetInteger("result", navigation_result);
302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      AutomationJSONReply(automation_, reply_message_.release())
303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          .SendSuccess(&dict);
304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    } else {
305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          reply_message_.get(), navigation_result);
307dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      automation_->Send(reply_message_.release());
308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabStripNotificationObserver::TabStripNotificationObserver(
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType notification, AutomationProvider* automation)
31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      notification_(notification) {
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, notification_, NotificationService::AllSources());
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabStripNotificationObserver::~TabStripNotificationObserver() {
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabStripNotificationObserver::Observe(NotificationType type,
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const NotificationSource& source,
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const NotificationDetails& details) {
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == notification_) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ObserveTab(Source<NavigationController>(source).ptr());
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabAppendedNotificationObserver::TabAppendedNotificationObserver(
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* parent, AutomationProvider* automation,
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : TabStripNotificationObserver(NotificationType::TAB_PARENTED, automation),
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent_(parent),
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTabAppendedNotificationObserver::~TabAppendedNotificationObserver() {}
34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabAppendedNotificationObserver::ObserveTab(
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller) {
34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_)
34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (automation_->GetIndexForNavigationController(controller, parent_) ==
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::kNoTab) {
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This tab notification doesn't belong to the parent_.
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  new NavigationNotificationObserver(controller, automation_,
35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                     reply_message_.release(),
358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     1, false, false);
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabClosedNotificationObserver::TabClosedNotificationObserver(
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, bool wait_until_closed,
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : TabStripNotificationObserver(wait_until_closed ?
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          automation),
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message),
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for_browser_command_(false) {
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTabClosedNotificationObserver::~TabClosedNotificationObserver() {}
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabClosedNotificationObserver::ObserveTab(
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller) {
37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_)
37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (for_browser_command_) {
37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_.get(),
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         true);
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_CloseTab::WriteReplyParams(reply_message_.get(), true);
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  automation_->Send(reply_message_.release());
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabClosedNotificationObserver::set_for_browser_command(
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool for_browser_command) {
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for_browser_command_ = for_browser_command;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTabCountChangeObserver::TabCountChangeObserver(AutomationProvider* automation,
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                               Browser* browser,
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                               IPC::Message* reply_message,
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                               int target_tab_count)
39672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      reply_message_(reply_message),
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      tab_strip_model_(browser->tabstrip_model()),
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      target_tab_count_(target_tab_count) {
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_strip_model_->AddObserver(this);
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckTabCount();
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTabCountChangeObserver::~TabCountChangeObserver() {
4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_strip_model_->RemoveObserver(this);
4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid TabCountChangeObserver::TabInsertedAt(TabContentsWrapper* contents,
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           int index,
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           bool foreground) {
4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckTabCount();
4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid TabCountChangeObserver::TabDetachedAt(TabContentsWrapper* contents,
415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           int index) {
4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckTabCount();
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TabCountChangeObserver::TabStripModelDeleted() {
42072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForTabCountToBecome::WriteReplyParams(
42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), false);
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TabCountChangeObserver::CheckTabCount() {
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tab_strip_model_->count() != target_tab_count_)
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForTabCountToBecome::WriteReplyParams(
43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), true);
43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DidExtensionHostsStopLoading(ExtensionProcessManager* manager) {
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionProcessManager::const_iterator iter = manager->begin();
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != manager->end(); ++iter) {
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!(*iter)->did_stop_loading())
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionInstallNotificationObserver::ExtensionInstallNotificationObserver(
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, int id, IPC::Message* reply_message)
45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      id_(id),
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_INSTALL_ERROR,
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionInstallNotificationObserver::~ExtensionInstallNotificationObserver() {
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionInstallNotificationObserver::Observe(
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_LOADED:
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SendResponse(AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_INSTALL_ERROR:
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UPDATE_DISABLED:
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SendResponse(AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionInstallNotificationObserver::SendResponse(
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_ExtensionResponseValues response) {
48872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_ || !reply_message_.get()) {
48972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
49072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  switch (id_) {
49472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case AutomationMsg_InstallExtension::ID:
49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationMsg_InstallExtension::WriteReplyParams(reply_message_.get(),
49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                       response);
49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    default:
49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NOTREACHED();
50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  automation_->Send(reply_message_.release());
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtensionUninstallObserver::ExtensionUninstallObserver(
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationProvider* automation,
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Message* reply_message,
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& id)
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : automation_(automation->AsWeakPtr()),
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reply_message_(reply_message),
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      id_(id) {
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UNINSTALL_NOT_ALLOWED,
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtensionUninstallObserver::~ExtensionUninstallObserver() {
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionUninstallObserver::Observe(
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NotificationType type,
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const NotificationSource& source,
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const NotificationDetails& details) {
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!automation_) {
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete this;
528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  switch (type.value) {
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UNINSTALLED: {
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UninstalledExtensionInfo* info =
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          Details<UninstalledExtensionInfo>(details).ptr();
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (id_ == info->extension_id) {
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return_value->SetBoolean("success", true);
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationJSONReply(automation_, reply_message_.release())
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            .SendSuccess(return_value.get());
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        delete this;
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UNINSTALL_NOT_ALLOWED: {
547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const Extension* extension = Details<Extension>(details).ptr();
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (id_ == extension->id()) {
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return_value->SetBoolean("success", false);
551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationJSONReply(automation_, reply_message_.release())
552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            .SendSuccess(return_value.get());
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        delete this;
554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    default:
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NOTREACHED();
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionReadyNotificationObserver::ExtensionReadyNotificationObserver(
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionProcessManager* manager, AutomationProvider* automation, int id,
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : manager_(manager),
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      automation_(automation->AsWeakPtr()),
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      id_(id),
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message),
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_(NULL) {
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_INSTALL_ERROR,
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionReadyNotificationObserver::~ExtensionReadyNotificationObserver() {
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionReadyNotificationObserver::Observe(
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
58872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
58972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
59072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
59172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
59272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success = false;
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_HOST_DID_STOP_LOADING:
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Only continue on with this method if our extension has been loaded
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // and all the extension hosts have stopped loading.
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!extension_ || !DidExtensionHostsStopLoading(manager_))
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success = true;
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_LOADED:
603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      extension_ = Details<const Extension>(details).ptr();
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!DidExtensionHostsStopLoading(manager_))
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success = true;
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_INSTALL_ERROR:
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UPDATE_DISABLED:
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success = false;
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (id_ == AutomationMsg_InstallExtensionAndGetHandle::ID) {
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // A handle of zero indicates an error.
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int extension_handle = 0;
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension_)
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_handle = automation_->AddExtension(extension_);
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
62372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), extension_handle);
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (id_ == AutomationMsg_EnableExtension::ID) {
62572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_EnableExtension::WriteReplyParams(reply_message_.get(), true);
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(ERROR) << "Cannot write reply params for unknown message id.";
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  automation_->Send(reply_message_.release());
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionUnloadNotificationObserver::ExtensionUnloadNotificationObserver()
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : did_receive_unload_notification_(false) {
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionUnloadNotificationObserver::~ExtensionUnloadNotificationObserver() {
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionUnloadNotificationObserver::Observe(
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
64721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type.value == NotificationType::EXTENSION_UNLOADED) {
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    did_receive_unload_notification_ = true;
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtensionsUpdatedObserver::ExtensionsUpdatedObserver(
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionProcessManager* manager, AutomationProvider* automation,
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Message* reply_message)
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : manager_(manager), automation_(automation->AsWeakPtr()),
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reply_message_(reply_message), updater_finished_(false) {
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_INSTALL_ERROR,
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_INSTALL_NOT_ALLOWED,
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_FOUND,
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UPDATING_FINISHED,
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtensionsUpdatedObserver::~ExtensionsUpdatedObserver() {
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionsUpdatedObserver::Observe(
679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NotificationType type, const NotificationSource& source,
680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const NotificationDetails& details) {
681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!automation_) {
682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete this;
683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We expect the following sequence of events.  First, the ExtensionUpdater
687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // service notifies of each extension that needs to be updated.  Once the
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ExtensionUpdater has finished searching for extensions to update, it
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // notifies that it is finished.  Meanwhile, the extensions are updated
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // asynchronously: either they will be updated and loaded, or else they will
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // not load due to (1) not being allowed; (2) having updating disabled; or
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // (3) encountering an error.  Finally, notifications are also sent whenever
693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // an extension host stops loading.  Updating is not considered complete if
694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // any extension hosts are still loading.
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  switch (type.value) {
696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UPDATE_FOUND:
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Extension updater has identified an extension that needs to be updated.
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      in_progress_updates_.insert(*(Details<const std::string>(details).ptr()));
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UPDATING_FINISHED:
702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Extension updater has completed notifying all extensions to update
703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // themselves.
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      updater_finished_ = true;
705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_LOADED:
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_INSTALL_NOT_ALLOWED:
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UPDATE_DISABLED: {
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // An extension has either completed update installation and is now
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // loaded, or else the install has been skipped because it is
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // either not allowed or else has been disabled.
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const Extension* extension = Details<Extension>(details).ptr();
714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      in_progress_updates_.erase(extension->id());
715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_INSTALL_ERROR: {
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // An extension had an error on update installation.
720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      CrxInstaller* installer = Source<CrxInstaller>(source).ptr();
721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      in_progress_updates_.erase(installer->expected_id());
722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_HOST_DID_STOP_LOADING:
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Break out to the conditional check below to see if all extension hosts
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // have stopped loading.
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    default:
731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NOTREACHED();
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Send the reply if (1) the extension updater has finished notifying all
736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // extensions to update themselves; (2) all extensions that need to be updated
737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // have completed installation and are now loaded; and (3) all extension hosts
738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // have stopped loading.
739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (updater_finished_ && in_progress_updates_.empty() &&
740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DidExtensionHostsStopLoading(manager_)) {
741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationJSONReply reply(automation_, reply_message_.release());
742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendSuccess(NULL);
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete this;
744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionTestResultNotificationObserver::
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionTestResultNotificationObserver(AutomationProvider* automation)
74972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        : automation_(automation->AsWeakPtr()) {
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_TEST_PASSED,
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_TEST_FAILED,
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionTestResultNotificationObserver::
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ~ExtensionTestResultNotificationObserver() {
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionTestResultNotificationObserver::Observe(
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_TEST_PASSED:
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      results_.push_back(true);
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      messages_.push_back("");
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_TEST_FAILED:
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      results_.push_back(false);
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      messages_.push_back(*(Details<std::string>(details).ptr()));
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There may be a reply message waiting for this event, so check.
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MaybeSendResult();
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionTestResultNotificationObserver::MaybeSendResult() {
78272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_)
78372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
78472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
785dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!results_.empty()) {
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This release method should return the automation's current
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // reply message, or NULL if there is no current one. If it is not
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // NULL, we are stating that we will handle this reply message.
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message = automation_->reply_message_release();
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send the result back if we have a reply message.
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (reply_message) {
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AutomationMsg_WaitForExtensionTestResult::WriteReplyParams(
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          reply_message, results_.front(), messages_.front());
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      results_.pop_front();
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      messages_.pop_front();
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      automation_->Send(reply_message);
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserOpenedNotificationObserver::BrowserOpenedNotificationObserver(
802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationProvider* automation,
803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Message* reply_message)
80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message),
806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new_window_id_(extension_misc::kUnknownWindowId),
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for_browser_command_(false) {
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_OPENED,
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this, NotificationType::LOAD_STOP,
811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationService::AllSources());
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserOpenedNotificationObserver::~BrowserOpenedNotificationObserver() {
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserOpenedNotificationObserver::Observe(
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
82172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
82272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
82472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (type.value == NotificationType::BROWSER_OPENED) {
826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Store the new browser ID and continue waiting for a new tab within it
827ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // to stop loading.
828ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    new_window_id_ = ExtensionTabUtil::GetWindowId(
829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Source<Browser>(source).ptr());
830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (type.value == NotificationType::LOAD_STOP) {
831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Only send the result if the loaded tab is in the new window.
832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int window_id = Source<NavigationController>(source)->window_id().id();
833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (window_id == new_window_id_) {
834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (for_browser_command_) {
835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationMsg_WindowExecuteCommand::WriteReplyParams(
836ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            reply_message_.get(), true);
837ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      automation_->Send(reply_message_.release());
839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delete this;
840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserOpenedNotificationObserver::set_for_browser_command(
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool for_browser_command) {
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for_browser_command_ = for_browser_command;
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserClosedNotificationObserver::BrowserClosedNotificationObserver(
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* browser,
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
85672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message),
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for_browser_command_(false) {
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_CLOSED,
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Browser>(browser));
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenBrowserClosedNotificationObserver::~BrowserClosedNotificationObserver() {}
86472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserClosedNotificationObserver::Observe(
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::BROWSER_CLOSED);
86972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
87072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
87172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
87272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
87372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
87472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Details<bool> close_app(details);
87672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (for_browser_command_) {
87872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_.get(),
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         true);
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_.get(), true,
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 *(close_app.ptr()));
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
88472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  automation_->Send(reply_message_.release());
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserClosedNotificationObserver::set_for_browser_command(
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool for_browser_command) {
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for_browser_command_ = for_browser_command;
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserCountChangeNotificationObserver::BrowserCountChangeNotificationObserver(
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int target_count,
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : target_count_(target_count),
89872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      automation_(automation->AsWeakPtr()),
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_OPENED,
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_CLOSED,
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenBrowserCountChangeNotificationObserver::
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~BrowserCountChangeNotificationObserver() {}
90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserCountChangeNotificationObserver::Observe(
91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotificationType type,
91172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const NotificationSource& source,
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::BROWSER_OPENED ||
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         type == NotificationType::BROWSER_CLOSED);
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int current_count = static_cast<int>(BrowserList::size());
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::BROWSER_CLOSED) {
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // At the time of the notification the browser being closed is not removed
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // from the list. The real count is one less than the reported count.
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_LT(0, current_count);
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    current_count--;
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
92272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
92372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
92472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
92572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
92672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
92772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_count == target_count_) {
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
93072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), true);
93172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAppModalDialogShownObserver::AppModalDialogShownObserver(
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, IPC::Message* reply_message)
93872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN,
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAppModalDialogShownObserver::~AppModalDialogShownObserver() {
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AppModalDialogShownObserver::Observe(
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::APP_MODAL_DIALOG_SHOWN);
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
95372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), true);
95572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
95672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Define mapping from command to notification
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct CommandNotification {
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command;
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationType::Type notification_type;
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst struct CommandNotification command_notifications[] = {
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns as soon as the restored tab is created. To further wait until
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the content page is loaded, use WaitForTabToBeRestored.
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED},
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For the following commands, we need to wait for a new tab to be created,
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // load to finish, and title to change.
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_MANAGE_EXTENSIONS, NotificationType::TAB_CONTENTS_TITLE_UPDATED},
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_OPTIONS, NotificationType::TAB_CONTENTS_TITLE_UPDATED},
97921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  {IDC_PRINT, NotificationType::TAB_CONTENTS_TITLE_UPDATED},
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_SHOW_DOWNLOADS, NotificationType::TAB_CONTENTS_TITLE_UPDATED},
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {IDC_SHOW_HISTORY, NotificationType::TAB_CONTENTS_TITLE_UPDATED},
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExecuteBrowserCommandObserver::~ExecuteBrowserCommandObserver() {
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, Browser* browser, int command,
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message) {
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = true;
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (command) {
99572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case IDC_NEW_TAB: {
99672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new NewTabObserver(automation, reply_message);
99772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
99872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_NEW_WINDOW:
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_NEW_INCOGNITO_WINDOW: {
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BrowserOpenedNotificationObserver* observer =
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new BrowserOpenedNotificationObserver(automation, reply_message);
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer->set_for_browser_command(true);
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CLOSE_WINDOW: {
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BrowserClosedNotificationObserver* observer =
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new BrowserClosedNotificationObserver(browser, automation,
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                reply_message);
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer->set_for_browser_command(true);
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CLOSE_TAB: {
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabClosedNotificationObserver* observer =
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new TabClosedNotificationObserver(automation, true, reply_message);
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer->set_for_browser_command(true);
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_BACK:
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FORWARD:
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_RELOAD: {
102272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new NavigationNotificationObserver(
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &browser->GetSelectedTabContents()->controller(),
1024dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          automation, reply_message, 1, false, false);
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default: {
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExecuteBrowserCommandObserver* observer =
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new ExecuteBrowserCommandObserver(automation, reply_message);
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!observer->Register(command)) {
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        delete observer;
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        result = false;
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExecuteBrowserCommandObserver::Observe(
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == notification_type_) {
104472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (automation_) {
104572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_.get(),
104672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                           true);
104772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      automation_->Send(reply_message_.release());
104872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExecuteBrowserCommandObserver::ExecuteBrowserCommandObserver(
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, IPC::Message* reply_message)
105772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
10583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      notification_type_(NotificationType::ALL),
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExecuteBrowserCommandObserver::Register(int command) {
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!GetNotificationType(command, &notification_type_))
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, notification_type_, NotificationService::AllSources());
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExecuteBrowserCommandObserver::GetNotificationType(
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int command, NotificationType::Type* type) {
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!type)
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool found = false;
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (command_notifications[i].command == command) {
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *type = command_notifications[i].notification_type;
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      found = true;
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return found;
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindInPageNotificationObserver::FindInPageNotificationObserver(
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, TabContents* parent_tab,
1086731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool reply_with_json, IPC::Message* reply_message)
108772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      active_match_ordinal_(-1),
1089731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      reply_with_json_(reply_with_json),
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<TabContents>(parent_tab));
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindInPageNotificationObserver::~FindInPageNotificationObserver() {
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindInPageNotificationObserver::Observe(
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Details<FindNotificationDetails> find_details(details);
1102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!(find_details->final_update() && reply_message_ != NULL)) {
1103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    DVLOG(1) << "Ignoring, since we only care about the final message";
1104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
1105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
110672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
110772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
110972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
111072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
111172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // We get multiple responses and one of those will contain the ordinal.
1113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // This message comes to us before the final update is sent.
1114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (find_details->request_id() == kFindInPageRequestId) {
1115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (reply_with_json_) {
1116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return_value->SetInteger("match_count",
1118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          find_details->number_of_matches());
1119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      gfx::Rect rect = find_details->selection_rect();
1120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // If MatchCount is > 0, then rect should not be Empty.
1121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // We dont guard it here because we want to let the test
1122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // code catch this invalid case if needed.
1123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (!rect.IsEmpty()) {
1124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        return_value->SetInteger("match_left", rect.x());
1125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        return_value->SetInteger("match_top", rect.y());
1126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        return_value->SetInteger("match_right", rect.right());
1127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        return_value->SetInteger("match_bottom", rect.bottom());
1128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
112972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationJSONReply(automation_, reply_message_.release())
1130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          .SendSuccess(return_value.get());
1131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      delete this;
1132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    } else {
1133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (find_details->active_match_ordinal() > -1) {
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        active_match_ordinal_ = find_details->active_match_ordinal();
113572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        AutomationMsg_Find::WriteReplyParams(reply_message_.get(),
1136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            active_match_ordinal_, find_details->number_of_matches());
113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        automation_->Send(reply_message_.release());
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int FindInPageNotificationObserver::kFindInPageRequestId = -1;
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochDomOperationObserver::DomOperationObserver() {
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDomOperationObserver::~DomOperationObserver() {}
115272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DomOperationObserver::Observe(
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (NotificationType::DOM_OPERATION_RESPONSE == type) {
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Details<DomOperationNotificationDetails> dom_op_details(details);
11584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    OnDomOperationCompleted(dom_op_details->json());
11594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
11604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDomOperationMessageSender::DomOperationMessageSender(
1163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationProvider* automation,
1164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Message* reply_message,
1165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool use_json_interface)
1166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : automation_(automation->AsWeakPtr()),
1167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reply_message_(reply_message),
1168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      use_json_interface_(use_json_interface) {
116972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
117072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
117172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDomOperationMessageSender::~DomOperationMessageSender() {}
117272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DomOperationMessageSender::OnDomOperationCompleted(
11744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string& json) {
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (automation_) {
1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (use_json_interface_) {
1177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DictionaryValue dict;
1178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      dict.SetString("result", json);
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutomationJSONReply(automation_, reply_message_.release())
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .SendSuccess(&dict);
1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutomationMsg_DomOperation::WriteReplyParams(reply_message_.get(), json);
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      automation_->Send(reply_message_.release());
1184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete this;
1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDocumentPrintedNotificationObserver::DocumentPrintedNotificationObserver(
1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation, IPC::Message* reply_message)
119172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success_(false),
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message_(reply_message) {
1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDocumentPrintedNotificationObserver::~DocumentPrintedNotificationObserver() {
119972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
120072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_PrintNow::WriteReplyParams(reply_message_.get(), success_);
120172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
120272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DocumentPrintedNotificationObserver::Observe(
1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type, const NotificationSource& source,
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  using namespace printing;
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::PRINT_JOB_EVENT);
1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (Details<JobEventDetails>(details)->type()) {
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::JOB_DONE: {
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Succeeded.
1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success_ = true;
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      delete this;
1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::USER_INIT_CANCELED:
1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::FAILED: {
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Failed.
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      delete this;
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::NEW_DOC:
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::USER_INIT_DONE:
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::DEFAULT_INIT_DONE:
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::NEW_PAGE:
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::PAGE_DONE:
1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::DOC_DONE:
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case JobEventDetails::ALL_PAGES_REQUESTED: {
1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Don't care.
1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default: {
1234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMetricEventDurationObserver::MetricEventDurationObserver() {
1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::METRIC_EVENT_DURATION,
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1245731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickMetricEventDurationObserver::~MetricEventDurationObserver() {}
1246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint MetricEventDurationObserver::GetEventDurationMs(
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& event_name) {
1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EventDurationMap::const_iterator it = durations_.find(event_name);
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (it == durations_.end())
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return -1;
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return it->second;
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MetricEventDurationObserver::Observe(NotificationType type,
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationSource& source, const NotificationDetails& details) {
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type != NotificationType::METRIC_EVENT_DURATION) {
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MetricEventDurationDetails* metric_event_duration =
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<MetricEventDurationDetails>(details).ptr();
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  durations_[metric_event_duration->event_name] =
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      metric_event_duration->duration_ms;
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12673345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickPageTranslatedObserver::PageTranslatedObserver(AutomationProvider* automation,
12683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                               IPC::Message* reply_message,
12693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                               TabContents* tab_contents)
127072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  : automation_(automation->AsWeakPtr()),
12713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    reply_message_(reply_message) {
12723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::PAGE_TRANSLATED,
12733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 Source<TabContents>(tab_contents));
12743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
12753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1276731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickPageTranslatedObserver::~PageTranslatedObserver() {}
1277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
12783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid PageTranslatedObserver::Observe(NotificationType type,
12793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     const NotificationSource& source,
12803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     const NotificationDetails& details) {
128172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
128272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
128372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
128472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
128572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(type == NotificationType::PAGE_TRANSLATED);
128772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationJSONReply reply(automation_, reply_message_.release());
12883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
12893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PageTranslatedDetails* translated_details =
12903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Details<PageTranslatedDetails>(details).ptr();
12913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
12923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->SetBoolean(
12933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "translation_success",
12943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      translated_details->error_type == TranslateErrors::NONE);
12953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  reply.SendSuccess(return_value.get());
12963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
12973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
12983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
12993345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTabLanguageDeterminedObserver::TabLanguageDeterminedObserver(
13003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    AutomationProvider* automation, IPC::Message* reply_message,
13013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TabContents* tab_contents, TranslateInfoBarDelegate* translate_bar)
130272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
130372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
130472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      tab_contents_(tab_contents),
130572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      translate_bar_(translate_bar) {
13063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED,
13073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 Source<TabContents>(tab_contents));
13083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
131072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTabLanguageDeterminedObserver::~TabLanguageDeterminedObserver() {}
131172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TabLanguageDeterminedObserver::Observe(
13133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NotificationType type, const NotificationSource& source,
13143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const NotificationDetails& details) {
13153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(type == NotificationType::TAB_LANGUAGE_DETERMINED);
13163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
131772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
131872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
131972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
132072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
132172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents(
1323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents_)->translate_tab_helper();
13243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
13253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->SetBoolean("page_translated",
1326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           helper->language_state().IsPageTranslated());
13273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->SetBoolean(
13283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "can_translate_page", TranslatePrefs::CanTranslate(
13293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          automation_->profile()->GetPrefs(),
1330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          helper->language_state().original_language(),
13313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          tab_contents_->GetURL()));
1332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return_value->SetString("original_language",
1333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          helper->language_state().original_language());
13343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (translate_bar_) {
13353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DictionaryValue* bar_info = new DictionaryValue;
13363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::map<TranslateInfoBarDelegate::Type, std::string> type_to_string;
13373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    type_to_string[TranslateInfoBarDelegate::BEFORE_TRANSLATE] =
13383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "BEFORE_TRANSLATE";
13393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    type_to_string[TranslateInfoBarDelegate::TRANSLATING] =
13403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "TRANSLATING";
13413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    type_to_string[TranslateInfoBarDelegate::AFTER_TRANSLATE] =
13423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "AFTER_TRANSLATE";
13433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    type_to_string[TranslateInfoBarDelegate::TRANSLATION_ERROR] =
13443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "TRANSLATION_ERROR";
13453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bar_info->SetBoolean("always_translate_lang_button_showing",
13473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         translate_bar_->ShouldShowAlwaysTranslateButton());
13483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bar_info->SetBoolean("never_translate_lang_button_showing",
13493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         translate_bar_->ShouldShowNeverTranslateButton());
13503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bar_info->SetString("bar_state", type_to_string[translate_bar_->type()]);
13513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bar_info->SetString("target_lang_code",
13523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        translate_bar_->GetTargetLanguageCode());
13533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bar_info->SetString("original_lang_code",
13543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        translate_bar_->GetOriginalLanguageCode());
13553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return_value->Set("translate_bar", bar_info);
13563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
135772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationJSONReply(automation_, reply_message_.release())
13583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .SendSuccess(return_value.get());
13593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
13603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickInfoBarCountObserver::InfoBarCountObserver(AutomationProvider* automation,
13633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           IPC::Message* reply_message,
13643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           TabContents* tab_contents,
136572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                           size_t target_count)
136672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
13673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      reply_message_(reply_message),
13683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      tab_contents_(tab_contents),
13693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      target_count_(target_count) {
13703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Source<TabContents> source(tab_contents);
13713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, source);
13723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, source);
13733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckCount();
13743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
137672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenInfoBarCountObserver::~InfoBarCountObserver() {}
137772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid InfoBarCountObserver::Observe(NotificationType type,
13793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   const NotificationSource& source,
13803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   const NotificationDetails& details) {
13813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(type == NotificationType::TAB_CONTENTS_INFOBAR_ADDED ||
13823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED);
13833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckCount();
13843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid InfoBarCountObserver::CheckCount() {
138772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (tab_contents_->infobar_count() != target_count_)
13883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
13893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
139072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
139172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForInfoBarCount::WriteReplyParams(reply_message_.get(),
139272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                        true);
139372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
139472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
13953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
13963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
13973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13983345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAutomationProviderBookmarkModelObserver::
13993345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAutomationProviderBookmarkModelObserver(
1400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* provider,
1401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message,
140272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    BookmarkModel* model)
140372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_provider_(provider->AsWeakPtr()),
140472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
140572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      model_(model) {
1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  model_->AddObserver(this);
1407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14093345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAutomationProviderBookmarkModelObserver::
1410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderBookmarkModelObserver() {
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  model_->RemoveObserver(this);
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid AutomationProviderBookmarkModelObserver::Loaded(BookmarkModel* model) {
141521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReplyAndDelete(true);
141621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
141721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
141821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid AutomationProviderBookmarkModelObserver::BookmarkModelBeingDeleted(
141921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BookmarkModel* model) {
142021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReplyAndDelete(false);
142121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
142221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProviderBookmarkModelObserver::ReplyAndDelete(bool success) {
142472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_provider_) {
142572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
142672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), success);
142772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_provider_->Send(reply_message_.release());
142872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadItemObserver::AutomationProviderDownloadItemObserver(
143372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
143472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message,
143572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    int downloads)
143672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
143772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
1438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      downloads_(downloads),
1439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      interrupted_(false) {
144072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
144172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
144272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadItemObserver::
1443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderDownloadItemObserver() {}
144472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
144572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProviderDownloadItemObserver::OnDownloadUpdated(
144672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DownloadItem* download) {
1447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  interrupted_ |= download->IsInterrupted();
1448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If any download was interrupted, on the next update each outstanding
1449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // download is cancelled.
1450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (interrupted_) {
1451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // |Cancel()| does nothing if |download| is already interrupted.
1452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download->Cancel(true);
1453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RemoveAndCleanupOnLastEntry(download);
1454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download->IsComplete())
1457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RemoveAndCleanupOnLastEntry(download);
145872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
145972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// We don't want to send multiple messages, as the behavior is undefined.
1461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Set |interrupted_| on error, and on the last download completed/
1462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// interrupted, send either an error or a success message.
1463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutomationProviderDownloadItemObserver::RemoveAndCleanupOnLastEntry(
1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DownloadItem* download) {
1465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Forget about the download.
1466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  download->RemoveObserver(this);
1467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (--downloads_ == 0) {
146872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (provider_) {
1469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (interrupted_) {
1470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationJSONReply(provider_, reply_message_.release()).SendError(
1471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            "Download Interrupted");
1472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(
1474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            NULL);
1475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
147672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
1478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProviderDownloadItemObserver::OnDownloadOpened(
148272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DownloadItem* download) {
148372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
148472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
148572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadUpdatedObserver::
148672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadUpdatedObserver(
148772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
148872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message,
148972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool wait_for_open)
149072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
149172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
149272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      wait_for_open_(wait_for_open) {
149372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
149472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
149572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadUpdatedObserver::
1496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderDownloadUpdatedObserver() {}
149772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProviderDownloadUpdatedObserver::OnDownloadUpdated(
14993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DownloadItem* download) {
15003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If this observer is watching for open, only send the reply if the download
15013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // has been auto-opened.
15023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (wait_for_open_ && !download->auto_opened())
15033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
15043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download->RemoveObserver(this);
15063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<DictionaryValue> return_value(
15073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      provider_->GetDictionaryFromDownloadItem(download));
150872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
150972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_) {
151072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(
151172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        return_value.get());
151272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
15133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
15143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
15153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProviderDownloadUpdatedObserver::OnDownloadOpened(
15173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DownloadItem* download) {
15183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download->RemoveObserver(this);
15193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<DictionaryValue> return_value(
15203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      provider_->GetDictionaryFromDownloadItem(download));
152172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
152272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_) {
152372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(
152472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        return_value.get());
152572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
15263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
15273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
15283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
152972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadModelChangedObserver::
153072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadModelChangedObserver(
153172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
153272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message,
153372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DownloadManager* download_manager)
153472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
153572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
153672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      download_manager_(download_manager) {
153772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
153872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
153972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderDownloadModelChangedObserver::
1540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderDownloadModelChangedObserver() {}
154172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProviderDownloadModelChangedObserver::ModelChanged() {
15433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  download_manager_->RemoveObserver(this);
154472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
154572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_)
154672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(NULL);
15473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
15483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
15493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
155072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderSearchEngineObserver::AutomationProviderSearchEngineObserver(
155172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
155272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
155372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
155472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
155572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
155672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
155772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderSearchEngineObserver::
1558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderSearchEngineObserver() {}
155972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProviderSearchEngineObserver::OnTemplateURLModelChanged() {
15613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TemplateURLModel* url_model = provider_->profile()->GetTemplateURLModel();
15623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url_model->RemoveObserver(this);
156372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
156472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_)
156572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(NULL);
15663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delete this;
15673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
156972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderHistoryObserver::AutomationProviderHistoryObserver(
157072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
157172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
157272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
157372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
157472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
157572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
157672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderHistoryObserver::~AutomationProviderHistoryObserver() {}
157772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProviderHistoryObserver::HistoryQueryComplete(
1579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HistoryService::Handle request_handle,
1580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history::QueryResults* results) {
158172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!provider_) {
158272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
158372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
158472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
158572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* history_list = new ListValue;
1589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < results->size(); ++i) {
1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* page_value = new DictionaryValue;
1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history::URLResult const &page = (*results)[i];
15923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    page_value->SetString("title", page.title());
15933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    page_value->SetString("url", page.url().spec());
159472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    page_value->SetDouble("time",
159572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          static_cast<double>(page.visit_time().ToDoubleT()));
15963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    page_value->SetString("snippet", page.snippet().text());
1597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    page_value->SetBoolean(
15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "starred",
1599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        provider_->profile()->GetBookmarkModel()->IsBookmarked(page.url()));
1600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history_list->Append(page_value);
1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->Set("history", history_list);
1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return history info.
160572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationJSONReply reply(provider_, reply_message_.release());
1606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  reply.SendSuccess(return_value.get());
1607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderImportSettingsObserver::
161172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderImportSettingsObserver(
161272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
161372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
161472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
161572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
161672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
161772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
161872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderImportSettingsObserver::
1619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderImportSettingsObserver() {}
162072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
162172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProviderImportSettingsObserver::ImportStarted() {
162272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
162372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
162472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProviderImportSettingsObserver::ImportItemStarted(
162572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    importer::ImportItem item) {
162672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
162772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
162872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProviderImportSettingsObserver::ImportItemEnded(
162972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    importer::ImportItem item) {
163072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
163172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProviderImportSettingsObserver::ImportEnded() {
163372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_)
163472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(NULL);
1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderGetPasswordsObserver::AutomationProviderGetPasswordsObserver(
163972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
164072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
164172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
164272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
164372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
164472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
164572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderGetPasswordsObserver::
1646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderGetPasswordsObserver() {}
164772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProviderGetPasswordsObserver::OnPasswordStoreRequestDone(
1649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CancelableRequestProvider::Handle handle,
1650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::vector<webkit_glue::PasswordForm*>& result) {
165172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!provider_) {
165272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
165372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
165472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
165572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* passwords = new ListValue;
1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<webkit_glue::PasswordForm*>::const_iterator it =
1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          result.begin(); it != result.end(); ++it) {
1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* password_val = new DictionaryValue;
1662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    webkit_glue::PasswordForm* password_form = *it;
16633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("username_value", password_form->username_value);
16643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("password_value", password_form->password_value);
16653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("signon_realm", password_form->signon_realm);
166672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    password_val->SetDouble(
16673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "time", static_cast<double>(password_form->date_created.ToDoubleT()));
16683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("origin_url", password_form->origin.spec());
16693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("username_element",
16703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            password_form->username_element);
16713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("password_element",
16723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            password_form->password_element);
16733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("submit_element",
16743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     password_form->submit_element);
16753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetString("action_target", password_form->action.spec());
16763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    password_val->SetBoolean("blacklist", password_form->blacklisted_by_user);
1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    passwords->Append(password_val);
1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return_value->Set("passwords", passwords);
168172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return_value.get());
1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderBrowsingDataObserver::AutomationProviderBrowsingDataObserver(
168772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* provider,
168872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
168972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : provider_(provider->AsWeakPtr()),
169072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
169172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
169272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
169372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutomationProviderBrowsingDataObserver::
1694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~AutomationProviderBrowsingDataObserver() {}
169572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProviderBrowsingDataObserver::OnBrowsingDataRemoverDone() {
169772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (provider_)
169872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(provider_, reply_message_.release()).SendSuccess(NULL);
1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOmniboxAcceptNotificationObserver::OmniboxAcceptNotificationObserver(
1703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller,
1704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
1705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message)
170672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
170772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
170872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controller_(controller) {
1709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Source<NavigationController> source(controller_);
1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::LOAD_STOP, source);
1711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pages requiring auth don't send LOAD_STOP.
1712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOmniboxAcceptNotificationObserver::~OmniboxAcceptNotificationObserver() {
1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OmniboxAcceptNotificationObserver::Observe(
1719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type,
1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationSource& source,
1721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::LOAD_STOP ||
1723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type == NotificationType::AUTH_NEEDED) {
172472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (automation_) {
172572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationJSONReply(automation_,
172672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          reply_message_.release()).SendSuccess(NULL);
172772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
1728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
1729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
1730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1734c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSavePackageNotificationObserver::SavePackageNotificationObserver(
1735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SavePackage* save_package,
1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
173772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message)
173872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
173972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Source<SavePackage> source(save_package);
1741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 source);
1743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
174572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSavePackageNotificationObserver::~SavePackageNotificationObserver() {}
174672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SavePackageNotificationObserver::Observe(
1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type,
1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationSource& source,
1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
1751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED) {
175272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (automation_) {
175372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationJSONReply(automation_,
175472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          reply_message_.release()).SendSuccess(NULL);
175572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete this;
1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochPageSnapshotTaker::PageSnapshotTaker(AutomationProvider* automation,
17634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                     IPC::Message* reply_message,
17644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                     RenderViewHost* render_view,
17654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                     const FilePath& path)
176672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
17674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      reply_message_(reply_message),
17684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      render_view_(render_view),
17694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      image_path_(path),
17704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      received_width_(false) {}
17714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
177272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenPageSnapshotTaker::~PageSnapshotTaker() {}
177372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid PageSnapshotTaker::Start() {
17754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExecuteScript(L"window.domAutomationController.send(document.width);");
17764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
17774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
17784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid PageSnapshotTaker::OnDomOperationCompleted(const std::string& json) {
17794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int dimension;
17804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!base::StringToInt(json, &dimension)) {
17814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    LOG(ERROR) << "Could not parse received dimensions: " << json;
17824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    SendMessage(false);
17834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else if (!received_width_) {
17844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    received_width_ = true;
17854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    entire_page_size_.set_width(dimension);
17864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
17874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ExecuteScript(L"window.domAutomationController.send(document.height);");
17884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else {
17894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    entire_page_size_.set_height(dimension);
17904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
17914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ThumbnailGenerator* generator =
17924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        g_browser_process->GetThumbnailGenerator();
17934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ThumbnailGenerator::ThumbnailReadyCallback* callback =
17944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        NewCallback(this, &PageSnapshotTaker::OnSnapshotTaken);
17954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Don't actually start the thumbnail generator, this leads to crashes on
17964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Mac, crbug.com/62986. Instead, just hook the generator to the
17974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // RenderViewHost manually.
179872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
179972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    generator->MonitorRenderer(render_view_, true);
18004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    generator->AskForSnapshot(render_view_, false, callback,
18014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              entire_page_size_, entire_page_size_);
18024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
18034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
18044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
18054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid PageSnapshotTaker::OnSnapshotTaken(const SkBitmap& bitmap) {
18064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::ThreadRestrictions::ScopedAllowIO allow_io;
18074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::vector<unsigned char> png_data;
18084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data);
18094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int bytes_written = file_util::WriteFile(image_path_,
18104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      reinterpret_cast<char*>(&png_data[0]), png_data.size());
18114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  SendMessage(bytes_written == static_cast<int>(png_data.size()));
18124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
18134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
18144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid PageSnapshotTaker::ExecuteScript(const std::wstring& javascript) {
18154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::wstring set_automation_id;
18164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::SStringPrintf(
18174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      &set_automation_id,
18184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      L"window.domAutomationController.setAutomationId(%d);",
18194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      reply_message_->routing_id());
18204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
182172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  render_view_->ExecuteJavascriptInWebFrame(string16(),
182272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                            WideToUTF16Hack(set_automation_id));
182372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  render_view_->ExecuteJavascriptInWebFrame(string16(),
182472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                            WideToUTF16Hack(javascript));
18254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
18264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
18274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid PageSnapshotTaker::SendMessage(bool success) {
182872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
1829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (success) {
1830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutomationJSONReply(automation_, reply_message_.release())
1831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .SendSuccess(NULL);
1832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutomationJSONReply(automation_, reply_message_.release())
1834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .SendError("Failed to take snapshot of page");
1835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
183672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
18374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  delete this;
18384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
18394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
1841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Returns a vector of dictionaries containing information about installed apps,
1843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// as identified from a given list of extensions.  The caller takes ownership
1844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// of the created vector.
1845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::vector<DictionaryValue*>* GetAppInfoFromExtensions(
1846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const ExtensionList* extensions,
1847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionPrefs* ext_prefs) {
1848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DictionaryValue*>* apps_list =
1849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new std::vector<DictionaryValue*>();
1850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (ExtensionList::const_iterator ext = extensions->begin();
1851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       ext != extensions->end(); ++ext) {
1852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Only return information about extensions that are actually apps.
1853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ((*ext)->is_app()) {
1854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DictionaryValue* app_info = new DictionaryValue();
1855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AppLauncherHandler::CreateAppInfo(*ext, ext_prefs, app_info);
1856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      app_info->SetBoolean("is_component_extension",
1857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           (*ext)->location() == Extension::COMPONENT);
1858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Convert the launch_type integer into a more descriptive string.
1860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int launch_type;
1861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      app_info->GetInteger("launch_type", &launch_type);
1862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (launch_type == ExtensionPrefs::LAUNCH_PINNED) {
1863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        app_info->SetString("launch_type", "pinned");
1864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (launch_type == ExtensionPrefs::LAUNCH_REGULAR) {
1865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        app_info->SetString("launch_type", "regular");
1866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN) {
1867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        app_info->SetString("launch_type", "fullscreen");
1868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (launch_type == ExtensionPrefs::LAUNCH_WINDOW) {
1869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        app_info->SetString("launch_type", "window");
1870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
1871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        app_info->SetString("launch_type", "unknown");
1872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      apps_list->push_back(app_info);
1875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return apps_list;
1878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
1881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1882201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochNTPInfoObserver::NTPInfoObserver(
1883201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    AutomationProvider* automation,
1884201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    IPC::Message* reply_message,
1885201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    CancelableRequestConsumer* consumer)
188672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
188772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
188872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      consumer_(consumer),
188972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      request_(0),
189072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ntp_info_(new DictionaryValue) {
1891201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  top_sites_ = automation_->profile()->GetTopSites();
1892201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!top_sites_) {
189372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(automation_, reply_message_.release())
1894201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        .SendError("Profile does not have service for querying the top sites.");
1895201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
1896201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1897201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabRestoreService* service = automation_->profile()->GetTabRestoreService();
1898201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!service) {
189972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(automation_, reply_message_.release())
1900201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        .SendError("No TabRestoreService.");
1901201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
1902201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1903201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Collect information about the apps in the new tab page.
1905dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExtensionService* ext_service = automation_->profile()->GetExtensionService();
1906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!ext_service) {
1907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationJSONReply(automation_, reply_message_.release())
1908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        .SendError("No ExtensionService.");
1909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
1910dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Process enabled extensions.
1912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionPrefs* ext_prefs = ext_service->extension_prefs();
1913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ListValue* apps_list = new ListValue();
1914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const ExtensionList* extensions = ext_service->extensions();
1915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DictionaryValue*>* enabled_apps = GetAppInfoFromExtensions(
1916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      extensions, ext_prefs);
1917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (std::vector<DictionaryValue*>::const_iterator app =
1918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       enabled_apps->begin(); app != enabled_apps->end(); ++app) {
1919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    (*app)->SetBoolean("is_disabled", false);
1920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    apps_list->Append(*app);
1921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete enabled_apps;
1923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Process disabled extensions.
1924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const ExtensionList* disabled_extensions = ext_service->disabled_extensions();
1925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DictionaryValue*>* disabled_apps = GetAppInfoFromExtensions(
1926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      disabled_extensions, ext_prefs);
1927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (std::vector<DictionaryValue*>::const_iterator app =
1928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       disabled_apps->begin(); app != disabled_apps->end(); ++app) {
1929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    (*app)->SetBoolean("is_disabled", true);
1930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    apps_list->Append(*app);
1931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete disabled_apps;
1933dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ntp_info_->Set("apps", apps_list);
1934dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1935201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Get the info that would be displayed in the recently closed section.
1936201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ListValue* recently_closed_list = new ListValue;
1937201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  NewTabUI::AddRecentlyClosedEntries(service->entries(),
1938201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                     recently_closed_list);
1939201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ntp_info_->Set("recently_closed", recently_closed_list);
1940201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1941201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Add default site URLs.
1942201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ListValue* default_sites_list = new ListValue;
1943201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<GURL> urls = MostVisitedHandler::GetPrePopulatedUrls();
1944201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < urls.size(); ++i) {
1945201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    default_sites_list->Append(Value::CreateStringValue(
1946201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        urls[i].possibly_invalid_spec()));
1947201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1948201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ntp_info_->Set("default_sites", default_sites_list);
1949201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1950201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  registrar_.Add(this, NotificationType::TOP_SITES_UPDATED,
1951201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 Source<history::TopSites>(top_sites_));
1952201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (top_sites_->loaded()) {
1953201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    OnTopSitesLoaded();
1954201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  } else {
1955201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    registrar_.Add(this, NotificationType::TOP_SITES_LOADED,
1956201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                   Source<Profile>(automation_->profile()));
1957201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1958201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1959201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
196021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenNTPInfoObserver::~NTPInfoObserver() {}
196121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1962201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NTPInfoObserver::Observe(NotificationType type,
1963201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                              const NotificationSource& source,
1964201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                              const NotificationDetails& details) {
1965201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (type == NotificationType::TOP_SITES_LOADED) {
1966201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    OnTopSitesLoaded();
1967201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  } else if (type == NotificationType::TOP_SITES_UPDATED) {
1968201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    Details<CancelableRequestProvider::Handle> request_details(details);
1969201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (request_ == *request_details.ptr()) {
1970201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      top_sites_->GetMostVisitedURLs(
1971201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          consumer_,
1972201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          NewCallback(this, &NTPInfoObserver::OnTopSitesReceived));
1973201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
1974201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1975201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1976201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1977201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NTPInfoObserver::OnTopSitesLoaded() {
1978201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  request_ = top_sites_->StartQueryForMostVisited();
1979201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1980201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1981201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NTPInfoObserver::OnTopSitesReceived(
1982201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const history::MostVisitedURLList& visited_list) {
198372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!automation_) {
198472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
198572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
198672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
198772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1988201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ListValue* list_value = new ListValue;
1989201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < visited_list.size(); ++i) {
1990201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const history::MostVisitedURL& visited = visited_list[i];
1991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (visited.url.spec().empty())
1992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      break;  // This is the signal that there are no more real visited sites.
1993201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DictionaryValue* dict = new DictionaryValue;
1994201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    dict->SetString("url", visited.url.spec());
1995201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    dict->SetString("title", visited.title);
1996201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    dict->SetBoolean("is_pinned", top_sites_->IsURLPinned(visited.url));
1997201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    list_value->Append(dict);
1998201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1999201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ntp_info_->Set("most_visited", list_value);
200072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutomationJSONReply(automation_,
200172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      reply_message_.release()).SendSuccess(ntp_info_.get());
2002201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  delete this;
2003201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
2004201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenAppLaunchObserver::AppLaunchObserver(
2006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NavigationController* controller,
2007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AutomationProvider* automation,
2008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Message* reply_message,
2009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    extension_misc::LaunchContainer launch_container)
2010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : controller_(controller),
2011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      automation_(automation->AsWeakPtr()),
2012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reply_message_(reply_message),
2013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      launch_container_(launch_container),
2014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new_window_id_(extension_misc::kUnknownWindowId) {
2015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (launch_container_ == extension_misc::LAUNCH_TAB) {
2016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Need to wait for the currently-active tab to reload.
2017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Source<NavigationController> source(controller_);
2018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    registrar_.Add(this, NotificationType::LOAD_STOP, source);
2019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
2020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Need to wait for a new tab in a new window to load.
2021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    registrar_.Add(this, NotificationType::LOAD_STOP,
2022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   NotificationService::AllSources());
2023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    registrar_.Add(this, NotificationType::BROWSER_WINDOW_READY,
2024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   NotificationService::AllSources());
2025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenAppLaunchObserver::~AppLaunchObserver() {}
2029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AppLaunchObserver::Observe(NotificationType type,
2031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const NotificationSource& source,
2032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const NotificationDetails& details) {
2033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (type.value == NotificationType::LOAD_STOP) {
2034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (launch_container_ == extension_misc::LAUNCH_TAB) {
2035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The app has been launched in the new tab.
2036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (automation_) {
2037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutomationJSONReply(automation_,
2038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            reply_message_.release()).SendSuccess(NULL);
2039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
2040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delete this;
2041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
2042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
2043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The app has launched only if the loaded tab is in the new window.
2044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int window_id = Source<NavigationController>(source)->window_id().id();
2045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (window_id == new_window_id_) {
2046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (automation_) {
2047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          AutomationJSONReply(automation_,
2048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              reply_message_.release()).SendSuccess(NULL);
2049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
2050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        delete this;
2051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
2052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
2053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (type.value == NotificationType::BROWSER_WINDOW_READY) {
2055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    new_window_id_ = ExtensionTabUtil::GetWindowId(
2056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Source<Browser>(source).ptr());
2057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
2058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NOTREACHED();
2059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
20623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAutocompleteEditFocusedObserver::AutocompleteEditFocusedObserver(
2063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationProvider* automation,
20643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    AutocompleteEditModel* autocomplete_edit,
20653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    IPC::Message* reply_message)
206672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
20673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      reply_message_(reply_message),
20683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      autocomplete_edit_model_(autocomplete_edit) {
20693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Source<AutocompleteEditModel> source(autocomplete_edit);
20703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::AUTOCOMPLETE_EDIT_FOCUSED, source);
2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAutocompleteEditFocusedObserver::~AutocompleteEditFocusedObserver() {}
207472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutocompleteEditFocusedObserver::Observe(
2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type,
2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationSource& source,
2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
20793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(type == NotificationType::AUTOCOMPLETE_EDIT_FOCUSED);
208072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
208172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WaitForAutocompleteEditFocus::WriteReplyParams(
208272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reply_message_.get(), true);
208372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
208472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
2085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
2086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2087731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
208821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace {
208921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
209021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Returns whether the notification's host has a non-null process handle.
209121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsNotificationProcessReady(Balloon* balloon) {
209221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return balloon->view() &&
209321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen         balloon->view()->GetHost() &&
209421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen         balloon->view()->GetHost()->render_view_host() &&
209521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen         balloon->view()->GetHost()->render_view_host()->process()->GetHandle();
209621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
209721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
209821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Returns whether all active notifications have an associated process ID.
209921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool AreActiveNotificationProcessesReady() {
210021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationUIManager* manager = g_browser_process->notification_ui_manager();
210121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const BalloonCollection::Balloons& balloons =
210221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      manager->balloon_collection()->GetActiveBalloons();
210321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BalloonCollection::Balloons::const_iterator iter;
210421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (iter = balloons.begin(); iter != balloons.end(); ++iter) {
210521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!IsNotificationProcessReady(*iter))
210621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return false;
210721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
210821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return true;
210921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
211021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
211121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace
211221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
211321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenGetActiveNotificationsObserver::GetActiveNotificationsObserver(
211421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    AutomationProvider* automation,
211521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    IPC::Message* reply_message)
211621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : reply_(automation, reply_message) {
211721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (AreActiveNotificationProcessesReady()) {
211821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SendMessage();
211921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
212021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    registrar_.Add(this, NotificationType::RENDERER_PROCESS_CREATED,
212121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   NotificationService::AllSources());
212221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
212321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
212421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
212572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenGetActiveNotificationsObserver::~GetActiveNotificationsObserver() {}
212672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
212721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid GetActiveNotificationsObserver::Observe(
212821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NotificationType type,
212921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const NotificationSource& source,
213021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const NotificationDetails& details) {
213121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (AreActiveNotificationProcessesReady())
213221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SendMessage();
213321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
213421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
213521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid GetActiveNotificationsObserver::SendMessage() {
213621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationUIManager* manager =
213721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      g_browser_process->notification_ui_manager();
213821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const BalloonCollection::Balloons& balloons =
213921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      manager->balloon_collection()->GetActiveBalloons();
214021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
214121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ListValue* list = new ListValue;
214221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return_value->Set("notifications", list);
214321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BalloonCollection::Balloons::const_iterator iter;
214421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (iter = balloons.begin(); iter != balloons.end(); ++iter) {
214521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const Notification& notification = (*iter)->notification();
214621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DictionaryValue* balloon = new DictionaryValue;
214721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    balloon->SetString("content_url", notification.content_url().spec());
214821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    balloon->SetString("origin_url", notification.origin_url().spec());
214921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    balloon->SetString("display_source", notification.display_source());
215021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BalloonView* view = (*iter)->view();
215121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    balloon->SetInteger("pid", base::GetProcId(
215221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        view->GetHost()->render_view_host()->process()->GetHandle()));
215321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    list->Append(balloon);
215421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
215521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  reply_.SendSuccess(return_value.get());
215621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  delete this;
215721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
215821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2159513209b27ff55e2841eac0e4120199c23acce758Ben MurdochOnNotificationBalloonCountObserver::OnNotificationBalloonCountObserver(
2160513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    AutomationProvider* provider,
2161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    IPC::Message* reply_message,
2162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    BalloonCollection* collection,
2163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    int count)
2164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    : reply_(provider, reply_message),
2165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      collection_(collection),
2166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      count_(count) {
2167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  collection->set_on_collection_changed_callback(NewCallback(
2168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      this, &OnNotificationBalloonCountObserver::OnBalloonCollectionChanged));
2169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
2170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2171513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid OnNotificationBalloonCountObserver::OnBalloonCollectionChanged() {
2172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (static_cast<int>(collection_->GetActiveBalloons().size()) == count_) {
2173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    collection_->set_on_collection_changed_callback(NULL);
2174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reply_.SendSuccess(NULL);
2175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    delete this;
2176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
2177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
217821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
217921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenRendererProcessClosedObserver::RendererProcessClosedObserver(
218021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    AutomationProvider* automation,
218121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    IPC::Message* reply_message)
218272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
218321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      reply_message_(reply_message) {
218421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED,
218521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
218621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
218721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
218872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRendererProcessClosedObserver::~RendererProcessClosedObserver() {}
218972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
219021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid RendererProcessClosedObserver::Observe(
219121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NotificationType type,
219221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const NotificationSource& source,
219321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const NotificationDetails& details) {
219472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
219572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationJSONReply(automation_,
219672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        reply_message_.release()).SendSuccess(NULL);
219772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
219872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delete this;
219972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
220072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
220172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenInputEventAckNotificationObserver::InputEventAckNotificationObserver(
220272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* automation,
220372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC::Message* reply_message,
220472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    int event_type)
220572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
220672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message),
220772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      event_type_(event_type) {
220872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  registrar_.Add(
220972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      this, NotificationType::RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
221072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NotificationService::AllSources());
221172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
221272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
221372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenInputEventAckNotificationObserver::~InputEventAckNotificationObserver() {}
221472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
221572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid InputEventAckNotificationObserver::Observe(
221672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotificationType type,
221772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const NotificationSource& source,
221872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const NotificationDetails& details) {
221972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Details<int> request_details(details);
222072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (event_type_ == *request_details.ptr()) {
222172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (automation_) {
222272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      AutomationJSONReply(automation_,
222372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          reply_message_.release()).SendSuccess(NULL);
222472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
222572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delete this;
222672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
222772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LOG(WARNING) << "Ignoring unexpected event types.";
222872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
222972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
223072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2231dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAllTabsStoppedLoadingObserver::AllTabsStoppedLoadingObserver(
2232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    AutomationProvider* automation,
2233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    IPC::Message* reply_message)
2234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : automation_(automation->AsWeakPtr()),
2235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      reply_message_(reply_message) {
2236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (BrowserList::const_iterator iter = BrowserList::begin();
2237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       iter != BrowserList::end();
2238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       ++iter) {
2239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Browser* browser = *iter;
2240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (int i = 0; i < browser->tab_count(); ++i) {
2241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabContentsWrapper* contents_wrapper =
2242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          browser->GetTabContentsWrapperAt(i);
2243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      StartObserving(contents_wrapper->automation_tab_helper());
2244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (contents_wrapper->automation_tab_helper()->has_pending_loads())
2245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        pending_tabs_.insert(contents_wrapper->tab_contents());
2246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
2247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CheckIfNoMorePendingLoads();
2249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
2250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
2251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenAllTabsStoppedLoadingObserver::~AllTabsStoppedLoadingObserver() {
2252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
2254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AllTabsStoppedLoadingObserver::OnFirstPendingLoad(
2255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContents* tab_contents) {
2256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_tabs_.insert(tab_contents);
2257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
2258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
2259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AllTabsStoppedLoadingObserver::OnNoMorePendingLoads(
2260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContents* tab_contents) {
2261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!automation_) {
2262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    delete this;
2263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
2264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
2265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabSet::iterator iter = pending_tabs_.find(tab_contents);
2267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (iter == pending_tabs_.end()) {
2268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(ERROR) << "Received OnNoMorePendingLoads for tab without "
2269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               << "OnFirstPendingLoad.";
2270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
2271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_tabs_.erase(iter);
2273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CheckIfNoMorePendingLoads();
2274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AllTabsStoppedLoadingObserver::CheckIfNoMorePendingLoads() {
2277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!automation_) {
2278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete this;
2279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
2280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
2281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (pending_tabs_.empty()) {
2283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    AutomationJSONReply(automation_,
2284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        reply_message_.release()).SendSuccess(NULL);
2285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    delete this;
2286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
2287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
2288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
228972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNewTabObserver::NewTabObserver(AutomationProvider* automation,
229072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               IPC::Message* reply_message)
229172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
229272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
229372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Use TAB_PARENTED to detect the new tab.
229472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  registrar_.Add(this,
229572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 NotificationType::TAB_PARENTED,
229672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 NotificationService::AllSources());
229772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
229872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
229972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NewTabObserver::Observe(NotificationType type,
230072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             const NotificationSource& source,
230172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             const NotificationDetails& details) {
230272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(NotificationType::TAB_PARENTED, type.value);
230372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NavigationController* controller = Source<NavigationController>(source).ptr();
230472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_) {
230572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // TODO(phajdan.jr): Clean up this hack. We write the correct return type
230672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // here, but don't send the message. NavigationNotificationObserver
230772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // will wait properly for the load to finish, and send the message,
230872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // but it will also append its own return value at the end of the reply.
230972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_.get(),
231072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                         true);
231172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    new NavigationNotificationObserver(controller, automation_,
231272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       reply_message_.release(),
2313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       1, false, false);
231472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
231521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  delete this;
231621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
231772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
231872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNewTabObserver::~NewTabObserver() {
231972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
232072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
232172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWaitForProcessLauncherThreadToGoIdleObserver::
232272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWaitForProcessLauncherThreadToGoIdleObserver(
232372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AutomationProvider* automation, IPC::Message* reply_message)
232472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : automation_(automation->AsWeakPtr()),
232572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reply_message_(reply_message) {
232672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Balanced in RunOnUIThread.
232772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AddRef();
232872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BrowserThread::PostTask(
232972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
233072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(
233172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          this,
233272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          &WaitForProcessLauncherThreadToGoIdleObserver::
233372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              RunOnProcessLauncherThread));
233472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
233572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
233672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWaitForProcessLauncherThreadToGoIdleObserver::
2337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~WaitForProcessLauncherThreadToGoIdleObserver() {
233872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
233972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
234072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid WaitForProcessLauncherThreadToGoIdleObserver::
234172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRunOnProcessLauncherThread() {
2342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER));
234372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BrowserThread::PostTask(
234472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
234572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(
234672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          this,
2347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          &WaitForProcessLauncherThreadToGoIdleObserver::
2348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          RunOnProcessLauncherThread2));
2349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
2350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
2351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid WaitForProcessLauncherThreadToGoIdleObserver::
2352dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenRunOnProcessLauncherThread2() {
2353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER));
2354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BrowserThread::PostTask(
2355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      BrowserThread::UI, FROM_HERE,
2356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NewRunnableMethod(
2357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          this,
235872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          &WaitForProcessLauncherThreadToGoIdleObserver::RunOnUIThread));
235972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
236072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
236172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid WaitForProcessLauncherThreadToGoIdleObserver::RunOnUIThread() {
2362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (automation_)
236472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    automation_->Send(reply_message_.release());
236572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Release();
236672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
2367