910e62b5创建于 1月15日历史提交
// Copyright 2016 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_DEVICES_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_DEVICES_DISPATCHER_HOST_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/types/expected.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/media/media_devices_util.h"
#include "content/browser/renderer_host/media/media_devices_manager.h"
#include "content/common/content_export.h"
#include "content/public/browser/select_audio_output_request.h"
#include "content/public/common/buildflags.h"
#include "media/base/scoped_async_trace.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "media/capture/video/video_capture_device_descriptor.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
#include "url/origin.h"

namespace content {

class AudioOutputAuthorizationHandler;
class MediaStreamManager;

class CONTENT_EXPORT MediaDevicesDispatcherHost
    : public blink::mojom::MediaDevicesDispatcherHost {
 public:
  MediaDevicesDispatcherHost(
      const GlobalRenderFrameHostToken& main_frame_host_token,
      GlobalRenderFrameHostId render_frame_host_id,
      MediaStreamManager* media_stream_manager);

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

  ~MediaDevicesDispatcherHost() override;

  static void Create(
      const GlobalRenderFrameHostToken& main_frame_host_token,
      GlobalRenderFrameHostId render_frame_host_id,
      MediaStreamManager* media_stream_manager,
      mojo::PendingReceiver<blink::mojom::MediaDevicesDispatcherHost> receiver);

  // blink::mojom::MediaDevicesDispatcherHost implementation.
  void EnumerateDevices(bool request_audio_input,
                        bool request_video_input,
                        bool request_audio_output,
                        bool request_video_input_capabilities,
                        bool request_audio_input_capabilities,
                        EnumerateDevicesCallback client_callback) override;
  void GetVideoInputCapabilities(
      GetVideoInputCapabilitiesCallback client_callback) override;
  void GetAllVideoInputDeviceFormats(
      const std::string& device_id,
      GetAllVideoInputDeviceFormatsCallback client_callback) override;
  void GetAvailableVideoInputDeviceFormats(
      const std::string& device_id,
      GetAvailableVideoInputDeviceFormatsCallback client_callback) override;
  void GetAudioInputCapabilities(
      GetAudioInputCapabilitiesCallback client_callback) override;

  void SelectAudioOutput(const std::string& hashed_device_id,
                         SelectAudioOutputCallback callback) override;

  void AddMediaDevicesListener(
      bool subscribe_audio_input,
      bool subscribe_video_input,
      bool subscribe_audio_output,
      mojo::PendingRemote<blink::mojom::MediaDevicesListener> listener)
      override;
  void SetCaptureHandleConfig(
      blink::mojom::CaptureHandleConfigPtr config) override;

#if BUILDFLAG(ENABLE_SCREEN_CAPTURE)
  void CloseFocusWindowOfOpportunity(const std::string& label) override;
  void ProduceSubCaptureTargetId(
      media::mojom::SubCaptureTargetType type,
      ProduceSubCaptureTargetIdCallback callback) override;
#endif  // BUILDFLAG(ENABLE_SCREEN_CAPTURE)

  void SetPreferredSinkId(const std::string& hashed_sink_id,
                          SetPreferredSinkIdCallback callback) override;

 private:
  void OnGotTransientUserActivationResult(const std::string& hashed_device_id,
                                          bool has_user_activation);

  void OnAudioOutputPermissionResult(const std::string& hashed_device_id,
                                     MediaDevicesManager::PermissionDeniedState
                                         speaker_selection_permission_state,
                                     bool has_microphone_permission);

  void OnGotSaltAndOriginForAudioOutput(
      const std::string& hashed_device_id,
      bool has_microphone_permission,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  void OnEnumeratedAudioOutputDevices(
      const std::string& hashed_device_id,
      bool has_microphone_permission,
      const MediaDeviceSaltAndOrigin& salt_and_origin,
      const MediaDeviceEnumeration& enumeration);

  void OnAvailableAudioOutputDevices(
      const std::string& device_id,
      const MediaDeviceEnumeration& enumeration);

  void OnSelectedDeviceInfo(MediaDeviceEnumeration enumeration,
                            base::expected<std::string, SelectAudioOutputError>
                                selected_device_id_or_error);

  void FinalizeSelectAudioOutput(
      MediaDeviceEnumeration enumeration,
      const std::string& selected_device_id,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  blink::mojom::SelectAudioOutputResultPtr CreateSelectAudioOutputResult(
      const blink::WebMediaDeviceInfo& device_info,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  friend class MediaDevicesDispatcherHostTest;

  using GetVideoInputDeviceFormatsCallback =
      GetAllVideoInputDeviceFormatsCallback;

  void OnVideoGotSaltAndOrigin(
      GetVideoInputCapabilitiesCallback client_callback,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  void AuthorizationCompleted(
      std::unique_ptr<AudioOutputAuthorizationHandler> authorization_handler,
      SetPreferredSinkIdCallback callback,
      media::OutputDeviceStatus status,
      const media::AudioParameters&,
      const std::string& raw_device_id,
      const std::string& device_id_for_renderer);

  std::unique_ptr<AudioOutputAuthorizationHandler> CreateAuthorizationHandler();

  void FinalizeGetVideoInputCapabilities(
      GetVideoInputCapabilitiesCallback client_callback,
      const MediaDeviceSaltAndOrigin& salt_and_origin,
      const MediaDeviceEnumeration& enumeration);

  void OnAudioGotSaltAndOrigin(
      GetAudioInputCapabilitiesCallback client_callback,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  void GotAudioInputEnumeration(const MediaDeviceEnumeration& enumeration);

  void GotAudioInputParameters(
      size_t index,
      const std::optional<media::AudioParameters>& parameters);

  void FinalizeGetAudioInputCapabilities();

  using ScopedMediaStreamTrace =
      media::TypedScopedAsyncTrace<media::TraceCategory::kMediaStream>;

  void GetVideoInputDeviceFormats(
      const std::string& hashed_device_id,
      bool try_in_use_first,
      GetVideoInputDeviceFormatsCallback client_callback,
      std::unique_ptr<ScopedMediaStreamTrace> scoped_trace,
      const MediaDeviceSaltAndOrigin& salt_and_origin);

  void GetVideoInputDeviceFormatsWithRawId(
      const std::string& hashed_device_id,
      bool try_in_use_first,
      GetVideoInputDeviceFormatsCallback client_callback,
      std::unique_ptr<ScopedMediaStreamTrace> scoped_trace,
      const std::optional<std::string>& raw_id);

  void ReceivedBadMessage(int render_process_id,
                          bad_message::BadMessageReason reason);

  using AuthorizationHandlerCreateFactoryCallback = base::RepeatingCallback<
      std::unique_ptr<AudioOutputAuthorizationHandler>()>;

  void SetBadMessageCallbackForTesting(
      base::RepeatingCallback<void(int, bad_message::BadMessageReason)>
          callback);

  void SetCaptureHandleConfigCallbackForTesting(
      base::RepeatingCallback<
          void(int, int, blink::mojom::CaptureHandleConfigPtr)> callback);

  void SetAuthorizationForTesting(
      AuthorizationHandlerCreateFactoryCallback authorization_handler);

  // The following const fields can be accessed on any thread.
  const GlobalRenderFrameHostToken main_frame_host_token_;

  // The following const fields can be accessed on any thread.
  const GlobalRenderFrameHostId render_frame_host_id_;

  // The following fields can only be accessed on the IO thread.
  const raw_ptr<MediaStreamManager> media_stream_manager_;

  SelectAudioOutputCallback select_audio_output_callback_;

  struct AudioInputCapabilitiesRequest;
  // Queued requests for audio-input capabilities.
  std::vector<AudioInputCapabilitiesRequest>
      pending_audio_input_capabilities_requests_;
  size_t num_pending_audio_input_parameters_;
  std::vector<blink::mojom::AudioInputDeviceCapabilities>
      current_audio_input_capabilities_;

  std::vector<uint32_t> subscription_ids_;

  base::RepeatingCallback<void(int, bad_message::BadMessageReason)>
      bad_message_callback_for_testing_;

  base::RepeatingCallback<void(int, int, blink::mojom::CaptureHandleConfigPtr)>
      capture_handle_config_callback_for_testing_;

  // The callback to create AudioOutputAuthorizationHandler.
  AuthorizationHandlerCreateFactoryCallback
      authorization_handler_factory_callback_;

  base::WeakPtrFactory<MediaDevicesDispatcherHost> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_DEVICES_DISPATCHER_HOST_H_