OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/speech/speech_input_dispatcher_host.h" | 5 #include "content/browser/speech/input_tag_speech_dispatcher_host.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "content/browser/speech/speech_input_manager_impl.h" | 8 #include "content/browser/speech/speech_recognition_manager_impl.h" |
9 #include "content/browser/speech/speech_recognizer_impl.h" | 9 #include "content/browser/speech/speech_recognizer_impl.h" |
10 #include "content/common/speech_input_messages.h" | 10 #include "content/common/speech_recognition_messages.h" |
11 #include "content/public/browser/speech_input_preferences.h" | 11 #include "content/public/browser/speech_recognition_preferences.h" |
12 | 12 |
13 using content::BrowserThread; | 13 using content::BrowserThread; |
14 | 14 |
15 namespace speech_input { | 15 namespace speech { |
16 | 16 |
17 //----------------------------- SpeechInputCallers ----------------------------- | 17 //----------------------------- Callers ----------------------------- |
18 | 18 |
19 // A singleton class to map the tuple | 19 // A singleton class to map the tuple |
20 // (render-process-id, render-view-id, requestid) to a single ID which is passed | 20 // (render-process-id, render-view-id, requestid) to a single ID which is passed |
21 // through rest of the speech code. | 21 // through rest of the speech code. |
22 class SpeechInputDispatcherHost::SpeechInputCallers { | 22 class InputTagSpeechDispatcherHost::Callers { |
23 public: | 23 public: |
24 // Creates a new ID for a given tuple. | 24 // Creates a new ID for a given tuple. |
25 int CreateId(int render_process_id, int render_view_id, int request_id); | 25 int CreateId(int render_process_id, int render_view_id, int request_id); |
26 | 26 |
27 // Returns the ID for a tuple assuming the ID was created earlier. | 27 // Returns the ID for a tuple assuming the ID was created earlier. |
28 int GetId(int render_process_id, int render_view_id, int request_id); | 28 int GetId(int render_process_id, int render_view_id, int request_id); |
29 | 29 |
30 // Removes the ID and associated tuple from the map. | 30 // Removes the ID and associated tuple from the map. |
31 void RemoveId(int id); | 31 void RemoveId(int id); |
32 | 32 |
33 // Getters for the various tuple elements for the given ID. | 33 // Getters for the various tuple elements for the given ID. |
34 int render_process_id(int id); | 34 int render_process_id(int id); |
35 int render_view_id(int id); | 35 int render_view_id(int id); |
36 int request_id(int id); | 36 int request_id(int id); |
37 | 37 |
38 private: | 38 private: |
39 struct CallerInfo { | 39 struct CallerInfo { |
40 int render_process_id; | 40 int render_process_id; |
41 int render_view_id; | 41 int render_view_id; |
42 int request_id; | 42 int request_id; |
43 }; | 43 }; |
44 friend struct base::DefaultLazyInstanceTraits<SpeechInputCallers>; | 44 friend struct base::DefaultLazyInstanceTraits<Callers>; |
45 | 45 |
46 SpeechInputCallers(); | 46 Callers(); |
47 | 47 |
48 std::map<int, CallerInfo> callers_; | 48 std::map<int, CallerInfo> callers_; |
49 int next_id_; | 49 int next_id_; |
50 }; | 50 }; |
51 | 51 |
52 static base::LazyInstance<SpeechInputDispatcherHost::SpeechInputCallers> | 52 static base::LazyInstance<InputTagSpeechDispatcherHost::Callers> |
53 g_speech_input_callers = LAZY_INSTANCE_INITIALIZER; | 53 g_callers = LAZY_INSTANCE_INITIALIZER; |
54 | 54 |
55 SpeechInputDispatcherHost::SpeechInputCallers::SpeechInputCallers() | 55 InputTagSpeechDispatcherHost::Callers::Callers() |
56 : next_id_(1) { | 56 : next_id_(1) { |
57 } | 57 } |
58 | 58 |
59 int SpeechInputDispatcherHost::SpeechInputCallers::GetId(int render_process_id, | 59 int InputTagSpeechDispatcherHost::Callers::GetId(int render_process_id, |
60 int render_view_id, | 60 int render_view_id, |
61 int request_id) { | 61 int request_id) { |
62 for (std::map<int, CallerInfo>::iterator it = callers_.begin(); | 62 for (std::map<int, CallerInfo>::iterator it = callers_.begin(); |
63 it != callers_.end(); it++) { | 63 it != callers_.end(); it++) { |
64 const CallerInfo& item = it->second; | 64 const CallerInfo& item = it->second; |
65 if (item.render_process_id == render_process_id && | 65 if (item.render_process_id == render_process_id && |
66 item.render_view_id == render_view_id && | 66 item.render_view_id == render_view_id && |
67 item.request_id == request_id) { | 67 item.request_id == request_id) { |
68 return it->first; | 68 return it->first; |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 // Not finding an entry here is valid since a cancel/stop may have been issued | 72 // Not finding an entry here is valid since a cancel/stop may have been issued |
73 // by the renderer and before it received our response the user may have | 73 // by the renderer and before it received our response the user may have |
74 // clicked the button to stop again. The caller of this method should take | 74 // clicked the button to stop again. The caller of this method should take |
75 // care of this case. | 75 // care of this case. |
76 return 0; | 76 return 0; |
77 } | 77 } |
78 | 78 |
79 int SpeechInputDispatcherHost::SpeechInputCallers::CreateId( | 79 int InputTagSpeechDispatcherHost::Callers::CreateId(int render_process_id, |
80 int render_process_id, | 80 int render_view_id, |
81 int render_view_id, | 81 int request_id) { |
82 int request_id) { | |
83 CallerInfo info; | 82 CallerInfo info; |
84 info.render_process_id = render_process_id; | 83 info.render_process_id = render_process_id; |
85 info.render_view_id = render_view_id; | 84 info.render_view_id = render_view_id; |
86 info.request_id = request_id; | 85 info.request_id = request_id; |
87 callers_[next_id_] = info; | 86 callers_[next_id_] = info; |
88 return next_id_++; | 87 return next_id_++; |
89 } | 88 } |
90 | 89 |
91 void SpeechInputDispatcherHost::SpeechInputCallers::RemoveId(int id) { | 90 void InputTagSpeechDispatcherHost::Callers::RemoveId(int id) { |
92 callers_.erase(id); | 91 callers_.erase(id); |
93 } | 92 } |
94 | 93 |
95 int SpeechInputDispatcherHost::SpeechInputCallers::render_process_id(int id) { | 94 int InputTagSpeechDispatcherHost::Callers::render_process_id( |
| 95 int id) { |
96 return callers_[id].render_process_id; | 96 return callers_[id].render_process_id; |
97 } | 97 } |
98 | 98 |
99 int SpeechInputDispatcherHost::SpeechInputCallers::render_view_id(int id) { | 99 int InputTagSpeechDispatcherHost::Callers::render_view_id( |
| 100 int id) { |
100 return callers_[id].render_view_id; | 101 return callers_[id].render_view_id; |
101 } | 102 } |
102 | 103 |
103 int SpeechInputDispatcherHost::SpeechInputCallers::request_id(int id) { | 104 int InputTagSpeechDispatcherHost::Callers::request_id(int id) { |
104 return callers_[id].request_id; | 105 return callers_[id].request_id; |
105 } | 106 } |
106 | 107 |
107 //-------------------------- SpeechInputDispatcherHost ------------------------- | 108 //----------------------- InputTagSpeechDispatcherHost ---------------------- |
108 | 109 |
109 SpeechInputManagerImpl* SpeechInputDispatcherHost::manager_; | 110 SpeechRecognitionManagerImpl* InputTagSpeechDispatcherHost::manager_; |
110 | 111 |
111 void SpeechInputDispatcherHost::set_manager(SpeechInputManagerImpl* manager) { | 112 void InputTagSpeechDispatcherHost::set_manager( |
| 113 SpeechRecognitionManagerImpl* manager) { |
112 manager_ = manager; | 114 manager_ = manager; |
113 } | 115 } |
114 | 116 |
115 SpeechInputDispatcherHost::SpeechInputDispatcherHost( | 117 InputTagSpeechDispatcherHost::InputTagSpeechDispatcherHost( |
116 int render_process_id, | 118 int render_process_id, |
117 net::URLRequestContextGetter* context_getter, | 119 net::URLRequestContextGetter* context_getter, |
118 content::SpeechInputPreferences* speech_input_preferences, | 120 content::SpeechRecognitionPreferences* recognition_preferences, |
119 AudioManager* audio_manager) | 121 AudioManager* audio_manager) |
120 : render_process_id_(render_process_id), | 122 : render_process_id_(render_process_id), |
121 may_have_pending_requests_(false), | 123 may_have_pending_requests_(false), |
122 context_getter_(context_getter), | 124 context_getter_(context_getter), |
123 speech_input_preferences_(speech_input_preferences), | 125 recognition_preferences_(recognition_preferences), |
124 audio_manager_(audio_manager) { | 126 audio_manager_(audio_manager) { |
125 // This is initialized by Browser. Do not add any non-trivial | 127 // This is initialized by Browser. Do not add any non-trivial |
126 // initialization here, instead do it lazily when required (e.g. see the | 128 // initialization here, instead do it lazily when required (e.g. see the |
127 // method |manager()|) or add an Init() method. | 129 // method |manager()|) or add an Init() method. |
128 } | 130 } |
129 | 131 |
130 SpeechInputDispatcherHost::~SpeechInputDispatcherHost() { | 132 InputTagSpeechDispatcherHost::~InputTagSpeechDispatcherHost() { |
131 // If the renderer crashed for some reason or if we didn't receive a proper | 133 // If the renderer crashed for some reason or if we didn't receive a proper |
132 // Cancel/Stop call for an existing session, cancel such active sessions now. | 134 // Cancel/Stop call for an existing session, cancel such active sessions now. |
133 // We first check if this dispatcher received any speech IPC requst so that | 135 // We first check if this dispatcher received any speech IPC requst so that |
134 // we don't end up creating the speech input manager for web pages which don't | 136 // we don't end up creating the speech input manager for web pages which don't |
135 // use speech input. | 137 // use speech input. |
136 if (may_have_pending_requests_) | 138 if (may_have_pending_requests_) |
137 manager()->CancelAllRequestsWithDelegate(this); | 139 manager()->CancelAllRequestsWithDelegate(this); |
138 } | 140 } |
139 | 141 |
140 SpeechInputManagerImpl* SpeechInputDispatcherHost::manager() { | 142 SpeechRecognitionManagerImpl* InputTagSpeechDispatcherHost::manager() { |
141 if (manager_) | 143 if (manager_) |
142 return manager_; | 144 return manager_; |
143 #if defined(ENABLE_INPUT_SPEECH) | 145 #if defined(ENABLE_INPUT_SPEECH) |
144 return SpeechInputManagerImpl::GetInstance(); | 146 return SpeechRecognitionManagerImpl::GetInstance(); |
145 #else | 147 #else |
146 return NULL; | 148 return NULL; |
147 #endif | 149 #endif |
148 } | 150 } |
149 | 151 |
150 bool SpeechInputDispatcherHost::OnMessageReceived( | 152 bool InputTagSpeechDispatcherHost::OnMessageReceived( |
151 const IPC::Message& message, bool* message_was_ok) { | 153 const IPC::Message& message, bool* message_was_ok) { |
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
153 bool handled = true; | 155 bool handled = true; |
154 IPC_BEGIN_MESSAGE_MAP_EX(SpeechInputDispatcherHost, message, | 156 IPC_BEGIN_MESSAGE_MAP_EX(InputTagSpeechDispatcherHost, message, |
155 *message_was_ok) | 157 *message_was_ok) |
156 IPC_MESSAGE_HANDLER(SpeechInputHostMsg_StartRecognition, | 158 IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_StartRecognition, |
157 OnStartRecognition) | 159 OnStartRecognition) |
158 IPC_MESSAGE_HANDLER(SpeechInputHostMsg_CancelRecognition, | 160 IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_CancelRecognition, |
159 OnCancelRecognition) | 161 OnCancelRecognition) |
160 IPC_MESSAGE_HANDLER(SpeechInputHostMsg_StopRecording, | 162 IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_StopRecording, |
161 OnStopRecording) | 163 OnStopRecording) |
162 IPC_MESSAGE_UNHANDLED(handled = false) | 164 IPC_MESSAGE_UNHANDLED(handled = false) |
163 IPC_END_MESSAGE_MAP() | 165 IPC_END_MESSAGE_MAP() |
164 if (handled) | 166 if (handled) |
165 may_have_pending_requests_ = true; | 167 may_have_pending_requests_ = true; |
166 return handled; | 168 return handled; |
167 } | 169 } |
168 | 170 |
169 void SpeechInputDispatcherHost::OnStartRecognition( | 171 void InputTagSpeechDispatcherHost::OnStartRecognition( |
170 const SpeechInputHostMsg_StartRecognition_Params ¶ms) { | 172 const InputTagSpeechHostMsg_StartRecognition_Params ¶ms) { |
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
172 int caller_id = g_speech_input_callers.Get().CreateId( | 174 int caller_id = g_callers.Get().CreateId( |
173 render_process_id_, params.render_view_id, params.request_id); | 175 render_process_id_, params.render_view_id, params.request_id); |
174 manager()->StartRecognition(this, caller_id, | 176 manager()->StartRecognition(this, caller_id, |
175 render_process_id_, | 177 render_process_id_, |
176 params.render_view_id, params.element_rect, | 178 params.render_view_id, params.element_rect, |
177 params.language, params.grammar, | 179 params.language, params.grammar, |
178 params.origin_url, | 180 params.origin_url, |
179 context_getter_.get(), | 181 context_getter_.get(), |
180 speech_input_preferences_.get()); | 182 recognition_preferences_.get()); |
181 } | 183 } |
182 | 184 |
183 void SpeechInputDispatcherHost::OnCancelRecognition(int render_view_id, | 185 void InputTagSpeechDispatcherHost::OnCancelRecognition(int render_view_id, |
184 int request_id) { | 186 int request_id) { |
185 int caller_id = g_speech_input_callers.Get().GetId( | 187 int caller_id = g_callers.Get().GetId( |
186 render_process_id_, render_view_id, request_id); | 188 render_process_id_, render_view_id, request_id); |
187 if (caller_id) { | 189 if (caller_id) { |
188 manager()->CancelRecognition(caller_id); | 190 manager()->CancelRecognition(caller_id); |
189 // Request sequence ended so remove mapping. | 191 // Request sequence ended so remove mapping. |
190 g_speech_input_callers.Get().RemoveId(caller_id); | 192 g_callers.Get().RemoveId(caller_id); |
191 } | 193 } |
192 } | 194 } |
193 | 195 |
194 void SpeechInputDispatcherHost::OnStopRecording(int render_view_id, | 196 void InputTagSpeechDispatcherHost::OnStopRecording(int render_view_id, |
195 int request_id) { | 197 int request_id) { |
196 int caller_id = g_speech_input_callers.Get().GetId( | 198 int caller_id = g_callers.Get().GetId( |
197 render_process_id_, render_view_id, request_id); | 199 render_process_id_, render_view_id, request_id); |
198 if (caller_id) | 200 if (caller_id) |
199 manager()->StopRecording(caller_id); | 201 manager()->StopRecording(caller_id); |
200 } | 202 } |
201 | 203 |
202 void SpeechInputDispatcherHost::SetRecognitionResult( | 204 void InputTagSpeechDispatcherHost::SetRecognitionResult( |
203 int caller_id, const content::SpeechInputResult& result) { | 205 int caller_id, const content::SpeechRecognitionResult& result) { |
204 VLOG(1) << "SpeechInputDispatcherHost::SetRecognitionResult enter"; | 206 VLOG(1) << "InputTagSpeechDispatcherHost::SetRecognitionResult enter"; |
| 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 208 int caller_render_view_id = g_callers.Get().render_view_id(caller_id); |
| 209 int caller_request_id = g_callers.Get().request_id(caller_id); |
| 210 Send(new InputTagSpeechMsg_SetRecognitionResult(caller_render_view_id, |
| 211 caller_request_id, |
| 212 result)); |
| 213 VLOG(1) << "InputTagSpeechDispatcherHost::SetRecognitionResult exit"; |
| 214 } |
| 215 |
| 216 void InputTagSpeechDispatcherHost::DidCompleteRecording(int caller_id) { |
| 217 VLOG(1) << "InputTagSpeechDispatcherHost::DidCompleteRecording enter"; |
| 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 219 int caller_render_view_id = g_callers.Get().render_view_id(caller_id); |
| 220 int caller_request_id = g_callers.Get().request_id(caller_id); |
| 221 Send(new InputTagSpeechMsg_RecordingComplete(caller_render_view_id, |
| 222 caller_request_id)); |
| 223 VLOG(1) << "InputTagSpeechDispatcherHost::DidCompleteRecording exit"; |
| 224 } |
| 225 |
| 226 void InputTagSpeechDispatcherHost::DidCompleteRecognition(int caller_id) { |
| 227 VLOG(1) << "InputTagSpeechDispatcherHost::DidCompleteRecognition enter"; |
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
206 int caller_render_view_id = | 229 int caller_render_view_id = |
207 g_speech_input_callers.Get().render_view_id(caller_id); | 230 g_callers.Get().render_view_id(caller_id); |
208 int caller_request_id = g_speech_input_callers.Get().request_id(caller_id); | 231 int caller_request_id = g_callers.Get().request_id(caller_id); |
209 Send(new SpeechInputMsg_SetRecognitionResult(caller_render_view_id, | 232 Send(new InputTagSpeechMsg_RecognitionComplete(caller_render_view_id, |
210 caller_request_id, | 233 caller_request_id)); |
211 result)); | 234 // Request sequence ended, so remove mapping. |
212 VLOG(1) << "SpeechInputDispatcherHost::SetRecognitionResult exit"; | 235 g_callers.Get().RemoveId(caller_id); |
| 236 VLOG(1) << "InputTagSpeechDispatcherHost::DidCompleteRecognition exit"; |
213 } | 237 } |
214 | 238 |
215 void SpeechInputDispatcherHost::DidCompleteRecording(int caller_id) { | 239 } // namespace speech |
216 VLOG(1) << "SpeechInputDispatcherHost::DidCompleteRecording enter"; | |
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
218 int caller_render_view_id = | |
219 g_speech_input_callers.Get().render_view_id(caller_id); | |
220 int caller_request_id = g_speech_input_callers.Get().request_id(caller_id); | |
221 Send(new SpeechInputMsg_RecordingComplete(caller_render_view_id, | |
222 caller_request_id)); | |
223 VLOG(1) << "SpeechInputDispatcherHost::DidCompleteRecording exit"; | |
224 } | |
225 | |
226 void SpeechInputDispatcherHost::DidCompleteRecognition(int caller_id) { | |
227 VLOG(1) << "SpeechInputDispatcherHost::DidCompleteRecognition enter"; | |
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
229 int caller_render_view_id = | |
230 g_speech_input_callers.Get().render_view_id(caller_id); | |
231 int caller_request_id = g_speech_input_callers.Get().request_id(caller_id); | |
232 Send(new SpeechInputMsg_RecognitionComplete(caller_render_view_id, | |
233 caller_request_id)); | |
234 // Request sequence ended, so remove mapping. | |
235 g_speech_input_callers.Get().RemoveId(caller_id); | |
236 VLOG(1) << "SpeechInputDispatcherHost::DidCompleteRecognition exit"; | |
237 } | |
238 | |
239 } // namespace speech_input | |
OLD | NEW |