1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_AUDIO_AUDIO_DETAILED_VIEW_H_
#define ASH_SYSTEM_AUDIO_AUDIO_DETAILED_VIEW_H_
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include "ash/accessibility/accessibility_observer.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_controller.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/style/switch.h"
#include "ash/system/audio/audio_detailed_view_utils.h"
#include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/tray_detailed_view.h"
#include "base/memory/raw_ptr.h"
#include "chromeos/ash/components/audio/audio_device.h"
#include "chromeos/ash/components/audio/cras_audio_handler.h"
#include "components/services/app_service/public/cpp/app_capability_access_cache.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/soda/soda_installer.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/view.h"
namespace gfx {
struct VectorIcon;
}
namespace ash {
class MicGainSliderController;
class LabeledSliderView;
class UnifiedAudioDetailedViewControllerSodaTest;
class UnifiedAudioDetailedViewControllerTest;
class UnifiedVolumeSliderController;
class ASH_EXPORT AudioDetailedView
: public AccessibilityObserver,
public apps::AppCapabilityAccessCache::Observer,
public CrasAudioHandler::AudioObserver,
public SessionObserver,
public speech::SodaInstaller::Observer,
public TrayDetailedView {
METADATA_HEADER(AudioDetailedView, TrayDetailedView)
public:
explicit AudioDetailedView(DetailedViewDelegate* delegate);
AudioDetailedView(const AudioDetailedView&) = delete;
AudioDetailedView& operator=(const AudioDetailedView&) = delete;
~AudioDetailedView() override;
// IDs used for the views that compose the Audio UI.
// Note that these IDs are only guaranteed to be unique inside
// `AudioDetailedView`.
enum AudioDetailedViewID {
// Starts at 1000 to prevent potential overlapping.
kAudioDetailedView = 1000,
// Agc information row and corresponding text label.
kAgcInfoLabel,
kAgcInfoView,
// Warning message view when an NBS device is selected.
kNbsWarningView,
};
using NoiseCancellationCallback =
base::RepeatingCallback<void(uint64_t, views::View*)>;
static void SetMapNoiseCancellationToggleCallbackForTest(
NoiseCancellationCallback* map_noise_cancellation_toggle_callback);
using StyleTransferCallback =
base::RepeatingCallback<void(uint64_t, views::View*)>;
static void SetMapStyleTransferToggleCallbackForTest(
StyleTransferCallback* map_style_transfer_toggle_callback);
views::View* GetAsView();
// Updates the `AudioDetailedView` and re-layout.
void Update();
// AccessibilityObserver:
void OnAccessibilityStatusChanged() override;
// apps::AppCapabilityAccessCache::Observer:
void OnCapabilityAccessUpdate(
const apps::CapabilityAccessUpdate& update) override;
void OnAppCapabilityAccessCacheWillBeDestroyed(
apps::AppCapabilityAccessCache* cache) override;
// SessionObserver:
void OnSessionStateChanged(session_manager::SessionState state) override;
// CrasAudioHandler::AudioObserver:
void OnNumStreamIgnoreUiGainsChanged(int32_t num) override;
void OnVoiceIsolationUIAppearanceChanged(
VoiceIsolationUIAppearance appearance) override;
private:
friend class AudioDetailedViewTest;
friend class AudioDetailedViewAgcInfoTest;
friend class UnifiedAudioDetailedViewControllerSodaTest;
friend class UnifiedAudioDetailedViewControllerTest;
// Helper function to add non-clickable header rows within the scrollable
// list.
void AddAudioSubHeader(views::View* container,
const gfx::VectorIcon& icon,
const int text_id);
// Creates the items other than the devices during initialization.
void CreateItems();
// Creates the NBS warning view.
std::unique_ptr<TriView> CreateNbsWarningView();
// Creates the `live_caption_view_`.
void CreateLiveCaptionView();
// Creates the noise cancellation toggle row in the input subsection.
std::unique_ptr<HoverHighlightView> CreateNoiseCancellationToggleRow(
const AudioDevice& device);
// Creates the style transfer toggle row in the input subsection.
std::unique_ptr<HoverHighlightView> CreateStyleTransferToggleRow(
const AudioDevice& device);
// Creates the agc info row in the input subsection.
std::unique_ptr<HoverHighlightView> CreateAgcInfoRow(
const AudioDevice& device);
// Creates and returns the `LabeledSliderView`. Focuses on the slider of
// `LabeledSliderView` if `device` is focused and active.
LabeledSliderView* CreateLabeledSliderView(views::View* container,
const AudioDevice& device);
// Sets the subtext for `live_caption_view_` based on whether live caption has
// updated if this feature is enabled and visible in tray.
void MaybeShowSodaMessage(speech::LanguageCode language_code,
std::u16string message);
// Callback passed to the noise cancellation toggle button.
void OnInputNoiseCancellationTogglePressed();
// Callback passed to the style transfer toggle button.
void OnInputStyleTransferTogglePressed();
// Callback passed to the Settings button.
void OnSettingsButtonClicked();
// Toggles live caption state to trigger `AccessibilityObserver` to update the
// UI.
void ToggleLiveCaptionState();
// Updates `live_caption_view_` via the UI based on `is_enabled`.
void UpdateLiveCaptionView(bool is_enabled);
// Updates `output_devices_` and `input_devices_`.
void UpdateAudioDevices();
// Adds a separator if the `device` is the last one in `input_devices_` if
// it's an input device or is the last one in `output_devices_` if it's an
// output device.
void AddSeparatorIfNotLast(views::View* container, const AudioDevice& device);
// Updates the child views in `scroll_content()`.
void UpdateScrollableList();
// Updates the label of AGC info when accessibility to microphone changed.
// Hide AGC info row if no apps is requesting AGC stream.
void UpdateAgcInfoRow();
bool ShowAgcInfoRow();
// TrayDetailedView:
void HandleViewClicked(views::View* view) override;
void CreateExtraTitleRowButtons() override;
// SodaInstaller::Observer:
void OnSodaInstalled(speech::LanguageCode language_code) override;
void OnSodaInstallError(speech::LanguageCode language_code,
speech::SodaInstaller::ErrorCode error_code) override;
void OnSodaProgress(speech::LanguageCode language_code,
int combined_progress) override;
// CrasAudioHandler::AudioObserver:
void OnOutputMuteChanged(bool mute_on) override;
void OnInputMuteChanged(
bool mute_on,
CrasAudioHandler::InputMuteChangeMethod method) override;
void OnInputMutedByMicrophoneMuteSwitchChanged(bool muted) override;
std::unique_ptr<MicGainSliderController> mic_gain_controller_;
std::unique_ptr<UnifiedVolumeSliderController>
unified_volume_slider_controller_;
AudioDeviceList output_devices_;
AudioDeviceList input_devices_;
AudioDeviceViewMap device_map_;
std::optional<uint64_t> focused_device_id_;
int num_stream_ignore_ui_gains_ = 0;
// Owned by the views hierarchy.
raw_ptr<HoverHighlightView> live_caption_view_ = nullptr;
raw_ptr<views::ImageView> live_caption_icon_ = nullptr;
raw_ptr<Switch> live_caption_button_ = nullptr;
raw_ptr<HoverHighlightView> noise_cancellation_view_ = nullptr;
raw_ptr<views::ImageView> noise_cancellation_icon_ = nullptr;
raw_ptr<Switch> noise_cancellation_button_ = nullptr;
raw_ptr<HoverHighlightView> style_transfer_view_ = nullptr;
raw_ptr<views::ImageView> style_transfer_icon_ = nullptr;
raw_ptr<Switch> style_transfer_button_ = nullptr;
raw_ptr<views::Button> settings_button_ = nullptr;
base::ScopedObservation<SessionController, SessionObserver>
session_observation_{this};
base::ScopedObservation<apps::AppCapabilityAccessCache,
apps::AppCapabilityAccessCache::Observer>
app_capability_observation_{this};
raw_ptr<apps::AppRegistryCache> app_registry_cache_;
raw_ptr<apps::AppCapabilityAccessCache> app_capability_access_cache_;
base::WeakPtrFactory<AudioDetailedView> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_AUDIO_AUDIO_DETAILED_VIEW_H_
|