Added CrOS startup sound.

BUG=315108
TEST=manual tests on lumpy and pixel

Review URL: https://codereview.chromium.org/98583004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238416 0039d316-1c4b-4281-b951-d872f2087c98
parent 740ce383
...@@ -83,7 +83,8 @@ ...@@ -83,7 +83,8 @@
namespace { namespace {
const int kStartupSoundInitialDelayMs = 500; // Maximum delay for startup sound after 'loginPromptVisible' signal.
const int kStartupSoundMaxDelayMs = 2000;
// URL which corresponds to the login WebUI. // URL which corresponds to the login WebUI.
const char kLoginURL[] = "chrome://oobe/login"; const char kLoginURL[] = "chrome://oobe/login";
...@@ -172,13 +173,6 @@ class AnimationObserver : public ui::ImplicitAnimationObserver { ...@@ -172,13 +173,6 @@ class AnimationObserver : public ui::ImplicitAnimationObserver {
DISALLOW_COPY_AND_ASSIGN(AnimationObserver); DISALLOW_COPY_AND_ASSIGN(AnimationObserver);
}; };
void PlayStartupSoundHelper(bool startup_sound_honors_spoken_feedback) {
if (!startup_sound_honors_spoken_feedback ||
chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
media::SoundsManager::Get()->Play(media::SoundsManager::SOUND_STARTUP);
}
}
// ShowLoginWizard is split into two parts. This function is sometimes called // ShowLoginWizard is split into two parts. This function is sometimes called
// from ShowLoginWizard(), and sometimes from OnLanguageSwitchedCallback() // from ShowLoginWizard(), and sometimes from OnLanguageSwitchedCallback()
// (if locale was updated). // (if locale was updated).
...@@ -264,10 +258,10 @@ LoginDisplayHostImpl::LoginDisplayHostImpl(const gfx::Rect& background_bounds) ...@@ -264,10 +258,10 @@ LoginDisplayHostImpl::LoginDisplayHostImpl(const gfx::Rect& background_bounds)
auto_enrollment_check_done_(false), auto_enrollment_check_done_(false),
finalize_animation_type_(ANIMATION_WORKSPACE), finalize_animation_type_(ANIMATION_WORKSPACE),
animation_weak_ptr_factory_(this), animation_weak_ptr_factory_(this),
startup_sound_requested_(false),
startup_sound_played_(false), startup_sound_played_(false),
startup_sound_honors_spoken_feedback_(false) { startup_sound_honors_spoken_feedback_(false) {
DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
CrasAudioHandler::Get()->AddAudioObserver(this);
// We need to listen to CLOSE_ALL_BROWSERS_REQUEST but not APP_TERMINATING // We need to listen to CLOSE_ALL_BROWSERS_REQUEST but not APP_TERMINATING
// because/ APP_TERMINATING will never be fired as long as this keeps // because/ APP_TERMINATING will never be fired as long as this keeps
...@@ -353,10 +347,29 @@ LoginDisplayHostImpl::LoginDisplayHostImpl(const gfx::Rect& background_bounds) ...@@ -353,10 +347,29 @@ LoginDisplayHostImpl::LoginDisplayHostImpl(const gfx::Rect& background_bounds)
<< " wait_for_wp_load_: " << waiting_for_wallpaper_load_ << " wait_for_wp_load_: " << waiting_for_wallpaper_load_
<< " wait_for_pods_: " << waiting_for_user_pods_ << " wait_for_pods_: " << waiting_for_user_pods_
<< " init_webui_hidden_: " << initialize_webui_hidden_; << " init_webui_hidden_: " << initialize_webui_hidden_;
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
std::vector<base::StringPiece> sound_resources(
media::SoundsManager::SOUND_COUNT);
sound_resources[media::SoundsManager::SOUND_STARTUP] =
bundle.GetRawDataResource(IDR_SOUND_STARTUP_WAV);
sound_resources[media::SoundsManager::SOUND_LOCK] =
bundle.GetRawDataResource(IDR_SOUND_LOCK_WAV);
sound_resources[media::SoundsManager::SOUND_UNLOCK] =
bundle.GetRawDataResource(IDR_SOUND_UNLOCK_WAV);
sound_resources[media::SoundsManager::SOUND_SHUTDOWN] =
bundle.GetRawDataResource(IDR_SOUND_SHUTDOWN_WAV);
for (size_t i = 0; i < sound_resources.size(); ++i) {
DCHECK(!sound_resources[i].empty()) << "System sound " << i << " "
<< "missing.";
}
if (!media::SoundsManager::Get()->Initialize(sound_resources))
LOG(ERROR) << "Failed to initialize SoundsManager.";
} }
LoginDisplayHostImpl::~LoginDisplayHostImpl() { LoginDisplayHostImpl::~LoginDisplayHostImpl() {
DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
CrasAudioHandler::Get()->RemoveAudioObserver(this);
views::FocusManager::set_arrow_key_traversal_enabled(false); views::FocusManager::set_arrow_key_traversal_enabled(false);
ResetLoginWindowAndView(); ResetLoginWindowAndView();
...@@ -488,7 +501,8 @@ void LoginDisplayHostImpl::GetAutoEnrollmentCheckResult( ...@@ -488,7 +501,8 @@ void LoginDisplayHostImpl::GetAutoEnrollmentCheckResult(
void LoginDisplayHostImpl::StartWizard( void LoginDisplayHostImpl::StartWizard(
const std::string& first_screen_name, const std::string& first_screen_name,
scoped_ptr<DictionaryValue> screen_parameters) { scoped_ptr<DictionaryValue> screen_parameters) {
TryToPlayStartupSound(false); startup_sound_honors_spoken_feedback_ = false;
TryToPlayStartupSound();
// Keep parameters to restore if renderer crashes. // Keep parameters to restore if renderer crashes.
restore_path_ = RESTORE_WIZARD; restore_path_ = RESTORE_WIZARD;
...@@ -563,7 +577,8 @@ void LoginDisplayHostImpl::StartUserAdding( ...@@ -563,7 +577,8 @@ void LoginDisplayHostImpl::StartUserAdding(
void LoginDisplayHostImpl::StartSignInScreen( void LoginDisplayHostImpl::StartSignInScreen(
const LoginScreenContext& context) { const LoginScreenContext& context) {
TryToPlayStartupSound(true); startup_sound_honors_spoken_feedback_ = true;
TryToPlayStartupSound();
restore_path_ = RESTORE_SIGN_IN; restore_path_ = RESTORE_SIGN_IN;
is_showing_login_ = true; is_showing_login_ = true;
...@@ -787,6 +802,10 @@ void LoginDisplayHostImpl::EmitLoginPromptVisibleCalled() { ...@@ -787,6 +802,10 @@ void LoginDisplayHostImpl::EmitLoginPromptVisibleCalled() {
OnLoginPromptVisible(); OnLoginPromptVisible();
} }
void LoginDisplayHostImpl::OnActiveOutputNodeChanged() {
TryToPlayStartupSound();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// LoginDisplayHostImpl, private // LoginDisplayHostImpl, private
...@@ -1010,69 +1029,31 @@ void LoginDisplayHostImpl::NotifyAutoEnrollmentCheckResult( ...@@ -1010,69 +1029,31 @@ void LoginDisplayHostImpl::NotifyAutoEnrollmentCheckResult(
callbacks[i].Run(should_auto_enroll); callbacks[i].Run(should_auto_enroll);
} }
void LoginDisplayHostImpl::TryToPlayStartupSound(bool honor_spoken_feedback) { void LoginDisplayHostImpl::TryToPlayStartupSound() {
if (startup_sound_requested_) if (startup_sound_played_ || login_prompt_visible_time_.is_null() ||
!CrasAudioHandler::Get()->GetActiveOutputNode()) {
return; return;
startup_sound_requested_ = true; }
startup_sound_honors_spoken_feedback_ = honor_spoken_feedback;
if (!login_prompt_visible_time_.is_null())
PlayStartupSound();
}
void LoginDisplayHostImpl::OnLoginPromptVisible() { // Don't play startup sound if login prompt is already visible for a
if (!login_prompt_visible_time_.is_null()) // long time.
if (base::TimeTicks::Now() - login_prompt_visible_time_ >
base::TimeDelta::FromMilliseconds(kStartupSoundMaxDelayMs)) {
return; return;
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
std::vector<base::StringPiece> sound_resources(
media::SoundsManager::SOUND_COUNT);
sound_resources[media::SoundsManager::SOUND_STARTUP] =
bundle.GetRawDataResource(IDR_SOUND_STARTUP_WAV);
sound_resources[media::SoundsManager::SOUND_LOCK] =
bundle.GetRawDataResource(IDR_SOUND_LOCK_WAV);
sound_resources[media::SoundsManager::SOUND_UNLOCK] =
bundle.GetRawDataResource(IDR_SOUND_UNLOCK_WAV);
sound_resources[media::SoundsManager::SOUND_SHUTDOWN] =
bundle.GetRawDataResource(IDR_SOUND_SHUTDOWN_WAV);
for (size_t i = 0; i < sound_resources.size(); ++i) {
DCHECK(!sound_resources[i].empty()) << "System sound " << i << " "
<< "missing.";
} }
if (!media::SoundsManager::Get()->Initialize(sound_resources))
LOG(ERROR) << "Failed to initialize SoundsManager.";
login_prompt_visible_time_ = base::TimeTicks::Now(); if (!startup_sound_honors_spoken_feedback_ ||
if (startup_sound_requested_ && !startup_sound_played_) chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
PlayStartupSound(); startup_sound_played_ = true;
media::SoundsManager::Get()->Play(media::SoundsManager::SOUND_STARTUP);
}
} }
void LoginDisplayHostImpl::PlayStartupSound() { void LoginDisplayHostImpl::OnLoginPromptVisible() {
if (startup_sound_played_) if (!login_prompt_visible_time_.is_null())
return; return;
startup_sound_played_ = true; login_prompt_visible_time_ = base::TimeTicks::Now();
TryToPlayStartupSound();
// TODO (ygorshenin@): remove this as soon as crbug.com/315108 will
// be fixed.
return;
const base::TimeDelta delay =
base::TimeDelta::FromMilliseconds(kStartupSoundInitialDelayMs);
const base::TimeDelta delta =
base::TimeTicks::Now() - login_prompt_visible_time_;
// Cras audio server starts initialization after
// login-prompt-visible signal from session manager. Alas, but it
// doesn't send notifications after initialization. Thus, we're
// trying to play startup sound after some delay.
if (delta > delay) {
PlayStartupSoundHelper(startup_sound_honors_spoken_feedback_);
} else {
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PlayStartupSoundHelper,
startup_sound_honors_spoken_feedback_),
delay - delta);
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "chrome/browser/chromeos/login/login_display_host.h" #include "chrome/browser/chromeos/login/login_display_host.h"
#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/dbus/session_manager_client.h" #include "chromeos/dbus/session_manager_client.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
...@@ -43,7 +44,8 @@ class WebUILoginView; ...@@ -43,7 +44,8 @@ class WebUILoginView;
class LoginDisplayHostImpl : public LoginDisplayHost, class LoginDisplayHostImpl : public LoginDisplayHost,
public content::NotificationObserver, public content::NotificationObserver,
public content::WebContentsObserver, public content::WebContentsObserver,
public chromeos::SessionManagerClient::Observer { public chromeos::SessionManagerClient::Observer,
public chromeos::CrasAudioHandler::AudioObserver {
public: public:
explicit LoginDisplayHostImpl(const gfx::Rect& background_bounds); explicit LoginDisplayHostImpl(const gfx::Rect& background_bounds);
virtual ~LoginDisplayHostImpl(); virtual ~LoginDisplayHostImpl();
...@@ -108,6 +110,9 @@ class LoginDisplayHostImpl : public LoginDisplayHost, ...@@ -108,6 +110,9 @@ class LoginDisplayHostImpl : public LoginDisplayHost,
// Overridden from chromeos::SessionManagerClient::Observer: // Overridden from chromeos::SessionManagerClient::Observer:
virtual void EmitLoginPromptVisibleCalled() OVERRIDE; virtual void EmitLoginPromptVisibleCalled() OVERRIDE;
// Overridden from chromeos::CrasAudioHandler::AudioObserver:
virtual void OnActiveOutputNodeChanged() OVERRIDE;
private: private:
// Way to restore if renderer have crashed. // Way to restore if renderer have crashed.
enum RestorePath { enum RestorePath {
...@@ -172,18 +177,12 @@ class LoginDisplayHostImpl : public LoginDisplayHost, ...@@ -172,18 +177,12 @@ class LoginDisplayHostImpl : public LoginDisplayHost,
// Tries to play startup sound. If sound can't be played right now, // Tries to play startup sound. If sound can't be played right now,
// for instance, because cras server is not initialized, playback // for instance, because cras server is not initialized, playback
// will be delayed. When |honor_spoken_feedback| is true, sound will // will be delayed.
// be reproduced iff spoken feedback is enabled. void TryToPlayStartupSound();
void TryToPlayStartupSound(bool honor_spoken_feedback);
// Called when login-prompt-visible signal is caught. // Called when login-prompt-visible signal is caught.
void OnLoginPromptVisible(); void OnLoginPromptVisible();
// Asks ChromeOSSoundsManager to play startup sound. If
// |startup_sound_at_signin_| is true, sound will be played iff
// spoken feedback is enabled.
void PlayStartupSound();
// Used to calculate position of the screens and background. // Used to calculate position of the screens and background.
gfx::Rect background_bounds_; gfx::Rect background_bounds_;
...@@ -293,9 +292,6 @@ class LoginDisplayHostImpl : public LoginDisplayHost, ...@@ -293,9 +292,6 @@ class LoginDisplayHostImpl : public LoginDisplayHost,
// calculations of delay before startup sound. // calculations of delay before startup sound.
base::TimeTicks login_prompt_visible_time_; base::TimeTicks login_prompt_visible_time_;
// True when startup sound is requested.
bool startup_sound_requested_;
// True when request to play startup sound was sent to // True when request to play startup sound was sent to
// SoundsManager. // SoundsManager.
bool startup_sound_played_; bool startup_sound_played_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment