Commit b0350b84 authored by Ahmed Mehfooz's avatar Ahmed Mehfooz Committed by Commit Bot

Add sliders to modify mic gain in system tray

Bug: 1065079
Change-Id: Iac3b64ea8246b044fd07aed41c2bce2cdf59b616
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2125429
Commit-Queue: Ahmed Mehfooz <amehfooz@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarJenny Zhang <jennyz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755572}
parent 70e8efce
...@@ -742,6 +742,10 @@ component("ash") { ...@@ -742,6 +742,10 @@ component("ash") {
"system/audio/audio_detailed_view.h", "system/audio/audio_detailed_view.h",
"system/audio/display_speaker_controller.cc", "system/audio/display_speaker_controller.cc",
"system/audio/display_speaker_controller.h", "system/audio/display_speaker_controller.h",
"system/audio/mic_gain_slider_controller.cc",
"system/audio/mic_gain_slider_controller.h",
"system/audio/mic_gain_slider_view.cc",
"system/audio/mic_gain_slider_view.h",
"system/audio/unified_audio_detailed_view_controller.cc", "system/audio/unified_audio_detailed_view_controller.cc",
"system/audio/unified_audio_detailed_view_controller.h", "system/audio/unified_audio_detailed_view_controller.h",
"system/audio/unified_volume_slider_controller.cc", "system/audio/unified_volume_slider_controller.cc",
......
...@@ -478,6 +478,16 @@ This file contains the strings for ash. ...@@ -478,6 +478,16 @@ This file contains the strings for ash.
Your screen will go blank for longer than usual (up to a minute) during this update. Please don't press the power button while the update is in progress. Your screen will go blank for longer than usual (up to a minute) during this update. Please don't press the power button while the update is in progress.
</message> </message>
<message name="IDS_ASH_STATUS_TRAY_MIC_GAIN" desc="The accessible text for the toggle mic muted button in the tray audio settings">
Toggle Mic. <ph name="STATE_TEXT">$1<ex>Mic is muted</ex></ph>
</message>
<message name="IDS_ASH_STATUS_TRAY_MIC_STATE_ON" desc="The accessible text used when the mic gain button is in the on state.">
Mic is on, toggling will mute input.
</message>
<message name="IDS_ASH_STATUS_TRAY_MIC_STATE_MUTED" desc="The accessible text used when the mic gain button is in the muted state.">
Mic is muted.
</message>
<message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the toggle volume muted button in the tray."> <message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the toggle volume muted button in the tray.">
Toggle Volume. <ph name="STATE_TEXT">$1<ex>Volume is muted</ex></ph> Toggle Volume. <ph name="STATE_TEXT">$1<ex>Volume is muted</ex></ph>
</message> </message>
......
47b10ec7985ca56244795803be5c41f23142df41
\ No newline at end of file
47b10ec7985ca56244795803be5c41f23142df41
\ No newline at end of file
0e00a09d6bdfd82937f9e9f458897d336539841e
\ No newline at end of file
...@@ -62,6 +62,7 @@ aggregate_vector_icons("ash_vector_icons") { ...@@ -62,6 +62,7 @@ aggregate_vector_icons("ash_vector_icons") {
"login_screen_menu_dropdown.icon", "login_screen_menu_dropdown.icon",
"login_screen_enterprise.icon", "login_screen_enterprise.icon",
"mic.icon", "mic.icon",
"muted_microphone.icon",
"network_badge_captive_portal.icon", "network_badge_captive_portal.icon",
"network_badge_off.icon", "network_badge_off.icon",
"network_badge_roaming.icon", "network_badge_roaming.icon",
......
CANVAS_DIMENSIONS, 20,
MOVE_TO, 12.57f, 4.5f,
LINE_TO, 12.56f, 9.5f,
CUBIC_TO, 12.56f, 9.96f, 12.44f, 10.38f, 12.22f, 10.75f,
LINE_TO, 11.01f, 9.53f,
CUBIC_TO, 11.01f, 9.52f, 11.01f, 9.52f, 11.01f, 9.51f,
LINE_TO, 11.05f, 4.51f,
CUBIC_TO, 11.05f, 3.95f, 10.6f, 3.5f, 10.05f, 3.5f,
CUBIC_TO, 9.5f, 3.5f, 9.05f, 3.94f, 9.05f, 4.49f,
LINE_TO, 9.02f, 7.55f,
LINE_TO, 7.43f, 5.95f,
V_LINE_TO, 4.5f,
CUBIC_TO, 7.43f, 3.12f, 8.58f, 2, 10, 2,
CUBIC_TO, 11.42f, 2, 12.57f, 3.12f, 12.57f, 4.5f,
CLOSE,
MOVE_TO, 2.24f, 3.24f,
LINE_TO, 1, 4.47f,
LINE_TO, 10.38f, 13.86f,
CUBIC_TO, 10.26f, 13.87f, 10.13f, 13.87f, 10, 13.87f,
CUBIC_TO, 7.63f, 13.87f, 5.46f, 12.11f, 5.46f, 9.58f,
H_LINE_TO, 4,
CUBIC_TO, 4, 12.46f, 6.33f, 14.83f, 9.14f, 15.24f,
V_LINE_TO, 18,
H_LINE_TO, 10.86f,
V_LINE_TO, 15.24f,
CUBIC_TO, 11.11f, 15.2f, 11.36f, 15.15f, 11.61f, 15.08f,
LINE_TO, 15.53f, 19,
LINE_TO, 16.76f, 17.76f,
LINE_TO, 2.24f, 3.24f,
CLOSE,
MOVE_TO, 13.64f, 12.16f,
LINE_TO, 14.64f, 13.16f,
CUBIC_TO, 15.48f, 12.18f, 16, 10.94f, 16, 9.58f,
H_LINE_TO, 14.54f,
CUBIC_TO, 14.54f, 10.58f, 14.2f, 11.46f, 13.64f, 12.16f,
CLOSE
\ No newline at end of file
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
#include "ash/system/audio/audio_detailed_view.h" #include "ash/system/audio/audio_detailed_view.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ash/system/audio/mic_gain_slider_controller.h"
#include "ash/system/audio/mic_gain_slider_view.h"
#include "ash/system/tray/hover_highlight_view.h" #include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/tray/tri_view.h" #include "ash/system/tray/tri_view.h"
...@@ -84,6 +87,7 @@ void AudioDetailedView::AddAudioSubHeader(const gfx::VectorIcon& icon, ...@@ -84,6 +87,7 @@ void AudioDetailedView::AddAudioSubHeader(const gfx::VectorIcon& icon,
void AudioDetailedView::CreateItems() { void AudioDetailedView::CreateItems() {
CreateScrollableList(); CreateScrollableList();
CreateTitleRow(IDS_ASH_STATUS_TRAY_AUDIO); CreateTitleRow(IDS_ASH_STATUS_TRAY_AUDIO);
mic_gain_controller_ = std::make_unique<MicGainSliderController>();
} }
void AudioDetailedView::UpdateAudioDevices() { void AudioDetailedView::UpdateAudioDevices() {
...@@ -158,6 +162,9 @@ void AudioDetailedView::UpdateScrollableList() { ...@@ -158,6 +162,9 @@ void AudioDetailedView::UpdateScrollableList() {
HoverHighlightView* container = HoverHighlightView* container =
AddScrollListCheckableItem(GetAudioDeviceName(device), device.active); AddScrollListCheckableItem(GetAudioDeviceName(device), device.active);
device_map_[container] = device; device_map_[container] = device;
if (features::IsSystemTrayMicGainSettingEnabled())
AddScrollListChild(mic_gain_controller_->CreateMicGainSlider(device.id));
} }
scroll_content()->SizeToPreferredSize(); scroll_content()->SizeToPreferredSize();
......
...@@ -16,6 +16,8 @@ struct VectorIcon; ...@@ -16,6 +16,8 @@ struct VectorIcon;
} }
namespace ash { namespace ash {
class MicGainSliderController;
namespace tray { namespace tray {
class AudioDetailedView : public TrayDetailedView { class AudioDetailedView : public TrayDetailedView {
...@@ -44,6 +46,7 @@ class AudioDetailedView : public TrayDetailedView { ...@@ -44,6 +46,7 @@ class AudioDetailedView : public TrayDetailedView {
typedef std::map<views::View*, chromeos::AudioDevice> AudioDeviceMap; typedef std::map<views::View*, chromeos::AudioDevice> AudioDeviceMap;
std::unique_ptr<MicGainSliderController> mic_gain_controller_;
chromeos::AudioDeviceList output_devices_; chromeos::AudioDeviceList output_devices_;
chromeos::AudioDeviceList input_devices_; chromeos::AudioDeviceList input_devices_;
AudioDeviceMap device_map_; AudioDeviceMap device_map_;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/audio/mic_gain_slider_controller.h"
#include "ash/shell.h"
#include "ash/system/audio/mic_gain_slider_view.h"
using chromeos::CrasAudioHandler;
namespace ash {
MicGainSliderController::MicGainSliderController() = default;
std::unique_ptr<MicGainSliderView> MicGainSliderController::CreateMicGainSlider(
uint64_t device_id) {
return std::make_unique<MicGainSliderView>(this, device_id);
}
views::View* MicGainSliderController::CreateView() {
return nullptr;
}
void MicGainSliderController::ButtonPressed(views::Button* sender,
const ui::Event& event) {
bool is_muted = !CrasAudioHandler::Get()->IsInputMuted();
// TODO(amehfooz): Add metrics and logging.
CrasAudioHandler::Get()->SetMuteForDevice(
CrasAudioHandler::Get()->GetPrimaryActiveInputNode(), is_muted);
}
void MicGainSliderController::SliderValueChanged(
views::Slider* sender,
float value,
float old_value,
views::SliderChangeReason reason) {
if (reason != views::SliderChangeReason::kByUser)
return;
CrasAudioHandler::Get()->SetInputGainPercent(value * 100);
}
} // namespace ash
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_CONTROLLER_H_
#define ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_CONTROLLER_H_
#include "ash/system/unified/unified_slider_view.h"
namespace ash {
class MicGainSliderView;
// Controller for mic gain sliders situated in audio detailed
// view in the system tray.
class MicGainSliderController : public UnifiedSliderListener {
public:
MicGainSliderController();
// Create a slider view for a specific input device.
std::unique_ptr<MicGainSliderView> CreateMicGainSlider(uint64_t device_id);
// UnifiedSliderListener:
views::View* CreateView() override;
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
void SliderValueChanged(views::Slider* sender,
float value,
float old_value,
views::SliderChangeReason reason) override;
};
} // namespace ash
#endif // ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_CONTROLLER_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/audio/mic_gain_slider_view.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/default_color_constants.h"
#include "ash/system/audio/mic_gain_slider_controller.h"
#include "ash/system/tray/tray_constants.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
using chromeos::CrasAudioHandler;
namespace ash {
MicGainSliderView::MicGainSliderView(MicGainSliderController* controller,
uint64_t device_id)
: UnifiedSliderView(controller,
kImeMenuMicrophoneIcon,
IDS_ASH_STATUS_TRAY_VOLUME_SLIDER_LABEL),
device_id_(device_id) {
CrasAudioHandler::Get()->AddAudioObserver(this);
Update(false /* by_user */);
}
MicGainSliderView::~MicGainSliderView() {
CrasAudioHandler::Get()->RemoveAudioObserver(this);
}
void MicGainSliderView::Update(bool by_user) {
if (CrasAudioHandler::Get()->GetPrimaryActiveInputNode() != device_id_) {
SetVisible(false);
return;
}
SetVisible(true);
bool is_muted = CrasAudioHandler::Get()->IsInputMuted();
float level = CrasAudioHandler::Get()->GetInputGainPercent() / 100.f;
// To indicate that the volume is muted, set the volume slider to the minimal
// visual style.
slider()->SetRenderingStyle(
is_muted ? views::Slider::RenderingStyle::kMinimalStyle
: views::Slider::RenderingStyle::kDefaultStyle);
// The button should be gray when muted and colored otherwise.
button()->SetToggled(!is_muted);
button()->SetVectorIcon(is_muted ? kMutedMicrophoneIcon
: kImeMenuMicrophoneIcon);
base::string16 state_tooltip_text =
l10n_util::GetStringUTF16(is_muted ? IDS_ASH_STATUS_TRAY_MIC_STATE_MUTED
: IDS_ASH_STATUS_TRAY_MIC_STATE_ON);
button()->SetTooltipText(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_MIC_GAIN, state_tooltip_text));
// Slider's value is in finer granularity than audio volume level(0.01),
// there will be a small discrepancy between slider's value and volume level
// on audio side. To avoid the jittering in slider UI, use the slider's
// current value.
if (std::abs(level - slider()->GetValue()) <
kAudioSliderIgnoreUpdateThreshold) {
level = slider()->GetValue();
}
// Note: even if the value does not change, we still need to call this
// function to enable accessibility events (crbug.com/1013251).
SetSliderValue(level, by_user);
}
void MicGainSliderView::OnInputNodeGainChanged(uint64_t node_id, int gain) {
Update(false /* by_user */);
}
void MicGainSliderView::OnInputMuteChanged(bool mute_on) {
Update(false /* by_user */);
}
void MicGainSliderView::OnActiveInputNodeChanged() {
Update(false /* by_user */);
}
const char* MicGainSliderView::GetClassName() const {
return "MicGainSliderView";
}
} // namespace ash
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_VIEW_H_
#define ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_VIEW_H_
#include "ash/system/unified/unified_slider_view.h"
#include "chromeos/audio/cras_audio_handler.h"
namespace ash {
class MicGainSliderController;
class MicGainSliderView : public UnifiedSliderView,
public chromeos::CrasAudioHandler::AudioObserver {
public:
MicGainSliderView(MicGainSliderController* controller, uint64_t device_id);
~MicGainSliderView() override;
uint64_t device_id() const { return device_id_; }
// CrasAudioHandler::AudioObserver:
void OnInputNodeGainChanged(uint64_t node_id, int gain) override;
void OnInputMuteChanged(bool mute_on) override;
void OnActiveInputNodeChanged() override;
// views::View:
const char* GetClassName() const override;
private:
void Update(bool by_user);
// device id for the input device tied to this slider.
const uint64_t device_id_;
};
} // namespace ash
#endif // ASH_SYSTEM_AUDIO_MIC_GAIN_SLIDER_VIEW_H_
...@@ -33,9 +33,6 @@ namespace ash { ...@@ -33,9 +33,6 @@ namespace ash {
namespace { namespace {
// Threshold to ignore update on the slider value.
const float kSliderIgnoreUpdateThreshold = 0.01;
// References to the icons that correspond to different volume levels. // References to the icons that correspond to different volume levels.
const gfx::VectorIcon* const kVolumeLevelIcons[] = { const gfx::VectorIcon* const kVolumeLevelIcons[] = {
&kUnifiedMenuVolumeLowIcon, // Low volume. &kUnifiedMenuVolumeLowIcon, // Low volume.
...@@ -183,9 +180,10 @@ void UnifiedVolumeView::Update(bool by_user) { ...@@ -183,9 +180,10 @@ void UnifiedVolumeView::Update(bool by_user) {
// there will be a small discrepancy between slider's value and volume level // there will be a small discrepancy between slider's value and volume level
// on audio side. To avoid the jittering in slider UI, use the slider's // on audio side. To avoid the jittering in slider UI, use the slider's
// current value. // current value.
if (std::abs(level - slider()->GetValue()) < kSliderIgnoreUpdateThreshold) if (std::abs(level - slider()->GetValue()) <
kAudioSliderIgnoreUpdateThreshold) {
level = slider()->GetValue(); level = slider()->GetValue();
}
// Note: even if the value does not change, we still need to call this // Note: even if the value does not change, we still need to call this
// function to enable accessibility events (crbug.com/1013251). // function to enable accessibility events (crbug.com/1013251).
SetSliderValue(level, by_user); SetSliderValue(level, by_user);
......
...@@ -94,10 +94,13 @@ extern const int kTrayPopupInkDropCornerRadius; ...@@ -94,10 +94,13 @@ extern const int kTrayPopupInkDropCornerRadius;
constexpr float kUnifiedMenuBackgroundBlur = 30.f; constexpr float kUnifiedMenuBackgroundBlur = 30.f;
// Threshold to ignore update on the slider value.
constexpr float kAudioSliderIgnoreUpdateThreshold = 0.01;
constexpr gfx::Insets kUnifiedMenuItemPadding(0, 16, 16, 16); constexpr gfx::Insets kUnifiedMenuItemPadding(0, 16, 16, 16);
constexpr gfx::Insets kUnifiedSystemInfoViewPadding(0, 16, 16, 16); constexpr gfx::Insets kUnifiedSystemInfoViewPadding(0, 16, 16, 16);
constexpr gfx::Insets kUnifiedManagedDeviceViewPadding(4, 19, 4, 16); constexpr gfx::Insets kUnifiedManagedDeviceViewPadding(4, 19, 4, 16);
constexpr gfx::Insets kUnifiedSliderRowPadding(0, 12, 8, 16); constexpr gfx::Insets kUnifiedSliderRowPadding(0, 16, 8, 16);
constexpr gfx::Insets kUnifiedSliderBubblePadding(12, 0, 4, 0); constexpr gfx::Insets kUnifiedSliderBubblePadding(12, 0, 4, 0);
constexpr gfx::Insets kUnifiedSliderPadding(0, 16); constexpr gfx::Insets kUnifiedSliderPadding(0, 16);
...@@ -105,7 +108,7 @@ constexpr int kMessageCenterCollapseThreshold = 175; ...@@ -105,7 +108,7 @@ constexpr int kMessageCenterCollapseThreshold = 175;
constexpr int kStackedNotificationBarHeight = 32; constexpr int kStackedNotificationBarHeight = 32;
constexpr int kStackedNotificationBarCollapsedHeight = 40; constexpr int kStackedNotificationBarCollapsedHeight = 40;
constexpr int kNotificationIconStackThreshold = 28; constexpr int kNotificationIconStackThreshold = 28;
constexpr int kUnifiedSliderViewSpacing = 12; constexpr int kUnifiedSliderViewSpacing = 16;
constexpr int kUnifiedMenuPadding = 8; constexpr int kUnifiedMenuPadding = 8;
constexpr int kUnifiedMessageCenterBubbleSpacing = 8; constexpr int kUnifiedMessageCenterBubbleSpacing = 8;
constexpr int kUnifiedNotificationCenterSpacing = 16; constexpr int kUnifiedNotificationCenterSpacing = 16;
......
...@@ -318,6 +318,10 @@ void TrayDetailedView::CreateScrollableList() { ...@@ -318,6 +318,10 @@ void TrayDetailedView::CreateScrollableList() {
box_layout_->SetFlexForView(scroller_, 1); box_layout_->SetFlexForView(scroller_, 1);
} }
void TrayDetailedView::AddScrollListChild(std::unique_ptr<views::View> child) {
scroll_content_->AddChildView(std::move(child));
}
HoverHighlightView* TrayDetailedView::AddScrollListItem( HoverHighlightView* TrayDetailedView::AddScrollListItem(
const gfx::VectorIcon& icon, const gfx::VectorIcon& icon,
const base::string16& text) { const base::string16& text) {
......
...@@ -70,6 +70,9 @@ class ASH_EXPORT TrayDetailedView : public views::View, ...@@ -70,6 +70,9 @@ class ASH_EXPORT TrayDetailedView : public views::View,
HoverHighlightView* AddScrollListItem(const gfx::VectorIcon& icon, HoverHighlightView* AddScrollListItem(const gfx::VectorIcon& icon,
const base::string16& text); const base::string16& text);
// Add a child view to the scroll list.
void AddScrollListChild(std::unique_ptr<views::View> child);
// Adds a targetable row to |scroll_content_| containing |icon|, |text|, and a // Adds a targetable row to |scroll_content_| containing |icon|, |text|, and a
// checkbox. |checked| determines whether the checkbox is checked or not. // checkbox. |checked| determines whether the checkbox is checked or not.
// |enterprise_managed| determines whether or not there will be an enterprise // |enterprise_managed| determines whether or not there will be an enterprise
......
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