Index: chrome/browser/ui/app_list/start_page_service.cc |
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc |
index 930088926bb181fb02b5843816e4977750cc15e6..b9216b75751ef55fa1576a76302c702a20e1ee49 100644 |
--- a/chrome/browser/ui/app_list/start_page_service.cc |
+++ b/chrome/browser/ui/app_list/start_page_service.cc |
@@ -36,6 +36,10 @@ |
#include "extensions/common/extension.h" |
#include "ui/app_list/app_list_switches.h" |
+#if defined(OS_CHROMEOS) |
+#include "chromeos/audio/cras_audio_handler.h" |
+#endif |
+ |
using base::RecordAction; |
using base::UserMetricsAction; |
@@ -48,7 +52,7 @@ bool InSpeechRecognition(SpeechRecognitionState state) { |
state == SPEECH_RECOGNITION_IN_SPEECH; |
} |
-} |
+} // namespace |
class StartPageService::ProfileDestroyObserver |
: public content::NotificationObserver { |
@@ -102,6 +106,48 @@ class StartPageService::StartPageWebContentsDelegate |
DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); |
}; |
+#if defined(OS_CHROMEOS) |
+ |
+class StartPageService::AudioStatus |
+ : public chromeos::CrasAudioHandler::AudioObserver { |
+ public: |
+ explicit AudioStatus(StartPageService* start_page_service) |
+ : start_page_service_(start_page_service) { |
+ chromeos::CrasAudioHandler::Get()->AddAudioObserver(this); |
+ CheckAndUpdate(); |
+ } |
+ |
+ ~AudioStatus() override { |
+ chromeos::CrasAudioHandler::Get()->RemoveAudioObserver(this); |
+ } |
+ |
+ bool CanListen() { |
+ chromeos::CrasAudioHandler* audio_handler = |
+ chromeos::CrasAudioHandler::Get(); |
+ return (audio_handler->GetPrimaryActiveInputNode() != 0) && |
+ !audio_handler->IsInputMuted(); |
+ } |
+ |
+ private: |
+ void CheckAndUpdate() { |
+ // TODO(mukai): If the system can listen, this should also restart the |
+ // hotword recognition. |
+ start_page_service_->OnSpeechRecognitionStateChanged( |
+ CanListen() ? SPEECH_RECOGNITION_READY : SPEECH_RECOGNITION_OFF); |
+ } |
+ |
+ // chromeos::CrasAudioHandler::AudioObserver: |
+ void OnInputMuteChanged() override { CheckAndUpdate(); } |
+ |
+ void OnActiveInputNodeChanged() override { CheckAndUpdate(); } |
+ |
+ StartPageService* start_page_service_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AudioStatus); |
+}; |
+ |
+#endif // OS_CHROMEOS |
+ |
// static |
StartPageService* StartPageService::Get(Profile* profile) { |
return StartPageServiceFactory::GetForProfile(profile); |
@@ -119,8 +165,9 @@ StartPageService::StartPageService(Profile* profile) |
// If experimental hotwording is enabled, then we're always "ready". |
// Transitioning into the "hotword recognizing" state is handled by the |
// hotword extension. |
- if (HotwordService::IsExperimentalHotwordingEnabled()) |
+ if (HotwordService::IsExperimentalHotwordingEnabled()) { |
state_ = app_list::SPEECH_RECOGNITION_READY; |
+ } |
if (app_list::switches::IsExperimentalAppListEnabled()) |
LoadContents(); |
@@ -148,6 +195,10 @@ void StartPageService::AppListShown() { |
"appList.startPage.onAppListShown", |
base::FundamentalValue(HotwordEnabled())); |
} |
+ |
+#if defined(OS_CHROMEOS) |
+ audio_status_.reset(new AudioStatus(this)); |
+#endif |
} |
void StartPageService::AppListHidden() { |
@@ -162,6 +213,10 @@ void StartPageService::AppListHidden() { |
speech_recognizer_) { |
speech_recognizer_->Stop(); |
} |
+ |
+#if defined(OS_CHROMEOS) |
+ audio_status_.reset(); |
+#endif |
} |
void StartPageService::ToggleSpeechRecognition() { |
@@ -251,6 +306,14 @@ void StartPageService::OnSpeechSoundLevelChanged(int16_t level) { |
void StartPageService::OnSpeechRecognitionStateChanged( |
SpeechRecognitionState new_state) { |
+#if defined(OS_CHROMEOS) |
+ // Sometimes this can be called even though there are no audio input devices. |
+ if (!audio_status_->CanListen()) |
+ new_state = SPEECH_RECOGNITION_OFF; |
+#endif |
+ |
+ if (state_ == new_state) |
+ return; |
if (HotwordService::IsExperimentalHotwordingEnabled() && |
new_state == SPEECH_RECOGNITION_READY && |
@@ -283,6 +346,9 @@ content::WebContents* StartPageService::GetSpeechContents() { |
void StartPageService::Shutdown() { |
UnloadContents(); |
+#if defined(OS_CHROMEOS) |
+ audio_status_.reset(); |
+#endif |
} |
void StartPageService::WebUILoaded() { |