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

Side by Side Diff: chrome/browser/ui/app_list/start_page_service.cc

Issue 676593003: Implement native speech recognition for the launcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove refcount and better use WeakPtr. Created 6 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/ui/app_list/start_page_service.h" 5 #include "chrome/browser/ui/app_list/start_page_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "base/metrics/user_metrics.h" 12 #include "base/metrics/user_metrics.h"
13 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chrome_notification_types.h" 15 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/media/media_stream_infobar_delegate.h" 16 #include "chrome/browser/media/media_stream_infobar_delegate.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/search/hotword_service.h" 18 #include "chrome/browser/search/hotword_service.h"
18 #include "chrome/browser/search/hotword_service_factory.h" 19 #include "chrome/browser/search/hotword_service_factory.h"
19 #include "chrome/browser/ui/app_list/recommended_apps.h" 20 #include "chrome/browser/ui/app_list/recommended_apps.h"
21 #include "chrome/browser/ui/app_list/speech_recognizer.h"
20 #include "chrome/browser/ui/app_list/start_page_observer.h" 22 #include "chrome/browser/ui/app_list/start_page_observer.h"
21 #include "chrome/browser/ui/app_list/start_page_service_factory.h" 23 #include "chrome/browser/ui/app_list/start_page_service_factory.h"
22 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
24 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
25 #include "content/public/browser/notification_details.h" 27 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_observer.h" 28 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h" 29 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_source.h" 31 #include "content/public/browser/notification_source.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 observers_.AddObserver(observer); 131 observers_.AddObserver(observer);
130 } 132 }
131 133
132 void StartPageService::RemoveObserver(StartPageObserver* observer) { 134 void StartPageService::RemoveObserver(StartPageObserver* observer) {
133 observers_.RemoveObserver(observer); 135 observers_.RemoveObserver(observer);
134 } 136 }
135 137
136 void StartPageService::AppListShown() { 138 void StartPageService::AppListShown() {
137 if (!contents_) { 139 if (!contents_) {
138 LoadContents(); 140 LoadContents();
139 } else if (contents_->GetWebUI()) { 141 } else if (contents_->GetWebUI() &&
140 // If experimental hotwording is enabled, don't enable hotwording in the 142 !HotwordService::IsExperimentalHotwordingEnabled()) {
141 // start page, since the hotword extension is taking care of this. 143 // If experimental hotwording is enabled, don't call onAppListShown.
142 bool hotword_enabled = HotwordEnabled() && 144 // onAppListShown() initializes the web speech API, which is not used with
143 !HotwordService::IsExperimentalHotwordingEnabled(); 145 // experimental hotwording.
144 contents_->GetWebUI()->CallJavascriptFunction( 146 contents_->GetWebUI()->CallJavascriptFunction(
145 "appList.startPage.onAppListShown", 147 "appList.startPage.onAppListShown",
146 base::FundamentalValue(hotword_enabled)); 148 base::FundamentalValue(HotwordEnabled()));
147 } 149 }
148 } 150 }
149 151
150 void StartPageService::AppListHidden() { 152 void StartPageService::AppListHidden() {
151 if (contents_->GetWebUI()) { 153 if (contents_->GetWebUI()) {
152 contents_->GetWebUI()->CallJavascriptFunction( 154 contents_->GetWebUI()->CallJavascriptFunction(
153 "appList.startPage.onAppListHidden"); 155 "appList.startPage.onAppListHidden");
154 } 156 }
155 if (!app_list::switches::IsExperimentalAppListEnabled()) 157 if (!app_list::switches::IsExperimentalAppListEnabled())
156 UnloadContents(); 158 UnloadContents();
159
160 if (HotwordService::IsExperimentalHotwordingEnabled() &&
161 speech_recognizer_) {
162 speech_recognizer_->Stop();
163 }
157 } 164 }
158 165
159 void StartPageService::ToggleSpeechRecognition() { 166 void StartPageService::ToggleSpeechRecognition() {
160 DCHECK(contents_); 167 DCHECK(contents_);
161 speech_button_toggled_manually_ = true; 168 speech_button_toggled_manually_ = true;
162 if (!contents_->GetWebUI()) 169 if (!contents_->GetWebUI())
163 return; 170 return;
164 171
165 if (webui_finished_loading_) { 172 if (!webui_finished_loading_) {
166 contents_->GetWebUI()->CallJavascriptFunction(
167 "appList.startPage.toggleSpeechRecognition");
168 } else {
169 pending_webui_callbacks_.push_back( 173 pending_webui_callbacks_.push_back(
170 base::Bind(&StartPageService::ToggleSpeechRecognition, 174 base::Bind(&StartPageService::ToggleSpeechRecognition,
171 base::Unretained(this))); 175 base::Unretained(this)));
176 return;
172 } 177 }
178
179 if (HotwordService::IsExperimentalHotwordingEnabled()) {
180 if (!speech_recognizer_) {
181 std::string profile_locale;
182 #if defined(OS_CHROMEOS)
183 profile_locale = profile_->GetPrefs()->GetString(
184 prefs::kApplicationLocale);
185 #endif
186 if (profile_locale.empty())
187 profile_locale = g_browser_process->GetApplicationLocale();
188
189 speech_recognizer_.reset(
190 new SpeechRecognizer(this,
191 profile_->GetRequestContext(),
192 profile_locale));
193 }
194
195 speech_recognizer_->Start();
196 return;
197 }
198
199 contents_->GetWebUI()->CallJavascriptFunction(
200 "appList.startPage.toggleSpeechRecognition");
173 } 201 }
174 202
175 bool StartPageService::HotwordEnabled() { 203 bool StartPageService::HotwordEnabled() {
176 if (HotwordService::IsExperimentalHotwordingEnabled()) { 204 if (HotwordService::IsExperimentalHotwordingEnabled()) {
177 auto prefs = profile_->GetPrefs(); 205 auto prefs = profile_->GetPrefs();
178 return HotwordServiceFactory::IsServiceAvailable(profile_) && 206 return HotwordServiceFactory::IsServiceAvailable(profile_) &&
179 (prefs->GetBoolean(prefs::kHotwordSearchEnabled) || 207 (prefs->GetBoolean(prefs::kHotwordSearchEnabled) ||
180 prefs->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled)); 208 prefs->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled));
181 } 209 }
182 #if defined(OS_CHROMEOS) 210 #if defined(OS_CHROMEOS)
(...skipping 22 matching lines...) Expand all
205 const base::string16& query, bool is_final) { 233 const base::string16& query, bool is_final) {
206 if (is_final) { 234 if (is_final) {
207 speech_result_obtained_ = true; 235 speech_result_obtained_ = true;
208 RecordAction(UserMetricsAction("AppList_SearchedBySpeech")); 236 RecordAction(UserMetricsAction("AppList_SearchedBySpeech"));
209 } 237 }
210 FOR_EACH_OBSERVER(StartPageObserver, 238 FOR_EACH_OBSERVER(StartPageObserver,
211 observers_, 239 observers_,
212 OnSpeechResult(query, is_final)); 240 OnSpeechResult(query, is_final));
213 } 241 }
214 242
215 void StartPageService::OnSpeechSoundLevelChanged(int16 level) { 243 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) {
216 FOR_EACH_OBSERVER(StartPageObserver, 244 FOR_EACH_OBSERVER(StartPageObserver,
217 observers_, 245 observers_,
218 OnSpeechSoundLevelChanged(level)); 246 OnSpeechSoundLevelChanged(level));
219 } 247 }
220 248
221 void StartPageService::OnSpeechRecognitionStateChanged( 249 void StartPageService::OnSpeechRecognitionStateChanged(
222 SpeechRecognitionState new_state) { 250 SpeechRecognitionState new_state) {
251
252 if (HotwordService::IsExperimentalHotwordingEnabled() &&
253 new_state == SPEECH_RECOGNITION_READY &&
254 speech_recognizer_) {
255 speech_recognizer_->Stop();
256 }
257
223 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) { 258 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) {
224 if (!speech_button_toggled_manually_ && 259 if (!speech_button_toggled_manually_ &&
225 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) { 260 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) {
226 RecordAction(UserMetricsAction("AppList_HotwordRecognized")); 261 RecordAction(UserMetricsAction("AppList_HotwordRecognized"));
227 } else { 262 } else {
228 RecordAction(UserMetricsAction("AppList_VoiceSearchStartedManually")); 263 RecordAction(UserMetricsAction("AppList_VoiceSearchStartedManually"));
229 } 264 }
230 } else if (InSpeechRecognition(state_) && !InSpeechRecognition(new_state) && 265 } else if (InSpeechRecognition(state_) && !InSpeechRecognition(new_state) &&
231 !speech_result_obtained_) { 266 !speech_result_obtained_) {
232 RecordAction(UserMetricsAction("AppList_VoiceSearchCanceled")); 267 RecordAction(UserMetricsAction("AppList_VoiceSearchCanceled"));
233 } 268 }
234 speech_button_toggled_manually_ = false; 269 speech_button_toggled_manually_ = false;
235 speech_result_obtained_ = false; 270 speech_result_obtained_ = false;
236 state_ = new_state; 271 state_ = new_state;
237 FOR_EACH_OBSERVER(StartPageObserver, 272 FOR_EACH_OBSERVER(StartPageObserver,
238 observers_, 273 observers_,
239 OnSpeechRecognitionStateChanged(new_state)); 274 OnSpeechRecognitionStateChanged(new_state));
240 } 275 }
241 276
277 content::WebContents* StartPageService::GetSpeechContents() {
278 return GetSpeechRecognitionContents();
279 }
280
242 void StartPageService::Shutdown() { 281 void StartPageService::Shutdown() {
243 UnloadContents(); 282 UnloadContents();
244 } 283 }
245 284
246 void StartPageService::WebUILoaded() { 285 void StartPageService::WebUILoaded() {
247 // There's a race condition between the WebUI loading, and calling its JS 286 // There's a race condition between the WebUI loading, and calling its JS
248 // functions. Specifically, calling LoadContents() doesn't mean that the page 287 // functions. Specifically, calling LoadContents() doesn't mean that the page
249 // has loaded, but several code paths make this assumption. This function 288 // has loaded, but several code paths make this assumption. This function
250 // allows us to defer calling JS functions until after the page has finished 289 // allows us to defer calling JS functions until after the page has finished
251 // loading. 290 // loading.
(...skipping 22 matching lines...) Expand all
274 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 313 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
275 std::string()); 314 std::string());
276 } 315 }
277 316
278 void StartPageService::UnloadContents() { 317 void StartPageService::UnloadContents() {
279 contents_.reset(); 318 contents_.reset();
280 webui_finished_loading_ = false; 319 webui_finished_loading_ = false;
281 } 320 }
282 321
283 } // namespace app_list 322 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698