| OLD | NEW |
| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #include "content/public/browser/web_contents.h" | 53 #include "content/public/browser/web_contents.h" |
| 54 #include "content/public/browser/web_contents_delegate.h" | 54 #include "content/public/browser/web_contents_delegate.h" |
| 55 #include "content/public/common/content_switches.h" | 55 #include "content/public/common/content_switches.h" |
| 56 #include "extensions/browser/extension_system_provider.h" | 56 #include "extensions/browser/extension_system_provider.h" |
| 57 #include "extensions/browser/extensions_browser_client.h" | 57 #include "extensions/browser/extensions_browser_client.h" |
| 58 #include "extensions/common/extension.h" | 58 #include "extensions/common/extension.h" |
| 59 #include "net/base/load_flags.h" | 59 #include "net/base/load_flags.h" |
| 60 #include "net/base/network_change_notifier.h" | 60 #include "net/base/network_change_notifier.h" |
| 61 #include "net/url_request/url_fetcher.h" | 61 #include "net/url_request/url_fetcher.h" |
| 62 #include "ui/app_list/app_list_switches.h" | 62 #include "ui/app_list/app_list_switches.h" |
| 63 | |
| 64 #if defined(OS_CHROMEOS) | |
| 65 #include "chromeos/audio/cras_audio_handler.h" | 63 #include "chromeos/audio/cras_audio_handler.h" |
| 66 #endif | |
| 67 | 64 |
| 68 using base::RecordAction; | 65 using base::RecordAction; |
| 69 using base::UserMetricsAction; | 66 using base::UserMetricsAction; |
| 70 | 67 |
| 71 namespace app_list { | 68 namespace app_list { |
| 72 | 69 |
| 73 namespace { | 70 namespace { |
| 74 | 71 |
| 75 // Path to google.com's doodle JSON. | 72 // Path to google.com's doodle JSON. |
| 76 const char kDoodleJsonPath[] = "async/ddljson"; | 73 const char kDoodleJsonPath[] = "async/ddljson"; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 event.type() == blink::WebGestureEvent::GesturePinchEnd; | 200 event.type() == blink::WebGestureEvent::GesturePinchEnd; |
| 204 } | 201 } |
| 205 | 202 |
| 206 | 203 |
| 207 private: | 204 private: |
| 208 Profile* profile_; | 205 Profile* profile_; |
| 209 | 206 |
| 210 DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); | 207 DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); |
| 211 }; | 208 }; |
| 212 | 209 |
| 213 #if defined(OS_CHROMEOS) | |
| 214 | 210 |
| 215 class StartPageService::AudioStatus | 211 class StartPageService::AudioStatus |
| 216 : public chromeos::CrasAudioHandler::AudioObserver { | 212 : public chromeos::CrasAudioHandler::AudioObserver { |
| 217 public: | 213 public: |
| 218 explicit AudioStatus(StartPageService* start_page_service) | 214 explicit AudioStatus(StartPageService* start_page_service) |
| 219 : start_page_service_(start_page_service) { | 215 : start_page_service_(start_page_service) { |
| 220 chromeos::CrasAudioHandler::Get()->AddAudioObserver(this); | 216 chromeos::CrasAudioHandler::Get()->AddAudioObserver(this); |
| 221 CheckAndUpdate(); | 217 CheckAndUpdate(); |
| 222 } | 218 } |
| 223 | 219 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 242 // chromeos::CrasAudioHandler::AudioObserver: | 238 // chromeos::CrasAudioHandler::AudioObserver: |
| 243 void OnInputMuteChanged(bool /* mute_on */) override { CheckAndUpdate(); } | 239 void OnInputMuteChanged(bool /* mute_on */) override { CheckAndUpdate(); } |
| 244 | 240 |
| 245 void OnActiveInputNodeChanged() override { CheckAndUpdate(); } | 241 void OnActiveInputNodeChanged() override { CheckAndUpdate(); } |
| 246 | 242 |
| 247 StartPageService* start_page_service_; | 243 StartPageService* start_page_service_; |
| 248 | 244 |
| 249 DISALLOW_COPY_AND_ASSIGN(AudioStatus); | 245 DISALLOW_COPY_AND_ASSIGN(AudioStatus); |
| 250 }; | 246 }; |
| 251 | 247 |
| 252 #endif // OS_CHROMEOS | |
| 253 | |
| 254 class StartPageService::NetworkChangeObserver | 248 class StartPageService::NetworkChangeObserver |
| 255 : public net::NetworkChangeNotifier::NetworkChangeObserver { | 249 : public net::NetworkChangeNotifier::NetworkChangeObserver { |
| 256 public: | 250 public: |
| 257 explicit NetworkChangeObserver(StartPageService* start_page_service) | 251 explicit NetworkChangeObserver(StartPageService* start_page_service) |
| 258 : start_page_service_(start_page_service) { | 252 : start_page_service_(start_page_service) { |
| 259 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 253 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 260 // NOTE: This is used to detect network connectivity changes. However, what | 254 // NOTE: This is used to detect network connectivity changes. However, what |
| 261 // we really want is internet connectivity changes because voice recognition | 255 // we really want is internet connectivity changes because voice recognition |
| 262 // needs to talk to a web service. However, this information isn't | 256 // needs to talk to a web service. However, this information isn't |
| 263 // available, so network changes are the best we can do. | 257 // available, so network changes are the best we can do. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 void StartPageService::AppListShown() { | 376 void StartPageService::AppListShown() { |
| 383 if (!contents_) { | 377 if (!contents_) { |
| 384 LoadContents(); | 378 LoadContents(); |
| 385 } else if (contents_->IsCrashed()) { | 379 } else if (contents_->IsCrashed()) { |
| 386 LoadStartPageURL(); | 380 LoadStartPageURL(); |
| 387 } else if (contents_->GetWebUI()) { | 381 } else if (contents_->GetWebUI()) { |
| 388 contents_->GetWebUI()->CallJavascriptFunctionUnsafe( | 382 contents_->GetWebUI()->CallJavascriptFunctionUnsafe( |
| 389 "appList.startPage.onAppListShown"); | 383 "appList.startPage.onAppListShown"); |
| 390 } | 384 } |
| 391 | 385 |
| 392 #if defined(OS_CHROMEOS) | |
| 393 audio_status_.reset(new AudioStatus(this)); | 386 audio_status_.reset(new AudioStatus(this)); |
| 394 #endif | |
| 395 } | 387 } |
| 396 | 388 |
| 397 void StartPageService::AppListHidden() { | 389 void StartPageService::AppListHidden() { |
| 398 if (speech_recognizer_) { | 390 if (speech_recognizer_) { |
| 399 StopSpeechRecognition(); | 391 StopSpeechRecognition(); |
| 400 } | 392 } |
| 401 | 393 |
| 402 #if defined(OS_CHROMEOS) | |
| 403 audio_status_.reset(); | 394 audio_status_.reset(); |
| 404 #endif | |
| 405 } | 395 } |
| 406 | 396 |
| 407 void StartPageService::StartSpeechRecognition( | 397 void StartPageService::StartSpeechRecognition( |
| 408 const scoped_refptr<content::SpeechRecognitionSessionPreamble>& preamble) { | 398 const scoped_refptr<content::SpeechRecognitionSessionPreamble>& preamble) { |
| 409 DCHECK(contents_); | 399 DCHECK(contents_); |
| 410 speech_button_toggled_manually_ = true; | 400 speech_button_toggled_manually_ = true; |
| 411 | 401 |
| 412 if (!speech_recognizer_) { | 402 if (!speech_recognizer_) { |
| 413 std::string profile_locale; | 403 std::string profile_locale; |
| 414 #if defined(OS_CHROMEOS) | |
| 415 profile_locale = profile_->GetPrefs()->GetString( | 404 profile_locale = profile_->GetPrefs()->GetString( |
| 416 prefs::kApplicationLocale); | 405 prefs::kApplicationLocale); |
| 417 #endif | |
| 418 if (profile_locale.empty()) | 406 if (profile_locale.empty()) |
| 419 profile_locale = g_browser_process->GetApplicationLocale(); | 407 profile_locale = g_browser_process->GetApplicationLocale(); |
| 420 | 408 |
| 421 speech_recognizer_.reset( | 409 speech_recognizer_.reset( |
| 422 new SpeechRecognizer(weak_factory_.GetWeakPtr(), | 410 new SpeechRecognizer(weak_factory_.GetWeakPtr(), |
| 423 profile_->GetRequestContext(), | 411 profile_->GetRequestContext(), |
| 424 profile_locale)); | 412 profile_locale)); |
| 425 } | 413 } |
| 426 | 414 |
| 427 speech_recognizer_->Start(preamble); | 415 speech_recognizer_->Start(preamble); |
| 428 } | 416 } |
| 429 | 417 |
| 430 void StartPageService::StopSpeechRecognition() { | 418 void StartPageService::StopSpeechRecognition() { |
| 431 // A call to Stop() isn't needed since deleting the recognizer implicitly | 419 // A call to Stop() isn't needed since deleting the recognizer implicitly |
| 432 // stops. | 420 // stops. |
| 433 speech_recognizer_.reset(); | 421 speech_recognizer_.reset(); |
| 434 | 422 |
| 435 // When the SpeechRecognizer is destroyed above, we get stuck in the current | 423 // When the SpeechRecognizer is destroyed above, we get stuck in the current |
| 436 // speech state instead of being reset into the READY state. Reset the speech | 424 // speech state instead of being reset into the READY state. Reset the speech |
| 437 // state explicitly so that speech works when the launcher is opened again. | 425 // state explicitly so that speech works when the launcher is opened again. |
| 438 OnSpeechRecognitionStateChanged(SPEECH_RECOGNITION_READY); | 426 OnSpeechRecognitionStateChanged(SPEECH_RECOGNITION_READY); |
| 439 } | 427 } |
| 440 | 428 |
| 441 bool StartPageService::HotwordEnabled() { | 429 bool StartPageService::HotwordEnabled() { |
| 442 // Voice input for the launcher is unsupported on non-ChromeOS platforms. | |
| 443 // TODO(amistry): Make speech input, and hotwording, work on non-ChromeOS. | |
| 444 #if defined(OS_CHROMEOS) | |
| 445 HotwordService* service = HotwordServiceFactory::GetForProfile(profile_); | 430 HotwordService* service = HotwordServiceFactory::GetForProfile(profile_); |
| 446 return state_ != SPEECH_RECOGNITION_OFF && | 431 return state_ != SPEECH_RECOGNITION_OFF && |
| 447 service && | 432 service && |
| 448 (service->IsSometimesOnEnabled() || service->IsAlwaysOnEnabled()) && | 433 (service->IsSometimesOnEnabled() || service->IsAlwaysOnEnabled()) && |
| 449 service->IsServiceAvailable(); | 434 service->IsServiceAvailable(); |
| 450 #else | |
| 451 return false; | |
| 452 #endif | |
| 453 } | 435 } |
| 454 | 436 |
| 455 content::WebContents* StartPageService::GetStartPageContents() { | 437 content::WebContents* StartPageService::GetStartPageContents() { |
| 456 return contents_.get(); | 438 return contents_.get(); |
| 457 } | 439 } |
| 458 | 440 |
| 459 content::WebContents* StartPageService::GetSpeechRecognitionContents() { | 441 content::WebContents* StartPageService::GetSpeechRecognitionContents() { |
| 460 if (app_list::switches::IsVoiceSearchEnabled()) { | 442 if (app_list::switches::IsVoiceSearchEnabled()) { |
| 461 if (!contents_) | 443 if (!contents_) |
| 462 LoadContents(); | 444 LoadContents(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 475 observer.OnSpeechResult(query, is_final); | 457 observer.OnSpeechResult(query, is_final); |
| 476 } | 458 } |
| 477 | 459 |
| 478 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) { | 460 void StartPageService::OnSpeechSoundLevelChanged(int16_t level) { |
| 479 for (auto& observer : observers_) | 461 for (auto& observer : observers_) |
| 480 observer.OnSpeechSoundLevelChanged(level); | 462 observer.OnSpeechSoundLevelChanged(level); |
| 481 } | 463 } |
| 482 | 464 |
| 483 void StartPageService::OnSpeechRecognitionStateChanged( | 465 void StartPageService::OnSpeechRecognitionStateChanged( |
| 484 SpeechRecognitionState new_state) { | 466 SpeechRecognitionState new_state) { |
| 485 #if defined(OS_CHROMEOS) | |
| 486 // Sometimes this can be called even though there are no audio input devices. | 467 // Sometimes this can be called even though there are no audio input devices. |
| 487 if (audio_status_ && !audio_status_->CanListen()) | 468 if (audio_status_ && !audio_status_->CanListen()) |
| 488 new_state = SPEECH_RECOGNITION_OFF; | 469 new_state = SPEECH_RECOGNITION_OFF; |
| 489 #endif | |
| 490 if (!microphone_available_) | 470 if (!microphone_available_) |
| 491 new_state = SPEECH_RECOGNITION_OFF; | 471 new_state = SPEECH_RECOGNITION_OFF; |
| 492 if (!network_available_) | 472 if (!network_available_) |
| 493 new_state = SPEECH_RECOGNITION_NETWORK_ERROR; | 473 new_state = SPEECH_RECOGNITION_NETWORK_ERROR; |
| 494 | 474 |
| 495 if (state_ == new_state) | 475 if (state_ == new_state) |
| 496 return; | 476 return; |
| 497 | 477 |
| 498 if ((new_state == SPEECH_RECOGNITION_READY || | 478 if ((new_state == SPEECH_RECOGNITION_READY || |
| 499 new_state == SPEECH_RECOGNITION_OFF || | 479 new_state == SPEECH_RECOGNITION_OFF || |
| (...skipping 27 matching lines...) Expand all Loading... |
| 527 service->IsOptedIntoAudioLogging() && | 507 service->IsOptedIntoAudioLogging() && |
| 528 service->IsAlwaysOnEnabled() && | 508 service->IsAlwaysOnEnabled() && |
| 529 !speech_auth_helper_->GetToken().empty()) { | 509 !speech_auth_helper_->GetToken().empty()) { |
| 530 *auth_scope = speech_auth_helper_->GetScope(); | 510 *auth_scope = speech_auth_helper_->GetScope(); |
| 531 *auth_token = speech_auth_helper_->GetToken(); | 511 *auth_token = speech_auth_helper_->GetToken(); |
| 532 } | 512 } |
| 533 } | 513 } |
| 534 | 514 |
| 535 void StartPageService::Shutdown() { | 515 void StartPageService::Shutdown() { |
| 536 UnloadContents(); | 516 UnloadContents(); |
| 537 #if defined(OS_CHROMEOS) | |
| 538 audio_status_.reset(); | 517 audio_status_.reset(); |
| 539 #endif | |
| 540 | |
| 541 speech_auth_helper_.reset(); | 518 speech_auth_helper_.reset(); |
| 542 network_change_observer_.reset(); | 519 network_change_observer_.reset(); |
| 543 } | 520 } |
| 544 | 521 |
| 545 void StartPageService::DidFinishNavigation( | 522 void StartPageService::DidFinishNavigation( |
| 546 content::NavigationHandle* navigation_handle) { | 523 content::NavigationHandle* navigation_handle) { |
| 547 if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()) | 524 if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()) |
| 548 return; | 525 return; |
| 549 | 526 |
| 550 if (navigation_handle->IsErrorPage()) { | 527 if (navigation_handle->IsErrorPage()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 | 644 |
| 668 // Check for a new doodle. | 645 // Check for a new doodle. |
| 669 content::BrowserThread::PostDelayedTask( | 646 content::BrowserThread::PostDelayedTask( |
| 670 content::BrowserThread::UI, FROM_HERE, | 647 content::BrowserThread::UI, FROM_HERE, |
| 671 base::Bind(&StartPageService::FetchDoodleJson, | 648 base::Bind(&StartPageService::FetchDoodleJson, |
| 672 weak_factory_.GetWeakPtr()), | 649 weak_factory_.GetWeakPtr()), |
| 673 recheck_delay); | 650 recheck_delay); |
| 674 } | 651 } |
| 675 | 652 |
| 676 } // namespace app_list | 653 } // namespace app_list |
| OLD | NEW |