File: media_stream_capture_indicator.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 (204 lines) | stat: -rw-r--r-- 8,446 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
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
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_CAPTURE_INDICATOR_H_
#define CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_CAPTURE_INDICATOR_H_

#include <unordered_map>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/functional/function_ref.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chrome/browser/status_icons/status_icon_menu_model.h"
#include "content/public/browser/media_stream_request.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include "ui/gfx/native_widget_types.h"

namespace content {
class WebContents;
}  // namespace content

namespace gfx {
class ImageSkia;
}  // namespace gfx

class StatusIcon;

// Interface to display custom UI during screen-capture (tab/window/screen).
class MediaStreamUI {
 public:
  // Called when stream capture is stopped.
  virtual ~MediaStreamUI() = default;

  // Called when screen capture starts.
  // |stop_callback| is a callback to stop the stream.
  // |source_callback| is a callback to change the desktop capture source.
  // Returns the platform-dependent window ID for the UI, or 0 if not
  // applicable.
  // |media_ids| represent the display-surfaces whose capture has started.
  virtual gfx::NativeViewId OnStarted(
      base::OnceClosure stop_callback,
      content::MediaStreamUI::SourceCallback source_callback,
      const std::vector<content::DesktopMediaID>& media_ids) = 0;

  // Called when Region Capture starts/stops, or when the cropped area changes.
  virtual void OnRegionCaptureRectChanged(
      const std::optional<gfx::Rect>& region_capture_rect) {}
};

// Keeps track of which WebContents are capturing media streams. Used to display
// indicators (e.g. in the tab strip, via notifications) and to make resource
// allocation decisions (e.g. WebContents capturing streams are not discarded).
//
// Owned by MediaCaptureDevicesDispatcher, which is a singleton.
class MediaStreamCaptureIndicator
    : public base::RefCountedThreadSafe<MediaStreamCaptureIndicator>,
      public StatusIconMenuModel::Delegate {
 public:
  enum MediaType {
    kUnknown = 0,
    kUserMedia = 1,
    kDisplayMedia = 2,
    kAllScreensMedia = 4,
  };

  // Maps blink::mojom::MediaStreamType to MediaType.
  static MediaType GetMediaType(blink::mojom::MediaStreamType type);

  class Observer : public base::CheckedObserver {
   public:
    virtual void OnIsCapturingVideoChanged(content::WebContents* web_contents,
                                           bool is_capturing_video) {}
    virtual void OnIsCapturingAudioChanged(content::WebContents* web_contents,
                                           bool is_capturing_audio) {}
    virtual void OnIsBeingMirroredChanged(content::WebContents* web_contents,
                                          bool is_being_mirrored) {}
    virtual void OnIsCapturingTabChanged(content::WebContents* web_contents,
                                         bool is_capturing_tab) {}
    virtual void OnIsCapturingWindowChanged(content::WebContents* web_contents,
                                            bool is_capturing_window) {}
    virtual void OnIsCapturingDisplayChanged(content::WebContents* web_contents,
                                             bool is_capturing_display) {}

   protected:
    ~Observer() override;
  };

  MediaStreamCaptureIndicator();

  MediaStreamCaptureIndicator(const MediaStreamCaptureIndicator&) = delete;
  MediaStreamCaptureIndicator& operator=(const MediaStreamCaptureIndicator&) =
      delete;

  // Registers a new media stream for |web_contents| and returns an object used
  // by the content layer to notify about the state of the stream. Optionally,
  // |ui| is used to display custom UI while the stream is captured.
  std::unique_ptr<content::MediaStreamUI> RegisterMediaStream(
      content::WebContents* web_contents,
      const blink::mojom::StreamDevices& devices,
      std::unique_ptr<MediaStreamUI> ui = nullptr,
      const std::u16string application_title = std::u16string());

  // Overrides from StatusIconMenuModel::Delegate implementation.
  void ExecuteCommand(int command_id, int event_flags) override;

  // Returns true if |web_contents| is capturing user media (e.g., webcam or
  // microphone input).
  bool IsCapturingUserMedia(content::WebContents* web_contents) const;

  // Returns true if |web_contents| is capturing video (e.g., webcam).
  bool IsCapturingVideo(content::WebContents* web_contents) const;

  // Returns true if |web_contents| is capturing audio (e.g., microphone).
  bool IsCapturingAudio(content::WebContents* web_contents) const;

  // Returns true if |web_contents| itself is being mirrored (e.g., a source of
  // media for remote broadcast).
  bool IsBeingMirrored(content::WebContents* web_contents) const;

  // Returns true if |web_contents| is capturing a a tab.
  bool IsCapturingTab(content::WebContents* web_contents) const;

  // Returns true if |web_contents| is capturing a desktop window or audio.
  bool IsCapturingWindow(content::WebContents* web_contents) const;

  // Returns true if |web_contents| is capturing a display.
  bool IsCapturingDisplay(content::WebContents* web_contents) const;

  // Called to stop media capturing of the |media_type|.
  // |media_type| is underlying_type of MediaType.
  void StopMediaCapturing(content::WebContents* web_contents,
                          int media_type) const;

  // Adds/Removes observers. Observers needs to be removed during the lifetime
  // of this object.
  void AddObserver(Observer* obs) { observers_.AddObserver(obs); }
  void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); }

 private:
  class UIDelegate;
  class WebContentsDeviceUsage;
  friend class WebContentsDeviceUsage;

  friend class base::RefCountedThreadSafe<MediaStreamCaptureIndicator>;
  ~MediaStreamCaptureIndicator() override;

  // Following functions/variables are executed/accessed only on UI thread.

  // Called by WebContentsDeviceUsage when it's about to destroy itself, i.e.
  // when WebContents is being destroyed.
  void UnregisterWebContents(content::WebContents* web_contents);

  // Updates the status tray menu. Called by WebContentsDeviceUsage.
  void UpdateNotificationUserInterface();

  // Helpers to create and destroy status tray icon. Called from
  // UpdateNotificationUserInterface().
  void EnsureStatusTrayIconResources();
  void MaybeCreateStatusTrayIcon(bool audio, bool video);
  void MaybeDestroyStatusTrayIcon();

  // Gets the status icon image and the string to use as the tooltip.
  void GetStatusTrayIconInfo(bool audio,
                             bool video,
                             gfx::ImageSkia* image,
                             std::u16string* tool_tip);

  // Checks if |web_contents| or any inner WebContents in its tree is using
  // a device for capture. The type of capture is specified using |pred|.
  using WebContentsDeviceUsagePredicate =
      base::FunctionRef<bool(const WebContentsDeviceUsage*)>;
  bool CheckUsage(content::WebContents* web_contents,
                  const WebContentsDeviceUsagePredicate& pred) const;

  // Reference to our status icon - owned by the StatusTray. If null,
  // the platform doesn't support status icons.
  raw_ptr<StatusIcon> status_icon_ = nullptr;

  // A map that contains the usage counts of the opened capture devices for each
  // WebContents instance.
  std::unordered_map<content::WebContents*,
                     std::unique_ptr<WebContentsDeviceUsage>>
      usage_map_;

  // g_stop_callback_id_ is used to identify each stop_callbacks when
  // AddDevices or RemoveDevices is called. We need this because the device_id
  // are not unique.
  static int g_stop_callback_id_;

  // A vector which maps command IDs to their associated WebContents
  // instance. This is rebuilt each time the status tray icon context menu is
  // updated.
  typedef std::vector<raw_ptr<content::WebContents, VectorExperimental>>
      CommandTargets;
  CommandTargets command_targets_;

  base::ObserverList<Observer, /* check_empty =*/true> observers_;
};

#endif  // CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_CAPTURE_INDICATOR_H_