Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / speech / tts_message_filter.cc
index 3c397cd..71c3df0 100644 (file)
@@ -6,19 +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)
-    : render_process_id_(render_process_id),
-      profile_(profile) {
+TtsMessageFilter::TtsMessageFilter(int render_process_id,
+                                   content::BrowserContext* browser_context)
+    : BrowserMessageFilter(TtsMsgStart),
+      render_process_id_(render_process_id),
+      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(
@@ -34,10 +38,9 @@ void TtsMessageFilter::OverrideThreadForMessage(
   }
 }
 
-bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message,
-                                         bool* message_was_ok) {
+bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(TtsMessageFilter, message, *message_was_ok)
+  IPC_BEGIN_MESSAGE_MAP(TtsMessageFilter, message)
     IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
     IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
     IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
@@ -49,16 +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());
@@ -75,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);
@@ -112,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:
@@ -149,14 +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() {
+void TtsMessageFilter::Cleanup() {
+  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
+  TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
 }