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

Side by Side Diff: chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc

Issue 1132163004: Remove NOTIFICATION_RENDER_VIEW_HOST_CHANGED. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove web_contents_ from WebContentsTracker as we can get it from WCO Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" 5 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
15 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/profiles/profile_manager.h" 16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/tab_contents/tab_util.h" 17 #include "chrome/browser/tab_contents/tab_util.h"
18 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h" 19 #include "chrome/common/url_constants.h"
20 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/render_process_host.h"
25 #include "content/public/browser/render_view_host.h" 22 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/resource_context.h" 23 #include "content/public/browser/resource_context.h"
27 #include "content/public/browser/speech_recognition_manager.h" 24 #include "content/public/browser/speech_recognition_manager.h"
28 #include "content/public/browser/speech_recognition_session_config.h" 25 #include "content/public/browser/speech_recognition_session_config.h"
29 #include "content/public/browser/speech_recognition_session_context.h" 26 #include "content/public/browser/speech_recognition_session_context.h"
30 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_observer.h"
31 #include "content/public/common/speech_recognition_error.h" 29 #include "content/public/common/speech_recognition_error.h"
32 #include "content/public/common/speech_recognition_result.h" 30 #include "content/public/common/speech_recognition_result.h"
33 #include "net/url_request/url_request_context_getter.h" 31 #include "net/url_request/url_request_context_getter.h"
34 32
35 #if defined(OS_WIN) 33 #if defined(OS_WIN)
36 #include "chrome/installer/util/wmi.h" 34 #include "chrome/installer/util/wmi.h"
37 #endif 35 #endif
38 36
39 #if defined(ENABLE_EXTENSIONS) 37 #if defined(ENABLE_EXTENSIONS)
40 #include "chrome/browser/extensions/extension_service.h" 38 #include "chrome/browser/extensions/extension_service.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 128
131 DISALLOW_COPY_AND_ASSIGN(OptionalRequestInfo); 129 DISALLOW_COPY_AND_ASSIGN(OptionalRequestInfo);
132 }; 130 };
133 131
134 // Simple utility to get notified when a WebContent (a tab or an extension's 132 // Simple utility to get notified when a WebContent (a tab or an extension's
135 // background page) is closed or crashes. The callback will always be called on 133 // background page) is closed or crashes. The callback will always be called on
136 // the UI thread. 134 // the UI thread.
137 // There is no restriction on the constructor, however this class must be 135 // There is no restriction on the constructor, however this class must be
138 // destroyed on the UI thread, due to the NotificationRegistrar dependency. 136 // destroyed on the UI thread, due to the NotificationRegistrar dependency.
139 class ChromeSpeechRecognitionManagerDelegate::TabWatcher 137 class ChromeSpeechRecognitionManagerDelegate::TabWatcher
140 : public base::RefCountedThreadSafe<TabWatcher>, 138 : public base::RefCountedThreadSafe<TabWatcher> {
141 public content::NotificationObserver {
142 public: 139 public:
143 typedef base::Callback<void(int render_process_id, int render_view_id)> 140 typedef base::Callback<void(int render_process_id, int render_view_id)>
144 TabClosedCallback; 141 TabClosedCallback;
145 142
146 explicit TabWatcher(TabClosedCallback tab_closed_callback) 143 explicit TabWatcher(TabClosedCallback tab_closed_callback)
147 : tab_closed_callback_(tab_closed_callback) { 144 : tab_closed_callback_(tab_closed_callback) {
148 } 145 }
149 146
150 // Starts monitoring the WebContents corresponding to the given 147 // Starts monitoring the WebContents corresponding to the given
151 // |render_process_id|, |render_view_id| pair, invoking |tab_closed_callback_| 148 // |render_process_id|, |render_view_id| pair, invoking |tab_closed_callback_|
152 // if closed/unloaded. 149 // if closed/unloaded.
153 void Watch(int render_process_id, int render_view_id) { 150 void Watch(int render_process_id, int render_view_id) {
154 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 151 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
155 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 152 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
156 &TabWatcher::Watch, this, render_process_id, render_view_id)); 153 &TabWatcher::Watch, this, render_process_id, render_view_id));
157 return; 154 return;
158 } 155 }
159 156
160 WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, 157 WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id,
161 render_view_id); 158 render_view_id);
162 // Sessions initiated by speech input extension APIs will end up in a NULL 159 // Sessions initiated by speech input extension APIs will end up in a NULL
163 // WebContent here, but they are properly managed by the 160 // WebContent here, but they are properly managed by the
164 // chrome::SpeechInputExtensionManager. However, sessions initiated within a 161 // chrome::SpeechInputExtensionManager. However, sessions initiated within a
165 // extension using the (new) speech JS APIs, will be properly handled here. 162 // extension using the (new) speech JS APIs, will be properly handled here.
166 // TODO(primiano) turn this line into a DCHECK once speech input extension 163 // TODO(primiano) turn this line into a DCHECK once speech input extension
167 // API is deprecated. 164 // API is deprecated.
168 if (!web_contents) 165 if (!web_contents)
169 return; 166 return;
170 167
171 // Avoid multiple registrations on |registrar_| for the same |web_contents|. 168 // Avoid multiple registrations for the same |web_contents|.
172 if (FindWebContents(web_contents) != registered_web_contents_.end()) { 169 if (FindWebContents(web_contents) != registered_web_contents_.end()) {
173 return; 170 return;
174 } 171 }
175 registered_web_contents_.push_back( 172 registered_web_contents_.push_back(new WebContentsTracker(
176 WebContentsInfo(web_contents, render_process_id, render_view_id)); 173 web_contents, base::Bind(&TabWatcher::OnTabClosed,
177 174 // |this| outlives WebContentsTracker.
178 // Lazy initialize the registrar. 175 base::Unretained(this), web_contents),
179 if (!registrar_.get()) 176 render_process_id, render_view_id));
180 registrar_.reset(new content::NotificationRegistrar());
181
182 registrar_->Add(this,
183 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
184 content::Source<WebContents>(web_contents));
185 registrar_->Add(this,
186 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
187 content::Source<WebContents>(web_contents));
188 } 177 }
189 178
190 // content::NotificationObserver implementation. 179 void OnTabClosed(content::WebContents* web_contents) {
191 void Observe(int type, 180 ScopedVector<WebContentsTracker>::iterator iter =
192 const content::NotificationSource& source, 181 FindWebContents(web_contents);
193 const content::NotificationDetails& details) override {
194 DCHECK_CURRENTLY_ON(BrowserThread::UI);
195 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED ||
196 type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED);
197
198 WebContents* web_contents = content::Source<WebContents>(source).ptr();
199 std::vector<WebContentsInfo>::iterator iter = FindWebContents(web_contents);
200 DCHECK(iter != registered_web_contents_.end()); 182 DCHECK(iter != registered_web_contents_.end());
201 int render_process_id = iter->render_process_id; 183 int render_process_id = (*iter)->render_process_id();
202 int render_view_id = iter->render_view_id; 184 int render_view_id = (*iter)->render_view_id();
203 registered_web_contents_.erase(iter); 185 registered_web_contents_.erase(iter);
204 186
205 registrar_->Remove(this,
206 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
207 content::Source<WebContents>(web_contents));
208 registrar_->Remove(this,
209 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
210 content::Source<WebContents>(web_contents));
211
212 tab_closed_callback_.Run(render_process_id, render_view_id); 187 tab_closed_callback_.Run(render_process_id, render_view_id);
213 } 188 }
214 189
215 private: 190 private:
216 struct WebContentsInfo { 191 class WebContentsTracker : public content::WebContentsObserver {
217 WebContentsInfo(content::WebContents* web_contents, 192 public:
218 int render_process_id, 193 WebContentsTracker(content::WebContents* web_contents,
219 int render_view_id) 194 const base::Closure& finished_callback,
220 : web_contents(web_contents), 195 int render_process_id,
221 render_process_id(render_process_id), 196 int render_view_id)
222 render_view_id(render_view_id) {} 197 : content::WebContentsObserver(web_contents),
198 finished_callback_(finished_callback),
199 render_process_id_(render_process_id),
200 render_view_id_(render_view_id) {}
223 201
224 ~WebContentsInfo() {} 202 ~WebContentsTracker() override {}
225 203
226 content::WebContents* web_contents; 204 int render_process_id() { return render_process_id_; }
227 int render_process_id; 205 int render_view_id() { return render_view_id_; }
228 int render_view_id; 206
207 private:
208 // content::WebContentsObserver overrides.
209 void WebContentsDestroyed() override {
210 Observe(nullptr);
211 finished_callback_.Run();
212 // NOTE: We are deleted now.
213 }
214 void RenderViewHostChanged(content::RenderViewHost* old_host,
215 content::RenderViewHost* new_host) override {
216 Observe(nullptr);
217 finished_callback_.Run();
218 // NOTE: We are deleted now.
219 }
220
221 base::Closure finished_callback_;
222 int render_process_id_;
223 int render_view_id_;
229 }; 224 };
230 225
231 friend class base::RefCountedThreadSafe<TabWatcher>; 226 friend class base::RefCountedThreadSafe<TabWatcher>;
232 227
233 ~TabWatcher() override { 228 ~TabWatcher() {
234 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. 229 // Must be destroyed on the UI thread due to |registrar_| non thread-safety.
230 // TODO(lazyboy): Do we still need this?
235 DCHECK_CURRENTLY_ON(BrowserThread::UI); 231 DCHECK_CURRENTLY_ON(BrowserThread::UI);
236 } 232 }
237 233
238 // Helper function to find the iterator in |registered_web_contents_| which 234 // Helper function to find the iterator in |registered_web_contents_| which
239 // contains |web_contents|. 235 // contains |web_contents|.
240 std::vector<WebContentsInfo>::iterator FindWebContents( 236 ScopedVector<WebContentsTracker>::iterator FindWebContents(
241 content::WebContents* web_contents) { 237 content::WebContents* web_contents) {
242 for (std::vector<WebContentsInfo>::iterator i( 238 for (ScopedVector<WebContentsTracker>::iterator i(
243 registered_web_contents_.begin()); 239 registered_web_contents_.begin());
244 i != registered_web_contents_.end(); ++i) { 240 i != registered_web_contents_.end(); ++i) {
245 if (i->web_contents == web_contents) 241 if ((*i)->web_contents() == web_contents)
246 return i; 242 return i;
247 } 243 }
248 244
249 return registered_web_contents_.end(); 245 return registered_web_contents_.end();
250 } 246 }
251 247
252 // Lazy-initialized and used on the UI thread to handle web contents
253 // notifications (tab closing).
254 scoped_ptr<content::NotificationRegistrar> registrar_;
255
256 // Keeps track of which WebContent(s) have been registered, in order to avoid 248 // Keeps track of which WebContent(s) have been registered, in order to avoid
257 // double registrations on |registrar_| and to pass the correct render 249 // double registrations on WebContentsObserver and to pass the correct render
258 // process id and render view id to |tab_closed_callback_| after the process 250 // process id and render view id to |tab_closed_callback_| after the process
259 // has gone away. 251 // has gone away.
260 std::vector<WebContentsInfo> registered_web_contents_; 252 ScopedVector<WebContentsTracker> registered_web_contents_;
261 253
262 // Callback used to notify, on the thread specified by |callback_thread_| the 254 // Callback used to notify, on the thread specified by |callback_thread_| the
263 // closure of a registered tab. 255 // closure of a registered tab.
264 TabClosedCallback tab_closed_callback_; 256 TabClosedCallback tab_closed_callback_;
265 257
266 DISALLOW_COPY_AND_ASSIGN(TabWatcher); 258 DISALLOW_COPY_AND_ASSIGN(TabWatcher);
267 }; 259 };
268 260
269 ChromeSpeechRecognitionManagerDelegate 261 ChromeSpeechRecognitionManagerDelegate
270 ::ChromeSpeechRecognitionManagerDelegate() { 262 ::ChromeSpeechRecognitionManagerDelegate() {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 // Otherwise this should be a regular tab contents. 426 // Otherwise this should be a regular tab contents.
435 allowed = true; 427 allowed = true;
436 check_permission = true; 428 check_permission = true;
437 #endif 429 #endif
438 430
439 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 431 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
440 base::Bind(callback, check_permission, allowed)); 432 base::Bind(callback, check_permission, allowed));
441 } 433 }
442 434
443 } // namespace speech 435 } // namespace speech
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698