| Index: chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| index 87752b62c0edc257f4848cdbd3bc38dccbc1796a..c62666cc116babbc1ed5d7f09be697a07e711aad 100644
|
| --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| @@ -472,8 +472,22 @@ void AppListViewDelegate::ViewClosing() {
|
| if (service->HotwordEnabled()) {
|
| HotwordService* hotword_service =
|
| HotwordServiceFactory::GetForProfile(profile_);
|
| - if (hotword_service)
|
| + if (hotword_service) {
|
| hotword_service->StopHotwordSession(this);
|
| +
|
| + // If we're in always-on mode, we always want to restart hotwording
|
| + // after closing the launcher window. So, in always-on mode, hotwording
|
| + // is stopped, and then started again right away. Note that hotwording
|
| + // may already be stopped. The call to StopHotwordSession() above both
|
| + // explicitly stops hotwording, if it's running, and clears the
|
| + // association between the hotword service and |this|. When starting up
|
| + // hotwording, pass nullptr as the client so that hotword triggers cause
|
| + // the launcher to open.
|
| + // TODO(amistry): This only works on ChromeOS since Chrome hides the
|
| + // launcher instead of destroying it. Make this work on Chrome.
|
| + if (hotword_service->IsAlwaysOnEnabled())
|
| + hotword_service->RequestHotwordSession(nullptr);
|
| + }
|
| }
|
| }
|
| }
|
| @@ -519,6 +533,23 @@ void AppListViewDelegate::ToggleSpeechRecognition() {
|
| app_list::StartPageService::Get(profile_);
|
| if (service)
|
| service->ToggleSpeechRecognition();
|
| +
|
| + // With the new hotword extension, stop the hotword session. With the launcher
|
| + // and NTP, this is unnecessary since the hotwording is implicitly stopped.
|
| + // However, for always on, hotword triggering launches the launcher which
|
| + // starts a session and hence starts the hotword detector. This results in the
|
| + // hotword detector and the speech-to-text engine running in parallel, which
|
| + // will conflict with each other (i.e. saying 'Ok Google' twice in a row
|
| + // should cause a search to happen for 'Ok Google', not two hotword triggers).
|
| + // To get around this, always stop the session when switching to speech
|
| + // recognition.
|
| + if (HotwordService::IsExperimentalHotwordingEnabled() &&
|
| + service && service->HotwordEnabled()) {
|
| + HotwordService* hotword_service =
|
| + HotwordServiceFactory::GetForProfile(profile_);
|
| + if (hotword_service)
|
| + hotword_service->StopHotwordSession(this);
|
| + }
|
| }
|
|
|
| void AppListViewDelegate::ShowForProfileByPath(
|
| @@ -547,10 +578,12 @@ void AppListViewDelegate::OnSpeechRecognitionStateChanged(
|
| app_list::StartPageService* service =
|
| app_list::StartPageService::Get(profile_);
|
| // With the new hotword extension, we need to re-request hotwording after
|
| - // speech recognition has stopped.
|
| + // speech recognition has stopped. Do not request hotwording after the app
|
| + // list has already closed.
|
| if (new_state == app_list::SPEECH_RECOGNITION_READY &&
|
| HotwordService::IsExperimentalHotwordingEnabled() &&
|
| - service && service->HotwordEnabled()) {
|
| + service && service->HotwordEnabled() &&
|
| + controller_->GetAppListWindow()) {
|
| HotwordService* hotword_service =
|
| HotwordServiceFactory::GetForProfile(profile_);
|
| if (hotword_service) {
|
|
|