Skip to content

Commit

Permalink
Add a new audio extension event OnMuteChanged.
Browse files Browse the repository at this point in the history
This is the part of audio extension redesign efforts. The original audio extension only has one OnDeviceChanged event without any input arguments to notify all sorts of audio events, which is not efficient. The hotrod app has to query getInfo to get all sets of the devices with properties, comparing the old data to decide what change really happens and handles the change. Therefore, in the new design, we will add new events to accurately report what exact audio change occurs. Eventually, we will migrate to use the new events and retire the old OnDeviceChanged event.

See details in design doc:
https://docs.google.com/a/google.com/document/d/1YFFLwX4mcKJyuAsZB13GhDid0MEt0QguKX0AxgvBoko/edit?usp=sharing

BUG=429312
TBR=mnissler

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

Cr-Commit-Position: refs/heads/master@{#322907}
  • Loading branch information
jennyz authored and Commit bot committed Mar 30, 2015
1 parent 5f3a341 commit 170e7fb
Show file tree
Hide file tree
Showing 26 changed files with 194 additions and 38 deletions.
2 changes: 1 addition & 1 deletion ash/system/audio/audio_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class AudioObserver {
virtual void OnOutputNodeVolumeChanged(uint64_t node_id, double volume) = 0;

// Called when output mute state changed.
virtual void OnOutputMuteChanged() = 0;
virtual void OnOutputMuteChanged(bool mute_on) = 0;

// Called when audio nodes changed.
virtual void OnAudioNodesChanged() = 0;
Expand Down
2 changes: 1 addition & 1 deletion ash/system/audio/tray_audio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void TrayAudio::OnOutputNodeVolumeChanged(uint64_t /* node_id */,
PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
}

void TrayAudio::OnOutputMuteChanged() {
void TrayAudio::OnOutputMuteChanged(bool /* mute_on */) {
if (tray_view())
tray_view()->SetVisible(GetInitialVisibility());

Expand Down
2 changes: 1 addition & 1 deletion ash/system/audio/tray_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TrayAudio : public TrayImageItem,

// Overridden from AudioObserver.
void OnOutputNodeVolumeChanged(uint64_t node_id, double volume) override;
void OnOutputMuteChanged() override;
void OnOutputMuteChanged(bool mute_on) override;
void OnAudioNodesChanged() override;
void OnActiveOutputNodeChanged() override;
void OnActiveInputNodeChanged() override;
Expand Down
8 changes: 3 additions & 5 deletions ash/system/tray/system_tray_notifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,9 @@ void SystemTrayNotifier::NotifyAudioOutputVolumeChanged(uint64_t node_id,
OnOutputNodeVolumeChanged(node_id, volume));
}

void SystemTrayNotifier::NotifyAudioOutputMuteChanged() {
FOR_EACH_OBSERVER(
AudioObserver,
audio_observers_,
OnOutputMuteChanged());
void SystemTrayNotifier::NotifyAudioOutputMuteChanged(bool mute_on) {
FOR_EACH_OBSERVER(AudioObserver, audio_observers_,
OnOutputMuteChanged(mute_on));
}

void SystemTrayNotifier::NotifyAudioNodesChanged() {
Expand Down
2 changes: 1 addition & 1 deletion ash/system/tray/system_tray_notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class ASH_EXPORT SystemTrayNotifier {
void NotifyAccessibilityModeChanged(
ui::AccessibilityNotificationVisibility notify);
void NotifyAudioOutputVolumeChanged(uint64_t node_id, double volume);
void NotifyAudioOutputMuteChanged();
void NotifyAudioOutputMuteChanged(bool mute_on);
void NotifyAudioNodesChanged();
void NotifyAudioActiveOutputNodeChanged();
void NotifyAudioActiveInputNodeChanged();
Expand Down
4 changes: 3 additions & 1 deletion chrome/browser/policy/policy_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,9 @@ class TestAudioObserver : public chromeos::CrasAudioHandler::AudioObserver {

protected:
// chromeos::CrasAudioHandler::AudioObserver overrides.
void OnOutputMuteChanged() override { ++output_mute_changed_count_; }
void OnOutputMuteChanged(bool /* mute_on */) override {
++output_mute_changed_count_;
}

private:
int output_mute_changed_count_;
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/ui/app_list/start_page_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class StartPageService::AudioStatus
}

// chromeos::CrasAudioHandler::AudioObserver:
void OnInputMuteChanged() override { CheckAndUpdate(); }
void OnInputMuteChanged(bool /* mute_on */) override { CheckAndUpdate(); }

void OnActiveInputNodeChanged() override { CheckAndUpdate(); }

Expand Down
6 changes: 3 additions & 3 deletions chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1224,15 +1224,15 @@ void SystemTrayDelegateChromeOS::OnOutputNodeVolumeChanged(uint64_t node_id,
GetSystemTrayNotifier()->NotifyAudioOutputVolumeChanged(node_id, volume);
}

void SystemTrayDelegateChromeOS::OnOutputMuteChanged() {
GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged();
void SystemTrayDelegateChromeOS::OnOutputMuteChanged(bool mute_on) {
GetSystemTrayNotifier()->NotifyAudioOutputMuteChanged(mute_on);
}

void SystemTrayDelegateChromeOS::OnInputNodeGainChanged(uint64_t /* node_id */,
int /* gain */) {
}

void SystemTrayDelegateChromeOS::OnInputMuteChanged() {
void SystemTrayDelegateChromeOS::OnInputMuteChanged(bool /* mute_on */) {
}

void SystemTrayDelegateChromeOS::OnAudioNodesChanged() {
Expand Down
4 changes: 2 additions & 2 deletions chrome/browser/ui/ash/system_tray_delegate_chromeos.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,9 @@ class SystemTrayDelegateChromeOS

// Overridden from CrasAudioHandler::AudioObserver.
void OnOutputNodeVolumeChanged(uint64_t node_id, int volume) override;
void OnOutputMuteChanged() override;
void OnOutputMuteChanged(bool mute_on) override;
void OnInputNodeGainChanged(uint64_t node_id, int gain) override;
void OnInputMuteChanged() override;
void OnInputMuteChanged(bool mute_on) override;
void OnAudioNodesChanged() override;
void OnActiveOutputNodeChanged() override;
void OnActiveInputNodeChanged() override;
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/ui/ash/volume_controller_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void VolumeController::OnOutputNodeVolumeChanged(uint64_t node_id, int volume) {
audio_handler->IsOutputMuted());
}

void VolumeController::OnOutputMuteChanged() {
void VolumeController::OnOutputMuteChanged(bool /* mute_on */) {
CrasAudioHandler* audio_handler = CrasAudioHandler::Get();
extensions::DispatchVolumeChangedEvent(
audio_handler->GetOutputVolumePercent(),
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/ui/ash/volume_controller_chromeos.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class VolumeController : public ash::VolumeControlDelegate,

// Overridden from chromeos::CrasAudioHandler::AudioObserver.
void OnOutputNodeVolumeChanged(uint64_t node_id, int volume) override;
void OnOutputMuteChanged() override;
void OnOutputMuteChanged(bool mute_on) override;

private:

Expand Down
10 changes: 6 additions & 4 deletions chromeos/audio/cras_audio_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ void CrasAudioHandler::AudioObserver::OnInputNodeGainChanged(
int /* gain */) {
}

void CrasAudioHandler::AudioObserver::OnOutputMuteChanged() {
void CrasAudioHandler::AudioObserver::OnOutputMuteChanged(bool /* mute_on */) {
}

void CrasAudioHandler::AudioObserver::OnInputMuteChanged() {
void CrasAudioHandler::AudioObserver::OnInputMuteChanged(bool /* mute_on */) {
}

void CrasAudioHandler::AudioObserver::OnAudioNodesChanged() {
Expand Down Expand Up @@ -367,7 +367,8 @@ void CrasAudioHandler::SetOutputMute(bool mute_on) {
}
}

FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputMuteChanged());
FOR_EACH_OBSERVER(AudioObserver, observers_,
OnOutputMuteChanged(output_mute_on_));
}

void CrasAudioHandler::AdjustOutputVolumeToAudibleLevel() {
Expand All @@ -380,7 +381,8 @@ void CrasAudioHandler::AdjustOutputVolumeToAudibleLevel() {

void CrasAudioHandler::SetInputMute(bool mute_on) {
SetInputMuteInternal(mute_on);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputMuteChanged());
FOR_EACH_OBSERVER(AudioObserver, observers_,
OnInputMuteChanged(input_mute_on_));
}

void CrasAudioHandler::SetActiveOutputNode(uint64_t node_id, bool notify) {
Expand Down
4 changes: 2 additions & 2 deletions chromeos/audio/cras_audio_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
virtual void OnOutputNodeVolumeChanged(uint64_t node_id, int volume);

// Called when output mute state changed.
virtual void OnOutputMuteChanged();
virtual void OnOutputMuteChanged(bool mute_on);

// Called when active input node's gain changed.
virtual void OnInputNodeGainChanged(uint64_t node_id, int gain);

// Called when input mute state changed.
virtual void OnInputMuteChanged();
virtual void OnInputMuteChanged(bool mute_on);

// Called when audio nodes changed.
virtual void OnAudioNodesChanged();
Expand Down
8 changes: 6 additions & 2 deletions chromeos/audio/cras_audio_handler_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,13 @@ class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {

void OnAudioNodesChanged() override { ++audio_nodes_changed_count_; }

void OnOutputMuteChanged() override { ++output_mute_changed_count_; }
void OnOutputMuteChanged(bool /* mute_on */) override {
++output_mute_changed_count_;
}

void OnInputMuteChanged() override { ++input_mute_changed_count_; }
void OnInputMuteChanged(bool /* mute_on */) override {
++input_mute_changed_count_;
}

void OnOutputNodeVolumeChanged(uint64 /* node_id */,
int /* volume */) override {
Expand Down
14 changes: 12 additions & 2 deletions extensions/browser/api/audio/audio_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ AudioService* AudioAPI::GetService() const {
}

void AudioAPI::OnDeviceChanged() {
if (browser_context_ && EventRouter::Get(browser_context_)) {
if (EventRouter::Get(browser_context_)) {
scoped_ptr<Event> event(new Event(
audio::OnDeviceChanged::kEventName,
scoped_ptr<base::ListValue>(new base::ListValue())));
Expand All @@ -46,14 +46,24 @@ void AudioAPI::OnDeviceChanged() {
}

void AudioAPI::OnLevelChanged(const std::string& id, int level) {
if (browser_context_ && EventRouter::Get(browser_context_)) {
if (EventRouter::Get(browser_context_)) {
scoped_ptr<base::ListValue> args = audio::OnLevelChanged::Create(id, level);
scoped_ptr<Event> event(
new Event(audio::OnLevelChanged::kEventName, args.Pass()));
EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
}
}

void AudioAPI::OnMuteChanged(bool is_input, bool is_muted) {
if (EventRouter::Get(browser_context_)) {
scoped_ptr<base::ListValue> args =
audio::OnMuteChanged::Create(is_input, is_muted);
scoped_ptr<Event> event(
new Event(audio::OnMuteChanged::kEventName, args.Pass()));
EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
}
}

///////////////////////////////////////////////////////////////////////////////

bool AudioGetInfoFunction::RunAsync() {
Expand Down
1 change: 1 addition & 0 deletions extensions/browser/api/audio/audio_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AudioAPI : public BrowserContextKeyedAPI, public AudioService::Observer {
// AudioService::Observer implementation.
void OnDeviceChanged() override;
void OnLevelChanged(const std::string& id, int level) override;
void OnMuteChanged(bool is_input, bool is_muted) override;

private:
friend class BrowserContextKeyedAPIFactory<AudioAPI>;
Expand Down
65 changes: 65 additions & 0 deletions extensions/browser/api/audio/audio_apitest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,71 @@ IN_PROC_BROWSER_TEST_F(AudioApiTest, OnLevelChangedOutputDevice) {
ASSERT_TRUE(result_listener.WaitUntilSatisfied());
EXPECT_EQ("success", result_listener.message());
}

IN_PROC_BROWSER_TEST_F(AudioApiTest, OnOutputMuteChanged) {
AudioNodeList audio_nodes;
audio_nodes.push_back(kJabraSpeaker1);
audio_nodes.push_back(kHDMIOutput);
SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);

// Verify the jabra speaker is the active output device.
AudioDevice device;
EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(&device));
EXPECT_EQ(device.id, kJabraSpeaker1.id);

// Mute the output.
cras_audio_handler_->SetOutputMute(true);
EXPECT_TRUE(cras_audio_handler_->IsOutputMuted());

// Loads background app.
ExtensionTestMessageListener load_listener("loaded", false);
ExtensionTestMessageListener result_listener("success", false);
result_listener.set_failure_message("failure");
ASSERT_TRUE(LoadApp("api_test/audio/output_mute_change"));
ASSERT_TRUE(load_listener.WaitUntilSatisfied());

// Un-mute the output.
cras_audio_handler_->SetOutputMute(false);
EXPECT_FALSE(cras_audio_handler_->IsOutputMuted());

// Verify the background app got the OnMuteChanged event
// with the expected output un-muted state.
ASSERT_TRUE(result_listener.WaitUntilSatisfied());
EXPECT_EQ("success", result_listener.message());
}

IN_PROC_BROWSER_TEST_F(AudioApiTest, OnInputMuteChanged) {
AudioNodeList audio_nodes;
audio_nodes.push_back(kJabraMic1);
audio_nodes.push_back(kUSBCameraMic);
SetUpCrasAudioHandlerWithTestingNodes(audio_nodes);

// Set the jabra mic to be the active input device.
AudioDevice jabra_mic(kJabraMic1);
cras_audio_handler_->SwitchToDevice(jabra_mic, true);
EXPECT_EQ(kJabraMic1.id, cras_audio_handler_->GetPrimaryActiveInputNode());

// Un-mute the input.
cras_audio_handler_->SetInputMute(false);
EXPECT_FALSE(cras_audio_handler_->IsInputMuted());

// Loads background app.
ExtensionTestMessageListener load_listener("loaded", false);
ExtensionTestMessageListener result_listener("success", false);
result_listener.set_failure_message("failure");
ASSERT_TRUE(LoadApp("api_test/audio/input_mute_change"));
ASSERT_TRUE(load_listener.WaitUntilSatisfied());

// Mute the input.
cras_audio_handler_->SetInputMute(true);
EXPECT_TRUE(cras_audio_handler_->IsInputMuted());

// Verify the background app got the OnMuteChanged event
// with the expected input muted state.
ASSERT_TRUE(result_listener.WaitUntilSatisfied());
EXPECT_EQ("success", result_listener.message());
}

#endif // OS_CHROMEOS

} // namespace extensions
3 changes: 3 additions & 0 deletions extensions/browser/api/audio/audio_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class AudioService {
// Called when the sound level of an active audio node changes.
virtual void OnLevelChanged(const std::string& id, int level) = 0;

// Called when the mute state of audio input/output changes.
virtual void OnMuteChanged(bool is_input, bool is_muted) = 0;

protected:
virtual ~Observer() {}
};
Expand Down
22 changes: 16 additions & 6 deletions extensions/browser/api/audio/audio_service_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ class AudioServiceImpl : public AudioService,
// chromeos::CrasAudioHandler::AudioObserver overrides.
void OnOutputNodeVolumeChanged(uint64_t id, int volume) override;
void OnInputNodeGainChanged(uint64_t id, int gain) override;
void OnOutputMuteChanged() override;
void OnInputMuteChanged() override;
void OnOutputMuteChanged(bool mute_on) override;
void OnInputMuteChanged(bool mute_on) override;
void OnAudioNodesChanged() override;
void OnActiveOutputNodeChanged() override;
void OnActiveInputNodeChanged() override;

private:
void NotifyDeviceChanged();
void NotifyLevelChanged(uint64_t id, int level);
void NotifyMuteChanged(bool is_input, bool is_muted);

bool FindDevice(uint64_t id, chromeos::AudioDevice* device);
uint64_t GetIdFromStr(const std::string& id_str);
Expand Down Expand Up @@ -196,16 +197,16 @@ void AudioServiceImpl::OnOutputNodeVolumeChanged(uint64_t id, int volume) {
NotifyLevelChanged(id, volume);
}

void AudioServiceImpl::OnOutputMuteChanged() {
NotifyDeviceChanged();
void AudioServiceImpl::OnOutputMuteChanged(bool mute_on) {
NotifyMuteChanged(false, mute_on);
}

void AudioServiceImpl::OnInputNodeGainChanged(uint64_t id, int gain) {
NotifyLevelChanged(id, gain);
}

void AudioServiceImpl::OnInputMuteChanged() {
NotifyDeviceChanged();
void AudioServiceImpl::OnInputMuteChanged(bool mute_on) {
NotifyMuteChanged(true, mute_on);
}

void AudioServiceImpl::OnAudioNodesChanged() {
Expand Down Expand Up @@ -233,6 +234,15 @@ void AudioServiceImpl::NotifyLevelChanged(uint64_t id, int level) {
NotifyDeviceChanged();
}

void AudioServiceImpl::NotifyMuteChanged(bool is_input, bool is_muted) {
FOR_EACH_OBSERVER(AudioService::Observer, observer_list_,
OnMuteChanged(is_input, is_muted));

// Notify DeviceChanged event for backward compatibility.
// TODO(jennyz): remove this code when the old version of hotrod retires.
NotifyDeviceChanged();
}

AudioService* AudioService::CreateInstance() {
return new AudioServiceImpl;
}
Expand Down
5 changes: 5 additions & 0 deletions extensions/common/api/audio.idl
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,10 @@ namespace audio {
// |id|: id of the audio node.
// |level|: new sound level of the node(volume for output, gain for input).
static void OnLevelChanged(DOMString id, long level);

// Fired when the mute state of the audio input or output changes.
// |isInput|: true indicating audio input; false indicating audio output.
// |isMuted|: new value of mute state.
static void OnMuteChanged(boolean isInput, boolean isMuted);
};
};
6 changes: 4 additions & 2 deletions extensions/shell/browser/shell_audio_controller_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ void ShellAudioController::OnOutputNodeVolumeChanged(uint64_t /* node_id */,
int /* volume */) {
}

void ShellAudioController::OnOutputMuteChanged() {}
void ShellAudioController::OnOutputMuteChanged(bool /* mute_on */) {
}

void ShellAudioController::OnInputNodeGainChanged(uint64_t /* node_id */,
int /* gain */) {
}

void ShellAudioController::OnInputMuteChanged() {}
void ShellAudioController::OnInputMuteChanged(bool /* mute_on */) {
}

void ShellAudioController::OnAudioNodesChanged() {
VLOG(1) << "Audio nodes changed";
Expand Down
Loading

0 comments on commit 170e7fb

Please sign in to comment.