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 234 235 236 237 238 239 240
|
// 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 CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_DISPATCHER_HOST_H_
#include <string>
#include <utility>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/media/media_devices_util.h"
#include "content/browser/media/media_stream_web_contents_observer.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
namespace content {
class MediaStreamManager;
// MediaStreamDispatcherHost is a delegate for Media Stream API messages used by
// MediaStreamImpl. There is one MediaStreamDispatcherHost per
// RenderFrameHost, the former owned by the latter.
class CONTENT_EXPORT MediaStreamDispatcherHost
: public blink::mojom::MediaStreamDispatcherHost {
public:
MediaStreamDispatcherHost(GlobalRenderFrameHostId render_frame_host_id,
MediaStreamManager* media_stream_manager);
MediaStreamDispatcherHost(const MediaStreamDispatcherHost&) = delete;
MediaStreamDispatcherHost& operator=(const MediaStreamDispatcherHost&) =
delete;
~MediaStreamDispatcherHost() override;
static void Create(
GlobalRenderFrameHostId render_frame_host_id,
MediaStreamManager* media_stream_manager,
mojo::PendingReceiver<blink::mojom::MediaStreamDispatcherHost> receiver);
void OnWebContentsFocused();
void set_get_salt_and_origin_cb_for_testing(
GetMediaDeviceSaltAndOriginCallback callback) {
get_salt_and_origin_cb_ = std::move(callback);
}
void SetMediaStreamDeviceObserverForTesting(
mojo::PendingRemote<blink::mojom::MediaStreamDeviceObserver> observer) {
media_stream_device_observer_.Bind(std::move(observer));
}
private:
friend class MediaStreamDispatcherHostTest;
friend class MockMediaStreamDispatcherHost;
FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherHostMultiCaptureTest,
NoRenderFrameHostMultiCaptureNotAllowed);
FRIEND_TEST_ALL_PREFIXES(
MediaStreamDispatcherHostMultiCaptureTest,
RenderFrameHostExistsButNoPolicySetMultiCaptureNotAllowed);
FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherHostMultiCaptureTest,
PolicySetMultiCaptureAllowed);
struct GenerateStreamsUIThreadCheckResult {
bool request_allowed = false;
MediaDeviceSaltAndOrigin salt_and_origin;
};
struct PendingAccessRequest;
using RequestsQueue =
base::circular_deque<std::unique_ptr<PendingAccessRequest>>;
RequestsQueue pending_requests_;
// Performs checks / computations that need to be done on the UI
// thread (i.e. if a select all screens request is permitted and
// the computation of the device salt and origin).
static void GenerateStreamsChecksOnUIThread(
GlobalRenderFrameHostId render_frame_host_id,
bool request_all_screens,
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback);
static void CheckRequestAllScreensAllowed(
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback,
GlobalRenderFrameHostId render_frame_host_id);
static void CheckStreamsPermissionResultReceived(
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback,
bool result);
const mojo::Remote<blink::mojom::MediaStreamDeviceObserver>&
GetMediaStreamDeviceObserver();
void OnMediaStreamDeviceObserverConnectionError();
void CancelAllRequests();
// mojom::MediaStreamDispatcherHost implementation
void GenerateStreams(
int32_t request_id,
const blink::StreamControls& controls,
bool user_gesture,
blink::mojom::StreamSelectionInfoPtr audio_stream_selection_info_ptr,
GenerateStreamsCallback callback) override;
void CancelRequest(int32_t request_id) override;
void StopStreamDevice(
const std::string& device_id,
const std::optional<base::UnguessableToken>& session_id) override;
void OpenDevice(int32_t request_id,
const std::string& device_id,
blink::mojom::MediaStreamType type,
OpenDeviceCallback callback) override;
void CloseDevice(const std::string& label) override;
void SetCapturingLinkSecured(
const std::optional<base::UnguessableToken>& session_id,
blink::mojom::MediaStreamType type,
bool is_secure) override;
using KeepDeviceAliveForTransferCallback =
base::OnceCallback<void(bool device_found)>;
void KeepDeviceAliveForTransfer(
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
KeepDeviceAliveForTransferCallback callback) override;
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
void FocusCapturedSurface(const std::string& label, bool focus) override;
void ApplySubCaptureTarget(const base::UnguessableToken& session_id,
media::mojom::SubCaptureTargetType type,
const base::Token& sub_capture_target,
uint32_t sub_capture_target_version,
ApplySubCaptureTargetCallback callback) override;
void SendWheel(const base::UnguessableToken& session_id,
blink::mojom::CapturedWheelActionPtr action) override;
void UpdateZoomLevel(const base::UnguessableToken& session_id,
blink::mojom::ZoomLevelAction action,
UpdateZoomLevelCallback callback) override;
void RequestCapturedSurfaceControlPermission(
const base::UnguessableToken& session_id,
RequestCapturedSurfaceControlPermissionCallback callback) override;
void OnSubCaptureTargetValidationComplete(
const base::UnguessableToken& session_id,
media::mojom::SubCaptureTargetType type,
const base::Token& target,
uint32_t sub_capture_target_version,
ApplySubCaptureTargetCallback callback,
bool target_passed_validation);
#endif
void GetOpenDevice(int32_t page_request_id,
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
GetOpenDeviceCallback callback) override;
void DoGetOpenDevice(int32_t page_request_id,
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
GetOpenDeviceCallback callback,
const MediaDeviceSaltAndOrigin& salt_and_origin);
void DoGenerateStreams(
int32_t request_id,
const blink::StreamControls& controls,
bool user_gesture,
blink::mojom::StreamSelectionInfoPtr audio_stream_selection_info_ptr,
GenerateStreamsCallback callback,
GenerateStreamsUIThreadCheckResult ui_check_result);
void DoOpenDevice(int32_t request_id,
const std::string& device_id,
blink::mojom::MediaStreamType type,
OpenDeviceCallback callback,
const MediaDeviceSaltAndOrigin& salt_and_origin);
void OnDeviceStopped(const std::string& label,
const blink::MediaStreamDevice& device);
void OnDeviceChanged(const std::string& label,
const blink::MediaStreamDevice& old_device,
const blink::MediaStreamDevice& new_device);
void OnDeviceRequestStateChange(
const std::string& label,
const blink::MediaStreamDevice& device,
const blink::mojom::MediaStreamStateChange new_state);
void OnDeviceCaptureConfigurationChange(
const std::string& label,
const blink::MediaStreamDevice& device);
void OnDeviceCaptureHandleChange(const std::string& label,
const blink::MediaStreamDevice& device);
void OnZoomLevelChange(const std::string& label,
const blink::MediaStreamDevice& device,
int zoom_level);
void SetWebContentsObserver(
std::unique_ptr<MediaStreamWebContentsObserver,
BrowserThread::DeleteOnUIThread> web_contents_observer);
// If valid, std::nullopt is returned.
// If invalid, the relevant BadMessageReason is returned.
std::optional<bad_message::BadMessageReason>
ValidateControlsForGenerateStreams(const blink::StreamControls& controls);
void ReceivedBadMessage(int render_process_id,
bad_message::BadMessageReason reason);
void SetBadMessageCallbackForTesting(
base::RepeatingCallback<void(int, bad_message::BadMessageReason)>
callback);
static int next_requester_id_;
const GlobalRenderFrameHostId render_frame_host_id_;
const int requester_id_;
raw_ptr<MediaStreamManager> media_stream_manager_;
mojo::Remote<blink::mojom::MediaStreamDeviceObserver>
media_stream_device_observer_;
GetMediaDeviceSaltAndOriginCallback get_salt_and_origin_cb_;
std::unique_ptr<MediaStreamWebContentsObserver,
BrowserThread::DeleteOnUIThread>
web_contents_observer_;
base::RepeatingCallback<void(int, bad_message::BadMessageReason)>
bad_message_callback_for_testing_;
base::WeakPtrFactory<MediaStreamDispatcherHost> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_DISPATCHER_HOST_H_
|