Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / speech / tts_message_filter.cc
index 3c47074..71c3df0 100644 (file)
@@ -6,20 +6,23 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/speech/tts_controller.h"
-#include "chrome/browser/speech/tts_message_filter.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_process_host.h"
 
 using content::BrowserThread;
 
-TtsMessageFilter::TtsMessageFilter(int render_process_id, Profile* profile)
+TtsMessageFilter::TtsMessageFilter(int render_process_id,
+                                   content::BrowserContext* browser_context)
     : BrowserMessageFilter(TtsMsgStart),
       render_process_id_(render_process_id),
-      profile_(profile) {
+      browser_context_(browser_context),
+      valid_(true) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   TtsController::GetInstance()->AddVoicesChangedDelegate(this);
+
+  // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero
+  // until all pointers to this class are invalidated.
+  AddRef();
 }
 
 void TtsMessageFilter::OverrideThreadForMessage(
@@ -49,20 +52,36 @@ bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
 }
 
 void TtsMessageFilter::OnChannelClosing() {
+  base::AutoLock lock(mutex_);
+  valid_ = false;
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
 }
 
+bool TtsMessageFilter::Valid() {
+  base::AutoLock lock(mutex_);
+  return valid_;
+}
+
 void TtsMessageFilter::OnDestruct() const {
+  {
+    base::AutoLock lock(mutex_);
+    valid_ = false;
+  }
   BrowserThread::DeleteOnUIThread::Destruct(this);
 }
 
+TtsMessageFilter::~TtsMessageFilter() {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  Cleanup();
+}
+
 void TtsMessageFilter::OnInitializeVoiceList() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   TtsController* tts_controller = TtsController::GetInstance();
   std::vector<VoiceData> voices;
-  tts_controller->GetVoices(profile_, &voices);
+  tts_controller->GetVoices(browser_context_, &voices);
 
   std::vector<TtsVoice> out_voices;
   out_voices.resize(voices.size());
@@ -79,7 +98,8 @@ void TtsMessageFilter::OnInitializeVoiceList() {
 
 void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  scoped_ptr<Utterance> utterance(new Utterance(profile_));
+
+  scoped_ptr<Utterance> utterance(new Utterance(browser_context_));
   utterance->set_src_id(request.id);
   utterance->set_text(request.text);
   utterance->set_lang(request.lang);
@@ -92,7 +112,7 @@ void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
   params.volume = request.volume;
   utterance->set_continuous_parameters(params);
 
-  utterance->set_event_delegate(this->AsWeakPtr());
+  utterance->set_event_delegate(this);
 
   TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
 }
@@ -116,6 +136,9 @@ void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
                                   TtsEventType event_type,
                                   int char_index,
                                   const std::string& error_message) {
+  if (!Valid())
+    return;
+
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   switch (event_type) {
     case TTS_EVENT_START:
@@ -153,16 +176,20 @@ void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
 }
 
 void TtsMessageFilter::OnVoicesChanged() {
+  if (!Valid())
+    return;
+
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   OnInitializeVoiceList();
 }
 
 void TtsMessageFilter::OnChannelClosingInUIThread() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
+  Cleanup();
+  Release();  // Balanced in TtsMessageFilter().
 }
 
-TtsMessageFilter::~TtsMessageFilter() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void TtsMessageFilter::Cleanup() {
   TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
+  TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
 }