File: preferred_audio_output_device_manager.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (134 lines) | stat: -rw-r--r-- 5,923 bytes parent folder | download | duplicates (5)
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
// 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 CONTENT_BROWSER_RENDERER_HOST_MEDIA_PREFERRED_AUDIO_OUTPUT_DEVICE_MANAGER_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_PREFERRED_AUDIO_OUTPUT_DEVICE_MANAGER_H_

#include <map>
#include <string>
#include <vector>

#include "base/functional/callback.h"
#include "base/unguessable_token.h"
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
#include "content/public/browser/global_routing_id.h"
#include "media/base/output_device_info.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"

namespace content {

class AudioOutputDeviceSwitcher {
 public:
  virtual ~AudioOutputDeviceSwitcher() = default;

  virtual void SwitchAudioOutputDeviceId(const std::string& device_id) = 0;
};

using SetPreferredSinkIdCallback =
    base::OnceCallback<void(media::OutputDeviceStatus)>;

// This class keeps track of which frame tree each switcher belongs to,
// and applies preferred output device changes to all switchers belonging
// to a tree of a given main frame.

// It allows switching the audio output for the page, handling both
// main frames and subframes.
class CONTENT_EXPORT PreferredAudioOutputDeviceManager {
 public:
  virtual ~PreferredAudioOutputDeviceManager() = default;

  // Sets the preferred sink id for the main frame and all its subframes.
  // At this moment, all belonging to the frame tree of the main frame
  // identified by `main_frame_token` will be updated with preferred sink id.
  // `raw_device_id` is the id of the sink to be set as the preferred sink. It
  // is a raw device id, which could be acquired by
  // AudioOutputAuthorizationHandler.
  // `callback` is the callback to be called with the status of the sink id set.
  virtual void SetPreferredSinkId(
      const GlobalRenderFrameHostToken& main_frame_token,
      const std::string& raw_device_id,
      SetPreferredSinkIdCallback callback) = 0;
  // Adds the device switcher to the device switchers list.
  // `main_frame_token` is the token of the main frame to whose frame tree
  // the device switcher belongs.
  // `device_switcher` is the device switcher to be added to the device
  // switchers list. The caller should call the RemoveSwitcher API if the
  // device switcher is no longer needed or the object is being destroyed
  // in order to prevent dangling pointers.
  virtual void AddSwitcher(const GlobalRenderFrameHostToken& main_frame_token,
                           AudioOutputDeviceSwitcher* device_switcher) = 0;

  // Removes the device switcher from the device switchers list.
  // `main_frame_token` is the token of the main frame to whose frame tree
  // the device switcher belongs.
  // `device_switcher` is the device switcher to be removed from the
  // device switchers list.
  // It is expected that the API is called with the same parameters of
  // AddSwitcher().
  virtual void RemoveSwitcher(
      const GlobalRenderFrameHostToken& main_frame_token,
      AudioOutputDeviceSwitcher* device_switcher) = 0;

  // Returns the preferred device id for the frame if it is
  // registered, or an empty device id otherwise.
  // `main_frame_token` is the token of the main frame to whose frame tree
  // the device switcher belongs.
  virtual const std::string& GetPreferredSinkId(
      const GlobalRenderFrameHostToken& main_frame_token) = 0;

  // Unregisters the main frame and all its subframes with their switchers.
  // `render_frame_host` is the frame for which the entry is to be
  // removed. It is expected that it is the main frame,
  // otherwise it does nothing. It should be called from the UI thread.
  virtual void UnregisterMainFrameOnUIThread(
      RenderFrameHost* render_frame_host) = 0;
};

// The class is expected to be created and destroyed on the IO thread as
// as singleton per the browser instance.

// Threading model: Most of the APIs are expected to be called on the IO thread
// except for the `UnregisterMainFrameOnUIThread` which is on the UI thread.
class CONTENT_EXPORT PreferredAudioOutputDeviceManagerImpl final
    : public PreferredAudioOutputDeviceManager {
 public:
  explicit PreferredAudioOutputDeviceManagerImpl();

  ~PreferredAudioOutputDeviceManagerImpl() override;

  void SetPreferredSinkId(const GlobalRenderFrameHostToken& main_frame_token,
                          const std::string& hashed_sink_id,
                          SetPreferredSinkIdCallback callback) override;
  void AddSwitcher(const GlobalRenderFrameHostToken& main_frame_token,
                   AudioOutputDeviceSwitcher* device_switcher) override;
  void RemoveSwitcher(const GlobalRenderFrameHostToken& main_frame_token,
                      AudioOutputDeviceSwitcher* device_switcher) override;
  const std::string& GetPreferredSinkId(
      const GlobalRenderFrameHostToken& main_frame_token) override;
  void UnregisterMainFrameOnUIThread(
      RenderFrameHost* render_frame_host) override;

 private:
  void UnregisterMainFrameOnIOThread(
      const GlobalRenderFrameHostToken& main_frame_token);
  void AddNewConfigEntry(const GlobalRenderFrameHostToken& main_frame_token,
                         const std::string& sink_id,
                         AudioOutputDeviceSwitcher* device_switcher);

  class MainFramePreferredSinkIdConfig;
  MainFramePreferredSinkIdConfig* FindSinkIdConfig(
      const GlobalRenderFrameHostToken& main_frame_token) const;

  // The MainFramePreferredSinkIdConfig list. It should
  // be accessed only in the IO thread.
  std::vector<std::unique_ptr<MainFramePreferredSinkIdConfig>>
      preferred_sink_id_configs_;

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

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_PREFERRED_AUDIO_OUTPUT_DEVICE_MANAGER_H_