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

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: fix 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 30 matching lines...) Expand all
41 41
42 namespace app_list { 42 namespace app_list {
43 43
44 namespace { 44 namespace {
45 45
46 bool InSpeechRecognition(SpeechRecognitionState state) { 46 bool InSpeechRecognition(SpeechRecognitionState state) {
47 return state == SPEECH_RECOGNITION_RECOGNIZING || 47 return state == SPEECH_RECOGNITION_RECOGNIZING ||
48 state == SPEECH_RECOGNITION_IN_SPEECH; 48 state == SPEECH_RECOGNITION_IN_SPEECH;
49 } 49 }
50 50
51 } 51 } // namespace
52 52
53 class StartPageService::ProfileDestroyObserver 53 class StartPageService::ProfileDestroyObserver
54 : public content::NotificationObserver { 54 : public content::NotificationObserver {
55 public: 55 public:
56 explicit ProfileDestroyObserver(StartPageService* service) 56 explicit ProfileDestroyObserver(StartPageService* service)
57 : service_(service) { 57 : service_(service) {
58 registrar_.Add(this, 58 registrar_.Add(this,
59 chrome::NOTIFICATION_PROFILE_DESTROYED, 59 chrome::NOTIFICATION_PROFILE_DESTROYED,
60 content::Source<Profile>(service_->profile())); 60 content::Source<Profile>(service_->profile()));
61 } 61 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 const GURL& security_origin, 95 const GURL& security_origin,
96 content::MediaStreamType type) override { 96 content::MediaStreamType type) override {
97 return MediaCaptureDevicesDispatcher::GetInstance() 97 return MediaCaptureDevicesDispatcher::GetInstance()
98 ->CheckMediaAccessPermission(web_contents, security_origin, type); 98 ->CheckMediaAccessPermission(web_contents, security_origin, type);
99 } 99 }
100 100
101 private: 101 private:
102 DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); 102 DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate);
103 }; 103 };
104 104
105 #if defined(OS_CHROMEOS)
106
107 class StartPageService::AudioStatus
108 : public chromeos::CrasAudioHandler::AudioObserver {
109 public:
110 explicit AudioStatus(StartPageService* start_page_service)
111 : start_page_service_(start_page_service) {
112 chromeos::CrasAudioHandler::Get()->AddAudioObserver(this);
113 CheckAndUpdate();
114 }
115
116 ~AudioStatus() override {
117 chromeos::CrasAudioHandler::Get()->RemoveAudioObserver(this);
118 }
119
120 bool CanListen() {
121 chromeos::CrasAudioHandler* audio_handler =
122 chromeos::CrasAudioHandler::Get();
123 return (audio_handler->GetPrimaryActiveInputNode() != 0) &&
124 !audio_handler->IsInputMuted();
125 }
126
127 private:
128 void CheckAndUpdate() {
129 if (CanListen()) {
tapted 2014/11/26 02:05:59 nit: perhaps start_page_service_->OnSpeechRecogni
Jun Mukai 2014/11/26 23:29:51 Done.
130 start_page_service_->OnSpeechRecognitionStateChanged(
131 SPEECH_RECOGNITION_READY);
132 } else {
133 start_page_service_->OnSpeechRecognitionStateChanged(
134 SPEECH_RECOGNITION_OFF);
135 }
136 }
137
138 // chromeos::CrasAudioHandler::AudioObserver:
139 void OnInputMuteChanged() override { CheckAndUpdate(); }
140
141 void OnActiveInputNodeChanged() override { CheckAndUpdate(); }
142
143 StartPageService* start_page_service_;
144 };
tapted 2014/11/26 02:05:59 nit: DISALLOW_COPY_AND_ASSIGN
Jun Mukai 2014/11/26 23:29:51 Done.
145
146 #endif // OS_CHROMEOS
147
105 // static 148 // static
106 StartPageService* StartPageService::Get(Profile* profile) { 149 StartPageService* StartPageService::Get(Profile* profile) {
107 return StartPageServiceFactory::GetForProfile(profile); 150 return StartPageServiceFactory::GetForProfile(profile);
108 } 151 }
109 152
110 StartPageService::StartPageService(Profile* profile) 153 StartPageService::StartPageService(Profile* profile)
111 : profile_(profile), 154 : profile_(profile),
112 profile_destroy_observer_(new ProfileDestroyObserver(this)), 155 profile_destroy_observer_(new ProfileDestroyObserver(this)),
113 recommended_apps_(new RecommendedApps(profile)), 156 recommended_apps_(new RecommendedApps(profile)),
114 state_(app_list::SPEECH_RECOGNITION_OFF), 157 state_(app_list::SPEECH_RECOGNITION_OFF),
115 speech_button_toggled_manually_(false), 158 speech_button_toggled_manually_(false),
116 speech_result_obtained_(false), 159 speech_result_obtained_(false),
117 webui_finished_loading_(false), 160 webui_finished_loading_(false),
118 weak_factory_(this) { 161 weak_factory_(this) {
119 // If experimental hotwording is enabled, then we're always "ready". 162 // If experimental hotwording is enabled, then we're always "ready".
120 // Transitioning into the "hotword recognizing" state is handled by the 163 // Transitioning into the "hotword recognizing" state is handled by the
121 // hotword extension. 164 // hotword extension.
122 if (HotwordService::IsExperimentalHotwordingEnabled()) 165 if (HotwordService::IsExperimentalHotwordingEnabled()) {
123 state_ = app_list::SPEECH_RECOGNITION_READY; 166 state_ = app_list::SPEECH_RECOGNITION_READY;
167 }
124 168
125 if (app_list::switches::IsExperimentalAppListEnabled()) 169 if (app_list::switches::IsExperimentalAppListEnabled())
126 LoadContents(); 170 LoadContents();
127 } 171 }
128 172
129 StartPageService::~StartPageService() {} 173 StartPageService::~StartPageService() {}
130 174
131 void StartPageService::AddObserver(StartPageObserver* observer) { 175 void StartPageService::AddObserver(StartPageObserver* observer) {
132 observers_.AddObserver(observer); 176 observers_.AddObserver(observer);
133 } 177 }
134 178
135 void StartPageService::RemoveObserver(StartPageObserver* observer) { 179 void StartPageService::RemoveObserver(StartPageObserver* observer) {
136 observers_.RemoveObserver(observer); 180 observers_.RemoveObserver(observer);
137 } 181 }
138 182
139 void StartPageService::AppListShown() { 183 void StartPageService::AppListShown() {
140 if (!contents_) { 184 if (!contents_) {
141 LoadContents(); 185 LoadContents();
142 } else if (contents_->GetWebUI() && 186 } else if (contents_->GetWebUI() &&
143 !HotwordService::IsExperimentalHotwordingEnabled()) { 187 !HotwordService::IsExperimentalHotwordingEnabled()) {
144 // If experimental hotwording is enabled, don't call onAppListShown. 188 // If experimental hotwording is enabled, don't call onAppListShown.
145 // onAppListShown() initializes the web speech API, which is not used with 189 // onAppListShown() initializes the web speech API, which is not used with
146 // experimental hotwording. 190 // experimental hotwording.
147 contents_->GetWebUI()->CallJavascriptFunction( 191 contents_->GetWebUI()->CallJavascriptFunction(
148 "appList.startPage.onAppListShown", 192 "appList.startPage.onAppListShown",
149 base::FundamentalValue(HotwordEnabled())); 193 base::FundamentalValue(HotwordEnabled()));
150 } 194 }
195
196 #if defined(OS_CHROMEOS)
197 audio_status_.reset(new AudioStatus(this));
198 #endif
151 } 199 }
152 200
153 void StartPageService::AppListHidden() { 201 void StartPageService::AppListHidden() {
154 if (contents_->GetWebUI()) { 202 if (contents_->GetWebUI()) {
155 contents_->GetWebUI()->CallJavascriptFunction( 203 contents_->GetWebUI()->CallJavascriptFunction(
156 "appList.startPage.onAppListHidden"); 204 "appList.startPage.onAppListHidden");
157 } 205 }
158 if (!app_list::switches::IsExperimentalAppListEnabled()) 206 if (!app_list::switches::IsExperimentalAppListEnabled())
159 UnloadContents(); 207 UnloadContents();
160 208
161 if (HotwordService::IsExperimentalHotwordingEnabled() && 209 if (HotwordService::IsExperimentalHotwordingEnabled() &&
162 speech_recognizer_) { 210 speech_recognizer_) {
163 speech_recognizer_->Stop(); 211 speech_recognizer_->Stop();
164 } 212 }
213
214 #if defined(OS_CHROMEOS)
215 audio_status_.reset();
216 #endif
165 } 217 }
166 218
167 void StartPageService::ToggleSpeechRecognition() { 219 void StartPageService::ToggleSpeechRecognition() {
168 DCHECK(contents_); 220 DCHECK(contents_);
169 speech_button_toggled_manually_ = true; 221 speech_button_toggled_manually_ = true;
170 if (!contents_->GetWebUI()) 222 if (!contents_->GetWebUI())
171 return; 223 return;
172 224
173 if (!webui_finished_loading_) { 225 if (!webui_finished_loading_) {
174 pending_webui_callbacks_.push_back( 226 pending_webui_callbacks_.push_back(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 297 }
246 298
247 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) { 299 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) {
248 FOR_EACH_OBSERVER(StartPageObserver, 300 FOR_EACH_OBSERVER(StartPageObserver,
249 observers_, 301 observers_,
250 OnSpeechSoundLevelChanged(level)); 302 OnSpeechSoundLevelChanged(level));
251 } 303 }
252 304
253 void StartPageService::OnSpeechRecognitionStateChanged( 305 void StartPageService::OnSpeechRecognitionStateChanged(
254 SpeechRecognitionState new_state) { 306 SpeechRecognitionState new_state) {
307 #if defined(OS_CHROMEOS)
308 // Sometimes this can be called even though there are no audio input devices.
309 if (!audio_status_->CanListen())
310 new_state = SPEECH_RECOGNITION_OFF;
311 #endif
312
313 if (state_ == new_state)
314 return;
255 315
256 if (HotwordService::IsExperimentalHotwordingEnabled() && 316 if (HotwordService::IsExperimentalHotwordingEnabled() &&
257 new_state == SPEECH_RECOGNITION_READY && 317 new_state == SPEECH_RECOGNITION_READY &&
258 speech_recognizer_) { 318 speech_recognizer_) {
259 speech_recognizer_->Stop(); 319 speech_recognizer_->Stop();
260 } 320 }
261 321
262 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) { 322 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) {
263 if (!speech_button_toggled_manually_ && 323 if (!speech_button_toggled_manually_ &&
264 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) { 324 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) {
(...skipping 12 matching lines...) Expand all
277 observers_, 337 observers_,
278 OnSpeechRecognitionStateChanged(new_state)); 338 OnSpeechRecognitionStateChanged(new_state));
279 } 339 }
280 340
281 content::WebContents* StartPageService::GetSpeechContents() { 341 content::WebContents* StartPageService::GetSpeechContents() {
282 return GetSpeechRecognitionContents(); 342 return GetSpeechRecognitionContents();
283 } 343 }
284 344
285 void StartPageService::Shutdown() { 345 void StartPageService::Shutdown() {
286 UnloadContents(); 346 UnloadContents();
347 #if defined(OS_CHROMEOS)
348 audio_status_.reset();
349 #endif
287 } 350 }
288 351
289 void StartPageService::WebUILoaded() { 352 void StartPageService::WebUILoaded() {
290 // There's a race condition between the WebUI loading, and calling its JS 353 // There's a race condition between the WebUI loading, and calling its JS
291 // functions. Specifically, calling LoadContents() doesn't mean that the page 354 // functions. Specifically, calling LoadContents() doesn't mean that the page
292 // has loaded, but several code paths make this assumption. This function 355 // 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 356 // allows us to defer calling JS functions until after the page has finished
294 // loading. 357 // loading.
295 webui_finished_loading_ = true; 358 webui_finished_loading_ = true;
296 for (const auto& cb : pending_webui_callbacks_) 359 for (const auto& cb : pending_webui_callbacks_)
(...skipping 20 matching lines...) Expand all
317 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 380 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
318 std::string()); 381 std::string());
319 } 382 }
320 383
321 void StartPageService::UnloadContents() { 384 void StartPageService::UnloadContents() {
322 contents_.reset(); 385 contents_.reset();
323 webui_finished_loading_ = false; 386 webui_finished_loading_ = false;
324 } 387 }
325 388
326 } // namespace app_list 389 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698