OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/speech/tts_message_filter.h" | 5 #include "chrome/browser/speech/tts_message_filter.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "content/public/browser/browser_context.h" | 9 #include "content/public/browser/browser_context.h" |
10 #include "content/public/browser/render_process_host.h" | 10 #include "content/public/browser/render_process_host.h" |
11 | 11 |
12 using content::BrowserThread; | 12 using content::BrowserThread; |
13 | 13 |
14 TtsMessageFilter::TtsMessageFilter(int render_process_id, | 14 TtsMessageFilter::TtsMessageFilter(int render_process_id, |
15 content::BrowserContext* browser_context) | 15 content::BrowserContext* browser_context) |
16 : BrowserMessageFilter(TtsMsgStart), | 16 : BrowserMessageFilter(TtsMsgStart), |
17 render_process_id_(render_process_id), | 17 render_process_id_(render_process_id), |
18 browser_context_(browser_context), | 18 browser_context_(browser_context), |
19 weak_ptr_factory_(this) { | 19 valid_(true) { |
20 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 20 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
21 TtsController::GetInstance()->AddVoicesChangedDelegate(this); | 21 TtsController::GetInstance()->AddVoicesChangedDelegate(this); |
22 | 22 |
23 // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero | 23 // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero |
24 // until all WeakPtr's are invalidated. | 24 // until all pointers to this class are invalidated. |
25 AddRef(); | 25 AddRef(); |
26 } | 26 } |
27 | 27 |
28 void TtsMessageFilter::OverrideThreadForMessage( | 28 void TtsMessageFilter::OverrideThreadForMessage( |
29 const IPC::Message& message, BrowserThread::ID* thread) { | 29 const IPC::Message& message, BrowserThread::ID* thread) { |
30 switch (message.type()) { | 30 switch (message.type()) { |
31 case TtsHostMsg_InitializeVoiceList::ID: | 31 case TtsHostMsg_InitializeVoiceList::ID: |
32 case TtsHostMsg_Speak::ID: | 32 case TtsHostMsg_Speak::ID: |
33 case TtsHostMsg_Pause::ID: | 33 case TtsHostMsg_Pause::ID: |
34 case TtsHostMsg_Resume::ID: | 34 case TtsHostMsg_Resume::ID: |
(...skipping 10 matching lines...) Expand all Loading... |
45 IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak) | 45 IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak) |
46 IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause) | 46 IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause) |
47 IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume) | 47 IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume) |
48 IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel) | 48 IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel) |
49 IPC_MESSAGE_UNHANDLED(handled = false) | 49 IPC_MESSAGE_UNHANDLED(handled = false) |
50 IPC_END_MESSAGE_MAP() | 50 IPC_END_MESSAGE_MAP() |
51 return handled; | 51 return handled; |
52 } | 52 } |
53 | 53 |
54 void TtsMessageFilter::OnChannelClosing() { | 54 void TtsMessageFilter::OnChannelClosing() { |
| 55 base::AutoLock lock(mutex_); |
| 56 valid_ = false; |
55 BrowserThread::PostTask( | 57 BrowserThread::PostTask( |
56 BrowserThread::UI, FROM_HERE, | 58 BrowserThread::UI, FROM_HERE, |
57 base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this)); | 59 base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this)); |
58 } | 60 } |
59 | 61 |
| 62 bool TtsMessageFilter::Valid() { |
| 63 base::AutoLock lock(mutex_); |
| 64 return valid_; |
| 65 } |
| 66 |
60 void TtsMessageFilter::OnDestruct() const { | 67 void TtsMessageFilter::OnDestruct() const { |
| 68 { |
| 69 base::AutoLock lock(mutex_); |
| 70 valid_ = false; |
| 71 } |
61 BrowserThread::DeleteOnUIThread::Destruct(this); | 72 BrowserThread::DeleteOnUIThread::Destruct(this); |
62 } | 73 } |
63 | 74 |
| 75 TtsMessageFilter::~TtsMessageFilter() { |
| 76 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 77 Cleanup(); |
| 78 } |
| 79 |
64 void TtsMessageFilter::OnInitializeVoiceList() { | 80 void TtsMessageFilter::OnInitializeVoiceList() { |
65 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 81 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
66 TtsController* tts_controller = TtsController::GetInstance(); | 82 TtsController* tts_controller = TtsController::GetInstance(); |
67 std::vector<VoiceData> voices; | 83 std::vector<VoiceData> voices; |
68 tts_controller->GetVoices(browser_context_, &voices); | 84 tts_controller->GetVoices(browser_context_, &voices); |
69 | 85 |
70 std::vector<TtsVoice> out_voices; | 86 std::vector<TtsVoice> out_voices; |
71 out_voices.resize(voices.size()); | 87 out_voices.resize(voices.size()); |
72 for (size_t i = 0; i < voices.size(); ++i) { | 88 for (size_t i = 0; i < voices.size(); ++i) { |
73 TtsVoice& out_voice = out_voices[i]; | 89 TtsVoice& out_voice = out_voices[i]; |
(...skipping 15 matching lines...) Expand all Loading... |
89 utterance->set_lang(request.lang); | 105 utterance->set_lang(request.lang); |
90 utterance->set_voice_name(request.voice); | 106 utterance->set_voice_name(request.voice); |
91 utterance->set_can_enqueue(true); | 107 utterance->set_can_enqueue(true); |
92 | 108 |
93 UtteranceContinuousParameters params; | 109 UtteranceContinuousParameters params; |
94 params.rate = request.rate; | 110 params.rate = request.rate; |
95 params.pitch = request.pitch; | 111 params.pitch = request.pitch; |
96 params.volume = request.volume; | 112 params.volume = request.volume; |
97 utterance->set_continuous_parameters(params); | 113 utterance->set_continuous_parameters(params); |
98 | 114 |
99 utterance->set_event_delegate(weak_ptr_factory_.GetWeakPtr()); | 115 utterance->set_event_delegate(this); |
100 | 116 |
101 TtsController::GetInstance()->SpeakOrEnqueue(utterance.release()); | 117 TtsController::GetInstance()->SpeakOrEnqueue(utterance.release()); |
102 } | 118 } |
103 | 119 |
104 void TtsMessageFilter::OnPause() { | 120 void TtsMessageFilter::OnPause() { |
105 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 121 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
106 TtsController::GetInstance()->Pause(); | 122 TtsController::GetInstance()->Pause(); |
107 } | 123 } |
108 | 124 |
109 void TtsMessageFilter::OnResume() { | 125 void TtsMessageFilter::OnResume() { |
110 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 126 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
111 TtsController::GetInstance()->Resume(); | 127 TtsController::GetInstance()->Resume(); |
112 } | 128 } |
113 | 129 |
114 void TtsMessageFilter::OnCancel() { | 130 void TtsMessageFilter::OnCancel() { |
115 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 131 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
116 TtsController::GetInstance()->Stop(); | 132 TtsController::GetInstance()->Stop(); |
117 } | 133 } |
118 | 134 |
119 void TtsMessageFilter::OnTtsEvent(Utterance* utterance, | 135 void TtsMessageFilter::OnTtsEvent(Utterance* utterance, |
120 TtsEventType event_type, | 136 TtsEventType event_type, |
121 int char_index, | 137 int char_index, |
122 const std::string& error_message) { | 138 const std::string& error_message) { |
| 139 if (!Valid()) |
| 140 return; |
| 141 |
123 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 142 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
124 switch (event_type) { | 143 switch (event_type) { |
125 case TTS_EVENT_START: | 144 case TTS_EVENT_START: |
126 Send(new TtsMsg_DidStartSpeaking(utterance->src_id())); | 145 Send(new TtsMsg_DidStartSpeaking(utterance->src_id())); |
127 break; | 146 break; |
128 case TTS_EVENT_END: | 147 case TTS_EVENT_END: |
129 Send(new TtsMsg_DidFinishSpeaking(utterance->src_id())); | 148 Send(new TtsMsg_DidFinishSpeaking(utterance->src_id())); |
130 break; | 149 break; |
131 case TTS_EVENT_WORD: | 150 case TTS_EVENT_WORD: |
132 Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index)); | 151 Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index)); |
(...skipping 17 matching lines...) Expand all Loading... |
150 case TTS_EVENT_PAUSE: | 169 case TTS_EVENT_PAUSE: |
151 Send(new TtsMsg_DidPauseSpeaking(utterance->src_id())); | 170 Send(new TtsMsg_DidPauseSpeaking(utterance->src_id())); |
152 break; | 171 break; |
153 case TTS_EVENT_RESUME: | 172 case TTS_EVENT_RESUME: |
154 Send(new TtsMsg_DidResumeSpeaking(utterance->src_id())); | 173 Send(new TtsMsg_DidResumeSpeaking(utterance->src_id())); |
155 break; | 174 break; |
156 } | 175 } |
157 } | 176 } |
158 | 177 |
159 void TtsMessageFilter::OnVoicesChanged() { | 178 void TtsMessageFilter::OnVoicesChanged() { |
| 179 if (!Valid()) |
| 180 return; |
| 181 |
160 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 182 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
161 OnInitializeVoiceList(); | 183 OnInitializeVoiceList(); |
162 } | 184 } |
163 | 185 |
164 void TtsMessageFilter::OnChannelClosingInUIThread() { | 186 void TtsMessageFilter::OnChannelClosingInUIThread() { |
165 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 187 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
166 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this); | 188 Cleanup(); |
167 | |
168 weak_ptr_factory_.InvalidateWeakPtrs(); | |
169 Release(); // Balanced in TtsMessageFilter(). | 189 Release(); // Balanced in TtsMessageFilter(). |
170 } | 190 } |
171 | 191 |
172 TtsMessageFilter::~TtsMessageFilter() { | 192 void TtsMessageFilter::Cleanup() { |
173 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
174 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); | |
175 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this); | 193 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this); |
| 194 TtsController::GetInstance()->RemoveUtteranceEventDelegate(this); |
176 } | 195 } |
OLD | NEW |