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

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

Issue 6115001: Listen for tab close notifications and cancel active speech sessions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 11 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/speech_input_bubble_controller.cc
diff --git a/chrome/browser/speech/speech_input_bubble_controller.cc b/chrome/browser/speech/speech_input_bubble_controller.cc
index 682d0283d27bc4ebbea220175f1e754ccecbb4c0..f17342c5813648a8daf19315c80d6e203a767561 100644
--- a/chrome/browser/speech/speech_input_bubble_controller.cc
+++ b/chrome/browser/speech/speech_input_bubble_controller.cc
@@ -7,13 +7,17 @@
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
#include "gfx/rect.h"
namespace speech_input {
SpeechInputBubbleController::SpeechInputBubbleController(Delegate* delegate)
: delegate_(delegate),
- current_bubble_caller_id_(0) {
+ current_bubble_caller_id_(0),
+ registrar_(new NotificationRegistrar) {
}
SpeechInputBubbleController::~SpeechInputBubbleController() {
@@ -43,6 +47,16 @@ void SpeechInputBubbleController::CreateBubble(int caller_id,
return;
bubbles_[caller_id] = bubble;
+
+ // If this is the first bubble in our list for this TabContents, register
hans 2011/01/06 12:30:54 "First in our list", but the call is to IsOnlyBubb
+ // for notifications when the tab closes. This ensures that we can safely
+ // kill the bubble and recording session even if the user clicked on the
+ // speech button and immediately closes the tab, or if the tab crashes in
bulach 2011/01/06 12:32:39 s/in the somewhere/
+ // the somewhere while the bubble & recording are active.
hans 2011/01/06 12:30:54 nit: "crashes in the somewhere" sounds weird
+ if (IsOnlyBubbleForTab(caller_id)) {
bulach 2011/01/06 12:32:39 as we chatted, the "IsOnlyBubbleForTab" is the bes
+ registrar_->Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_contents));
+ }
}
void SpeechInputBubbleController::CloseBubble(int caller_id) {
@@ -70,6 +84,47 @@ void SpeechInputBubbleController::SetBubbleMessage(int caller_id,
ProcessRequestInUiThread(caller_id, REQUEST_SET_MESSAGE, text, 0);
}
+bool SpeechInputBubbleController::IsOnlyBubbleForTab(int caller_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ TabContents* tab_contents = bubbles_[caller_id]->tab_contents();
+ for (BubbleCallerIdMap::iterator iter = bubbles_.begin();
+ iter != bubbles_.end(); ++iter) {
+ if (iter->second->tab_contents() == tab_contents &&
+ iter->first != caller_id) {
+ // At least one other bubble exists for the same TabContents.
bulach 2011/01/06 12:32:39 yeah, as above, this would be the best place to sa
+ return false;
+ }
+ }
+ return true;
+}
+
+void SpeechInputBubbleController::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
+ // Cancel all bubbles and active recognition sessions for this tab.
+ TabContents* tab_contents = Source<TabContents>(source).ptr();
+ BubbleCallerIdMap::iterator iter = bubbles_.begin();
+ while (iter != bubbles_.end()) {
+ if (iter->second->tab_contents() == tab_contents) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &SpeechInputBubbleController::InvokeDelegateButtonClicked,
+ iter->first, SpeechInputBubble::BUTTON_CANCEL));
+ CloseBubble(iter->first);
+ // We expect to have a very small number of items in this map so
+ // redo-ing from start is ok.
+ iter = bubbles_.begin();
+ } else {
+ ++iter;
+ }
+ }
+ } else {
+ NOTREACHED() << "Unknown notification";
+ }
+}
+
void SpeechInputBubbleController::ProcessRequestInUiThread(
int caller_id, RequestType type, const string16& text, float volume) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
@@ -109,6 +164,12 @@ void SpeechInputBubbleController::ProcessRequestInUiThread(
case REQUEST_CLOSE:
if (current_bubble_caller_id_ == caller_id)
current_bubble_caller_id_ = 0;
+ // If this is the last bubble for this TabContents, unregister from
+ // close notifications.
+ if (IsOnlyBubbleForTab(caller_id)) {
+ registrar_->Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(bubble->tab_contents()));
+ }
delete bubble;
bubbles_.erase(caller_id);
break;

Powered by Google App Engine
This is Rietveld 408576698