0

audio-settings: Add Settings button to audio quick settings tray

- The settings button opens to the new audio settings page
- This will show for current quick settings and revamped quick settings

screenshot: http://screen/4nzMjnJY22pD6Jo

Bug: b:260277007, b:264446152
Change-Id: If30c6adc381594c7fa749f941a9ad056bb0b3315
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4235218
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Ashley Prasad <ashleydp@google.com>
Cr-Commit-Position: refs/heads/main@{#1106845}
This commit is contained in:
Gavin Williams
2023-02-17 17:33:53 +00:00
committed by Chromium LUCI CQ
parent f8b6e45abb
commit 1b6b54dc68
11 changed files with 154 additions and 0 deletions

@ -3052,6 +3052,7 @@ test("ash_unittests") {
"system/accessibility/select_to_speak/select_to_speak_tray_unittest.cc",
"system/accessibility/switch_access/switch_access_back_button_bubble_controller_unittest.cc",
"system/accessibility/switch_access/switch_access_menu_bubble_controller_unittest.cc",
"system/audio/audio_detailed_view_unittest.cc",
"system/audio/audio_effects_controller_unittest.cc",
"system/audio/unified_audio_detailed_view_controller_unittest.cc",
"system/audio/unified_volume_view_unittest.cc",

@ -2721,6 +2721,9 @@ Connect your device to power.
<message name="IDS_ASH_STATUS_TRAY_AUDIO_INPUT" desc="The label used in audio detailed page for audio input section of ash tray pop up.">
Input
</message>
<message name="IDS_ASH_STATUS_TRAY_AUDIO_SETTINGS" desc="The label used in audio detailed page for the button that launches the OS audio settings page.">
Audio settings
</message>
<message name="IDS_ASH_STATUS_TRAY_DISPLAY" desc="The label used for the button in the status tray to show the display detailed page.">
Display
</message>

@ -0,0 +1 @@
2911580093fe0634413c9ad41afac78a76405fe4

@ -170,6 +170,9 @@ class ASH_PUBLIC_EXPORT SystemTrayClient {
// the "send feedback" button.
virtual void ShowChannelInfoGiveFeedback() = 0;
// Shows settings related to audio devices (input/output).
virtual void ShowAudioSettings() = 0;
// Returns 'true' if the user preference is set to allow users to submit
// feedback, 'false' otherwise.
virtual bool IsUserFeedbackEnabled() = 0;

@ -142,6 +142,10 @@ void TestSystemTrayClient::ShowChannelInfoGiveFeedback() {
++show_channel_info_give_feedback_count_;
}
void TestSystemTrayClient::ShowAudioSettings() {
++show_audio_settings_count_;
}
bool TestSystemTrayClient::IsUserFeedbackEnabled() {
return user_feedback_enabled_;
}

@ -69,6 +69,7 @@ class ASH_PUBLIC_EXPORT TestSystemTrayClient : public SystemTrayClient {
GURL& final_event_url) override;
void ShowChannelInfoAdditionalDetails() override;
void ShowChannelInfoGiveFeedback() override;
void ShowAudioSettings() override;
bool IsUserFeedbackEnabled() override;
int show_bluetooth_settings_count() const {
@ -153,6 +154,8 @@ class ASH_PUBLIC_EXPORT TestSystemTrayClient : public SystemTrayClient {
return show_channel_info_give_feedback_count_;
}
int show_audio_settings_count() const { return show_audio_settings_count_; }
void set_user_feedback_enabled(bool user_feedback_enabled) {
user_feedback_enabled_ = user_feedback_enabled;
}
@ -181,6 +184,7 @@ class ASH_PUBLIC_EXPORT TestSystemTrayClient : public SystemTrayClient {
std::string last_network_type_;
int show_channel_info_additional_details_count_ = 0;
int show_channel_info_give_feedback_count_ = 0;
int show_audio_settings_count_ = 0;
bool user_feedback_enabled_ = false;
};

@ -8,6 +8,7 @@
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/system_tray_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
@ -18,6 +19,7 @@
#include "ash/system/audio/mic_gain_slider_view.h"
#include "ash/system/audio/unified_volume_slider_controller.h"
#include "ash/system/audio/unified_volume_view.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_popup_utils.h"
@ -25,6 +27,7 @@
#include "ash/system/tray/tri_view.h"
#include "ash/system/unified/quick_settings_slider.h"
#include "ash/system/unified/unified_slider_view.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/ash/components/audio/cras_audio_handler.h"
@ -182,6 +185,10 @@ AudioDetailedView::~AudioDetailedView() {
}
}
views::View* AudioDetailedView::GetAsView() {
return this;
}
void AudioDetailedView::SetMapNoiseCancellationToggleCallbackForTest(
AudioDetailedView::NoiseCancellationCallback*
noise_cancellation_toggle_callback) {
@ -303,11 +310,26 @@ void AudioDetailedView::CreateItems() {
CreateTitleRow(IDS_ASH_STATUS_TRAY_AUDIO);
}
if (features::IsAudioSettingsPageEnabled()) {
CreateTitleSettingsButton();
}
mic_gain_controller_ = std::make_unique<MicGainSliderController>();
unified_volume_slider_controller_ =
std::make_unique<UnifiedVolumeSliderController>();
}
void AudioDetailedView::CreateTitleSettingsButton() {
tri_view()->SetContainerVisible(TriView::Container::END, /*visible=*/true);
std::unique_ptr<views::Button> settings =
base::WrapUnique(CreateSettingsButton(
base::BindRepeating(&AudioDetailedView::OnSettingsButtonClicked,
weak_factory_.GetWeakPtr()),
IDS_ASH_STATUS_TRAY_AUDIO_SETTINGS));
settings_button_ =
tri_view()->AddView(TriView::Container::END, std::move(settings));
}
void AudioDetailedView::CreateLiveCaptionView() {
auto* live_caption_container =
scroll_content()->AddChildViewAt(std::make_unique<RoundedContainer>(), 0);
@ -499,6 +521,16 @@ void AudioDetailedView::OnInputNoiseCancellationTogglePressed() {
}
}
void AudioDetailedView::OnSettingsButtonClicked() {
DCHECK(features::IsAudioSettingsPageEnabled());
if (!TrayPopupUtils::CanOpenWebUISettings()) {
return;
}
CloseBubble(); // Deletes |this|.
Shell::Get()->system_tray_model()->client()->ShowAudioSettings();
}
void AudioDetailedView::ToggleLiveCaptionState() {
AccessibilityControllerImpl* controller =
Shell::Get()->accessibility_controller();

@ -15,6 +15,7 @@
#include "ash/system/tray/tray_detailed_view.h"
#include "chromeos/ash/components/audio/audio_device.h"
#include "components/soda/soda_installer.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/toggle_button.h"
#include "ui/views/view.h"
@ -46,6 +47,8 @@ class ASH_EXPORT AudioDetailedView : public TrayDetailedView,
static void SetMapNoiseCancellationToggleCallbackForTest(
NoiseCancellationCallback* map_noise_cancellation_toggle_callback);
views::View* GetAsView();
// Updates the `AudioDetailedView` and re-layout.
void Update();
@ -53,6 +56,7 @@ class ASH_EXPORT AudioDetailedView : public TrayDetailedView,
void OnAccessibilityStatusChanged() override;
private:
friend class AudioDetailedViewTest;
friend class UnifiedAudioDetailedViewControllerSodaTest;
friend class UnifiedAudioDetailedViewControllerTest;
@ -71,6 +75,8 @@ class ASH_EXPORT AudioDetailedView : public TrayDetailedView,
// Creates the items other than the devices during initialization.
void CreateItems();
void CreateTitleSettingsButton();
// For QsRevamp: Creates the `live_caption_view_`.
void CreateLiveCaptionView();
@ -91,6 +97,9 @@ class ASH_EXPORT AudioDetailedView : public TrayDetailedView,
// Callback passed to the noise cancellation toggle button.
void OnInputNoiseCancellationTogglePressed();
// Callback passed to the Settings button.
void OnSettingsButtonClicked();
// Toggles live caption state to trigger `AccessibilityObserver` to update the
// UI.
void ToggleLiveCaptionState();
@ -130,6 +139,7 @@ class ASH_EXPORT AudioDetailedView : public TrayDetailedView,
HoverHighlightView* noise_cancellation_view_ = nullptr;
views::ImageView* noise_cancellation_icon_ = nullptr;
views::ToggleButton* noise_cancellation_button_ = nullptr;
views::Button* settings_button_ = nullptr;
base::WeakPtrFactory<AudioDetailedView> weak_factory_{this};
};

@ -0,0 +1,89 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/audio/audio_detailed_view.h"
#include <memory>
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/test/test_system_tray_client.h"
#include "ash/system/tray/detailed_view_delegate.h"
#include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h"
#include "ui/views/test/views_test_utils.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
// This class exists to stub out the CloseBubble() call. This allows tests to
// directly construct the detailed view, without depending on the entire quick
// settings bubble and view hierarchy.
class FakeDetailedViewDelegate : public DetailedViewDelegate {
public:
FakeDetailedViewDelegate()
: DetailedViewDelegate(/*tray_controller=*/nullptr) {}
~FakeDetailedViewDelegate() override = default;
// DetailedViewDelegate:
void CloseBubble() override { ++close_bubble_count_; }
int close_bubble_count_ = 0;
};
} // namespace
class AudioDetailedViewTest : public AshTestBase {
public:
// AshTestBase:
void SetUp() override {
scoped_feature_list_.InitWithFeatures({features::kAudioSettingsPage}, {});
AshTestBase::SetUp();
auto audio_detailed_view =
std::make_unique<AudioDetailedView>(&detailed_view_delegate_);
audio_detailed_view_ = audio_detailed_view.get();
widget_ = CreateFramelessTestWidget();
widget_->SetFullscreen(true);
widget_->SetContentsView(audio_detailed_view.release()->GetAsView());
}
void TearDown() override {
widget_.reset();
AshTestBase::TearDown();
}
views::Button* GetSettingsButton() {
return audio_detailed_view_->settings_button_;
}
std::unique_ptr<views::Widget> widget_;
FakeDetailedViewDelegate detailed_view_delegate_;
AudioDetailedView* audio_detailed_view_ = nullptr;
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(AudioDetailedViewTest, PressingSettingsButtonOpensSettings) {
views::Button* settings_button = GetSettingsButton();
// Clicking the button at the lock screen does nothing.
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOCKED);
LeftClickOn(settings_button);
EXPECT_EQ(0, GetSystemTrayClient()->show_audio_settings_count());
EXPECT_EQ(0, detailed_view_delegate_.close_bubble_count_);
// Clicking the button in an active user session opens OS settings.
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
LeftClickOn(settings_button);
EXPECT_EQ(1, GetSystemTrayClient()->show_audio_settings_count());
EXPECT_EQ(1, detailed_view_delegate_.close_bubble_count_);
}
} // namespace ash

@ -763,6 +763,12 @@ void SystemTrayClientImpl::ShowChannelInfoGiveFeedback() {
ash::NewWindowDelegate::kFeedbackSourceChannelIndicator);
}
void SystemTrayClientImpl::ShowAudioSettings() {
DCHECK(ash::features::IsAudioSettingsPageEnabled());
ShowSettingsSubPageForActiveUser(
chromeos::settings::mojom::kAudioSubpagePath);
}
bool SystemTrayClientImpl::IsUserFeedbackEnabled() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
ash::switches::kForceShowReleaseTrack)) {

@ -103,6 +103,7 @@ class SystemTrayClientImpl : public ash::SystemTrayClient,
GURL& finalized_event_url) override;
void ShowChannelInfoAdditionalDetails() override;
void ShowChannelInfoGiveFeedback() override;
void ShowAudioSettings() override;
bool IsUserFeedbackEnabled() override;
protected: