// Copyright 2013 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_WEBRTC_WEBRTC_INTERNALS_H_
#define CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_

#include <memory>
#include <string>
#include <unordered_set>

#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/process/process.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/peer_connection_tracker_host_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "ui/shell_dialogs/select_file_dialog.h"

namespace media {
class AudioDebugRecordingSession;
}

namespace content {

class WebContents;
class WebRtcInternalsConnectionsObserver;
class WebRTCInternalsUIObserver;

// This is a singleton class running in the browser UI thread.
// It collects peer connection infomation from the renderers,
// forwards the data to WebRTCInternalsUIObserver and
// sends data collecting commands to the renderers.
class CONTENT_EXPORT WebRTCInternals : public PeerConnectionTrackerHostObserver,
                                       public RenderProcessHostObserver,
                                       public ui::SelectFileDialog::Listener {
 public:
  // * CreateSingletonInstance() ensures that no previous instantiation of the
  //   class was performed, then instantiates the class and returns the object.
  // * GetInstance() returns the object previously constructed using
  //   CreateSingletonInstance(). It may return null in tests.
  // * Creation is separated from access because WebRTCInternals may only be
  //   created from a context that allows blocking. If GetInstance were allowed
  //   to instantiate, as with a lazily constructed singleton, it would be
  //   difficult to guarantee that its construction is always first attempted
  //   from a context that allows it.
  static WebRTCInternals* CreateSingletonInstance();
  static WebRTCInternals* GetInstance();

  ~WebRTCInternals() override;

  // PeerConnectionTrackerHostObserver implementation.
  void OnPeerConnectionAdded(GlobalRenderFrameHostId frame_id,
                             int lid,
                             base::ProcessId pid,
                             const std::string& url,
                             const std::string& rtc_configuration) override;
  void OnPeerConnectionRemoved(GlobalRenderFrameHostId frame_id,
                               int lid) override;
  void OnPeerConnectionUpdated(GlobalRenderFrameHostId frame_id,
                               int lid,
                               const std::string& type,
                               const std::string& value) override;
  void OnAddStandardStats(GlobalRenderFrameHostId frame_id,
                          int lid,
                          base::Value::List value) override;
  void OnGetUserMedia(GlobalRenderFrameHostId frame_id,
                      base::ProcessId pid,
                      int request_id,
                      bool audio,
                      bool video,
                      const std::string& audio_constraints,
                      const std::string& video_constraints) override;
  void OnGetUserMediaSuccess(GlobalRenderFrameHostId frame_id,
                             base::ProcessId pid,
                             int request_id,
                             const std::string& stream_id,
                             const std::string& audio_track_info,
                             const std::string& video_track_info) override;
  void OnGetUserMediaFailure(GlobalRenderFrameHostId frame_id,
                             base::ProcessId pid,
                             int request_id,
                             const std::string& error,
                             const std::string& error_message) override;

  void OnGetDisplayMedia(GlobalRenderFrameHostId frame_id,
                         base::ProcessId pid,
                         int request_id,
                         bool audio,
                         bool video,
                         const std::string& audio_constraints,
                         const std::string& video_constraints) override;
  void OnGetDisplayMediaSuccess(GlobalRenderFrameHostId frame_id,
                                base::ProcessId pid,
                                int request_id,
                                const std::string& stream_id,
                                const std::string& audio_track_info,
                                const std::string& video_track_info) override;
  void OnGetDisplayMediaFailure(GlobalRenderFrameHostId frame_id,
                                base::ProcessId pid,
                                int request_id,
                                const std::string& error,
                                const std::string& error_message) override;

  // Methods for adding or removing WebRTCInternalsUIObserver.
  void AddObserver(WebRTCInternalsUIObserver* observer);
  void RemoveObserver(WebRTCInternalsUIObserver* observer);

  // Methods for adding or removing WebRtcInternalsConnectionsObserver.
  // |observer| is notified when there is a change in the count of active WebRTC
  // connections.
  void AddConnectionsObserver(WebRtcInternalsConnectionsObserver* observer);
  void RemoveConnectionsObserver(WebRtcInternalsConnectionsObserver* observer);

  // Sends all update data to |observer|.
  void UpdateObserver(WebRTCInternalsUIObserver* observer);

  // Enables or disables diagnostic audio recordings for debugging purposes.
  void EnableAudioDebugRecordings(content::WebContents* web_contents);
  void DisableAudioDebugRecordings();

  bool IsAudioDebugRecordingsEnabled() const;
  const base::FilePath& GetAudioDebugRecordingsFilePath() const;

  // Enables or disables diagnostic event log.
  void EnableLocalEventLogRecordings(content::WebContents* web_contents);
  void DisableLocalEventLogRecordings();

  void EnableDataChannelRecordings(content::WebContents* web_contents);
  void DisableDataChannelRecordings();

  bool IsEventLogRecordingsEnabled() const;
  bool CanToggleEventLogRecordings() const;

  bool IsDataChannelRecordingsEnabled() const;

  int num_connected_connections() const { return num_connected_connections_; }

 protected:
  // Constructor/Destructor are protected to allow tests to derive from the
  // class and do per-instance testing without having to use the global
  // instance.
  // The default ctor sets |aggregate_updates_ms| to 500ms.
  WebRTCInternals();
  WebRTCInternals(int aggregate_updates_ms, bool should_block_power_saving);

  mojo::Remote<device::mojom::WakeLock> wake_lock_;

 private:
  FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest,
                           CallWithAudioDebugRecordings);
  FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest,
                           CallWithAudioDebugRecordingsEnabledThenDisabled);
  FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest,
                           TwoCallsWithAudioDebugRecordings);
  FRIEND_TEST_ALL_PREFIXES(WebRtcInternalsTest,
                           AudioDebugRecordingsFileSelectionCanceled);

  static WebRTCInternals* g_webrtc_internals;

  enum class SelectionType {
    kRtcEventLogs,
    kAudioDebugRecordings,
    kDataChannelRecordings,
  };

  void SendUpdate(const std::string& event_name, base::Value event_data);
  void SendUpdate(const std::string& event_name, base::Value::Dict event_data);

  // RenderProcessHostObserver implementation.
  void RenderProcessExited(RenderProcessHost* host,
                           const ChildProcessTerminationInfo& info) override;

  void MaybeShowSelectFileDialog(content::WebContents* web_contents,
                                 SelectionType log_type);
  // ui::SelectFileDialog::Listener implementation.
  void FileSelected(const ui::SelectedFileInfo& file, int index) override;
  void FileSelectionCanceled() override;

  // Called when a renderer exits (including crashes).
  void OnRendererExit(int render_process_id);

  // Enables diagnostic audio recordings on all render process hosts using
  // |audio_debug_recordings_file_path_|.
  void EnableAudioDebugRecordingsOnAllRenderProcessHosts();

  void EnableDataChannelRecordingsOnAllRenderProcessHosts();

  // Updates the number of open PeerConnections. Called when a PeerConnection
  // is stopped or removed.
  void MaybeClosePeerConnection(base::Value& record);

  void MaybeMarkPeerConnectionAsConnected(base::Value& record);
  void MaybeMarkPeerConnectionAsNotConnected(base::Value& record);

  // Called whenever a PeerConnection is created or stopped in order to
  // request/cancel a wake lock on suspending the current application for power
  // saving.
  void UpdateWakeLock();

  // Convenient method to access `peer_connection_data_` as a Value::List.
  base::Value::List& peer_connection_data() {
    return peer_connection_data_.GetList();
  }

  device::mojom::WakeLock* GetWakeLock();

  // Called on a timer to deliver updates to javascript.
  // We throttle and bulk together updates to avoid DOS like scenarios where
  // a page uses a lot of peerconnection instances with many event
  // notifications.
  void ProcessPendingUpdates();

  // Returns an iterator for peer_connection_data_.GetList (an end() iterator
  // if not found).
  base::Value::List::iterator FindRecord(GlobalRenderFrameHostId frame_id,
                                         int lid);

  base::ObserverList<WebRTCInternalsUIObserver>::Unchecked observers_;

  base::ObserverList<WebRtcInternalsConnectionsObserver> connections_observers_;

  // |peer_connection_data_| is a list containing all the PeerConnection
  // updates. Stored as a Value rather than as a List::Value so it can be passed
  // as a Value without having to copy it.
  //
  // Each item of the list represents the data for one PeerConnection, which
  // contains these fields:
  // "rid" -- the renderer id.
  // "pid" -- OS process id of the renderer that creates the PeerConnection.
  // "lid" -- local Id assigned to the PeerConnection.
  // "url" -- url of the web page that created the PeerConnection.
  // "rtcConfiguration" -- serialized rtcConfiguration object.
  // "constraints" -- serialized legacy peerconnection constraints.
  // used to initialize the PeerConnection respectively.
  // "log" -- a List contains all the updates for the PeerConnection. Each
  // list item is a DictionaryValue containing "time", which is the number of
  // milliseconds since epoch as a string, and "type" and "value", both of which
  // are strings representing the event.
  base::Value peer_connection_data_;

  // A list of getUserMedia requests or updates.
  // Each item is a DictionaryValue that contains some of these fields
  // depending on the type:
  // "rid" -- the renderer id.
  // "pid" -- OS process id of the renderer that creates the PeerConnection.
  // "origin" -- the security origin of the request.
  // "audio" -- the serialized audio constraints if audio is requested.
  // "video" -- the serialized video constraints if video is requested.
  // "timestamp" -- time of the request
  // "stream_id" -- the resulting stream id.
  // "audio_track_info" -- the serialized audio track (track id and label).
  // "video_track_info" -- the serialized video track (track id and label).
  base::Value::List get_user_media_requests_;

  // For managing select file dialog.
  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
  SelectionType selection_type_;

  // Diagnostic audio recording state.
  base::FilePath audio_debug_recordings_file_path_;
  std::unique_ptr<media::AudioDebugRecordingSession>
      audio_debug_recording_session_;

  // If non-empty, WebRTC (local) event logging should be enabled using this
  // path, and may not be turned off, except by restarting the browser.
  const base::FilePath command_line_derived_logging_path_;

  // Diagnostic event log recording state. These are meaningful only when
  // |command_line_derived_logging_path_| is empty.
  bool event_log_recordings_;
  base::FilePath event_log_recordings_file_path_;

  bool data_channel_recording_active_ = false;
  // If `data_channel_recording_active_` is `true`, the following path indicates
  // where logs are stored. If `data_channel_recording_active_` is `false`, then
  // should it ever be turned on, a path picker will be shown to the user, and
  // the following path indicates the initial path suggested by that picker.
  base::FilePath data_channel_recordings_file_path_;

  // While |num_connected_connections_| is greater than zero, request a wake
  // lock service. This prevents the application from being suspended while
  // remoting.
  int num_connected_connections_;
  const bool should_block_power_saving_;

  // Set of render process hosts that |this| is registered as an observer on.
  std::unordered_set<int> render_process_id_set_;

  // Used to bulk up updates that we send to javascript.
  // The class owns the value/dictionary and command name of an update.
  // For each update, a PendingUpdate is stored in the |pending_updates_| queue
  // and deleted as soon as the update has been delivered.
  // The class is moveble and not copyable to avoid copying while still allowing
  // us to use an stl container without needing scoped_ptr or similar.
  // The class is single threaded, so all operations must occur on the same
  // thread.
  class PendingUpdate {
   public:
    PendingUpdate(const std::string& event_name, base::Value event_data);
    PendingUpdate(PendingUpdate&& other);

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

    ~PendingUpdate();

    const std::string& event_name() const;
    const base::Value* event_data() const;

   private:
    base::ThreadChecker thread_checker_;
    const std::string event_name_;
    base::Value event_data_;
  };

  base::queue<PendingUpdate> pending_updates_;
  const int aggregate_updates_ms_;

  // Weak factory for this object that we use for bulking up updates.
  base::WeakPtrFactory<WebRTCInternals> weak_factory_{this};

  // Helper functions for getUserMedia/getDisplayMedia.
  void OnGetMedia(const std::string& request_type,
                  GlobalRenderFrameHostId frame_id,
                  base::ProcessId pid,
                  int request_id,
                  bool audio,
                  bool video,
                  const std::string& audio_constraints,
                  const std::string& video_constraints);
  void OnGetMediaSuccess(const std::string& request_type,
                         GlobalRenderFrameHostId frame_id,
                         base::ProcessId pid,
                         int request_id,
                         const std::string& stream_id,
                         const std::string& audio_track_info,
                         const std::string& video_track_info);
  void OnGetMediaFailure(const std::string& request_type,
                         GlobalRenderFrameHostId frame_id,
                         base::ProcessId pid,
                         int request_id,
                         const std::string& error,
                         const std::string& error_message);
};

}  // namespace content

#endif  // CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_
