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

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

Issue 752253002: Updates the mic icon status based on the device's audio state. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years 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"
(...skipping 25 matching lines...) Expand all
36 #include "extensions/common/extension.h" 36 #include "extensions/common/extension.h"
37 #include "ui/app_list/app_list_switches.h" 37 #include "ui/app_list/app_list_switches.h"
38 38
39 using base::RecordAction; 39 using base::RecordAction;
40 using base::UserMetricsAction; 40 using base::UserMetricsAction;
41 41
42 namespace app_list { 42 namespace app_list {
43 43
44 namespace { 44 namespace {
45 45
46 bool IsVoiceSearchEnabled() {
tapted 2014/11/25 05:03:10 It's a bit confusing having standalone `IsVoiceSea
Jun Mukai 2014/11/26 01:39:21 Done to rename it to CanListen. Not so sure about
47 if (!app_list::switches::IsVoiceSearchEnabled())
48 return false;
49 #if defined(OS_CHROMEOS)
50 if (!chromeos::CrasAudioHandler::IsInitialized())
51 return false;
52 chromeos::CrasAudioHandler* audio_handler = chromeos::CrasAudioHandler::Get();
53 if (!audio_handler->GetPrimaryActiveInputNode())
54 return false;
55 if (audio_handler->IsInputMuted())
56 return false;
57 #endif
58 return true;
59 }
60
46 bool InSpeechRecognition(SpeechRecognitionState state) { 61 bool InSpeechRecognition(SpeechRecognitionState state) {
47 return state == SPEECH_RECOGNITION_RECOGNIZING || 62 return state == SPEECH_RECOGNITION_RECOGNIZING ||
48 state == SPEECH_RECOGNITION_IN_SPEECH; 63 state == SPEECH_RECOGNITION_IN_SPEECH;
49 } 64 }
50 65
51 } 66 } // namespace
52 67
53 class StartPageService::ProfileDestroyObserver 68 class StartPageService::ProfileDestroyObserver
54 : public content::NotificationObserver { 69 : public content::NotificationObserver {
55 public: 70 public:
56 explicit ProfileDestroyObserver(StartPageService* service) 71 explicit ProfileDestroyObserver(StartPageService* service)
57 : service_(service) { 72 : service_(service) {
58 registrar_.Add(this, 73 registrar_.Add(this,
59 chrome::NOTIFICATION_PROFILE_DESTROYED, 74 chrome::NOTIFICATION_PROFILE_DESTROYED,
60 content::Source<Profile>(service_->profile())); 75 content::Source<Profile>(service_->profile()));
61 } 76 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 profile_destroy_observer_(new ProfileDestroyObserver(this)), 127 profile_destroy_observer_(new ProfileDestroyObserver(this)),
113 recommended_apps_(new RecommendedApps(profile)), 128 recommended_apps_(new RecommendedApps(profile)),
114 state_(app_list::SPEECH_RECOGNITION_OFF), 129 state_(app_list::SPEECH_RECOGNITION_OFF),
115 speech_button_toggled_manually_(false), 130 speech_button_toggled_manually_(false),
116 speech_result_obtained_(false), 131 speech_result_obtained_(false),
117 webui_finished_loading_(false), 132 webui_finished_loading_(false),
118 weak_factory_(this) { 133 weak_factory_(this) {
119 // If experimental hotwording is enabled, then we're always "ready". 134 // If experimental hotwording is enabled, then we're always "ready".
120 // Transitioning into the "hotword recognizing" state is handled by the 135 // Transitioning into the "hotword recognizing" state is handled by the
121 // hotword extension. 136 // hotword extension.
122 if (HotwordService::IsExperimentalHotwordingEnabled()) 137 if (IsVoiceSearchEnabled() &&
138 HotwordService::IsExperimentalHotwordingEnabled()) {
123 state_ = app_list::SPEECH_RECOGNITION_READY; 139 state_ = app_list::SPEECH_RECOGNITION_READY;
140 }
124 141
125 if (app_list::switches::IsExperimentalAppListEnabled()) 142 if (app_list::switches::IsExperimentalAppListEnabled())
126 LoadContents(); 143 LoadContents();
127 } 144 }
128 145
129 StartPageService::~StartPageService() {} 146 StartPageService::~StartPageService() {}
130 147
131 void StartPageService::AddObserver(StartPageObserver* observer) { 148 void StartPageService::AddObserver(StartPageObserver* observer) {
132 observers_.AddObserver(observer); 149 observers_.AddObserver(observer);
133 } 150 }
134 151
135 void StartPageService::RemoveObserver(StartPageObserver* observer) { 152 void StartPageService::RemoveObserver(StartPageObserver* observer) {
136 observers_.RemoveObserver(observer); 153 observers_.RemoveObserver(observer);
137 } 154 }
138 155
139 void StartPageService::AppListShown() { 156 void StartPageService::AppListShown() {
140 if (!contents_) { 157 if (!contents_) {
141 LoadContents(); 158 LoadContents();
142 } else if (contents_->GetWebUI() && 159 } else if (contents_->GetWebUI() &&
143 !HotwordService::IsExperimentalHotwordingEnabled()) { 160 !HotwordService::IsExperimentalHotwordingEnabled()) {
144 // If experimental hotwording is enabled, don't call onAppListShown. 161 // If experimental hotwording is enabled, don't call onAppListShown.
145 // onAppListShown() initializes the web speech API, which is not used with 162 // onAppListShown() initializes the web speech API, which is not used with
146 // experimental hotwording. 163 // experimental hotwording.
147 contents_->GetWebUI()->CallJavascriptFunction( 164 contents_->GetWebUI()->CallJavascriptFunction(
148 "appList.startPage.onAppListShown", 165 "appList.startPage.onAppListShown",
149 base::FundamentalValue(HotwordEnabled())); 166 base::FundamentalValue(HotwordEnabled()));
150 } 167 }
168 #if defined(OS_CHROMEOS)
169 chromeos::CrasAudioHandler::Get()->AddAudioObserver(this);
tapted 2014/11/25 11:07:52 Also, what are the implications for always-on-hotw
Jun Mukai 2014/11/26 01:39:21 If that flag is specified, indeed it attempts to r
tapted 2014/11/26 02:05:58 So long as always-on isn't worse with it like this
Anand Mistry (off Chromium) 2014/11/26 10:49:58 If I understand this change correctly, under the n
Jun Mukai 2014/11/26 21:59:44 That is right. But I guess the hotworder will stop
Jun Mukai 2014/11/26 23:29:50 After thinking again, I've realized that this is s
170 #endif
151 } 171 }
152 172
153 void StartPageService::AppListHidden() { 173 void StartPageService::AppListHidden() {
154 if (contents_->GetWebUI()) { 174 if (contents_->GetWebUI()) {
155 contents_->GetWebUI()->CallJavascriptFunction( 175 contents_->GetWebUI()->CallJavascriptFunction(
156 "appList.startPage.onAppListHidden"); 176 "appList.startPage.onAppListHidden");
157 } 177 }
158 if (!app_list::switches::IsExperimentalAppListEnabled()) 178 if (!app_list::switches::IsExperimentalAppListEnabled())
159 UnloadContents(); 179 UnloadContents();
160 180
161 if (HotwordService::IsExperimentalHotwordingEnabled() && 181 if (HotwordService::IsExperimentalHotwordingEnabled() &&
162 speech_recognizer_) { 182 speech_recognizer_) {
163 speech_recognizer_->Stop(); 183 speech_recognizer_->Stop();
164 } 184 }
185 #if defined(OS_CHROMEOS)
186 chromeos::CrasAudioHandler::Get()->RemoveAudioObserver(this);
187 #endif
165 } 188 }
166 189
167 void StartPageService::ToggleSpeechRecognition() { 190 void StartPageService::ToggleSpeechRecognition() {
168 DCHECK(contents_); 191 DCHECK(contents_);
169 speech_button_toggled_manually_ = true; 192 speech_button_toggled_manually_ = true;
170 if (!contents_->GetWebUI()) 193 if (!contents_->GetWebUI())
171 return; 194 return;
172 195
173 if (!webui_finished_loading_) { 196 if (!webui_finished_loading_) {
174 pending_webui_callbacks_.push_back( 197 pending_webui_callbacks_.push_back(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 return false; 241 return false;
219 #endif 242 #endif
220 } 243 }
221 244
222 content::WebContents* StartPageService::GetStartPageContents() { 245 content::WebContents* StartPageService::GetStartPageContents() {
223 return app_list::switches::IsExperimentalAppListEnabled() ? contents_.get() 246 return app_list::switches::IsExperimentalAppListEnabled() ? contents_.get()
224 : NULL; 247 : NULL;
225 } 248 }
226 249
227 content::WebContents* StartPageService::GetSpeechRecognitionContents() { 250 content::WebContents* StartPageService::GetSpeechRecognitionContents() {
228 if (app_list::switches::IsVoiceSearchEnabled()) { 251 if (IsVoiceSearchEnabled()) {
tapted 2014/11/25 05:03:10 Why this change? It doesn't seem robust to return
Jun Mukai 2014/11/26 01:39:21 Reverted back to the original. The original motiv
229 if (!contents_) 252 if (!contents_)
230 LoadContents(); 253 LoadContents();
231 return contents_.get(); 254 return contents_.get();
232 } 255 }
233 return NULL; 256 return NULL;
234 } 257 }
235 258
236 void StartPageService::OnSpeechResult( 259 void StartPageService::OnSpeechResult(
237 const base::string16& query, bool is_final) { 260 const base::string16& query, bool is_final) {
238 if (is_final) { 261 if (is_final) {
239 speech_result_obtained_ = true; 262 speech_result_obtained_ = true;
240 RecordAction(UserMetricsAction("AppList_SearchedBySpeech")); 263 RecordAction(UserMetricsAction("AppList_SearchedBySpeech"));
241 } 264 }
242 FOR_EACH_OBSERVER(StartPageObserver, 265 FOR_EACH_OBSERVER(StartPageObserver,
243 observers_, 266 observers_,
244 OnSpeechResult(query, is_final)); 267 OnSpeechResult(query, is_final));
245 } 268 }
246 269
247 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) { 270 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) {
248 FOR_EACH_OBSERVER(StartPageObserver, 271 FOR_EACH_OBSERVER(StartPageObserver,
249 observers_, 272 observers_,
250 OnSpeechSoundLevelChanged(level)); 273 OnSpeechSoundLevelChanged(level));
251 } 274 }
252 275
253 void StartPageService::OnSpeechRecognitionStateChanged( 276 void StartPageService::OnSpeechRecognitionStateChanged(
254 SpeechRecognitionState new_state) { 277 SpeechRecognitionState new_state) {
278 // Sometimes this can be called even though there are no audio input devices.
279 if (!IsVoiceSearchEnabled())
280 new_state = SPEECH_RECOGNITION_OFF;
tapted 2014/11/25 05:03:10 This can leave new_state == state_ -- should that
Jun Mukai 2014/11/26 01:39:21 Done.
255 281
256 if (HotwordService::IsExperimentalHotwordingEnabled() && 282 if (HotwordService::IsExperimentalHotwordingEnabled() &&
257 new_state == SPEECH_RECOGNITION_READY && 283 new_state == SPEECH_RECOGNITION_READY &&
258 speech_recognizer_) { 284 speech_recognizer_) {
259 speech_recognizer_->Stop(); 285 speech_recognizer_->Stop();
260 } 286 }
261 287
262 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) { 288 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) {
263 if (!speech_button_toggled_manually_ && 289 if (!speech_button_toggled_manually_ &&
264 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) { 290 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) {
(...skipping 14 matching lines...) Expand all
279 } 305 }
280 306
281 content::WebContents* StartPageService::GetSpeechContents() { 307 content::WebContents* StartPageService::GetSpeechContents() {
282 return GetSpeechRecognitionContents(); 308 return GetSpeechRecognitionContents();
283 } 309 }
284 310
285 void StartPageService::Shutdown() { 311 void StartPageService::Shutdown() {
286 UnloadContents(); 312 UnloadContents();
287 } 313 }
288 314
315 #if defined(OS_CHROMEOS)
316 void StartPageService::OnInputMuteChanged() {
317 if (IsVoiceSearchEnabled())
318 OnSpeechRecognitionStateChanged(SPEECH_RECOGNITION_READY);
319 else
320 OnSpeechRecognitionStateChanged(SPEECH_RECOGNITION_OFF);
321 }
322
323 void StartPageService::OnActiveInputNodeChanged() {
324 OnInputMuteChanged();
325 }
326 #endif
327
289 void StartPageService::WebUILoaded() { 328 void StartPageService::WebUILoaded() {
290 // There's a race condition between the WebUI loading, and calling its JS 329 // There's a race condition between the WebUI loading, and calling its JS
291 // functions. Specifically, calling LoadContents() doesn't mean that the page 330 // functions. Specifically, calling LoadContents() doesn't mean that the page
292 // has loaded, but several code paths make this assumption. This function 331 // has loaded, but several code paths make this assumption. This function
293 // allows us to defer calling JS functions until after the page has finished 332 // allows us to defer calling JS functions until after the page has finished
294 // loading. 333 // loading.
295 webui_finished_loading_ = true; 334 webui_finished_loading_ = true;
296 for (const auto& cb : pending_webui_callbacks_) 335 for (const auto& cb : pending_webui_callbacks_)
297 cb.Run(); 336 cb.Run();
298 pending_webui_callbacks_.clear(); 337 pending_webui_callbacks_.clear();
(...skipping 18 matching lines...) Expand all
317 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 356 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
318 std::string()); 357 std::string());
319 } 358 }
320 359
321 void StartPageService::UnloadContents() { 360 void StartPageService::UnloadContents() {
322 contents_.reset(); 361 contents_.reset();
323 webui_finished_loading_ = false; 362 webui_finished_loading_ = false;
324 } 363 }
325 364
326 } // namespace app_list 365 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698