diff options
author | primiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-04 17:01:26 +0000 |
---|---|---|
committer | primiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-04 17:01:26 +0000 |
commit | e36b0266a87002810f4622dee55e12e21b00c007 (patch) | |
tree | 632362a8b14d1da4fce6bd12e3bd78a831b67f18 /chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc | |
parent | 0b0750f822e02871f88ac69f3a193ea511287b45 (diff) | |
download | chromium_src-e36b0266a87002810f4622dee55e12e21b00c007.zip chromium_src-e36b0266a87002810f4622dee55e12e21b00c007.tar.gz chromium_src-e36b0266a87002810f4622dee55e12e21b00c007.tar.bz2 |
[Input element speech API] Close the bubble synchronously on tab closure.
When a tab is closed while an <input x-webkit-speech> element is
performing speech recognition and showing the corresponding bubble,
the bubble must be closed.
The previous implementation was doing that asyncrhonously by means of
(a couple of) PostTask. It turned out this is not correct and the
bubble must be closed synchronously, because the underlying
WebContents are going to be disposed immediately after the call.
This CL makes this action synchronous.
BUG=262606
Review URL: https://codereview.chromium.org/25948002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227023 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc')
-rw-r--r-- | chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc index e2d991f..54671d7 100644 --- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc +++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc @@ -43,6 +43,24 @@ using content::WebContents; namespace speech { +namespace { + +void TabClosedCallbackOnIOThread(int render_process_id, int render_view_id) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); + // |manager| becomes NULL if a browser shutdown happens between the post of + // this task (from the UI thread) and this call (on the IO thread). In this + // case we just return. + if (!manager) + return; + + manager->AbortAllSessionsForRenderView(render_process_id, render_view_id); +} + +} // namespace + + // Asynchronously fetches the PC and audio hardware/driver info if // the user has opted into UMA. This information is sent with speech input // requests to the server for identifying and improving quality issues with @@ -110,8 +128,8 @@ class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo }; // Simple utility to get notified when a WebContent (a tab or an extension's -// background page) is closed or crashes. Both the callback site and the -// callback thread are passed by the caller in the constructor. +// background page) is closed or crashes. The callback will always be called on +// the UI thread. // 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 @@ -121,10 +139,8 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher typedef base::Callback<void(int render_process_id, int render_view_id)> TabClosedCallback; - TabWatcher(TabClosedCallback tab_closed_callback, - BrowserThread::ID callback_thread) - : tab_closed_callback_(tab_closed_callback), - callback_thread_(callback_thread) { + explicit TabWatcher(TabClosedCallback tab_closed_callback) + : tab_closed_callback_(tab_closed_callback) { } // Starts monitoring the WebContents corresponding to the given @@ -189,8 +205,7 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, content::Source<WebContents>(web_contents)); - BrowserThread::PostTask(callback_thread_, FROM_HERE, base::Bind( - tab_closed_callback_, render_process_id, render_view_id)); + tab_closed_callback_.Run(render_process_id, render_view_id); } private: @@ -243,7 +258,6 @@ class ChromeSpeechRecognitionManagerDelegate::TabWatcher // Callback used to notify, on the thread specified by |callback_thread_| the // closure of a registered tab. TabClosedCallback tab_closed_callback_; - content::BrowserThread::ID callback_thread_; DISALLOW_COPY_AND_ASSIGN(TabWatcher); }; @@ -258,16 +272,12 @@ ChromeSpeechRecognitionManagerDelegate void ChromeSpeechRecognitionManagerDelegate::TabClosedCallback( int render_process_id, int render_view_id) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); - // |manager| becomes NULL if a browser shutdown happens between the post of - // this task (from the UI thread) and this call (on the IO thread). In this - // case we just return. - if (!manager) - return; + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - manager->AbortAllSessionsForRenderView(render_process_id, render_view_id); + // Tell the S.R. Manager (which lives on the IO thread) to abort all the + // sessions for the given renderer view. + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( + &TabClosedCallbackOnIOThread, render_process_id, render_view_id)); } void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( @@ -280,8 +290,7 @@ void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( if (!tab_watcher_.get()) { tab_watcher_ = new TabWatcher( base::Bind(&ChromeSpeechRecognitionManagerDelegate::TabClosedCallback, - base::Unretained(this)), - BrowserThread::IO); + base::Unretained(this))); } tab_watcher_->Watch(context.render_process_id, context.render_view_id); } |