File: audio_selection_notification_handler.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (169 lines) | stat: -rw-r--r-- 7,298 bytes parent folder | download | duplicates (6)
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
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_AUDIO_AUDIO_SELECTION_NOTIFICATION_HANDLER_H_
#define CHROMEOS_ASH_COMPONENTS_AUDIO_AUDIO_SELECTION_NOTIFICATION_HANDLER_H_

#include <optional>

#include "base/component_export.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/audio/audio_device.h"
#include "chromeos/ash/components/audio/audio_device_id.h"
#include "chromeos/ash/components/audio/audio_device_metrics_handler.h"
#include "chromeos/ash/components/audio/device_activate_type.h"
#include "ui/message_center/message_center.h"

namespace ash {

// A callback of CrasAudioHandler::SwitchToDevice function, used to handle the
// switch button on audio selection notification being clicked.
using SwitchToDeviceCallback =
    base::RepeatingCallback<void(const AudioDevice& device,
                                 bool notify,
                                 DeviceActivateType activate_by)>;

// A callback function to open OS Settings audio page.
using OpenSettingsAudioPageCallback = base::RepeatingCallback<void()>;

// AudioSelectionNotificationHandler handles the creation and display of the
// audio selection notification.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_AUDIO)
    AudioSelectionNotificationHandler {
 public:
  AudioSelectionNotificationHandler();
  AudioSelectionNotificationHandler(const AudioSelectionNotificationHandler&) =
      delete;
  AudioSelectionNotificationHandler& operator=(
      const AudioSelectionNotificationHandler&) = delete;
  ~AudioSelectionNotificationHandler();

  // Time delta to debounce the audio selection notification.
  static constexpr base::TimeDelta kDebounceTime = base::Milliseconds(1500);

  // The audio selection notification id, used to identify the notification
  // itself.
  static constexpr char kAudioSelectionNotificationId[] =
      "audio_selection_notification";

  // The audio selection notifier id.
  static constexpr char kAudioSelectionNotifierId[] =
      "ash.audio_selection_notification_handler";

  // Different types of audio selection notification.
  // Do not reorder since it's used in histogram metrics.
  enum class NotificationType {
    // A single audio device source with only input audio device. e.g. a web
    // cam.
    kSingleSourceWithInputOnly = 0,
    // A single audio device source with only output audio device. e.g. a HDMI
    // display.
    kSingleSourceWithOutputOnly = 1,
    // A single audio device source with both input and output audio devices.
    // e.g. a USB audio device.
    kSingleSourceWithInputAndOutput = 2,
    // Multiple audio device sources, e.g. a web cam and a HDMI display.
    kMultipleSources = 3,
    kMaxValue = kMultipleSources,
  };

  // Stores minimal info to create a notification. The device names will be
  // displayed in notification body. If the notification type is
  // kMultipleSources, device name refers to currently activated device name.
  // Otherwise, device name refers to hot plugged device name.
  struct NotificationTemplate {
    NotificationTemplate(NotificationType type,
                         std::optional<std::string> input_device_name,
                         std::optional<std::string> output_device_name);
    ~NotificationTemplate();

    NotificationType type;
    std::optional<std::string> input_device_name;
    std::optional<std::string> output_device_name;
  };

  // Creates and displays an audio selection notification to let users make the
  // switching or not switching decision.
  // TODO(b/333608911): Revisit audio selection notification after updated audio
  // sliders in quick settings.
  void ShowAudioSelectionNotification(
      const AudioDeviceList& hotplug_input_devices,
      const AudioDeviceList& hotplug_output_devices,
      const std::optional<std::string>& active_input_device_name,
      const std::optional<std::string>& active_output_device_name,
      SwitchToDeviceCallback switch_to_device_callback,
      OpenSettingsAudioPageCallback open_settings_audio_page_callback);

  // Handles the situation when a hotplugged device which triggers the
  // notification has been activated by users via settings or quick settings,
  // rather than via the switch button on notification body. Remove the
  // notification in this case.
  void RemoveNotificationIfHotpluggedDeviceActivated(
      const AudioDeviceList& activated_devices);

  // Handles the situation when a hotplugged device which triggers the
  // notification has been removed. Remove the notification in this case.
  void RemoveNotificationIfHotpluggedDeviceDisconnected(
      bool is_input,
      const AudioDeviceList& current_devices);

 private:
  // Grant friend access for comprehensive testing of private/protected members.
  friend class AudioSelectionNotificationHandlerTest;

  // Handles when the switch button is clicked.
  void HandleSwitchButtonClicked(
      const AudioDeviceList& devices_to_activate,
      SwitchToDeviceCallback switch_to_device_callback,
      NotificationType notification_type,
      std::optional<int> button_index);

  // Handles when the settings button is clicked. |open_settigns_callback| is
  // the callback to open the system settings audio page. |button_index|
  // indicates the index of the button on notification body that is clicked.
  void HandleSettingsButtonClicked(
      OpenSettingsAudioPageCallback open_settigns_callback,
      std::optional<int> button_index);

  // Checks if one audio input device and one audio output device belong to the
  // same physical audio device.
  bool AudioNodesBelongToSameSource(const AudioDevice& input_device,
                                    const AudioDevice& output_device);

  // Gets necessary information to create and display notitification, such as
  // notitication type and device name.
  NotificationTemplate GetNotificationTemplate(
      const AudioDeviceList& hotplug_input_devices,
      const AudioDeviceList& hotplug_output_devices,
      const std::optional<std::string>& active_input_device_name,
      const std::optional<std::string>& active_output_device_name);

  // A helper function to determine notification type and show notification.
  void ShowNotification(
      const std::optional<std::string>& active_input_device_name,
      const std::optional<std::string>& active_output_device_name,
      SwitchToDeviceCallback switch_to_device_callback,
      OpenSettingsAudioPageCallback open_settings_audio_page_callback);

  // Handles firing of audio selection related metrics.
  AudioDeviceMetricsHandler audio_device_metrics_handler_;

  // The hotplugged devices that trigger the notification. Clear the list if the
  // notification is removed.
  AudioDeviceList hotplug_input_devices_;
  AudioDeviceList hotplug_output_devices_;

  // Used to debounce the notification.
  base::RetainingOneShotTimer show_notification_debounce_timer_;

  base::WeakPtrFactory<AudioSelectionNotificationHandler> weak_ptr_factory_{
      this};
};

}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_AUDIO_AUDIO_SELECTION_NOTIFICATION_HANDLER_H_