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

Unified Diff: chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc

Issue 10663018: Changing tab closure handling logic in speech recognition code and cleaning bubble controller. (Spe… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Satish review + rebase Created 8 years, 6 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 side-by-side diff with in-line comments
Download patch
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 f22f95541e0bd6f6ef1382511134b637126e3a2c..81b1c7fdfbeed03d1fb601106edf06054c169de6 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
#include "chrome/browser/speech/speech_recognition_tray_icon_controller.h"
+#include "chrome/browser/speech/tab_watcher.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/view_type_utils.h"
#include "chrome/common/pref_names.h"
@@ -39,12 +40,9 @@
using content::BrowserThread;
using content::SpeechRecognitionManager;
-using content::SpeechRecognitionSessionContext;
using content::WebContents;
namespace {
-const int kNoActiveBubble =
- content::SpeechRecognitionManager::kSessionIDInvalid;
const char kExtensionPrefix[] = "chrome-extension://";
@@ -124,38 +122,33 @@ class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo
};
ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate()
- : active_bubble_session_id_(kNoActiveBubble) {
+{
Satish 2012/07/03 15:11:57 move to previous line
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 It will overflow the row. Chrome....Delegate() tak
Satish 2012/07/04 09:52:51 In such cases we write it as ChromeSpeechRecogniti
Primiano Tucci (use gerrit) 2012/07/04 11:18:15 Done.
}
ChromeSpeechRecognitionManagerDelegate::
~ChromeSpeechRecognitionManagerDelegate() {
Satish 2012/07/03 15:11:57 could move to previous line
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 As above, overflows 80 cols.
Satish 2012/07/04 09:52:51 Ok, no 4 space indentation then
Primiano Tucci (use gerrit) 2012/07/04 11:18:15 Done.
if (tray_icon_controller_.get())
tray_icon_controller_->Hide();
- if (active_bubble_session_id_ != kNoActiveBubble) {
- DCHECK(bubble_controller_.get());
- bubble_controller_->CloseBubble(active_bubble_session_id_);
- }
+ if (bubble_controller_.get() && bubble_controller_->GetActiveSessionID())
Satish 2012/07/03 15:11:57 can the second check be moved inside CloseBubble()
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 Well, the check wasn't needed. Removed.
+ bubble_controller_->CloseBubble();
}
void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked(
int session_id, SpeechRecognitionBubble::Button button) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK_EQ(active_bubble_session_id_, session_id);
// Note, the session might have been destroyed, therefore avoid calls to the
// manager which imply its existance (e.g., GetSessionContext()).
if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
- GetBubbleController()->CloseBubble(session_id);
+ GetBubbleController()->CloseBubble();
last_session_config_.reset();
- active_bubble_session_id_ = kNoActiveBubble;
// We can safely call AbortSession even if the session has already ended,
// the manager's public methods are reliable and will handle it properly.
SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
} else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
- GetBubbleController()->CloseBubble(session_id);
- active_bubble_session_id_ = kNoActiveBubble;
+ GetBubbleController()->CloseBubble();
RestartLastSession();
}
Satish 2012/07/03 15:11:57 if the above are the only 2 possible values for |b
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 Done.
}
@@ -163,14 +156,18 @@ void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked(
void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged(
int session_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK_EQ(active_bubble_session_id_, session_id);
+
+ // This check is needed since on some systems (MacOS), in rare cases, if the
+ // user clicks repeatedly and fast on the input element, the FocusChanged
+ // event (corresponding to the old session that should be aborted) can be
+ // received after a new session (corresponding to the 2nd click) is started.
+ if (GetBubbleController()->GetActiveSessionID() != session_id)
Satish 2012/07/03 15:11:57 If you ignore the focus change event for the first
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 Yes, even if the UI events are received out of ord
+ return;
// Note, the session might have been destroyed, therefore avoid calls to the
// manager which imply its existance (e.g., GetSessionContext()).
-
- GetBubbleController()->CloseBubble(session_id);
+ GetBubbleController()->CloseBubble();
last_session_config_.reset();
- active_bubble_session_id_ = kNoActiveBubble;
// If the user clicks outside the bubble while capturing audio we abort the
// session. Otherwise, i.e. audio capture is ended and we are just waiting for
@@ -183,11 +180,25 @@ void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() {
DCHECK(last_session_config_.get());
SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance();
const int new_session_id = manager->CreateSession(*last_session_config_);
- DCHECK_NE(new_session_id, kNoActiveBubble);
+ DCHECK_NE(SpeechRecognitionManager::kSessionIDInvalid, new_session_id);
last_session_config_.reset();
manager->StartSession(new_session_id);
}
+void ChromeSpeechRecognitionManagerDelegate::TabClosedCallback(
+ int render_process_id, int render_view_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (SpeechRecognitionManager* mgr = SpeechRecognitionManager::GetInstance())
Satish 2012/07/03 15:11:57 mgr -> manager
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 Done.
+ mgr->AbortAllSessionsForRenderer(render_process_id, render_view_id);
+
+ if (bubble_controller_.get() &&
+ bubble_controller_->IsShowingBubbleOn(render_process_id,
Satish 2012/07/03 15:11:57 looks like bubble controller holds the current ren
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 Hmm similar to the offline discussion about active
+ render_view_id)) {
+ bubble_controller_->CloseBubble();
+ }
+}
+
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(
int session_id) {
const content::SpeechRecognitionSessionContext& context =
@@ -199,21 +210,27 @@ void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(
SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id)));
// Create and show the bubble.
- DCHECK_EQ(active_bubble_session_id_, kNoActiveBubble);
- active_bubble_session_id_ = session_id;
GetBubbleController()->CreateBubble(session_id,
context.render_process_id,
context.render_view_id,
context.element_rect);
+ }
- // TODO(primiano) Why not creating directly the bubble in warmup mode?
- GetBubbleController()->SetBubbleWarmUpMode(session_id);
+ // Register callback to auto abort session on tab closure.
+ // |tab_watcher_| is lazyly istantiated on the first call.
+ if (!tab_watcher_.get()) {
+ tab_watcher_ = new TabWatcher(
+ base::Bind(&ChromeSpeechRecognitionManagerDelegate::TabClosedCallback,
+ base::Unretained(this)),
+ BrowserThread::IO);
}
+ tab_watcher_->Watch(context.render_process_id, context.render_view_id);
Satish 2012/07/03 15:11:57 can you also stop observing the tab when the bubbl
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 I thought about that but it means that in such cas
Satish 2012/07/04 09:52:51 If the user had 20 tabs open and used speech recog
Primiano Tucci (use gerrit) 2012/07/04 11:18:15 Events are pre-filtered by the notification servic
}
void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {
if (RequiresBubble(session_id)) {
- GetBubbleController()->SetBubbleRecordingMode(session_id);
+ DCHECK_EQ(session_id, GetBubbleController()->GetActiveSessionID());
Satish 2012/07/03 15:11:57 It doesn't feel right to ask the bubble controller
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 As discussed offline, it doesn't look pretty nice,
+ GetBubbleController()->SetBubbleRecordingMode();
} else if (RequiresTrayIcon(session_id)) {
// We post the action to the UI thread for sessions requiring a tray icon,
// since ChromeSpeechRecognitionPreferences (which requires UI thread) is
@@ -242,8 +259,9 @@ void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) {
void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
// OnAudioEnd can be also raised after an abort, when the bubble has already
// been closed.
- if (RequiresBubble(session_id) && active_bubble_session_id_ == session_id) {
- GetBubbleController()->SetBubbleRecognizingMode(session_id);
+ if (GetBubbleController()->GetActiveSessionID() == session_id) {
Satish 2012/07/03 15:11:57 why is this condition different from what you have
Primiano Tucci (use gerrit) 2012/07/03 16:54:35 In the AudioStart event, in the case that that par
+ DCHECK(RequiresBubble(session_id));
+ GetBubbleController()->SetBubbleRecognizingMode();
} else if (RequiresTrayIcon(session_id)) {
GetTrayIconController()->Hide();
}
@@ -251,19 +269,13 @@ void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResult(
int session_id, const content::SpeechRecognitionResult& result) {
- // A result can be dispatched when the bubble is not visible anymore (e.g.,
- // lost focus while waiting for a result, thus continuing in background).
- if (RequiresBubble(session_id) && active_bubble_session_id_ == session_id) {
- GetBubbleController()->CloseBubble(session_id);
- last_session_config_.reset();
- active_bubble_session_id_ = kNoActiveBubble;
- }
+ // The bubble will be closed upon the OnEnd event, which will follow soon.
}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(
int session_id, const content::SpeechRecognitionError& error) {
// An error can be dispatched when the bubble is not visible anymore.
- if (active_bubble_session_id_ != session_id)
+ if (GetBubbleController()->GetActiveSessionID() != session_id)
return;
DCHECK(RequiresBubble(session_id));
@@ -299,28 +311,29 @@ void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(
return;
}
GetBubbleController()->SetBubbleMessage(
- session_id, l10n_util::GetStringUTF16(error_message_id));
+ l10n_util::GetStringUTF16(error_message_id));
}
void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
int session_id, float volume, float noise_volume) {
- if (active_bubble_session_id_ == session_id) {
+ if (GetBubbleController()->GetActiveSessionID() == session_id) {
DCHECK(RequiresBubble(session_id));
- GetBubbleController()->SetBubbleInputVolume(session_id,
- volume, noise_volume);
+ GetBubbleController()->SetBubbleInputVolume(volume, noise_volume);
} else if (RequiresTrayIcon(session_id)) {
GetTrayIconController()->SetVUMeterVolume(volume);
}
}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) {
- // No need to remove the bubble here, since either one of the following events
- // must have happened prior to this callback:
- // - A previous OnRecognitionResult event already closed the bubble.
- // - An error occurred, so the bubble is showing the error and will be closed
- // when it will lose focus (by InfoBubbleFocusChanged()).
- // - The bubble lost focus or the user pressed the Cancel button, thus it has
- // been closed by InfoBubbleFocusChanged(), which triggered an AbortSession.
+ // The only case in which the OnRecognitionEnd should not close the bubble is
+ // when we are showing an error. In this case the bubble will be closed by
+ // the |InfoBubbleFocusChanged| method, when the users clicks either the
+ // "Cancel" button or outside of the bubble.
+ if (GetBubbleController()->GetActiveSessionID() == session_id &&
+ !GetBubbleController()->IsShowingMessage()) {
+ DCHECK(RequiresBubble(session_id));
+ GetBubbleController()->CloseBubble();
+ }
}
void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation(

Powered by Google App Engine
This is Rietveld 408576698