Index: chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc |
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc |
index 47a870720d4f1891d5c7b216f3c9c366485e4020..dc89463864d52283fb3fa8bc7d73f214462c5aa6 100644 |
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc |
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc |
@@ -18,9 +18,6 @@ |
#include "chrome/common/pref_names.h" |
#include "chrome/common/url_constants.h" |
#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/notification_registrar.h" |
-#include "content/public/browser/notification_source.h" |
-#include "content/public/browser/notification_types.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/resource_context.h" |
@@ -28,6 +25,7 @@ |
#include "content/public/browser/speech_recognition_session_config.h" |
#include "content/public/browser/speech_recognition_session_context.h" |
#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_contents_observer.h" |
#include "content/public/common/speech_recognition_error.h" |
#include "content/public/common/speech_recognition_result.h" |
#include "net/url_request/url_request_context_getter.h" |
@@ -137,8 +135,7 @@ class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo |
// There is no restriction on the constructor, however this class must be |
// destroyed on the UI thread, due to the NotificationRegistrar dependency. |
class ChromeSpeechRecognitionManagerDelegate::TabWatcher |
- : public base::RefCountedThreadSafe<TabWatcher>, |
- public content::NotificationObserver { |
+ : public base::RefCountedThreadSafe<TabWatcher> { |
public: |
typedef base::Callback<void(int render_process_id, int render_view_id)> |
TabClosedCallback; |
@@ -168,96 +165,91 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher |
if (!web_contents) |
return; |
- // Avoid multiple registrations on |registrar_| for the same |web_contents|. |
+ // Avoid multiple registrations for the same |web_contents|. |
if (FindWebContents(web_contents) != registered_web_contents_.end()) { |
return; |
} |
- registered_web_contents_.push_back( |
- WebContentsInfo(web_contents, render_process_id, render_view_id)); |
- |
- // Lazy initialize the registrar. |
- if (!registrar_.get()) |
- registrar_.reset(new content::NotificationRegistrar()); |
- |
- registrar_->Add(this, |
- content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
- content::Source<WebContents>(web_contents)); |
- registrar_->Add(this, |
- content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
- content::Source<WebContents>(web_contents)); |
+ registered_web_contents_.push_back(new WebContentsTracker( |
+ web_contents, base::Bind(&TabWatcher::OnTabClosed, |
+ // |this| outlives WebContentsTracker. |
+ base::Unretained(this), web_contents), |
+ render_process_id, render_view_id)); |
} |
- // content::NotificationObserver implementation. |
- void Observe(int type, |
- const content::NotificationSource& source, |
- const content::NotificationDetails& details) override { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED || |
- type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED); |
- |
- WebContents* web_contents = content::Source<WebContents>(source).ptr(); |
- std::vector<WebContentsInfo>::iterator iter = FindWebContents(web_contents); |
+ void OnTabClosed(content::WebContents* web_contents) { |
+ ScopedVector<WebContentsTracker>::iterator iter = |
+ FindWebContents(web_contents); |
DCHECK(iter != registered_web_contents_.end()); |
- int render_process_id = iter->render_process_id; |
- int render_view_id = iter->render_view_id; |
+ int render_process_id = (*iter)->render_process_id(); |
+ int render_view_id = (*iter)->render_view_id(); |
registered_web_contents_.erase(iter); |
- registrar_->Remove(this, |
- content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
- content::Source<WebContents>(web_contents)); |
- registrar_->Remove(this, |
- content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
- content::Source<WebContents>(web_contents)); |
- |
tab_closed_callback_.Run(render_process_id, render_view_id); |
} |
private: |
- struct WebContentsInfo { |
- WebContentsInfo(content::WebContents* web_contents, |
- int render_process_id, |
- int render_view_id) |
- : web_contents(web_contents), |
- render_process_id(render_process_id), |
- render_view_id(render_view_id) {} |
- |
- ~WebContentsInfo() {} |
- |
- content::WebContents* web_contents; |
- int render_process_id; |
- int render_view_id; |
+ class WebContentsTracker : public content::WebContentsObserver { |
+ public: |
+ WebContentsTracker(content::WebContents* web_contents, |
+ const base::Closure& finished_callback, |
+ int render_process_id, |
+ int render_view_id) |
+ : content::WebContentsObserver(web_contents), |
+ finished_callback_(finished_callback), |
+ render_process_id_(render_process_id), |
+ render_view_id_(render_view_id) {} |
+ |
+ ~WebContentsTracker() override {} |
+ |
+ int render_process_id() const { return render_process_id_; } |
+ int render_view_id() const { return render_view_id_; } |
+ |
+ private: |
+ // content::WebContentsObserver overrides. |
+ void WebContentsDestroyed() override { |
+ Observe(nullptr); |
+ finished_callback_.Run(); |
+ // NOTE: We are deleted now. |
+ } |
+ void RenderViewHostChanged(content::RenderViewHost* old_host, |
+ content::RenderViewHost* new_host) override { |
+ Observe(nullptr); |
+ finished_callback_.Run(); |
+ // NOTE: We are deleted now. |
+ } |
+ |
+ const base::Closure finished_callback_; |
+ const int render_process_id_; |
+ const int render_view_id_; |
}; |
friend class base::RefCountedThreadSafe<TabWatcher>; |
- ~TabWatcher() override { |
+ ~TabWatcher() { |
// Must be destroyed on the UI thread due to |registrar_| non thread-safety. |
+ // TODO(lazyboy): Do we still need this? |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
} |
// Helper function to find the iterator in |registered_web_contents_| which |
// contains |web_contents|. |
- std::vector<WebContentsInfo>::iterator FindWebContents( |
+ ScopedVector<WebContentsTracker>::iterator FindWebContents( |
content::WebContents* web_contents) { |
- for (std::vector<WebContentsInfo>::iterator i( |
- registered_web_contents_.begin()); |
+ for (ScopedVector<WebContentsTracker>::iterator i( |
+ registered_web_contents_.begin()); |
i != registered_web_contents_.end(); ++i) { |
- if (i->web_contents == web_contents) |
+ if ((*i)->web_contents() == web_contents) |
return i; |
} |
return registered_web_contents_.end(); |
} |
- // Lazy-initialized and used on the UI thread to handle web contents |
- // notifications (tab closing). |
- scoped_ptr<content::NotificationRegistrar> registrar_; |
- |
// Keeps track of which WebContent(s) have been registered, in order to avoid |
- // double registrations on |registrar_| and to pass the correct render |
+ // double registrations on WebContentsObserver and to pass the correct render |
// process id and render view id to |tab_closed_callback_| after the process |
// has gone away. |
- std::vector<WebContentsInfo> registered_web_contents_; |
+ ScopedVector<WebContentsTracker> registered_web_contents_; |
// Callback used to notify, on the thread specified by |callback_thread_| the |
// closure of a registered tab. |