Commit 36f7d7b2 authored by Ken MacKay's avatar Ken MacKay Committed by Commit Bot

[Chromecast] Update volume change API

Add a volume change source param that is passed through to observers, to
make it easier to determine when to display UX feedback. Also, remove
weak functions since this API is required now.

Bug: internal b/121396128
Change-Id: Ie56168108810467bb3dcb8fb47efd1fc80eaca1f
Reviewed-on: https://chromium-review.googlesource.com/c/1493387Reviewed-by: default avatarLuke Halliwell <halliwell@chromium.org>
Commit-Queue: Kenneth MacKay <kmackay@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636703}
parent 4a3b2b40
...@@ -150,16 +150,12 @@ void MediaResourceTracker::CallFinalizeOnMediaThread() { ...@@ -150,16 +150,12 @@ void MediaResourceTracker::CallFinalizeOnMediaThread() {
void MediaResourceTracker::DoInitializeMediaLib() { void MediaResourceTracker::DoInitializeMediaLib() {
base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
media::CastMediaShlib::Initialize(cmd_line->argv()); media::CastMediaShlib::Initialize(cmd_line->argv());
if (VolumeControl::Initialize) { VolumeControl::Initialize(cmd_line->argv());
VolumeControl::Initialize(cmd_line->argv());
}
} }
void MediaResourceTracker::DoFinalizeMediaLib() { void MediaResourceTracker::DoFinalizeMediaLib() {
CastMediaShlib::Finalize(); CastMediaShlib::Finalize();
if (VolumeControl::Finalize) { VolumeControl::Finalize();
VolumeControl::Finalize();
}
} }
} // namespace media } // namespace media
......
...@@ -75,7 +75,9 @@ float VolumeControlAndroid::GetVolume(AudioContentType type) { ...@@ -75,7 +75,9 @@ float VolumeControlAndroid::GetVolume(AudioContentType type) {
volumes_[type]); volumes_[type]);
} }
void VolumeControlAndroid::SetVolume(AudioContentType type, float level) { void VolumeControlAndroid::SetVolume(VolumeChangeSource source,
AudioContentType type,
float level) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set volume for content type kOther"; NOTREACHED() << "Can't set volume for content type kOther";
return; return;
...@@ -87,8 +89,8 @@ void VolumeControlAndroid::SetVolume(AudioContentType type, float level) { ...@@ -87,8 +89,8 @@ void VolumeControlAndroid::SetVolume(AudioContentType type, float level) {
MapIntoDifferentVolumeTableDomain(AudioContentType::kMedia, type, level); MapIntoDifferentVolumeTableDomain(AudioContentType::kMedia, type, level);
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlAndroid::SetVolumeOnThread, FROM_HERE, base::BindOnce(&VolumeControlAndroid::SetVolumeOnThread,
base::Unretained(this), type, mapped_level, base::Unretained(this), source, type,
false /* from_android */)); mapped_level, false /* from_android */));
} }
bool VolumeControlAndroid::IsMuted(AudioContentType type) { bool VolumeControlAndroid::IsMuted(AudioContentType type) {
...@@ -96,7 +98,9 @@ bool VolumeControlAndroid::IsMuted(AudioContentType type) { ...@@ -96,7 +98,9 @@ bool VolumeControlAndroid::IsMuted(AudioContentType type) {
return muted_[type]; return muted_[type];
} }
void VolumeControlAndroid::SetMuted(AudioContentType type, bool muted) { void VolumeControlAndroid::SetMuted(VolumeChangeSource source,
AudioContentType type,
bool muted) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set mute state for content type kOther"; NOTREACHED() << "Can't set mute state for content type kOther";
return; return;
...@@ -104,7 +108,7 @@ void VolumeControlAndroid::SetMuted(AudioContentType type, bool muted) { ...@@ -104,7 +108,7 @@ void VolumeControlAndroid::SetMuted(AudioContentType type, bool muted) {
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlAndroid::SetMutedOnThread, FROM_HERE, base::BindOnce(&VolumeControlAndroid::SetMutedOnThread,
base::Unretained(this), type, muted, base::Unretained(this), source, type, muted,
false /* from_android */)); false /* from_android */));
} }
...@@ -194,14 +198,17 @@ void VolumeControlAndroid::InitializeOnThread() { ...@@ -194,14 +198,17 @@ void VolumeControlAndroid::InitializeOnThread() {
// mute (volume control for kOther is per-stream only). Therefore, ensure // mute (volume control for kOther is per-stream only). Therefore, ensure
// that the global volume and mute state fo kOther is initialized correctly // that the global volume and mute state fo kOther is initialized correctly
// (100% volume, and not muted). // (100% volume, and not muted).
SetVolumeOnThread(AudioContentType::kOther, 1.0f, false /* from_android */); SetVolumeOnThread(VolumeChangeSource::kAutomatic, AudioContentType::kOther,
SetMutedOnThread(AudioContentType::kOther, false, false /* from_android */); 1.0f, false /* from_android */);
SetMutedOnThread(VolumeChangeSource::kAutomatic, AudioContentType::kOther,
false, false /* from_android */);
#endif #endif
initialize_complete_event_.Signal(); initialize_complete_event_.Signal();
} }
void VolumeControlAndroid::SetVolumeOnThread(AudioContentType type, void VolumeControlAndroid::SetVolumeOnThread(VolumeChangeSource source,
AudioContentType type,
float level, float level,
bool from_android) { bool from_android) {
// Note: |level| is in the |type| volume table domain. // Note: |level| is in the |type| volume table domain.
...@@ -234,12 +241,13 @@ void VolumeControlAndroid::SetVolumeOnThread(AudioContentType type, ...@@ -234,12 +241,13 @@ void VolumeControlAndroid::SetVolumeOnThread(AudioContentType type,
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnVolumeChange(type, media_level); observer->OnVolumeChange(source, type, media_level);
} }
} }
} }
void VolumeControlAndroid::SetMutedOnThread(AudioContentType type, void VolumeControlAndroid::SetMutedOnThread(VolumeChangeSource source,
AudioContentType type,
bool muted, bool muted,
bool from_android) { bool from_android) {
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
...@@ -260,7 +268,7 @@ void VolumeControlAndroid::SetMutedOnThread(AudioContentType type, ...@@ -260,7 +268,7 @@ void VolumeControlAndroid::SetMutedOnThread(AudioContentType type,
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnMuteChange(type, muted); observer->OnMuteChange(source, type, muted);
} }
} }
} }
...@@ -278,7 +286,8 @@ void VolumeControlAndroid::ReportVolumeChangeOnThread(AudioContentType type, ...@@ -278,7 +286,8 @@ void VolumeControlAndroid::ReportVolumeChangeOnThread(AudioContentType type,
} }
#endif #endif
SetVolumeOnThread(type, level, true /* from android */); SetVolumeOnThread(VolumeChangeSource::kUser, type, level,
true /* from android */);
} }
void VolumeControlAndroid::ReportMuteChangeOnThread(AudioContentType type, void VolumeControlAndroid::ReportMuteChangeOnThread(AudioContentType type,
...@@ -294,7 +303,8 @@ void VolumeControlAndroid::ReportMuteChangeOnThread(AudioContentType type, ...@@ -294,7 +303,8 @@ void VolumeControlAndroid::ReportMuteChangeOnThread(AudioContentType type,
} }
#endif #endif
SetMutedOnThread(type, muted, true /* from_android */); SetMutedOnThread(VolumeChangeSource::kUser, type, muted,
true /* from_android */);
} }
float VolumeControlAndroid::MapIntoDifferentVolumeTableDomain( float VolumeControlAndroid::MapIntoDifferentVolumeTableDomain(
...@@ -348,8 +358,10 @@ float VolumeControl::GetVolume(AudioContentType type) { ...@@ -348,8 +358,10 @@ float VolumeControl::GetVolume(AudioContentType type) {
} }
// static // static
void VolumeControl::SetVolume(AudioContentType type, float level) { void VolumeControl::SetVolume(VolumeChangeSource source,
GetVolumeControl().SetVolume(type, level); AudioContentType type,
float level) {
GetVolumeControl().SetVolume(source, type, level);
} }
// static // static
...@@ -358,8 +370,10 @@ bool VolumeControl::IsMuted(AudioContentType type) { ...@@ -358,8 +370,10 @@ bool VolumeControl::IsMuted(AudioContentType type) {
} }
// static // static
void VolumeControl::SetMuted(AudioContentType type, bool muted) { void VolumeControl::SetMuted(VolumeChangeSource source,
GetVolumeControl().SetMuted(type, muted); AudioContentType type,
bool muted) {
GetVolumeControl().SetMuted(source, type, muted);
} }
// static // static
...@@ -380,5 +394,10 @@ float VolumeControl::DbFSToVolume(float db) { ...@@ -380,5 +394,10 @@ float VolumeControl::DbFSToVolume(float db) {
return GetVolumeControl().DbFSToVolumeCached(AudioContentType::kMedia, db); return GetVolumeControl().DbFSToVolumeCached(AudioContentType::kMedia, db);
} }
// static
void VolumeControl::SetPowerSaveMode(bool power_save_on) {
// Ignored.
}
} // namespace media } // namespace media
} // namespace chromecast } // namespace chromecast
...@@ -28,9 +28,9 @@ class VolumeControlAndroid : SystemVolumeTableAccessApi { ...@@ -28,9 +28,9 @@ class VolumeControlAndroid : SystemVolumeTableAccessApi {
void AddVolumeObserver(VolumeObserver* observer); void AddVolumeObserver(VolumeObserver* observer);
void RemoveVolumeObserver(VolumeObserver* observer); void RemoveVolumeObserver(VolumeObserver* observer);
float GetVolume(AudioContentType type); float GetVolume(AudioContentType type);
void SetVolume(AudioContentType type, float level); void SetVolume(VolumeChangeSource source, AudioContentType type, float level);
bool IsMuted(AudioContentType type); bool IsMuted(AudioContentType type);
void SetMuted(AudioContentType type, bool muted); void SetMuted(VolumeChangeSource source, AudioContentType type, bool muted);
void SetOutputLimit(AudioContentType type, float limit); void SetOutputLimit(AudioContentType type, float limit);
float VolumeToDbFSCached(AudioContentType type, float volume); float VolumeToDbFSCached(AudioContentType type, float volume);
float DbFSToVolumeCached(AudioContentType type, float db); float DbFSToVolumeCached(AudioContentType type, float db);
...@@ -52,8 +52,14 @@ class VolumeControlAndroid : SystemVolumeTableAccessApi { ...@@ -52,8 +52,14 @@ class VolumeControlAndroid : SystemVolumeTableAccessApi {
private: private:
void InitializeOnThread(); void InitializeOnThread();
void SetVolumeOnThread(AudioContentType type, float level, bool from_android); void SetVolumeOnThread(VolumeChangeSource source,
void SetMutedOnThread(AudioContentType type, bool muted, bool from_android); AudioContentType type,
float level,
bool from_android);
void SetMutedOnThread(VolumeChangeSource source,
AudioContentType type,
bool muted,
bool from_android);
void ReportVolumeChangeOnThread(AudioContentType type, float level); void ReportVolumeChangeOnThread(AudioContentType type, float level);
void ReportMuteChangeOnThread(AudioContentType type, bool muted); void ReportMuteChangeOnThread(AudioContentType type, bool muted);
......
...@@ -196,18 +196,14 @@ class AudioVideoPipelineDeviceTest : public testing::Test { ...@@ -196,18 +196,14 @@ class AudioVideoPipelineDeviceTest : public testing::Test {
void SetUp() override { void SetUp() override {
CastMediaShlib::Initialize( CastMediaShlib::Initialize(
base::CommandLine::ForCurrentProcess()->argv()); base::CommandLine::ForCurrentProcess()->argv());
if (VolumeControl::Initialize) { VolumeControl::Initialize(base::CommandLine::ForCurrentProcess()->argv());
VolumeControl::Initialize(base::CommandLine::ForCurrentProcess()->argv());
}
} }
void TearDown() override { void TearDown() override {
// Pipeline must be destroyed before finalizing media shlib. // Pipeline must be destroyed before finalizing media shlib.
backend_.reset(); backend_.reset();
effects_backends_.clear(); effects_backends_.clear();
if (VolumeControl::Finalize) { VolumeControl::Finalize();
VolumeControl::Finalize();
}
CastMediaShlib::Finalize(); CastMediaShlib::Finalize();
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "chromecast/public/cast_media_shlib.h" #include "chromecast/public/cast_media_shlib.h"
#include "chromecast/public/media/decoder_config.h" #include "chromecast/public/media/decoder_config.h"
#include "chromecast/public/media/media_capabilities_shlib.h" #include "chromecast/public/media/media_capabilities_shlib.h"
#include "chromecast/public/volume_control.h"
namespace chromecast { namespace chromecast {
namespace media { namespace media {
...@@ -58,5 +59,38 @@ bool MediaCapabilitiesShlib::IsSupportedAudioConfig(const AudioConfig& config) { ...@@ -58,5 +59,38 @@ bool MediaCapabilitiesShlib::IsSupportedAudioConfig(const AudioConfig& config) {
return false; return false;
} }
void VolumeControl::Initialize(const std::vector<std::string>& argv) {}
void VolumeControl::Finalize() {}
void VolumeControl::AddVolumeObserver(VolumeObserver* observer) {}
void VolumeControl::RemoveVolumeObserver(VolumeObserver* observer) {}
float VolumeControl::GetVolume(AudioContentType type) {
return 0.0f;
}
void VolumeControl::SetVolume(VolumeChangeSource source,
AudioContentType type,
float level) {}
bool VolumeControl::IsMuted(AudioContentType type) {
return false;
}
void VolumeControl::SetMuted(VolumeChangeSource source,
AudioContentType type,
bool muted) {}
void VolumeControl::SetOutputLimit(AudioContentType type, float limit) {}
float VolumeControl::VolumeToDbFS(float volume) {
return 0.0f;
}
float VolumeControl::DbFSToVolume(float db) {
return 0.0f;
}
void VolumeControl::SetPowerSaveMode(bool power_save_on) {}
} // namespace media } // namespace media
} // namespace chromecast } // namespace chromecast
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chromecast/public/cast_media_shlib.h" #include "chromecast/public/cast_media_shlib.h"
#include "chromecast/public/media/media_capabilities_shlib.h" #include "chromecast/public/media/media_capabilities_shlib.h"
#include "chromecast/public/volume_control.h"
namespace chromecast { namespace chromecast {
namespace media { namespace media {
...@@ -51,5 +52,38 @@ bool MediaCapabilitiesShlib::IsSupportedAudioConfig(const AudioConfig& config) { ...@@ -51,5 +52,38 @@ bool MediaCapabilitiesShlib::IsSupportedAudioConfig(const AudioConfig& config) {
config.codec == kCodecPCM || config.codec == kCodecVorbis; config.codec == kCodecPCM || config.codec == kCodecVorbis;
} }
void VolumeControl::Initialize(const std::vector<std::string>& argv) {}
void VolumeControl::Finalize() {}
void VolumeControl::AddVolumeObserver(VolumeObserver* observer) {}
void VolumeControl::RemoveVolumeObserver(VolumeObserver* observer) {}
float VolumeControl::GetVolume(AudioContentType type) {
return 0.0f;
}
void VolumeControl::SetVolume(VolumeChangeSource source,
AudioContentType type,
float level) {}
bool VolumeControl::IsMuted(AudioContentType type) {
return false;
}
void VolumeControl::SetMuted(VolumeChangeSource source,
AudioContentType type,
bool muted) {}
void VolumeControl::SetOutputLimit(AudioContentType type, float limit) {}
float VolumeControl::VolumeToDbFS(float volume) {
return 0.0f;
}
float VolumeControl::DbFSToVolume(float db) {
return 0.0f;
}
void VolumeControl::SetPowerSaveMode(bool power_save_on) {}
} // namespace media } // namespace media
} // namespace chromecast } // namespace chromecast
...@@ -62,7 +62,9 @@ class VolumeControlInternal { ...@@ -62,7 +62,9 @@ class VolumeControlInternal {
return volumes_[type]; return volumes_[type];
} }
void SetVolume(AudioContentType type, float level) { void SetVolume(media::VolumeChangeSource source,
AudioContentType type,
float level) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set volume for content type kOther"; NOTREACHED() << "Can't set volume for content type kOther";
return; return;
...@@ -71,7 +73,7 @@ class VolumeControlInternal { ...@@ -71,7 +73,7 @@ class VolumeControlInternal {
level = base::ClampToRange(level, 0.0f, 1.0f); level = base::ClampToRange(level, 0.0f, 1.0f);
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread, FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread,
base::Unretained(this), type, level)); base::Unretained(this), source, type, level));
} }
bool IsMuted(AudioContentType type) { bool IsMuted(AudioContentType type) {
...@@ -79,7 +81,9 @@ class VolumeControlInternal { ...@@ -79,7 +81,9 @@ class VolumeControlInternal {
return muted_[type]; return muted_[type];
} }
void SetMuted(AudioContentType type, bool muted) { void SetMuted(media::VolumeChangeSource source,
AudioContentType type,
bool muted) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set mute state for content type kOther"; NOTREACHED() << "Can't set mute state for content type kOther";
return; return;
...@@ -87,11 +91,13 @@ class VolumeControlInternal { ...@@ -87,11 +91,13 @@ class VolumeControlInternal {
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlInternal::SetMutedOnThread, FROM_HERE, base::BindOnce(&VolumeControlInternal::SetMutedOnThread,
base::Unretained(this), type, muted)); base::Unretained(this), source, type, muted));
} }
private: private:
void SetVolumeOnThread(AudioContentType type, float level) { void SetVolumeOnThread(media::VolumeChangeSource source,
AudioContentType type,
float level) {
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
DCHECK(type != AudioContentType::kOther); DCHECK(type != AudioContentType::kOther);
...@@ -106,12 +112,14 @@ class VolumeControlInternal { ...@@ -106,12 +112,14 @@ class VolumeControlInternal {
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnVolumeChange(type, level); observer->OnVolumeChange(source, type, level);
} }
} }
} }
void SetMutedOnThread(AudioContentType type, bool muted) { void SetMutedOnThread(media::VolumeChangeSource source,
AudioContentType type,
bool muted) {
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
DCHECK(type != AudioContentType::kOther); DCHECK(type != AudioContentType::kOther);
...@@ -126,7 +134,7 @@ class VolumeControlInternal { ...@@ -126,7 +134,7 @@ class VolumeControlInternal {
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnMuteChange(type, muted); observer->OnMuteChange(source, type, muted);
} }
} }
} }
...@@ -174,8 +182,10 @@ float VolumeControl::GetVolume(AudioContentType type) { ...@@ -174,8 +182,10 @@ float VolumeControl::GetVolume(AudioContentType type) {
} }
// static // static
void VolumeControl::SetVolume(AudioContentType type, float level) { void VolumeControl::SetVolume(media::VolumeChangeSource source,
GetVolumeControl().SetVolume(type, level); AudioContentType type,
float level) {
GetVolumeControl().SetVolume(source, type, level);
} }
// static // static
...@@ -184,8 +194,10 @@ bool VolumeControl::IsMuted(AudioContentType type) { ...@@ -184,8 +194,10 @@ bool VolumeControl::IsMuted(AudioContentType type) {
} }
// static // static
void VolumeControl::SetMuted(AudioContentType type, bool muted) { void VolumeControl::SetMuted(media::VolumeChangeSource source,
GetVolumeControl().SetMuted(type, muted); AudioContentType type,
bool muted) {
GetVolumeControl().SetMuted(source, type, muted);
} }
// static // static
......
...@@ -137,17 +137,16 @@ void MediaPipelineBackendManager::UpdatePlayingAudioCount( ...@@ -137,17 +137,16 @@ void MediaPipelineBackendManager::UpdatePlayingAudioCount(
bool had_playing_audio_streams = (TotalPlayingAudioStreamsCount() > 0); bool had_playing_audio_streams = (TotalPlayingAudioStreamsCount() > 0);
playing_audio_streams_count_[type] += change; playing_audio_streams_count_[type] += change;
DCHECK_GE(playing_audio_streams_count_[type], 0); DCHECK_GE(playing_audio_streams_count_[type], 0);
if (VolumeControl::SetPowerSaveMode) {
int new_playing_audio_streams = TotalPlayingAudioStreamsCount(); int new_playing_audio_streams = TotalPlayingAudioStreamsCount();
if (new_playing_audio_streams == 0) { if (new_playing_audio_streams == 0) {
power_save_timer_.Start(FROM_HERE, kPowerSaveWaitTime, this, power_save_timer_.Start(FROM_HERE, kPowerSaveWaitTime, this,
&MediaPipelineBackendManager::EnterPowerSaveMode); &MediaPipelineBackendManager::EnterPowerSaveMode);
} else if (!had_playing_audio_streams && new_playing_audio_streams > 0) { } else if (!had_playing_audio_streams && new_playing_audio_streams > 0) {
power_save_timer_.Stop(); power_save_timer_.Stop();
metrics::CastMetricsHelper::GetInstance()->RecordSimpleAction( metrics::CastMetricsHelper::GetInstance()->RecordSimpleAction(
"Cast.Platform.VolumeControl.PowerSaveOff"); "Cast.Platform.VolumeControl.PowerSaveOff");
VolumeControl::SetPowerSaveMode(false); VolumeControl::SetPowerSaveMode(false);
}
} }
if (sfx) { if (sfx) {
...@@ -266,9 +265,7 @@ void MediaPipelineBackendManager::SetPowerSaveEnabled(bool power_save_enabled) { ...@@ -266,9 +265,7 @@ void MediaPipelineBackendManager::SetPowerSaveEnabled(bool power_save_enabled) {
MAKE_SURE_MEDIA_THREAD(SetPowerSaveEnabled, power_save_enabled); MAKE_SURE_MEDIA_THREAD(SetPowerSaveEnabled, power_save_enabled);
power_save_enabled_ = power_save_enabled; power_save_enabled_ = power_save_enabled;
if (!power_save_enabled_) { if (!power_save_enabled_) {
if (VolumeControl::SetPowerSaveMode) { VolumeControl::SetPowerSaveMode(false);
VolumeControl::SetPowerSaveMode(false);
}
} }
} }
......
...@@ -134,18 +134,14 @@ class MultizoneBackendTest : public testing::TestWithParam<TestParams> { ...@@ -134,18 +134,14 @@ class MultizoneBackendTest : public testing::TestWithParam<TestParams> {
void SetUp() override { void SetUp() override {
srand(12345); srand(12345);
CastMediaShlib::Initialize(base::CommandLine::ForCurrentProcess()->argv()); CastMediaShlib::Initialize(base::CommandLine::ForCurrentProcess()->argv());
if (VolumeControl::Initialize) { VolumeControl::Initialize(base::CommandLine::ForCurrentProcess()->argv());
VolumeControl::Initialize(base::CommandLine::ForCurrentProcess()->argv());
}
} }
void TearDown() override { void TearDown() override {
// Pipeline must be destroyed before finalizing media shlib. // Pipeline must be destroyed before finalizing media shlib.
audio_feeder_.reset(); audio_feeder_.reset();
effects_feeders_.clear(); effects_feeders_.clear();
if (VolumeControl::Finalize) { VolumeControl::Finalize();
VolumeControl::Finalize();
}
CastMediaShlib::Finalize(); CastMediaShlib::Finalize();
} }
......
...@@ -152,7 +152,9 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -152,7 +152,9 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
return volumes_[type]; return volumes_[type];
} }
void SetVolume(AudioContentType type, float level) { void SetVolume(VolumeChangeSource source,
AudioContentType type,
float level) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set volume for content type kOther"; NOTREACHED() << "Can't set volume for content type kOther";
return; return;
...@@ -161,7 +163,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -161,7 +163,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
level = std::max(0.0f, std::min(level, 1.0f)); level = std::max(0.0f, std::min(level, 1.0f));
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread, FROM_HERE, base::BindOnce(&VolumeControlInternal::SetVolumeOnThread,
base::Unretained(this), type, level, base::Unretained(this), source, type, level,
false /* from_system */)); false /* from_system */));
} }
...@@ -170,7 +172,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -170,7 +172,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
return muted_[type]; return muted_[type];
} }
void SetMuted(AudioContentType type, bool muted) { void SetMuted(VolumeChangeSource source, AudioContentType type, bool muted) {
if (type == AudioContentType::kOther) { if (type == AudioContentType::kOther) {
NOTREACHED() << "Can't set mute state for content type kOther"; NOTREACHED() << "Can't set mute state for content type kOther";
return; return;
...@@ -178,7 +180,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -178,7 +180,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
thread_.task_runner()->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&VolumeControlInternal::SetMutedOnThread, FROM_HERE, base::BindOnce(&VolumeControlInternal::SetMutedOnThread,
base::Unretained(this), type, muted, base::Unretained(this), source, type, muted,
false /* from_system */)); false /* from_system */));
} }
...@@ -243,7 +245,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -243,7 +245,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
initialize_complete_event_.Signal(); initialize_complete_event_.Signal();
} }
void SetVolumeOnThread(AudioContentType type, float level, bool from_system) { void SetVolumeOnThread(VolumeChangeSource source,
AudioContentType type,
float level,
bool from_system) {
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
DCHECK(type != AudioContentType::kOther); DCHECK(type != AudioContentType::kOther);
DCHECK(!from_system || type == AudioContentType::kMedia); DCHECK(!from_system || type == AudioContentType::kMedia);
...@@ -272,7 +277,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -272,7 +277,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnVolumeChange(type, level); observer->OnVolumeChange(source, type, level);
} }
} }
...@@ -280,7 +285,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -280,7 +285,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
SerializeJsonToFile(storage_path_, stored_values_); SerializeJsonToFile(storage_path_, stored_values_);
} }
void SetMutedOnThread(AudioContentType type, bool muted, bool from_system) { void SetMutedOnThread(VolumeChangeSource source,
AudioContentType type,
bool muted,
bool from_system) {
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
DCHECK(type != AudioContentType::kOther); DCHECK(type != AudioContentType::kOther);
...@@ -303,7 +311,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -303,7 +311,7 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
{ {
base::AutoLock lock(observer_lock_); base::AutoLock lock(observer_lock_);
for (VolumeObserver* observer : volume_observers_) { for (VolumeObserver* observer : volume_observers_) {
observer->OnMuteChange(type, muted); observer->OnMuteChange(source, type, muted);
} }
} }
} }
...@@ -318,10 +326,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate { ...@@ -318,10 +326,10 @@ class VolumeControlInternal : public SystemVolumeControl::Delegate {
LOG(INFO) << "System volume/mute change, new volume = " << new_volume LOG(INFO) << "System volume/mute change, new volume = " << new_volume
<< ", new mute = " << new_mute; << ", new mute = " << new_mute;
DCHECK(thread_.task_runner()->BelongsToCurrentThread()); DCHECK(thread_.task_runner()->BelongsToCurrentThread());
SetVolumeOnThread(AudioContentType::kMedia, new_volume, SetVolumeOnThread(VolumeChangeSource::kUser, AudioContentType::kMedia,
true /* from_system */); new_volume, true /* from_system */);
SetMutedOnThread(AudioContentType::kMedia, new_mute, SetMutedOnThread(VolumeChangeSource::kUser, AudioContentType::kMedia,
true /* from_system */); new_mute, true /* from_system */);
} }
base::FilePath storage_path_; base::FilePath storage_path_;
...@@ -376,8 +384,10 @@ float VolumeControl::GetVolume(AudioContentType type) { ...@@ -376,8 +384,10 @@ float VolumeControl::GetVolume(AudioContentType type) {
} }
// static // static
void VolumeControl::SetVolume(AudioContentType type, float level) { void VolumeControl::SetVolume(VolumeChangeSource source,
GetVolumeControl().SetVolume(type, level); AudioContentType type,
float level) {
GetVolumeControl().SetVolume(source, type, level);
} }
// static // static
...@@ -386,8 +396,10 @@ bool VolumeControl::IsMuted(AudioContentType type) { ...@@ -386,8 +396,10 @@ bool VolumeControl::IsMuted(AudioContentType type) {
} }
// static // static
void VolumeControl::SetMuted(AudioContentType type, bool muted) { void VolumeControl::SetMuted(VolumeChangeSource source,
GetVolumeControl().SetMuted(type, muted); AudioContentType type,
bool muted) {
GetVolumeControl().SetMuted(source, type, muted);
} }
// static // static
......
...@@ -81,15 +81,6 @@ class AvSettings { ...@@ -81,15 +81,6 @@ class AvSettings {
// Initialize() was called. // Initialize() was called.
ACTIVE_STATE_CHANGED = 0, ACTIVE_STATE_CHANGED = 0,
// DEPRECATED - Prefer to implement volume control in the media shlib using
// the VolumeControl API (see chromecast/public/volume_control.h).
// This event shall be fired whenever the system volume level or muted state
// are changed including when user changed volume via a remote controller,
// or after a call to SetAudioVolume() or SetAudioMuted().
// On this event, GetAudioVolume() and IsAudioMuted() will be called on
// the thread where Initialize() was called.
AUDIO_VOLUME_CHANGED = 1,
// This event shall be fired whenever the audio codecs supported by the // This event shall be fired whenever the audio codecs supported by the
// device (or HDMI sinks connected to the device) are changed. // device (or HDMI sinks connected to the device) are changed.
// On this event, GetAudioCodecsSupported() and GetMaxAudioChannels() will // On this event, GetAudioCodecsSupported() and GetMaxAudioChannels() will
...@@ -254,32 +245,6 @@ class AvSettings { ...@@ -254,32 +245,6 @@ class AvSettings {
// - UNKNOWN_VOLUME: 0.01 (1%) // - UNKNOWN_VOLUME: 0.01 (1%)
virtual bool GetAudioVolumeStepInterval(float* step_inteval) = 0; virtual bool GetAudioVolumeStepInterval(float* step_inteval) = 0;
// DEPRECATED - Prefer to implement volume control in the media shlib using
// the VolumeControl API (see chromecast/public/volume_control.h).
// Returns the current volume level, which must be from 0.0 (inclusive) to
// 1.0 (inclusive).
virtual float GetAudioVolume() = 0;
// DEPRECATED - Prefer to implement volume control in the media shlib using
// the VolumeControl API (see chromecast/public/volume_control.h).
// Sets new volume level of the device (or HDMI sinks). |level| is from 0.0
// (inclusive) to 1.0 (inclusive).
// If successful and the level has changed, it must return true and fire
// AUDIO_VOLUME_CHANGED.
virtual bool SetAudioVolume(float level) = 0;
// DEPRECATED - Prefer to implement volume control in the media shlib using
// the VolumeControl API (see chromecast/public/volume_control.h).
// Whether or not the device (or HDMI sinks) is muted.
virtual bool IsAudioMuted() = 0;
// DEPRECATED - Prefer to implement volume control in the media shlib using
// the VolumeControl API (see chromecast/public/volume_control.h).
// Sets the device (or HDMI sinks) muted.
// If successful and the muted state has changed, it must return true and fire
// AUDIO_VOLUME_CHANGED.
virtual bool SetAudioMuted(bool muted) = 0;
// Gets audio codecs supported by the device (or HDMI sinks). // Gets audio codecs supported by the device (or HDMI sinks).
// The result is an integer of OR'ed AudioCodec values. // The result is an integer of OR'ed AudioCodec values.
virtual int GetAudioCodecsSupported() = 0; virtual int GetAudioCodecsSupported() = 0;
......
...@@ -24,6 +24,15 @@ enum class AudioContentType { ...@@ -24,6 +24,15 @@ enum class AudioContentType {
kNumTypes, // Not a valid type; should always be last in the enum. kNumTypes, // Not a valid type; should always be last in the enum.
}; };
// Different sources of volume changes. Used to change behaviour (eg feedback
// sounds) based on the source.
enum class VolumeChangeSource {
kUser, // User-initiated volume change.
kAutomatic, // Automatic volume change, no user involvement.
kAutoWithFeedback, // Automatic volume change, but we still want to have
// volume feedback UX.
};
// Observer for volume/mute state changes. This is useful to detect volume // Observer for volume/mute state changes. This is useful to detect volume
// changes that occur outside of cast_shell. Add/RemoveVolumeObserver() must not // changes that occur outside of cast_shell. Add/RemoveVolumeObserver() must not
// be called synchronously from OnVolumeChange() or OnMuteChange(). Note that // be called synchronously from OnVolumeChange() or OnMuteChange(). Note that
...@@ -33,11 +42,15 @@ class VolumeObserver { ...@@ -33,11 +42,15 @@ class VolumeObserver {
public: public:
// Called whenever the volume changes for a given stream |type|. May be called // Called whenever the volume changes for a given stream |type|. May be called
// on an arbitrary thread. // on an arbitrary thread.
virtual void OnVolumeChange(AudioContentType type, float new_volume) = 0; virtual void OnVolumeChange(VolumeChangeSource source,
AudioContentType type,
float new_volume) = 0;
// Called whenever the mute state changes for a given stream |type|. May be // Called whenever the mute state changes for a given stream |type|. May be
// called on an arbitrary thread. // called on an arbitrary thread.
virtual void OnMuteChange(AudioContentType type, bool new_muted) = 0; virtual void OnMuteChange(VolumeChangeSource source,
AudioContentType type,
bool new_muted) = 0;
protected: protected:
virtual ~VolumeObserver() = default; virtual ~VolumeObserver() = default;
...@@ -52,54 +65,52 @@ class CHROMECAST_EXPORT VolumeControl { ...@@ -52,54 +65,52 @@ class CHROMECAST_EXPORT VolumeControl {
// control is in an uninitialized state. The implementation of this method // control is in an uninitialized state. The implementation of this method
// should load previously set volume and mute states from persistent storage, // should load previously set volume and mute states from persistent storage,
// so that the volume and mute are preserved across reboots. // so that the volume and mute are preserved across reboots.
static void Initialize(const std::vector<std::string>& argv) static void Initialize(const std::vector<std::string>& argv);
__attribute__((__weak__));
// Tears down platform-specific volume control and returns to the // Tears down platform-specific volume control and returns to the
// uninitialized state. // uninitialized state.
static void Finalize() __attribute__((__weak__)); static void Finalize();
// Adds a volume observer. // Adds a volume observer.
static void AddVolumeObserver(VolumeObserver* observer) static void AddVolumeObserver(VolumeObserver* observer);
__attribute__((__weak__));
// Removes a volume observer. After this is called, the implementation must // Removes a volume observer. After this is called, the implementation must
// not call any more methods on the observer. // not call any more methods on the observer.
static void RemoveVolumeObserver(VolumeObserver* observer) static void RemoveVolumeObserver(VolumeObserver* observer);
__attribute__((__weak__));
// Gets/sets the output volume for a given audio stream |type|. The volume // Gets/sets the output volume for a given audio stream |type|. The volume
// |level| is in the range [0.0, 1.0]. AudioContentType::kOther is not a valid // |level| is in the range [0.0, 1.0]. AudioContentType::kOther is not a valid
// |type| for these methods. // |type| for these methods.
static float GetVolume(AudioContentType type) __attribute__((__weak__)); static float GetVolume(AudioContentType type);
static void SetVolume(AudioContentType type, float level) static void SetVolume(VolumeChangeSource source,
__attribute__((__weak__)); AudioContentType type,
float level);
// Gets/sets the mute state for a given audio stream |type|. // Gets/sets the mute state for a given audio stream |type|.
// AudioContentType::kOther is not a valid |type| for these methods. // AudioContentType::kOther is not a valid |type| for these methods.
static bool IsMuted(AudioContentType type) __attribute__((__weak__)); static bool IsMuted(AudioContentType type);
static void SetMuted(AudioContentType type, bool muted) static void SetMuted(VolumeChangeSource source,
__attribute__((__weak__)); AudioContentType type,
bool muted);
// Limits the output volume for a given stream |type| to no more than |limit|. // Limits the output volume for a given stream |type| to no more than |limit|.
// This does not affect the logical volume for the stream type; the volume // This does not affect the logical volume for the stream type; the volume
// returned by GetVolume() should not change, and no OnVolumeChange() event // returned by GetVolume() should not change, and no OnVolumeChange() event
// should be sent to observers. AudioContentType::kOther is not a valid |type| // should be sent to observers. AudioContentType::kOther is not a valid |type|
// for this method. // for this method.
static void SetOutputLimit(AudioContentType type, float limit) static void SetOutputLimit(AudioContentType type, float limit);
__attribute__((__weak__));
// Called to enable power save mode when no audio is being played // Called to enable power save mode when no audio is being played
// (|power_save_on| will be true in this case), and to disable power save mode // (|power_save_on| will be true in this case), and to disable power save mode
// when audio playback resumes (|power_save_on| will be false). // when audio playback resumes (|power_save_on| will be false).
static void SetPowerSaveMode(bool power_save_on) __attribute__((__weak__)); static void SetPowerSaveMode(bool power_save_on);
// Converts a volume level in the range [0.0, 1.0] to/from a volume in dB. // Converts a volume level in the range [0.0, 1.0] to/from a volume in dB.
// The volume in dB should be full-scale (so a volume level of 1.0 would be // The volume in dB should be full-scale (so a volume level of 1.0 would be
// 0.0 dBFS, and any lower volume level would be negative). // 0.0 dBFS, and any lower volume level would be negative).
// NOTE: Unlike the other VolumeControl methods, these may be called before // NOTE: Unlike the other VolumeControl methods, these may be called before
// Initialize() or after Finalize(). May be called from multiple processes. // Initialize() or after Finalize(). May be called from multiple processes.
static float VolumeToDbFS(float volume) __attribute__((__weak__)); static float VolumeToDbFS(float volume);
static float DbFSToVolume(float dbfs) __attribute__((__weak__)); static float DbFSToVolume(float dbfs);
}; };
} // namespace media } // namespace media
......
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